From 8679cd68d825bfe28ba0c833494c415bcfa6d8f6 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Sun, 8 Apr 2012 12:32:17 -0400 Subject: scripts/library: introduce parseopts This will replace our current options parser used in pacman-key, makepkg, and ideally elsewhere. It follows heuristics closer to that of GNU getopt long (and thus pacman itself), with the exception that it does not allow for options with optional arguments. Due to the way this parser will be used, this sort of functionality will not be needed. Instead of relying on eval+set, options are normalized into an array, OPTRET, which callers should expect to be populated after returning from parseopts. This avoids problems with quotes and spaces in arguments, assuming that the user quotes properly when passing into the application. A new test harness for parseopts is added in test/scripts. Signed-off-by: Dave Reisner --- scripts/library/README | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'scripts/library/README') diff --git a/scripts/library/README b/scripts/library/README index 1e9c962b..f43873f3 100644 --- a/scripts/library/README +++ b/scripts/library/README @@ -13,3 +13,23 @@ A getopt replacement to avoids portability issues, in particular the lack of long option name support in the default getopt provided by some platforms. Usage: parse_option $SHORT_OPTS $LONG_OPTS "$@" + +parseopts.sh: +A getopt_long-like parser which portably supports longopts and shortopts +with some GNU extensions. It does not allow for options with optional +arguments. For both short and long opts, options requiring an argument +should be suffixed with a colon. After the first argument containing +the short opts, any number of valid long opts may be be passed. The end +of the options delimiter must then be added, followed by the user arguments +to the calling program. + +Reccommended Usage: + OPT_SHORT='fb:z' + OPT_LONG=('foo' 'bar:' 'baz') + if ! parseopts "$OPT_SHORT" "${OPT_LONG[@]}" -- "$@"; then + exit 1 + fi + set -- "${OPTRET[@]}" +Returns: + 0: parse success + 1: parse failure (error message supplied) -- cgit v1.2.3-70-g09d2 From 00ab01e6342b7183d5a16ae57497b19dc1c2c7dc Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Sun, 8 Apr 2012 15:12:27 -0400 Subject: scripts/library: remove parse_options This is retired, as the two consumers of this function are now using the new parseopts instead. Signed-off-by: Dave Reisner --- scripts/Makefile.am | 3 +- scripts/library/README | 6 --- scripts/library/parse_options.sh | 105 --------------------------------------- scripts/po/POTFILES.in | 1 - 4 files changed, 1 insertion(+), 114 deletions(-) delete mode 100644 scripts/library/parse_options.sh (limited to 'scripts/library/README') diff --git a/scripts/Makefile.am b/scripts/Makefile.am index fc70732f..b8a19900 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -27,8 +27,7 @@ EXTRA_DIST = \ LIBRARY = \ library/output_format.sh \ - library/parseopts.sh \ - library/parse_options.sh + library/parseopts.sh # Files that should be removed, but which Automake does not know. MOSTLYCLEANFILES = $(bin_SCRIPTS) diff --git a/scripts/library/README b/scripts/library/README index f43873f3..c71c0714 100644 --- a/scripts/library/README +++ b/scripts/library/README @@ -8,12 +8,6 @@ and can be silenced by defining 'QUIET'. The 'warning' and 'error' functions print to stderr with the appropriate prefix added to the message. -parse_options.sh: -A getopt replacement to avoids portability issues, in particular the -lack of long option name support in the default getopt provided by some -platforms. -Usage: parse_option $SHORT_OPTS $LONG_OPTS "$@" - parseopts.sh: A getopt_long-like parser which portably supports longopts and shortopts with some GNU extensions. It does not allow for options with optional diff --git a/scripts/library/parse_options.sh b/scripts/library/parse_options.sh deleted file mode 100644 index 039eef92..00000000 --- a/scripts/library/parse_options.sh +++ /dev/null @@ -1,105 +0,0 @@ -# getopt like parser -parse_options() { - local short_options=$1; shift; - local long_options=$1; shift; - local ret=0; - local unused_options="" - local i - - while [[ -n $1 ]]; do - if [[ ${1:0:2} = '--' ]]; then - if [[ -n ${1:2} ]]; then - local match="" - for i in ${long_options//,/ }; do - if [[ ${1:2} = ${i//:} ]]; then - match=$i - break - fi - done - if [[ -n $match ]]; then - local needsargument=0 - - [[ ${match} = ${1:2}: ]] && needsargument=1 - [[ ${match} = ${1:2}:: && -n $2 && ${2:0:1} != "-" ]] && needsargument=1 - - if (( ! needsargument )); then - printf ' %s' "$1" - else - if [[ -n $2 ]]; then - printf ' %s ' "$1" - shift - printf "'%q" "$1" - while [[ -n $2 && ${2:0:1} != "-" ]]; do - shift - printf " %q" "$1" - done - printf "'" - else - printf "@SCRIPTNAME@: $(gettext "option %s requires an argument\n")" "'$1'" >&2 - ret=1 - fi - fi - else - echo "@SCRIPTNAME@: $(gettext "unrecognized option") '$1'" >&2 - ret=1 - fi - else - shift - break - fi - elif [[ ${1:0:1} = '-' ]]; then - for ((i=1; i<${#1}; i++)); do - if [[ $short_options =~ ${1:i:1} ]]; then - local needsargument=0 - - [[ $short_options =~ ${1:i:1}: && ! $short_options =~ ${1:i:1}:: ]] && needsargument=1 - [[ $short_options =~ ${1:i:1}:: && \ - ( -n ${1:$i+1} || ( -n $2 && ${2:0:1} != "-" ) ) ]] && needsargument=1 - - if (( ! needsargument )); then - printf ' -%s' "${1:i:1}" - else - if [[ -n ${1:$i+1} ]]; then - printf ' -%s ' "${1:i:1}" - printf "'%q" "${1:$i+1}" - while [[ -n $2 && ${2:0:1} != "-" ]]; do - shift - printf " %q" "$1" - done - printf "'" - else - if [[ -n $2 ]]; then - printf ' -%s ' "${1:i:1}" - shift - printf "'%q" "$1" - while [[ -n $2 && ${2:0:1} != "-" ]]; do - shift - printf " %q" "$1" - done - printf "'" - - else - printf "@SCRIPTNAME@: $(gettext "option %s requires an argument\n")" "'-${1:i:1}'" >&2 - ret=1 - fi - fi - break - fi - else - echo "@SCRIPTNAME@: $(gettext "unrecognized option") '-${1:i:1}'" >&2 - ret=1 - fi - done - else - unused_options="${unused_options} '$1'" - fi - shift - done - - printf " --" - [[ $unused_options ]] && printf ' %s' "${unused_options[@]}" - [[ $1 ]] && printf " '%s'" "$@" - printf "\n" - - return $ret -} diff --git a/scripts/po/POTFILES.in b/scripts/po/POTFILES.in index 01cc235f..162731b9 100644 --- a/scripts/po/POTFILES.in +++ b/scripts/po/POTFILES.in @@ -8,5 +8,4 @@ scripts/pacman-optimize.sh.in scripts/pkgdelta.sh.in scripts/repo-add.sh.in scripts/library/output_format.sh -scripts/library/parse_options.sh scripts/library/parseopts.sh -- cgit v1.2.3-70-g09d2