1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
# Test the getopts builtin.
%prep
test_getopts() {
local OPTARG OPTIND opt
local -a res
while getopts abc: opt 2>&1; do
[[ $opt == [?:] ]] || res+=( $opt )
done
(( $#res )) && print -r -- $res
return $(( $#res ? 0 : 1 ))
}
%test
test_getopts
1:no arguments
test_getopts foo
1:one operand
test_getopts -a
0:one option
>a
test_getopts -a foo
0:one option, one operand
>a
test_getopts -a foo -b
0:one option, two operands, leading hyphen
>a
test_getopts -ab
0:two options, single argument
>a b
test_getopts -a -b
0:two options, separate arguments
>a b
test_getopts -a -b +a
0:three options, + variant
>a b +a
test_getopts -cx
0:one option with value, single argument
>c
test_getopts +cx
0:one option with value, single argument, + variant
>+c
test_getopts -c x
0:one option with value, separate arguments
>c
test_getopts -acx
0:two options, one with value, single argument
>a c
test_getopts -ac x
0:two options, one with value, separate arguments
>a c
test_getopts -c
1:one option missing value
>test_getopts:3: argument expected after -c option
test_getopts +c
1:one option missing value, + variant
>test_getopts:3: argument expected after +c option
test_getopts -x
1:one illegal option
>test_getopts:3: bad option: -x
test_getopts +x
1:one illegal option, + variant
>test_getopts:3: bad option: +x
set -- -x
OPTIND=1
while getopts x: opt; do
echo "$opt,${OPTARG:-Empty}"
done
0:missing option-argument (error message mode)
>?,Empty
?(eval):3: argument expected after -x option
set -- -x
OPTIND=1
while getopts :x: opt; do
echo "$opt,${OPTARG:-Empty}"
done
0:missing option-argument (quiet mode)
>:,x
# This function is written so it can be easily referenced against other shells
t() {
local o i=0 n=$1
shift
while [ $i -lt $n ]; do
i=$(( i + 1 ))
getopts a: o "$@" 2> /dev/null
done
printf '<%d>' "$OPTIND"
}
# Try all these the native way, then the POSIX_BUILTINS way
for 1 in no_posix_builtins posix_builtins; do (
setopt $1
print -rn - "$1: "
t 1
t 1 foo
t 1 -- foo
t 1 -a
t 1 -b
t 2 -a -b
t 4 -a -b -c -d -a
t 5 -a -b -c -a -b -c
t 5 -a -b -c -d -ax -a
print
); done
0:OPTIND calculation with and without POSIX_BUILTINS (workers/42248)
>no_posix_builtins: <1><1><2><1><1><3><5><7><6>
>posix_builtins: <1><1><2><2><2><3><6><7><7>
for 1 in no_posix_builtins posix_builtins; do (
setopt $1
print -rn - $1:
set -- -a -b +b -c
while getopts :abc opt; do
case $opt in
a|b|+b|c) print -rn - " $opt" ;;
?) print -rn - " ?$OPTARG" ;;
esac
done
print
); done
0:POSIX_BUILTINS disables '+' variant handling
>no_posix_builtins: a b +b c
>posix_builtins: a b
(
setopt no_posix_builtins
for 1 in -a +a -x +x; do
() { local opt; getopts :abc opt; print -r - $opt } $1
done
for 1 in -a +a -x +x; do
() { local opt; getopts -p :abc opt; print -r - $opt } $1
done
)
0:-p works like POSIX_BUILTINS
>a
>+a
>?
>?
>a
>
>?
>
# not enough arguments
() { getopts }
() { getopts '' }
() { getopts x }
() { getopts - x }
() { getopts -p - x }
() { getopts -p -- x }
# invalid option to getopts
() { getopts -x x }
() { getopts -x x y }
() { getopts -x - x y }
# guarded spec
() { getopts - -x y }
# argv on command line
() { getopts x y a b c }
-:option parsing
?(anon):getopts: not enough arguments
?(anon):getopts: not enough arguments
?(anon):getopts: not enough arguments
?(anon):getopts: not enough arguments
?(anon):getopts: not enough arguments
?(anon):getopts: not enough arguments
?(anon):getopts: bad option: -x
?(anon):getopts: bad option: -x
?(anon):getopts: bad option: -x
|