[pacman-dev] [PATCH] Added the function parse_options to replace getopt
Yun Zheng Hu
yunzheng.hu at gmail.com
Wed Nov 19 18:43:30 EST 2008
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 at 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
More information about the pacman-dev
mailing list