1 /* vi: set sw=4 ts=4: */
3 * universal getopt32 implementation for busybox
5 * Copyright (C) 2003-2005 Vladimir Oleynik <dzo@simtreas.ru>
7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
16 getopt32(char **argv, const char *applet_opts, ...)
18 The command line options must be declared in const char
19 *applet_opts as a string of chars, for example:
21 flags = getopt32(argv, "rnug");
23 If one of the given options is found, a flag value is added to
24 the return value (an unsigned long).
26 The flag value is determined by the position of the char in
27 applet_opts string. For example, in the above case:
29 flags = getopt32(argv, "rnug");
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)
36 and so on. You can also look at the return value as a bit
37 field and each option sets one bit.
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]).
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:
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;
55 flags = getopt32(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);
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 opt_complementary (see below for more info).
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.
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:
73 Here we want env to process just the '-i', not the '-d'.
75 const char *applet_long_options
77 This struct allows you to define long options:
79 static const char applet_longopts[] ALIGN1 =
80 //"name\0" has_arg val
81 "verbose\0" No_argument "v"
83 applet_long_options = applet_longopts;
85 The last member of struct option (val) typically is set to
86 matching short option from applet_opts. If there is no matching
87 char in applet_opts, then:
88 - return bit have next position after short options
89 - if has_arg is not "No_argument", use ptr for arg also
90 - opt_complementary affects it too
92 Note: a good applet will make long options configurable via the
93 config process and not a required feature. The current standard
94 is to name the config option CONFIG_FEATURE_<applet>_LONG_OPTIONS.
96 const char *opt_complementary
98 ":" The colon (":") is used to separate groups of two or more chars
99 and/or groups of chars and special characters (stating some
100 conditions to be checked).
102 "abc" If groups of two or more chars are specified, the first char
103 is the main option and the other chars are secondary options.
104 Their flags will be turned on if the main option is found even
105 if they are not specifed on the command line. For example:
107 opt_complementary = "abc";
108 flags = getopt32(argv, "abcd")
110 If getopt() finds "-a" on the command line, then
111 getopt32's return value will be as if "-a -b -c" were
114 "ww" Adjacent double options have a counter associated which indicates
115 the number of occurences of the option.
116 For example the ps applet needs:
117 if w is given once, GNU ps sets the width to 132,
118 if w is given more than once, it is "unlimited"
120 int w_counter = 0; // must be initialized!
121 opt_complementary = "ww";
122 getopt32(argv, "w", &w_counter);
124 width = (w_counter == 1) ? 132 : INT_MAX;
126 get_terminal_width(...&width...);
128 w_counter is a pointer to an integer. It has to be passed to
129 getopt32() after all other option argument sinks.
131 For example: accept multiple -v to indicate the level of verbosity
132 and for each -b optarg, add optarg to my_b. Finally, if b is given,
133 turn off c and vice versa:
135 llist_t *my_b = NULL;
136 int verbose_level = 0;
137 opt_complementary = "vv:b::b-c:c-b";
138 f = getopt32(argv, "vb:c", &my_b, &verbose_level);
139 if (f & 2) // -c after -b unsets -b flag
140 while (my_b) { dosomething_with(my_b->data); my_b = my_b->link; }
141 if (my_b) // but llist is stored if -b is specified
143 if (verbose_level) printf("verbose level is %d\n", verbose_level);
147 "-" A dash as the first char in a opt_complementary group forces
148 all arguments to be treated as options, even if they have
149 no leading dashes. Next char in this case can't be a digit (0-9),
150 use ':' or end of line. For example:
152 opt_complementary = "-:w-x:x-w";
153 getopt32(argv, "wx");
155 Allows any arguments to be given without a dash (./program w x)
156 as well as with a dash (./program -x).
158 "--" A double dash at the beginning of opt_complementary means the
159 argv[1] string should always be treated as options, even if it isn't
160 prefixed with a "-". This is useful for special syntax in applets
161 such as "ar" and "tar":
164 "-N" A dash as the first char in a opt_complementary group followed
165 by a single digit (0-9) means that at least N non-option
166 arguments must be present on the command line
168 "=N" An equal sign as the first char in a opt_complementary group followed
169 by a single digit (0-9) means that exactly N non-option
170 arguments must be present on the command line
172 "?N" A "?" as the first char in a opt_complementary group followed
173 by a single digit (0-9) means that at most N arguments must be present
176 "V-" An option with dash before colon or end-of-line results in
177 bb_show_usage being called if this option is encountered.
178 This is typically used to implement "print verbose usage message
181 "a-b" A dash between two options causes the second of the two
182 to be unset (and ignored) if it is given on the command line.
184 [FIXME: what if they are the same? like "x-x"? Is it ever useful?]
187 The du applet has the options "-s" and "-d depth". If
188 getopt32 finds -s, then -d is unset or if it finds -d
189 then -s is unset. (Note: busybox implements the GNU
190 "--max-depth" option as "-d".) To obtain this behavior, you
191 set opt_complementary = "s-d:d-s". Only one flag value is
192 added to getopt32's return value depending on the
193 position of the options on the command line. If one of the
194 two options requires an argument pointer (":" in applet_opts
195 as in "d:") optarg is set accordingly.
197 char *smax_print_depth;
199 opt_complementary = "s-d:d-s:x-x";
200 opt = getopt32(argv, "sd:x", &smax_print_depth);
203 max_print_depth = atoi(smax_print_depth);
205 printf("Detected odd -x usage\n");
207 "a--b" A double dash between two options, or between an option and a group
208 of options, means that they are mutually exclusive. Unlike
209 the "-" case above, an error will be forced if the options
213 The cut applet must have only one type of list specified, so
214 -b, -c and -f are mutually exclusive and should raise an error
215 if specified together. In this case you must set
216 opt_complementary = "b--cf:c--bf:f--bc". If two of the
217 mutually exclusive options are found, getopt32 will call
218 bb_show_usage() and die.
220 "x--x" Variation of the above, it means that -x option should occur
223 "a+" A plus after a char in opt_complementary means that the parameter
224 for this option is a nonnegative integer. It will be processed
225 with xatoi_u() - allowed range is 0..INT_MAX.
227 int param; // "unsigned param;" will also work
228 opt_complementary = "p+";
229 getopt32(argv, "p:", ¶m);
231 "a::" A double colon after a char in opt_complementary means that the
232 option can occur multiple times. Each occurrence will be saved as
233 a llist_t element instead of char*.
236 The grep applet can have one or more "-e pattern" arguments.
237 In this case you should use getopt32() as follows:
239 llist_t *patterns = NULL;
241 (this pointer must be initializated to NULL if the list is empty
242 as required by llist_add_to_end(llist_t **old_head, char *new_item).)
244 opt_complementary = "e::";
246 getopt32(argv, "e:", &patterns);
247 $ grep -e user -e root /etc/passwd
248 root:x:0:0:root:/root:/bin/bash
249 user:x:500:500::/home/user:/bin/bash
251 "a?b" A "?" between an option and a group of options means that
252 at least one of them is required to occur if the first option
253 occurs in preceding command line arguments.
255 For example from "id" applet:
257 // Don't allow -n -r -rn -ug -rug -nug -rnug
258 opt_complementary = "r?ug:n?ug:u--g:g--u";
259 flags = getopt32(argv, "rnug");
261 This example allowed only:
262 $ id; id -u; id -g; id -ru; id -nu; id -rg; id -ng; id -rnu; id -rng
264 "X" A opt_complementary group with just a single letter means
265 that this option is required. If more than one such group exists,
266 at least one option is required to occur (not all of them).
267 For example from "start-stop-daemon" applet:
269 // Don't allow -KS -SK, but -S or -K is required
270 opt_complementary = "K:S:K--S:S--K";
271 flags = getopt32(argv, "KS...);
274 Don't forget to use ':'. For example, "?322-22-23X-x-a"
275 is interpreted as "?3:22:-2:2-2:2-3Xa:2--x" -
276 max 3 args; count uses of '-2'; min 2 args; if there is
277 a '-2' option then unset '-3', '-X' and '-a'; if there is
278 a '-2' and after it a '-x' then error out.
279 But it's far too obfuscated. Use ':' to separate groups.
282 /* Code here assumes that 'unsigned' is at least 32 bits wide */
284 const char *const bb_argv_dash[] = { "-", NULL };
286 const char *opt_complementary;
288 /* Many small applets don't want to suck in stdio.h only because
289 * they need to parse options by calling us */
290 #define DONT_USE_PRINTF 1
299 unsigned char opt_char;
303 unsigned incongruously;
305 void **optarg; /* char**, llist_t** or int *. */
309 /* You can set applet_long_options for parse called long options */
310 #if ENABLE_GETOPT_LONG
311 static const struct option bb_null_long_options[1] = {
314 const char *applet_long_options;
317 uint32_t option_mask32;
320 getopt32(char **argv, const char *applet_opts, ...)
324 unsigned requires = 0;
325 t_complementary complementary[33];
327 const unsigned char *s;
328 t_complementary *on_off;
330 #if ENABLE_GETOPT_LONG
331 const struct option *l_o;
332 struct option *long_options = (struct option *) &bb_null_long_options;
339 #define SHOW_USAGE_IF_ERROR 1
340 #define ALL_ARGV_IS_OPTS 2
341 #define FIRST_ARGV_IS_OPT 4
342 #define FREE_FIRST_ARGV_IS_OPT (8 * !DONT_USE_PRINTF)
350 va_start(p, applet_opts);
353 on_off = complementary;
354 memset(on_off, 0, sizeof(complementary));
356 /* skip GNU extension */
357 s = (const unsigned char *)applet_opts;
358 if (*s == '+' || *s == '-')
363 on_off->opt_char = *s;
364 on_off->switch_on = (1 << c);
366 on_off->optarg = va_arg(p, void **);
374 #if ENABLE_GETOPT_LONG
375 if (applet_long_options) {
380 optstr = applet_long_options;
382 optstr += strlen(optstr) + 3; /* skip NUL, has_arg, val */
385 /* count == no. of longopts + 1 */
386 long_options = alloca(count * sizeof(*long_options));
387 memset(long_options, 0, count * sizeof(*long_options));
389 optstr = applet_long_options;
391 long_options[i].name = optstr;
392 optstr += strlen(optstr) + 1;
393 long_options[i].has_arg = (unsigned char)(*optstr++);
394 /* long_options[i].flag = NULL; */
395 long_options[i].val = (unsigned char)(*optstr++);
398 for (l_o = long_options; l_o->name; l_o++) {
401 for (on_off = complementary; on_off->opt_char; on_off++)
402 if (on_off->opt_char == l_o->val)
406 on_off->opt_char = l_o->val;
407 on_off->switch_on = (1 << c);
408 if (l_o->has_arg != no_argument)
409 on_off->optarg = va_arg(p, void **);
414 #endif /* ENABLE_GETOPT_LONG */
415 for (s = (const unsigned char *)opt_complementary; s && *s; s++) {
416 t_complementary *pair;
417 unsigned *pair_switch;
423 if (c < '0' || c > '9') {
424 spec_flgs |= SHOW_USAGE_IF_ERROR;
432 if (c < '0' || c > '9') {
434 spec_flgs |= FIRST_ARGV_IS_OPT;
437 spec_flgs |= ALL_ARGV_IS_OPTS;
445 min_arg = max_arg = c - '0';
449 for (on_off = complementary; on_off->opt_char; on_off++)
450 if (on_off->opt_char == *s)
452 if (c == ':' && s[2] == ':') {
453 on_off->param_type = PARAM_LIST;
456 if (c == '+' && (s[2] == ':' || s[2] == '\0')) {
457 on_off->param_type = PARAM_INT;
460 if (c == ':' || c == '\0') {
461 requires |= on_off->switch_on;
464 if (c == '-' && (s[2] == ':' || s[2] == '\0')) {
465 flags |= on_off->switch_on;
466 on_off->incongruously |= on_off->switch_on;
471 on_off->counter = va_arg(p, int *);
475 pair_switch = &(pair->switch_on);
476 for (s++; *s && *s != ':'; s++) {
478 pair_switch = &(pair->requires);
479 } else if (*s == '-') {
480 if (pair_switch == &(pair->switch_off))
481 pair_switch = &(pair->incongruously);
483 pair_switch = &(pair->switch_off);
485 for (on_off = complementary; on_off->opt_char; on_off++)
486 if (on_off->opt_char == *s) {
487 *pair_switch |= on_off->switch_on;
496 if (spec_flgs & FIRST_ARGV_IS_OPT) {
497 if (argv[1] && argv[1][0] != '-' && argv[1][1] != '\0') {
499 char *pp = alloca(strlen(argv[1]) + 2);
501 argv[1] = strcpy(pp, argv[1]);
503 argv[1] = xasprintf("-%s", argv[1]);
504 if (ENABLE_FEATURE_CLEAN_UP)
505 spec_flgs |= FREE_FIRST_ARGV_IS_OPT;
510 /* In case getopt32 was already called:
511 * reset the libc getopt() function, which keeps internal state.
513 * BSD-derived getopt() functions require that optind be set to 1 in
514 * order to reset getopt() state. This used to be generally accepted
515 * way of resetting getopt(). However, glibc's getopt()
516 * has additional getopt() state beyond optind, and requires that
517 * optind be set to zero to reset its state. So the unfortunate state of
518 * affairs is that BSD-derived versions of getopt() misbehave if
519 * optind is set to 0 in order to reset getopt(), and glibc's getopt()
520 * will core dump if optind is set 1 in order to reset getopt().
522 * More modern versions of BSD require that optreset be set to 1 in
523 * order to reset getopt(). Sigh. Standards, anyone?
527 #else /* BSD style */
531 /* optarg = NULL; opterr = 0; optopt = 0; - do we need this?? */
533 /* Note: just "getopt() <= 0" will not work well for
534 * "fake" short options, like this one:
535 * wget $'-\203' "Test: test" http://kernel.org/
536 * (supposed to act as --header, but doesn't) */
537 #if ENABLE_GETOPT_LONG
538 while ((c = getopt_long(argc, argv, applet_opts,
539 long_options, NULL)) != -1) {
541 while ((c = getopt(argc, argv, applet_opts)) != -1) {
543 c &= 0xff; /* fight libc's sign extension */
545 for (on_off = complementary; on_off->opt_char != c; on_off++) {
546 /* c==0 if long opt have non NULL flag */
547 if (on_off->opt_char == '\0' && c != '\0')
550 if (flags & on_off->incongruously)
552 trigger = on_off->switch_on & on_off->switch_off;
553 flags &= ~(on_off->switch_off ^ trigger);
554 flags |= on_off->switch_on ^ trigger;
557 (*(on_off->counter))++;
558 if (on_off->param_type == PARAM_LIST) {
560 llist_add_to_end((llist_t **)(on_off->optarg), optarg);
561 } else if (on_off->param_type == PARAM_INT) {
563 //TODO: xatoi_u indirectly pulls in printf machinery
564 *(unsigned*)(on_off->optarg) = xatoi_u(optarg);
565 } else if (on_off->optarg) {
567 *(char **)(on_off->optarg) = optarg;
573 if (spec_flgs & ALL_ARGV_IS_OPTS) {
574 /* process argv is option, for example "ps" applet */
576 pargv = argv + optind;
583 goto loop_arg_is_opt;
588 #if ENABLE_FEATURE_CLEAN_UP
589 if (spec_flgs & FREE_FIRST_ARGV_IS_OPT)
592 /* check depending requires for given options */
593 for (on_off = complementary; on_off->opt_char; on_off++) {
594 if (on_off->requires && (flags & on_off->switch_on) &&
595 (flags & on_off->requires) == 0)
598 if (requires && (flags & requires) == 0)
601 if (argc < min_arg || (max_arg >= 0 && argc > max_arg))
604 option_mask32 = flags;