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 |
|