[pacman-dev] [PATCH] Added the function parse_options to replace getopt
Allan McRae
allan at archlinux.org
Tue Nov 18 20:46:02 EST 2008
Yun Zheng Hu wrote:
> 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;
>
I need to go through this more fully but this seems OK to me. One
comment: you should probably change the GETOPT GO BANG! stuff to
something like "PARSE_OPTIONS FAILED", or preferably handle the error
return properly.
Allan
More information about the pacman-dev
mailing list