|
8 | 8 | Options:
|
9 | 9 | --speed=<kn> Speed in knots [default: 10]."
|
10 | 10 | # docopt parser below, refresh this parser with `docopt.sh naval_fate.patched.sh`
|
11 |
| -# shellcheck disable=2016,1075 |
| 11 | +# shellcheck disable=2016,2086,2317,1075 |
12 | 12 | docopt() { parse() { if ${DOCOPT_DOC_CHECK:-true}; then local doc_hash;if \
|
13 | 13 | doc_hash=$(printf "%s" "$DOC" | (sha256sum 2>/dev/null || shasum -a 256)); then
|
14 | 14 | if [[ ${doc_hash:0:5} != "$digest" ]]; then stderr "The current usage doc \
|
15 | 15 | (${doc_hash:0:5}) does not match what the parser was generated with (${digest})
|
16 | 16 | Run \`docopt.sh\` to refresh the parser.";_return 70;fi;fi;fi;local root_idx=$1
|
17 |
| -shift;argv=("$@");parsed=();left=();testdepth=0;local arg i o;while [[ \ |
18 |
| -${#argv[@]} -gt 0 ]]; do if [[ ${argv[0]} = "--" ]]; then for arg in \ |
19 |
| -"${argv[@]}"; do parsed+=("a:$arg");done;break;elif [[ ${argv[0]} = --* ]]; then |
20 |
| -local long=${argv[0]%%=*};local similar=() match=false;i=0;for o in \ |
21 |
| -"${options[@]}"; do if [[ $o = *" $long "? ]]; then similar+=("$long");match=$i |
22 |
| -break;fi;: $((i++));done;if [[ $match = false ]]; then i=0;for o in \ |
23 |
| -"${options[@]}"; do if [[ $o = *" $long"*? ]]; then local long_match=${o#* } |
24 |
| -similar+=("${long_match% *}");match=$i;fi;: $((i++));done;fi;if [[ \ |
25 |
| -${#similar[@]} -gt 1 ]]; then error "${long} is not a unique prefix: \ |
26 |
| -${similar[*]}?";elif [[ ${#similar[@]} -lt 1 ]]; then if \ |
27 |
| -${DOCOPT_ADD_HELP:-true} && [[ $long = "--help" ]]; then stdout "$trimmed_doc" |
28 |
| -_return 0;elif [[ ${DOCOPT_PROGRAM_VERSION:-false} != 'false' && $long = \ |
29 |
| -"--version" ]]; then stdout "$DOCOPT_PROGRAM_VERSION";_return 0;else error;fi |
30 |
| -else if [[ ${options[$match]} = *0 ]]; then if [[ ${argv[0]} = *=* ]]; then |
31 |
| -local long_match=${o#* };error "${long_match% *} must not have an argument";else |
32 |
| -parsed+=("$match:true");argv=("${argv[@]:1}");fi;else if [[ ${argv[0]} = *=* \ |
33 |
| -]]; then parsed+=("$match:${argv[0]#*=}");argv=("${argv[@]:1}");else if [[ \ |
34 |
| -${#argv[@]} -le 1 || ${argv[1]} = '--' ]]; then error "${long} requires \ |
35 |
| -argument";fi;parsed+=("$match:${argv[1]}");argv=("${argv[@]:2}");fi;fi;fi;elif \ |
36 |
| -[[ ${argv[0]} = -* && ${argv[0]} != "-" ]]; then local remaining=${argv[0]#-} |
37 |
| -while [[ -n $remaining ]]; do local short="-${remaining:0:1}" matched=false |
| 17 | +shift;params=();testdepth=0;local argv=("$@") arg i o;while [[ ${#argv[@]} -gt \ |
| 18 | +0 ]]; do if [[ ${argv[0]} = "--" ]]; then for arg in "${argv[@]}"; do |
| 19 | +params+=("a:$arg");done;break;elif [[ ${argv[0]} = --* ]]; then local \ |
| 20 | +long=${argv[0]%%=*};if ${DOCOPT_ADD_HELP:-true} && [[ $long = "--help" ]]; then |
| 21 | +stdout "$trimmed_doc";_return 0;elif [[ ${DOCOPT_PROGRAM_VERSION:-false} != 'f'\ |
| 22 | +'alse' && $long = "--version" ]]; then stdout "$DOCOPT_PROGRAM_VERSION" |
| 23 | +_return 0;fi;local similar=() match=false;i=0;for o in "${options[@]}"; do if \ |
| 24 | +[[ $o = *" $long "? ]]; then similar+=("$long");match=$i;break;fi;: $((i++)) |
| 25 | +done;if [[ $match = false ]]; then i=0;for o in "${options[@]}"; do if [[ $o = \ |
| 26 | +*" $long"*? ]]; then local long_match=${o#* };similar+=("${long_match% *}") |
| 27 | +match=$i;fi;: $((i++));done;fi;if [[ ${#similar[@]} -gt 1 ]]; then error \ |
| 28 | +"${long} is not a unique prefix: ${similar[*]}?";elif [[ ${#similar[@]} -lt 1 \ |
| 29 | +]]; then error;else if [[ ${options[$match]} = *0 ]]; then if [[ ${argv[0]} = \ |
| 30 | +*=* ]]; then local long_match=${o#* };error "${long_match% *} must not have an \ |
| 31 | +argument";else params+=("$match:true");argv=("${argv[@]:1}");fi;else if [[ \ |
| 32 | +${argv[0]} = *=* ]]; then params+=("$match:${argv[0]#*=}");argv=("${argv[@]:1}") |
| 33 | +else if [[ ${#argv[@]} -le 1 || ${argv[1]} = '--' ]]; then error "${long} \ |
| 34 | +requires argument";fi;params+=("$match:${argv[1]}");argv=("${argv[@]:2}");fi;fi |
| 35 | +fi;elif [[ ${argv[0]} = -* && ${argv[0]} != "-" ]]; then local \ |
| 36 | +remaining=${argv[0]#-};while [[ -n $remaining ]]; do local \ |
| 37 | +short="-${remaining:0:1}";if ${DOCOPT_ADD_HELP:-true} && [[ $short = "-h" ]]; \ |
| 38 | +then stdout "$trimmed_doc";_return 0;fi;local matched=false |
38 | 39 | remaining="${remaining:1}";i=0;for o in "${options[@]}"; do if [[ $o = "$short \
|
39 |
| -"* ]]; then if [[ $o = *0 ]]; then parsed+=("$i:true");else if [[ $remaining = \ |
40 |
| -'' ]]; then if [[ ${#argv[@]} -le 1 || ${argv[1]} = '--' ]]; then error \ |
41 |
| -"${short} requires argument";fi;parsed+=("$i:${argv[1]}");argv=("${argv[@]:1}") |
42 |
| -else parsed+=("$i:$remaining");remaining='';fi;fi;matched=true;break;fi;: \ |
43 |
| -$((i++));done;if ! $matched; then if ${DOCOPT_ADD_HELP:-true} && [[ $short = \ |
44 |
| -"-h" ]]; then stdout "$trimmed_doc";_return 0;else error;fi;fi |
45 |
| -argv=("${argv[@]:1}");done;elif ${DOCOPT_OPTIONS_FIRST:-false}; then for arg \ |
46 |
| -in "${argv[@]}"; do parsed+=("a:$arg");done;break;else parsed+=("a:${argv[0]}") |
47 |
| -argv=("${argv[@]:1}");fi;done;i=0;while [[ $i -lt ${#parsed[@]} ]]; do |
48 |
| -left+=("$i");: $((i++));done;if ! "node_$root_idx" || [ ${#left[@]} -gt 0 ]; \ |
49 |
| -then error;fi;return 0;};sequence() { local initial_left=("${left[@]}") node_idx |
50 |
| -: $((testdepth++));for node_idx in "$@"; do if ! "node_$node_idx"; then |
51 |
| -left=("${initial_left[@]}");: $((testdepth--));return 1;fi;done;if [[ \ |
52 |
| -$((--testdepth)) -eq 0 ]]; then left=("${initial_left[@]}");for node_idx in \ |
53 |
| -"$@"; do "node_$node_idx";done;fi;return 0;};choice() { local \ |
54 |
| -initial_left=("${left[@]}") best_match_idx match_count node_idx;: \ |
| 40 | +"* ]]; then if [[ $o = *1 ]]; then if [[ $remaining = '' ]]; then if [[ \ |
| 41 | +${#argv[@]} -le 1 || ${argv[1]} = '--' ]]; then error "${short} requires \ |
| 42 | +argument";fi;params+=("$i:${argv[1]}");argv=("${argv[@]:1}");break 2;else |
| 43 | +params+=("$i:$remaining");break 2;fi;else params+=("$i:true");matched=true;break |
| 44 | +fi;fi;: $((i++));done;$matched || error;done;argv=("${argv[@]:1}");elif \ |
| 45 | +${DOCOPT_OPTIONS_FIRST:-false}; then for arg in "${argv[@]}"; do |
| 46 | +params+=("a:$arg");done;break;else params+=("a:${argv[0]}") |
| 47 | +argv=("${argv[@]:1}");fi;done;if ! "node_$root_idx" || [ ${#params[@]} -gt 0 \ |
| 48 | +]; then error;fi;return 0;};sequence() { local initial_params=("${params[@]}") \ |
| 49 | +node_idx;: $((testdepth++));for node_idx in "$@"; do if ! "node_$node_idx"; then |
| 50 | +params=("${initial_params[@]}");: $((testdepth--));return 1;fi;done;if [[ \ |
| 51 | +$((--testdepth)) -eq 0 ]]; then params=("${initial_params[@]}");for node_idx \ |
| 52 | +in "$@"; do "node_$node_idx";done;fi;return 0;};choice() { local \ |
| 53 | +initial_params=("${params[@]}") best_match_idx match_count node_idx;: \ |
55 | 54 | $((testdepth++));for node_idx in "$@"; do if "node_$node_idx"; then if [[ -z \
|
56 |
| -$match_count || ${#left[@]} -lt $match_count ]]; then best_match_idx=$node_idx |
57 |
| -match_count=${#left[@]};fi;fi;left=("${initial_left[@]}");done;if [[ -n \ |
| 55 | +$match_count || ${#params[@]} -lt $match_count ]]; then best_match_idx=$node_idx |
| 56 | +match_count=${#params[@]};fi;fi;params=("${initial_params[@]}");done;if [[ -n \ |
58 | 57 | $best_match_idx ]]; then if [[ $((--testdepth)) -eq 0 ]]; then
|
59 |
| -"node_$best_match_idx";fi;return 0;fi;left=("${initial_left[@]}");return 1;} |
| 58 | +"node_$best_match_idx";fi;return 0;fi;params=("${initial_params[@]}");return 1;} |
60 | 59 | optional() { local node_idx;for node_idx in "$@"; do "node_$node_idx";done
|
61 |
| -return 0;};switch() { local i;for i in "${!left[@]}"; do local l=${left[$i]} |
62 |
| -if [[ ${parsed[$l]} = "$2" || ${parsed[$l]} = "$2":* ]]; then |
63 |
| -left=("${left[@]:0:$i}" "${left[@]:((i+1))}");[[ $testdepth -gt 0 ]] && return 0 |
64 |
| -if [[ $3 = true ]]; then eval "((var_$1++))" || true;else eval "var_$1=true";fi |
65 |
| -return 0;elif [[ ${parsed[$l]} = a:* && $2 = a:* ]]; then return 1;fi;done |
66 |
| -return 1;};value() { local i;for i in "${!left[@]}"; do local l=${left[$i]};if \ |
67 |
| -[[ ${parsed[$l]} = "$2":* ]]; then left=("${left[@]:0:$i}" "${left[@]:((i+1))}") |
68 |
| -[[ $testdepth -gt 0 ]] && return 0;local value;value=$(printf -- "%q" \ |
69 |
| -"${parsed[$l]#*:}");if [[ $3 = true ]]; then eval "var_$1+=($value)";else eval \ |
70 |
| -"var_$1=$value";fi;return 0;fi;done;return 1;};stdout() { printf -- "cat \ |
71 |
| -<<'EOM'\n%s\nEOM\n" "$1";};stderr() { printf -- "cat <<'EOM' >&2\n%s\nEOM\n" \ |
72 |
| -"$1";};error() { [[ -n $1 ]] && stderr "$1";stderr "$usage";_return 1;} |
73 |
| -_return() { printf -- "exit %d\n" "$1";exit "$1";};set -e |
| 60 | +return 0;};switch() { local i param;for i in "${!params[@]}"; do local \ |
| 61 | +param=${params[$i]};if [[ $param = "$2" || $param = "$2":* ]]; then |
| 62 | +params=("${params[@]:0:$i}" "${params[@]:((i+1))}");[[ $testdepth -gt 0 ]] && \ |
| 63 | +return 0;if [[ $3 = true ]]; then eval "((var_$1++))" || true;else eval \ |
| 64 | +"var_$1=true";fi;return 0;elif [[ $param = a:* && $2 = a:* ]]; then return 1;fi |
| 65 | +done;return 1;};value() { local i param;for i in "${!params[@]}"; do local \ |
| 66 | +param=${params[$i]};if [[ $param = "$2":* ]]; then params=("${params[@]:0:$i}" \ |
| 67 | +"${params[@]:((i+1))}");[[ $testdepth -gt 0 ]] && return 0;local value |
| 68 | +value=$(printf -- "%q" "${param#*:}");if [[ $3 = true ]]; then eval \ |
| 69 | +"var_$1+=($value)";else eval "var_$1=$value";fi;return 0;fi;done;return 1;} |
| 70 | +stdout() { printf -- "cat <<'EOM'\n%s\nEOM\n" "$1";};stderr() { printf -- "cat \ |
| 71 | +<<'EOM' >&2\n%s\nEOM\n" "$1";};error() { [[ -n $1 ]] && stderr "$1";stderr \ |
| 72 | +"$usage";_return 1;};_return() { printf -- "exit %d\n" "$1";exit "$1";};set -e |
74 | 73 | trimmed_doc=${DOC:0:155};usage=${DOC:12:87};digest=3873e;options=(' --speed 1')
|
75 | 74 | node_0(){ value __speed 0;};node_1(){ value _name_ a;};node_2(){ value _x_ a;}
|
76 | 75 | node_3(){ value _y_ a;};node_4(){ switch move a:move;};node_5(){ switch shoot \
|
77 |
| -a:shoot;};node_6(){ optional 0;};node_7(){ sequence 1 4 2 3 6;};node_8(){ |
78 |
| -sequence 5 2 3;};node_9(){ choice 7 8;};cat <<<' docopt_exit() { [[ -n $1 ]] \ |
79 |
| -&& printf "%s\n" "$1" >&2;printf "%s\n" "${DOC:12:87}" >&2;exit 1;}';unset \ |
80 |
| -var___speed var__name_ var__x_ var__y_ var_move var_shoot;parse 9 "$@";local \ |
81 |
| -p=${DOCOPT_PREFIX:-''};unset "${p}__speed" "${p}_name_" "${p}_x_" "${p}_y_" \ |
82 |
| -"${p}move" "${p}shoot";eval "$p"'__speed=${var___speed:-10}';eval \ |
83 |
| -"$p"'_name_=${var__name_:-}';eval "$p"'_x_=${var__x_:-}';eval \ |
84 |
| -"$p"'_y_=${var__y_:-}';eval "$p"'move=${var_move:-false}';eval \ |
85 |
| -"$p"'shoot=${var_shoot:-false}';local docopt_i=1;[[ $BASH_VERSION =~ ^4.3 ]] \ |
86 |
| -&& docopt_i=2;for ((;docopt_i>0;docopt_i--)); do declare -p "${p}__speed" \ |
87 |
| -"${p}_name_" "${p}_x_" "${p}_y_" "${p}move" "${p}shoot";done;} |
| 76 | +a:shoot;};node_6(){ sequence 1 4 2 3 7;};node_7(){ optional 0;};node_8(){ |
| 77 | +sequence 5 2 3;};node_9(){ choice 6 8;};cat <<<' docopt_exit() { [[ -n $1 ]] \ |
| 78 | +&& printf "%s\n" "$1" >&2;printf "%s\n" "${DOC:12:87}" >&2;exit 1;}';local \ |
| 79 | +varnames=(__speed _name_ _x_ _y_ move shoot) varname;for varname in \ |
| 80 | +"${varnames[@]}"; do unset "var_$varname";done;parse 9 "$@";local \ |
| 81 | +p=${DOCOPT_PREFIX:-''};for varname in "${varnames[@]}"; do unset "$p$varname" |
| 82 | +done;eval $p'__speed=${var___speed:-10};'$p'_name_=${var__name_:-};'$p'_x_=${v'\ |
| 83 | +'ar__x_:-};'$p'_y_=${var__y_:-};'$p'move=${var_move:-false};'$p'shoot=${var_sh'\ |
| 84 | +'oot:-false};';local docopt_i=1;[[ $BASH_VERSION =~ ^4.3 ]] && docopt_i=2;for \ |
| 85 | +((;docopt_i>0;docopt_i--)); do for varname in "${varnames[@]}"; do declare -p \ |
| 86 | +"$p$varname";done;done;} |
88 | 87 | # docopt parser above, complete command for generating this parser is `docopt.sh naval_fate.patched.sh`
|
89 | 88 |
|
90 | 89 | naval_fate() {
|
|
0 commit comments