72 |
env -i ls -d / |
env -i ls -d / |
73 |
Here we want env to process just the '-i', not the '-d'. |
Here we want env to process just the '-i', not the '-d'. |
74 |
|
|
75 |
|
"!" Report bad option, missing required options, |
76 |
|
inconsistent options with all-ones return value (instead of abort). |
77 |
|
|
78 |
const char *applet_long_options |
const char *applet_long_options |
79 |
|
|
80 |
This struct allows you to define long options: |
This struct allows you to define long options: |
147 |
|
|
148 |
Special characters: |
Special characters: |
149 |
|
|
150 |
"-" A dash as the first char in a opt_complementary group forces |
"-" A group consisting of just a dash forces all arguments |
151 |
all arguments to be treated as options, even if they have |
to be treated as options, even if they have no leading dashes. |
152 |
no leading dashes. Next char in this case can't be a digit (0-9), |
Next char in this case can't be a digit (0-9), use ':' or end of line. |
153 |
use ':' or end of line. For example: |
Example: |
154 |
|
|
155 |
opt_complementary = "-:w-x:x-w"; |
opt_complementary = "-:w-x:x-w"; // "-w-x:x-w" would also work, |
156 |
getopt32(argv, "wx"); |
getopt32(argv, "wx"); // but is less readable |
157 |
|
|
158 |
Allows any arguments to be given without a dash (./program w x) |
This makes it possible to use options without a dash (./program w x) |
159 |
as well as with a dash (./program -x). |
as well as with a dash (./program -x). |
160 |
|
|
161 |
NB: getopt32() will leak a small amount of memory if you use |
NB: getopt32() will leak a small amount of memory if you use |
162 |
this option! Do not use it if there is a possibility of recursive |
this option! Do not use it if there is a possibility of recursive |
163 |
getopt32() calls. |
getopt32() calls. |
164 |
|
|
165 |
"--" A double dash at the beginning of opt_complementary means the |
"--" A double dash at the beginning of opt_complementary means the |
166 |
argv[1] string should always be treated as options, even if it isn't |
argv[1] string should always be treated as options, even if it isn't |
168 |
such as "ar" and "tar": |
such as "ar" and "tar": |
169 |
tar xvf foo.tar |
tar xvf foo.tar |
170 |
|
|
171 |
NB: getopt32() will leak a small amount of memory if you use |
NB: getopt32() will leak a small amount of memory if you use |
172 |
this option! Do not use it if there is a possibility of recursive |
this option! Do not use it if there is a possibility of recursive |
173 |
getopt32() calls. |
getopt32() calls. |
174 |
|
|
175 |
"-N" A dash as the first char in a opt_complementary group followed |
"-N" A dash as the first char in a opt_complementary group followed |
176 |
by a single digit (0-9) means that at least N non-option |
by a single digit (0-9) means that at least N non-option |
314 |
} t_complementary; |
} t_complementary; |
315 |
|
|
316 |
/* You can set applet_long_options for parse called long options */ |
/* You can set applet_long_options for parse called long options */ |
317 |
#if ENABLE_GETOPT_LONG |
#if ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG |
318 |
static const struct option bb_null_long_options[1] = { |
static const struct option bb_null_long_options[1] = { |
319 |
{ 0, 0, 0, 0 } |
{ 0, 0, 0, 0 } |
320 |
}; |
}; |
330 |
unsigned flags = 0; |
unsigned flags = 0; |
331 |
unsigned requires = 0; |
unsigned requires = 0; |
332 |
t_complementary complementary[33]; /* last stays zero-filled */ |
t_complementary complementary[33]; /* last stays zero-filled */ |
333 |
|
char first_char; |
334 |
int c; |
int c; |
335 |
const unsigned char *s; |
const unsigned char *s; |
336 |
t_complementary *on_off; |
t_complementary *on_off; |
337 |
va_list p; |
va_list p; |
338 |
#if ENABLE_GETOPT_LONG |
#if ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG |
339 |
const struct option *l_o; |
const struct option *l_o; |
340 |
struct option *long_options = (struct option *) &bb_null_long_options; |
struct option *long_options = (struct option *) &bb_null_long_options; |
341 |
#endif |
#endif |
361 |
on_off = complementary; |
on_off = complementary; |
362 |
memset(on_off, 0, sizeof(complementary)); |
memset(on_off, 0, sizeof(complementary)); |
363 |
|
|
364 |
|
/* skip bbox extension */ |
365 |
|
first_char = applet_opts[0]; |
366 |
|
if (first_char == '!') |
367 |
|
applet_opts++; |
368 |
|
|
369 |
/* skip GNU extension */ |
/* skip GNU extension */ |
370 |
s = (const unsigned char *)applet_opts; |
s = (const unsigned char *)applet_opts; |
371 |
if (*s == '+' || *s == '-') |
if (*s == '+' || *s == '-') |
384 |
c++; |
c++; |
385 |
} |
} |
386 |
|
|
387 |
#if ENABLE_GETOPT_LONG |
#if ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG |
388 |
if (applet_long_options) { |
if (applet_long_options) { |
389 |
const char *optstr; |
const char *optstr; |
390 |
unsigned i, count; |
unsigned i, count; |
424 |
next_long: ; |
next_long: ; |
425 |
} |
} |
426 |
} |
} |
427 |
#endif /* ENABLE_GETOPT_LONG */ |
#endif /* ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG */ |
428 |
for (s = (const unsigned char *)opt_complementary; s && *s; s++) { |
for (s = (const unsigned char *)opt_complementary; s && *s; s++) { |
429 |
t_complementary *pair; |
t_complementary *pair; |
430 |
unsigned *pair_switch; |
unsigned *pair_switch; |
543 |
* "fake" short options, like this one: |
* "fake" short options, like this one: |
544 |
* wget $'-\203' "Test: test" http://kernel.org/ |
* wget $'-\203' "Test: test" http://kernel.org/ |
545 |
* (supposed to act as --header, but doesn't) */ |
* (supposed to act as --header, but doesn't) */ |
546 |
#if ENABLE_GETOPT_LONG |
#if ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG |
547 |
while ((c = getopt_long(argc, argv, applet_opts, |
while ((c = getopt_long(argc, argv, applet_opts, |
548 |
long_options, NULL)) != -1) { |
long_options, NULL)) != -1) { |
549 |
#else |
#else |
558 |
* is always NULL (see above) */ |
* is always NULL (see above) */ |
559 |
if (on_off->opt_char == '\0' /* && c != '\0' */) { |
if (on_off->opt_char == '\0' /* && c != '\0' */) { |
560 |
/* c is probably '?' - "bad option" */ |
/* c is probably '?' - "bad option" */ |
561 |
bb_show_usage(); |
goto error; |
562 |
} |
} |
563 |
} |
} |
564 |
if (flags & on_off->incongruously) |
if (flags & on_off->incongruously) |
565 |
bb_show_usage(); |
goto error; |
566 |
trigger = on_off->switch_on & on_off->switch_off; |
trigger = on_off->switch_on & on_off->switch_off; |
567 |
flags &= ~(on_off->switch_off ^ trigger); |
flags &= ~(on_off->switch_off ^ trigger); |
568 |
flags |= on_off->switch_on ^ trigger; |
flags |= on_off->switch_on ^ trigger; |
586 |
|
|
587 |
/* check depending requires for given options */ |
/* check depending requires for given options */ |
588 |
for (on_off = complementary; on_off->opt_char; on_off++) { |
for (on_off = complementary; on_off->opt_char; on_off++) { |
589 |
if (on_off->requires && (flags & on_off->switch_on) && |
if (on_off->requires |
590 |
(flags & on_off->requires) == 0) |
&& (flags & on_off->switch_on) |
591 |
bb_show_usage(); |
&& (flags & on_off->requires) == 0 |
592 |
|
) { |
593 |
|
goto error; |
594 |
|
} |
595 |
} |
} |
596 |
if (requires && (flags & requires) == 0) |
if (requires && (flags & requires) == 0) |
597 |
bb_show_usage(); |
goto error; |
598 |
argc -= optind; |
argc -= optind; |
599 |
if (argc < min_arg || (max_arg >= 0 && argc > max_arg)) |
if (argc < min_arg || (max_arg >= 0 && argc > max_arg)) |
600 |
bb_show_usage(); |
goto error; |
601 |
|
|
602 |
option_mask32 = flags; |
option_mask32 = flags; |
603 |
return flags; |
return flags; |
604 |
|
|
605 |
|
error: |
606 |
|
if (first_char != '!') |
607 |
|
bb_show_usage(); |
608 |
|
return (int32_t)-1; |
609 |
} |
} |