[pacman-dev] [PATCH] Added the function parse_options to replace getopt

Yun Zheng Hu yunzheng.hu at gmail.com
Tue Nov 18 18:10:14 EST 2008


This will make makepkg work properly on systems like Mac OS X, where
the default installed getopt does not handle long options.

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 |   54 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index 6dc7db4..ddcb06e 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -27,7 +27,7 @@
 # makepkg uses quite a few external programs during its execution. You
 # need to have at least the following installed for makepkg to function:
 #   awk, bsdtar (libarchive), bzip2, coreutils, fakeroot, find (findutils),
-#   getopt (util-linux), gettext, grep, gzip, openssl, sed
+#   gettext, grep, gzip, openssl, sed
 
 # gettext initialization
 export TEXTDOMAIN='pacman'
@@ -1117,6 +1117,56 @@ devel_update() {
 	fi
 }
 
+##
+#  usage : match_long_opt( $needle, $options )
+# return : matched option
+##
+match_long_opt() {
+    local needle=$1; shift
+    local matches
+    local 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_param=0
+    until [ -z "$1" ]; do
+        if [ ${1:0:2} = '--' ]; then
+            # handle long option
+            [ "$needs_param" = 1 ] && return 1
+            opt=${1:2}
+            [ -z "$opt" ] && break
+            longopt=$(match_long_opt $opt ${long_options//,/ })
+            [ ! -z "$longopt" ] && printf " %s" "--${longopt}" || return 1
+        elif [ ${1:0:1} = '-' ]; then
+            # handle short option(s)
+            [ $needs_param = 1 ] && return 1
+            opts=${1:1}
+            local param
+            local i=0
+            while [ $i -lt ${#opts} ]; do
+                opt=${opts:$((i++)):1}
+                [[ "$needs_param" = 1 ]] && param="${param}${opt}" && continue
+                [[ "$short_options" =~ "${opt}" ]] && printf " %s" "-${opt}" || return 1
+                [[ "$short_options" =~ "${opt}:" ]] && needs_param=1
+            done
+            [ ! -z "$param" ] && printf " $param" && needs_param=0
+        else
+            # handle non option
+            [ "$needs_param" = 1 ] && printf " $1" && needs_param=0
+        fi
+        shift
+    done
+    printf " --\n"
+}
+
 usage() {
 	printf "makepkg (pacman) %s\n" "$myver"
 	echo
@@ -1182,7 +1232,7 @@ 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!')"
+OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@" || echo 'GETOPT GO BANG!')"
 if echo "$OPT_TEMP" | grep -q 'GETOPT GO BANG!'; then
 	# This is a small hack to stop the script bailing with 'set -e'
 	echo; usage; exit 1 # E_INVALID_OPTION;
-- 
1.5.6.5




More information about the pacman-dev mailing list