diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2006-10-03 21:00:06 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2006-10-03 21:00:06 +0000 |
commit | 67b23e6043d8e2b30b0bf3bc105b8583c2a26db5 (patch) | |
tree | edb58560b444979051b42ab7f0c0c718f7459754 /libbb/getopt_ulflags.c | |
parent | 40920825d59874cf285390434486e88c8498d2d8 (diff) | |
download | busybox-w32-67b23e6043d8e2b30b0bf3bc105b8583c2a26db5.tar.gz busybox-w32-67b23e6043d8e2b30b0bf3bc105b8583c2a26db5.tar.bz2 busybox-w32-67b23e6043d8e2b30b0bf3bc105b8583c2a26db5.zip |
getopt_ulflags -> getopt32.
It is impossible to formulate sane ABI based on
size of ulong because it can be 32-bit or 64-bit.
Basically it means that you cannot portably use
more that 32 option chars in one call anyway...
Make it explicit.
Diffstat (limited to 'libbb/getopt_ulflags.c')
-rw-r--r-- | libbb/getopt_ulflags.c | 519 |
1 files changed, 0 insertions, 519 deletions
diff --git a/libbb/getopt_ulflags.c b/libbb/getopt_ulflags.c deleted file mode 100644 index 9d27c1f11..000000000 --- a/libbb/getopt_ulflags.c +++ /dev/null | |||
@@ -1,519 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * universal getopt_ulflags implementation for busybox | ||
4 | * | ||
5 | * Copyright (C) 2003-2005 Vladimir Oleynik <dzo@simtreas.ru> | ||
6 | * | ||
7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | ||
8 | */ | ||
9 | |||
10 | #include "libbb.h" | ||
11 | #include <getopt.h> | ||
12 | |||
13 | /* Documentation | ||
14 | |||
15 | unsigned long | ||
16 | bb_getopt_ulflags(int argc, char **argv, const char *applet_opts, ...) | ||
17 | |||
18 | The command line options must be declared in const char | ||
19 | *applet_opts as a string of chars, for example: | ||
20 | |||
21 | flags = bb_getopt_ulflags(argc, argv, "rnug"); | ||
22 | |||
23 | If one of the given options is found, a flag value is added to | ||
24 | the return value (an unsigned long). | ||
25 | |||
26 | The flag value is determined by the position of the char in | ||
27 | applet_opts string. For example, in the above case: | ||
28 | |||
29 | flags = bb_getopt_ulflags(argc, argv, "rnug"); | ||
30 | |||
31 | "r" will add 1 (bit 0) | ||
32 | "n" will add 2 (bit 1) | ||
33 | "u will add 4 (bit 2) | ||
34 | "g" will add 8 (bit 3) | ||
35 | |||
36 | and so on. You can also look at the return value as a bit | ||
37 | field and each option sets one bit. | ||
38 | |||
39 | On exit, global variable optind is set so that if you | ||
40 | will do argc -= optind; argv += optind; then | ||
41 | argc will be equal to number of remaining non-option | ||
42 | arguments, first one would be in argv[0], next in argv[1] and so on | ||
43 | (options and their parameters will be moved into argv[] | ||
44 | positions prior to argv[optind]). | ||
45 | |||
46 | ":" If one of the options requires an argument, then add a ":" | ||
47 | after the char in applet_opts and provide a pointer to store | ||
48 | the argument. For example: | ||
49 | |||
50 | char *pointer_to_arg_for_a; | ||
51 | char *pointer_to_arg_for_b; | ||
52 | char *pointer_to_arg_for_c; | ||
53 | char *pointer_to_arg_for_d; | ||
54 | |||
55 | flags = bb_getopt_ulflags(argc, argv, "a:b:c:d:", | ||
56 | &pointer_to_arg_for_a, &pointer_to_arg_for_b, | ||
57 | &pointer_to_arg_for_c, &pointer_to_arg_for_d); | ||
58 | |||
59 | The type of the pointer (char* or llist_t*) may be controlled | ||
60 | by the "::" special separator that is set in the external string | ||
61 | bb_opt_complementally (see below for more info). | ||
62 | |||
63 | "::" If option can have an *optional* argument, then add a "::" | ||
64 | after its char in applet_opts and provide a pointer to store | ||
65 | the argument. Note that optional arguments _must_ | ||
66 | immediately follow the option: -oparam, not -o param. | ||
67 | |||
68 | "+" If the first character in the applet_opts string is a plus, | ||
69 | then option processing will stop as soon as a non-option is | ||
70 | encountered in the argv array. Useful for applets like env | ||
71 | which should not process arguments to subprograms: | ||
72 | env -i ls -d / | ||
73 | Here we want env to process just the '-i', not the '-d'. | ||
74 | |||
75 | const struct option *bb_applet_long_options | ||
76 | |||
77 | This struct allows you to define long options. The syntax for | ||
78 | declaring the array is just like that of getopt's longopts. | ||
79 | (see getopt(3)) | ||
80 | |||
81 | static const struct option applet_long_options[] = { | ||
82 | //name,has_arg,flag,val | ||
83 | { "verbose", 0, 0, 'v' }, | ||
84 | { 0, 0, 0, 0 } | ||
85 | }; | ||
86 | bb_applet_long_options = applet_long_options; | ||
87 | |||
88 | The last member of struct option (val) typically is set to | ||
89 | matching short option from applet_opts. If there is no matching | ||
90 | char in applet_opts, then: | ||
91 | - return bit have next position after short options | ||
92 | - if has_arg is not "no_argument", use ptr for arg also | ||
93 | - bb_opt_complementally affects it too | ||
94 | |||
95 | Note: a good applet will make long options configurable via the | ||
96 | config process and not a required feature. The current standard | ||
97 | is to name the config option CONFIG_FEATURE_<applet>_LONG_OPTIONS. | ||
98 | |||
99 | const char *bb_opt_complementally | ||
100 | |||
101 | this should be bb_opt_complementary, but we'll just keep it as | ||
102 | bb_opt_complementally due to the Russian origins | ||
103 | |||
104 | ":" The colon (":") is used to separate groups of two or more chars | ||
105 | and/or groups of chars and special characters (stating some | ||
106 | conditions to be checked). | ||
107 | |||
108 | "abc" If groups of two or more chars are specified, the first char | ||
109 | is the main option and the other chars are secondary options. | ||
110 | Their flags will be turned on if the main option is found even | ||
111 | if they are not specifed on the command line. For example: | ||
112 | |||
113 | bb_opt_complementally = "abc"; | ||
114 | flags = bb_getopt_ulflags(argc, argv, "abcd") | ||
115 | |||
116 | If getopt() finds "-a" on the command line, then | ||
117 | bb_getopt_ulflags's return value will be as if "-a -b -c" were | ||
118 | found. | ||
119 | |||
120 | "ww" Adjacent double options have a counter associated which indicates | ||
121 | the number of occurences of the option. | ||
122 | For example the ps applet needs: | ||
123 | if w is given once, GNU ps sets the width to 132, | ||
124 | if w is given more than once, it is "unlimited" | ||
125 | |||
126 | int w_counter = 0; | ||
127 | bb_opt_complementally = "ww"; | ||
128 | bb_getopt_ulflags(argc, argv, "w", &w_counter); | ||
129 | if (w_counter) | ||
130 | width = (w_counter == 1) ? 132 : INT_MAX; | ||
131 | else | ||
132 | get_terminal_width(...&width...); | ||
133 | |||
134 | w_counter is a pointer to an integer. It has to be passed to | ||
135 | bb_getopt_ulflags() after all other option argument sinks. | ||
136 | |||
137 | For example: accept multiple -v to indicate the level of verbosity | ||
138 | and for each -b optarg, add optarg to my_b. Finally, if b is given, | ||
139 | turn off c and vice versa: | ||
140 | |||
141 | llist_t *my_b = NULL; | ||
142 | int verbose_level = 0; | ||
143 | bb_opt_complementally = "vv:b::b-c:c-b"; | ||
144 | f = bb_getopt_ulflags(argc, argv, "vb:c", &my_b, &verbose_level); | ||
145 | if (f & 2) // -c after -b unsets -b flag | ||
146 | while (my_b) { dosomething_with(my_b->data); my_b = my_b->link; } | ||
147 | if (my_b) // but llist is stored if -b is specified | ||
148 | free_llist(my_b); | ||
149 | if (verbose_level) bb_printf("verbose level is %d\n", verbose_level); | ||
150 | |||
151 | Special characters: | ||
152 | |||
153 | "-" A dash between two options causes the second of the two | ||
154 | to be unset (and ignored) if it is given on the command line. | ||
155 | |||
156 | [FIXME: what if they are the same? like "x-x"? Is it ever useful?] | ||
157 | |||
158 | For example: | ||
159 | The du applet has the options "-s" and "-d depth". If | ||
160 | bb_getopt_ulflags finds -s, then -d is unset or if it finds -d | ||
161 | then -s is unset. (Note: busybox implements the GNU | ||
162 | "--max-depth" option as "-d".) To obtain this behavior, you | ||
163 | set bb_opt_complementally = "s-d:d-s". Only one flag value is | ||
164 | added to bb_getopt_ulflags's return value depending on the | ||
165 | position of the options on the command line. If one of the | ||
166 | two options requires an argument pointer (":" in applet_opts | ||
167 | as in "d:") optarg is set accordingly. | ||
168 | |||
169 | char *smax_print_depth; | ||
170 | |||
171 | bb_opt_complementally = "s-d:d-s:x-x"; | ||
172 | opt = bb_getopt_ulflags(argc, argv, "sd:x", &smax_print_depth); | ||
173 | |||
174 | if (opt & 2) | ||
175 | max_print_depth = atoi(smax_print_depth); | ||
176 | if (opt & 4) | ||
177 | printf("Detected odd -x usage\n"); | ||
178 | |||
179 | "-" A dash as the first char in a bb_opt_complementally group forces | ||
180 | all arguments to be treated as options, even if they have | ||
181 | no leading dashes. Next char in this case can't be a digit (0-9), | ||
182 | use ':' or end of line. For example: | ||
183 | |||
184 | bb_opt_complementally = "-:w-x:x-w"; | ||
185 | bb_getopt_ulflags(argc, argv, "wx"); | ||
186 | |||
187 | Allows any arguments to be given without a dash (./program w x) | ||
188 | as well as with a dash (./program -x). | ||
189 | |||
190 | "-N" A dash as the first char in a bb_opt_complementally group followed | ||
191 | by a single digit (0-9) means that at least N non-option | ||
192 | arguments must be present on the command line | ||
193 | |||
194 | "V-" An option with dash before colon or end-of-line results in | ||
195 | bb_show_usage being called if this option is encountered. | ||
196 | This is typically used to implement "print verbose usage message | ||
197 | and exit" option. | ||
198 | |||
199 | "--" A double dash between two options, or between an option and a group | ||
200 | of options, means that they are mutually exclusive. Unlike | ||
201 | the "-" case above, an error will be forced if the options | ||
202 | are used together. | ||
203 | |||
204 | For example: | ||
205 | The cut applet must have only one type of list specified, so | ||
206 | -b, -c and -f are mutally exclusive and should raise an error | ||
207 | if specified together. In this case you must set | ||
208 | bb_opt_complementally = "b--cf:c--bf:f--bc". If two of the | ||
209 | mutually exclusive options are found, bb_getopt_ulflags's | ||
210 | return value will have the error flag set (BB_GETOPT_ERROR) so | ||
211 | that we can check for it: | ||
212 | |||
213 | if (flags & BB_GETOPT_ERROR) | ||
214 | bb_show_usage(); | ||
215 | |||
216 | "x--x" Variation of the above, it means that -x option should occur | ||
217 | at most once. | ||
218 | |||
219 | "?" A "?" as the first char in a bb_opt_complementally group means: | ||
220 | if BB_GETOPT_ERROR is detected, don't return, call bb_show_usage | ||
221 | and exit instead. Next char after '?' can't be a digit. | ||
222 | |||
223 | "?N" A "?" as the first char in a bb_opt_complementally group followed | ||
224 | by a single digit (0-9) means that at most N arguments must be present | ||
225 | on the command line. | ||
226 | |||
227 | "::" A double colon after a char in bb_opt_complementally means that the | ||
228 | option can occur multiple times. Each occurrence will be saved as | ||
229 | a llist_t element instead of char*. | ||
230 | |||
231 | For example: | ||
232 | The grep applet can have one or more "-e pattern" arguments. | ||
233 | In this case you should use bb_getopt_ulflags() as follows: | ||
234 | |||
235 | llist_t *patterns = NULL; | ||
236 | |||
237 | (this pointer must be initializated to NULL if the list is empty | ||
238 | as required by *llist_add_to(llist_t *old_head, char *new_item).) | ||
239 | |||
240 | bb_opt_complementally = "e::"; | ||
241 | |||
242 | bb_getopt_ulflags(argc, argv, "e:", &patterns); | ||
243 | $ grep -e user -e root /etc/passwd | ||
244 | root:x:0:0:root:/root:/bin/bash | ||
245 | user:x:500:500::/home/user:/bin/bash | ||
246 | |||
247 | "--" A double dash at the beginning of bb_opt_complementally means the | ||
248 | argv[1] string should always be treated as options, even if it isn't | ||
249 | prefixed with a "-". This is useful for special syntax in applets | ||
250 | such as "ar" and "tar": | ||
251 | tar xvf foo.tar | ||
252 | |||
253 | "?" An "?" between an option and a group of options means that | ||
254 | at least one of them is required to occur if the first option | ||
255 | occurs in preceding command line arguments. | ||
256 | |||
257 | For example from "id" applet: | ||
258 | |||
259 | // Don't allow -n -r -rn -ug -rug -nug -rnug | ||
260 | bb_opt_complementally = "r?ug:n?ug:?u--g:g--u"; | ||
261 | flags = bb_getopt_ulflags(argc, argv, "rnug"); | ||
262 | |||
263 | This example allowed only: | ||
264 | $ id; id -u; id -g; id -ru; id -nu; id -rg; id -ng; id -rnu; id -rng | ||
265 | |||
266 | "X" A bb_opt_complementally group with just a single letter means | ||
267 | that this option is required. If more than one such group exists, | ||
268 | at least one option is required to occur (not all of them). | ||
269 | For example from "start-stop-daemon" applet: | ||
270 | |||
271 | // Don't allow -KS -SK, but -S or -K is required | ||
272 | bb_opt_complementally = "K:S:?K--S:S--K"; | ||
273 | flags = bb_getopt_ulflags(argc, argv, "KS...); | ||
274 | |||
275 | |||
276 | Don't forget to use ':'. For example, "?322-22-23X-x-a" | ||
277 | is interpreted as "?3:22:-2:2-2:2-3Xa:2--x" - | ||
278 | max 3 args; count uses of '-2'; min 2 args; if there is | ||
279 | a '-2' option then unset '-3', '-X' and '-a'; if there is | ||
280 | a '-2' and after it a '-x' then error out. | ||
281 | */ | ||
282 | |||
283 | /* this should be bb_opt_complementary, but we'll just keep it as | ||
284 | bb_opt_complementally due to the Russian origins */ | ||
285 | const char *bb_opt_complementally; | ||
286 | |||
287 | typedef struct { | ||
288 | int opt; | ||
289 | int list_flg; | ||
290 | unsigned long switch_on; | ||
291 | unsigned long switch_off; | ||
292 | unsigned long incongruously; | ||
293 | unsigned long requires; | ||
294 | void **optarg; /* char **optarg or llist_t **optarg */ | ||
295 | int *counter; | ||
296 | } t_complementally; | ||
297 | |||
298 | /* You can set bb_applet_long_options for parse called long options */ | ||
299 | #if ENABLE_GETOPT_LONG | ||
300 | static const struct option bb_default_long_options[] = { | ||
301 | /* { "help", 0, NULL, '?' }, */ | ||
302 | { 0, 0, 0, 0 } | ||
303 | }; | ||
304 | |||
305 | const struct option *bb_applet_long_options = bb_default_long_options; | ||
306 | #endif | ||
307 | |||
308 | unsigned long | ||
309 | bb_getopt_ulflags(int argc, char **argv, const char *applet_opts, ...) | ||
310 | { | ||
311 | unsigned long flags = 0; | ||
312 | unsigned long requires = 0; | ||
313 | t_complementally complementally[sizeof(flags) * 8 + 1]; | ||
314 | int c; | ||
315 | const unsigned char *s; | ||
316 | t_complementally *on_off; | ||
317 | va_list p; | ||
318 | #if ENABLE_GETOPT_LONG | ||
319 | const struct option *l_o; | ||
320 | #endif | ||
321 | unsigned long trigger; | ||
322 | char **pargv = NULL; | ||
323 | int min_arg = 0; | ||
324 | int max_arg = -1; | ||
325 | |||
326 | #define SHOW_USAGE_IF_ERROR 1 | ||
327 | #define ALL_ARGV_IS_OPTS 2 | ||
328 | #define FIRST_ARGV_IS_OPT 4 | ||
329 | #define FREE_FIRST_ARGV_IS_OPT 8 | ||
330 | int spec_flgs = 0; | ||
331 | |||
332 | va_start(p, applet_opts); | ||
333 | |||
334 | c = 0; | ||
335 | on_off = complementally; | ||
336 | memset(on_off, 0, sizeof(complementally)); | ||
337 | |||
338 | /* skip GNU extension */ | ||
339 | s = (const unsigned char *)applet_opts; | ||
340 | if (*s == '+' || *s == '-') | ||
341 | s++; | ||
342 | for (; *s; s++) { | ||
343 | if (c >= (int)(sizeof(flags)*8)) | ||
344 | break; | ||
345 | on_off->opt = *s; | ||
346 | on_off->switch_on = (1 << c); | ||
347 | if (s[1] == ':') { | ||
348 | on_off->optarg = va_arg(p, void **); | ||
349 | do | ||
350 | s++; | ||
351 | while (s[1] == ':'); | ||
352 | } | ||
353 | on_off++; | ||
354 | c++; | ||
355 | } | ||
356 | |||
357 | #if ENABLE_GETOPT_LONG | ||
358 | for (l_o = bb_applet_long_options; l_o->name; l_o++) { | ||
359 | if (l_o->flag) | ||
360 | continue; | ||
361 | for (on_off = complementally; on_off->opt != 0; on_off++) | ||
362 | if (on_off->opt == l_o->val) | ||
363 | break; | ||
364 | if (on_off->opt == 0) { | ||
365 | if (c >= (int)(sizeof(flags)*8)) | ||
366 | break; | ||
367 | on_off->opt = l_o->val; | ||
368 | on_off->switch_on = (1 << c); | ||
369 | if (l_o->has_arg != no_argument) | ||
370 | on_off->optarg = va_arg(p, void **); | ||
371 | c++; | ||
372 | } | ||
373 | } | ||
374 | #endif /* ENABLE_GETOPT_LONG */ | ||
375 | for (s = (const unsigned char *)bb_opt_complementally; s && *s; s++) { | ||
376 | t_complementally *pair; | ||
377 | unsigned long *pair_switch; | ||
378 | |||
379 | if (*s == ':') | ||
380 | continue; | ||
381 | c = s[1]; | ||
382 | if (*s == '?') { | ||
383 | if (c < '0' || c > '9') { | ||
384 | spec_flgs |= SHOW_USAGE_IF_ERROR; | ||
385 | } else { | ||
386 | max_arg = c - '0'; | ||
387 | s++; | ||
388 | } | ||
389 | continue; | ||
390 | } | ||
391 | if (*s == '-') { | ||
392 | if (c < '0' || c > '9') { | ||
393 | if (c == '-') { | ||
394 | spec_flgs |= FIRST_ARGV_IS_OPT; | ||
395 | s++; | ||
396 | } else | ||
397 | spec_flgs |= ALL_ARGV_IS_OPTS; | ||
398 | } else { | ||
399 | min_arg = c - '0'; | ||
400 | s++; | ||
401 | } | ||
402 | continue; | ||
403 | } | ||
404 | for (on_off = complementally; on_off->opt; on_off++) | ||
405 | if (on_off->opt == *s) | ||
406 | break; | ||
407 | if (c == ':' && s[2] == ':') { | ||
408 | on_off->list_flg++; | ||
409 | continue; | ||
410 | } | ||
411 | if (c == ':' || c == '\0') { | ||
412 | requires |= on_off->switch_on; | ||
413 | continue; | ||
414 | } | ||
415 | if (c == '-' && (s[2] == ':' || s[2] == '\0')) { | ||
416 | flags |= on_off->switch_on; | ||
417 | on_off->incongruously |= on_off->switch_on; | ||
418 | s++; | ||
419 | continue; | ||
420 | } | ||
421 | if (c == *s) { | ||
422 | on_off->counter = va_arg(p, int *); | ||
423 | s++; | ||
424 | } | ||
425 | pair = on_off; | ||
426 | pair_switch = &(pair->switch_on); | ||
427 | for (s++; *s && *s != ':'; s++) { | ||
428 | if (*s == '?') { | ||
429 | pair_switch = &(pair->requires); | ||
430 | } else if (*s == '-') { | ||
431 | if (pair_switch == &(pair->switch_off)) | ||
432 | pair_switch = &(pair->incongruously); | ||
433 | else | ||
434 | pair_switch = &(pair->switch_off); | ||
435 | } else { | ||
436 | for (on_off = complementally; on_off->opt; on_off++) | ||
437 | if (on_off->opt == *s) { | ||
438 | *pair_switch |= on_off->switch_on; | ||
439 | break; | ||
440 | } | ||
441 | } | ||
442 | } | ||
443 | s--; | ||
444 | } | ||
445 | va_end (p); | ||
446 | |||
447 | #if ENABLE_AR || ENABLE_TAR | ||
448 | if (spec_flgs & FIRST_ARGV_IS_OPT) { | ||
449 | if (argv[1] && argv[1][0] != '-' && argv[1][0] != '\0') { | ||
450 | argv[1] = xasprintf("-%s", argv[1]); | ||
451 | if (ENABLE_FEATURE_CLEAN_UP) | ||
452 | spec_flgs |= FREE_FIRST_ARGV_IS_OPT; | ||
453 | } | ||
454 | } | ||
455 | #endif | ||
456 | #if ENABLE_GETOPT_LONG | ||
457 | while ((c = getopt_long(argc, argv, applet_opts, | ||
458 | bb_applet_long_options, NULL)) >= 0) { | ||
459 | #else | ||
460 | while ((c = getopt(argc, argv, applet_opts)) >= 0) { | ||
461 | #endif /* ENABLE_GETOPT_LONG */ | ||
462 | loop_arg_is_opt: | ||
463 | for (on_off = complementally; on_off->opt != c; on_off++) { | ||
464 | /* c==0 if long opt have non NULL flag */ | ||
465 | if (on_off->opt == 0 && c != 0) | ||
466 | bb_show_usage(); | ||
467 | } | ||
468 | if (flags & on_off->incongruously) { | ||
469 | if ((spec_flgs & SHOW_USAGE_IF_ERROR)) | ||
470 | bb_show_usage(); | ||
471 | flags |= BB_GETOPT_ERROR; | ||
472 | } | ||
473 | trigger = on_off->switch_on & on_off->switch_off; | ||
474 | flags &= ~(on_off->switch_off ^ trigger); | ||
475 | flags |= on_off->switch_on ^ trigger; | ||
476 | flags ^= trigger; | ||
477 | if (on_off->counter) | ||
478 | (*(on_off->counter))++; | ||
479 | if (on_off->list_flg) { | ||
480 | llist_add_to((llist_t **)(on_off->optarg), optarg); | ||
481 | } else if (on_off->optarg) { | ||
482 | *(char **)(on_off->optarg) = optarg; | ||
483 | } | ||
484 | if (pargv != NULL) | ||
485 | break; | ||
486 | } | ||
487 | |||
488 | if (spec_flgs & ALL_ARGV_IS_OPTS) { | ||
489 | /* process argv is option, for example "ps" applet */ | ||
490 | if (pargv == NULL) | ||
491 | pargv = argv + optind; | ||
492 | while (*pargv) { | ||
493 | c = **pargv; | ||
494 | if (c == '\0') { | ||
495 | pargv++; | ||
496 | } else { | ||
497 | (*pargv)++; | ||
498 | goto loop_arg_is_opt; | ||
499 | } | ||
500 | } | ||
501 | } | ||
502 | |||
503 | #if (ENABLE_AR || ENABLE_TAR) && ENABLE_FEATURE_CLEAN_UP | ||
504 | if (spec_flgs & FREE_FIRST_ARGV_IS_OPT) | ||
505 | free(argv[1]); | ||
506 | #endif | ||
507 | /* check depending requires for given options */ | ||
508 | for (on_off = complementally; on_off->opt; on_off++) { | ||
509 | if (on_off->requires && (flags & on_off->switch_on) && | ||
510 | (flags & on_off->requires) == 0) | ||
511 | bb_show_usage(); | ||
512 | } | ||
513 | if (requires && (flags & requires) == 0) | ||
514 | bb_show_usage(); | ||
515 | argc -= optind; | ||
516 | if (argc < min_arg || (max_arg >= 0 && argc > max_arg)) | ||
517 | bb_show_usage(); | ||
518 | return flags; | ||
519 | } | ||