This will make makepkg work properly on systems like Mac OS X, where the default installed getopt does not handle long options. The new parse_options function tries to behave like the original getopt command as much as possible. see also: http://www.archlinux.org/pipermail/pacman-dev/2008-May/011830.html Signed-off-by: Yun Zheng Hu <yunzheng.hu@gmail.com> --- scripts/makepkg.sh.in | 81 +++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 79 insertions(+), 2 deletions(-) diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index 6dc7db4..8e3ad25 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -1117,6 +1117,83 @@ devel_update() { fi } +## +# usage : match_long_opt( $needle, $options ) +# return : matched option +## +match_long_opt() { + local needle=$1; shift + local matches item + for item in "$@"; do + [[ "$item" =~ ^"$needle" ]] && matches="$matches $item" + done + matches=( $matches ) + [[ ${#matches[@]} == 1 ]] && echo ${matches[0]} +} + +# getopt like parser, returns 1 on error +parse_options() { + local short_options=$1; shift; + local long_options=$1; shift; + + local needs_args=0 consume_args=0 retcode=0 + local opt_args="" last_opt="" + until [ -z "$1" ]; do + local handle_opt=$((!$needs_args && !$consume_args)) + + if [[ ${1:0:2} = '--' && $handle_opt == 1 ]]; then + # handle long option + opt=${1:2} + if [ ! -z "$opt" ]; then + longopt_match=$(match_long_opt $opt ${long_options//,/ }) + longopt_real="${longopt_match/:/}" # strip possible ':' + [[ "${longopt_match}" == "${longopt_real}:" ]] && needs_args=1 + [[ ! -z "$longopt_match" ]] && printf ' --%s' "$longopt_real" || { + echo "makepkg: $(gettext "unrecognized option") '$1'" >&2 + retcode=1 + } + elif [ $consume_args == 0 ]; then + # option '--', stop parsing options + consume_args=1 + fi + elif [[ ${1:0:1} = '-' && $handle_opt == 1 ]]; then + # handle short option(s) + opts=${1:1} + local i=0 args="" + while [ $i -lt ${#opts} ]; do + opt=${opts:$((i++)):1} + [[ "$needs_args" == 1 ]] && args="${param}${opt}" && continue + [[ "$short_options" =~ "${opt}:" ]] && needs_args=1 + [[ "$short_options" =~ "${opt}" ]] && printf ' -%s' "${opt}" || { + echo "makepkg: $(gettext "invalid option") -- '$opt'" >&2 + retcode=1 + } + done + # check if the user supplied the argument directly after the option + [ ! -z "$args" ] && printf " '$param'" && needs_args=0 + else + # handle non option + [ "$needs_args" == 1 ] && printf " '$1'" && needs_args=0 + [ "$consume_args" == 1 ] && opt_args="$opt_args '$1'" + fi + last_opt="$1" + shift + done + + # check if the user forgot to supply a required argument + if [[ "$needs_args" == 1 ]]; then + if [[ ${last_opt:0:2} = '--' ]]; then + echo "makepkg: option '$last_opt' $(gettext "requires an argument")" >&2 + else + echo "makepkg: option $(gettext "requires an argument") -- '${last_opt:1}'" >&2 + fi + retcode=1 + fi + + printf " --$opt_args\n" + return $retcode +} + usage() { printf "makepkg (pacman) %s\n" "$myver" echo @@ -1182,8 +1259,8 @@ OPT_LONG="$OPT_LONG,install,log,nocolor,nobuild,rmdeps,repackage,source" OPT_LONG="$OPT_LONG,syncdeps,version,config:" # Pacman Options OPT_LONG="$OPT_LONG,noconfirm,noprogressbar" -OPT_TEMP="$(getopt -o "$OPT_SHORT" -l "$OPT_LONG" -n "$(basename "$0")" -- "$@" || echo 'GETOPT GO BANG!')" -if echo "$OPT_TEMP" | grep -q 'GETOPT GO BANG!'; then +OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@" || echo 'PARSE_OPTIONS FAILED')" +if echo "$OPT_TEMP" | grep -q 'PARSE_OPTIONS FAILED'; then # This is a small hack to stop the script bailing with 'set -e' echo; usage; exit 1 # E_INVALID_OPTION; fi -- 1.5.6.5