| 1 | #!/usr/bin/env bash
|
| 2 | #
|
| 3 | # A string processing test case copied from bash_completion.
|
| 4 |
|
| 5 | shopt -s extglob # needed for Oil, but not bash
|
| 6 |
|
| 7 | # This function shell-quotes the argument
|
| 8 | quote()
|
| 9 | {
|
| 10 | local quoted=${1//\'/\'\\\'\'}
|
| 11 | printf "'%s'" "$quoted"
|
| 12 | }
|
| 13 |
|
| 14 | # This function shell-dequotes the argument
|
| 15 | dequote()
|
| 16 | {
|
| 17 | eval printf %s "$1" 2> /dev/null
|
| 18 | }
|
| 19 |
|
| 20 | # Helper function for _parse_help and _parse_usage.
|
| 21 | __parse_options()
|
| 22 | {
|
| 23 | local option option2 i IFS=$' \t\n,/|'
|
| 24 |
|
| 25 | # Take first found long option, or first one (short) if not found.
|
| 26 | option=
|
| 27 | local -a array
|
| 28 | read -a array <<<"$1"
|
| 29 | for i in "${array[@]}"; do
|
| 30 | case "$i" in
|
| 31 | ---*) break ;;
|
| 32 | --?*) option=$i ; break ;;
|
| 33 | -?*) [[ $option ]] || option=$i ;;
|
| 34 | *) break ;;
|
| 35 | esac
|
| 36 | done
|
| 37 | [[ $option ]] || return
|
| 38 |
|
| 39 | IFS=$' \t\n' # affects parsing of the regexps below...
|
| 40 |
|
| 41 | # Expand --[no]foo to --foo and --nofoo etc
|
| 42 | if [[ $option =~ (\[((no|dont)-?)\]). ]]; then
|
| 43 | option2=${option/"${BASH_REMATCH[1]}"/}
|
| 44 | option2=${option2%%[<{().[]*}
|
| 45 | printf '%s\n' "${option2/=*/=}"
|
| 46 | option=${option/"${BASH_REMATCH[1]}"/"${BASH_REMATCH[2]}"}
|
| 47 | fi
|
| 48 |
|
| 49 | option=${option%%[<{().[]*}
|
| 50 | printf '%s\n' "${option/=*/=}"
|
| 51 | }
|
| 52 |
|
| 53 | # Parse GNU style help output of the given command.
|
| 54 | # @param $1 command; if "-", read from stdin and ignore rest of args
|
| 55 | # @param $2 command options (default: --help)
|
| 56 | #
|
| 57 | _parse_help()
|
| 58 | {
|
| 59 | eval local cmd=$( quote "$1" )
|
| 60 | local line
|
| 61 | { case $cmd in
|
| 62 | -) cat ;;
|
| 63 | *) LC_ALL=C "$( dequote "$cmd" )" ${2:---help} 2>&1 ;;
|
| 64 | esac } \
|
| 65 | | while read -r line; do
|
| 66 |
|
| 67 | [[ $line == *([[:blank:]])-* ]] || continue
|
| 68 | # transform "-f FOO, --foo=FOO" to "-f , --foo=FOO" etc
|
| 69 | while [[ $line =~ \
|
| 70 | ((^|[^-])-[A-Za-z0-9?][[:space:]]+)\[?[A-Z0-9]+\]? ]]; do
|
| 71 | line=${line/"${BASH_REMATCH[0]}"/"${BASH_REMATCH[1]}"}
|
| 72 | done
|
| 73 | __parse_options "${line// or /, }"
|
| 74 |
|
| 75 | done
|
| 76 | }
|
| 77 |
|
| 78 | "$@"
|
| 79 |
|