X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=libbb%2Fgetopt_ulflags.c;h=2e2ee0b6b6242fa5ad9d01db4a6070e3a1b7775d;hb=56b217117afe70384ea27ba9ecbe0831623e7e48;hp=8c03214a92c7fd785d653a60f48cfd97aad7fd3c;hpb=be0ed3d0b94489e08cc9280f65075c42ba80bf8c;p=oweals%2Fbusybox.git diff --git a/libbb/getopt_ulflags.c b/libbb/getopt_ulflags.c index 8c03214a9..2e2ee0b6b 100644 --- a/libbb/getopt_ulflags.c +++ b/libbb/getopt_ulflags.c @@ -110,21 +110,36 @@ const char *bb_opt_complementally bb_getopt_ulflags's return value will be as if "-a -b -c" were found. - "ww" Option have int counter usaging. For example ps applet: + "ww" Adjacent double options have a counter associated which indicates + the number of occurances of the option. + For example the ps applet needs: if w is given once, GNU ps sets the width to 132, if w is given more than once, it is "unlimited" int w_counter = 0; bb_opt_complementally = "ww"; - flags = bb_getopt_ulflags(argc, argv, "w", &w_counter); + bb_getopt_ulflags(argc, argv, "w", &w_counter); - if((flags & 1)) + if(w_counter) width = (w_counter == 1) ? 132 : INT_MAX; else get_terminal_width(...&width...); - w_counter - have counter -w usaging, must set int pointer - to bb_getopt_ulflags() after all other requires + w_counter is a pointer to an integer. It has to be passed to + bb_getopt_ulflags() after all other option argument sinks. + For example: accept multiple -v to indicate the level of verbosity and + for each -b optarg, add optarg to my_b. Finally, if b is given, turn off + c and vice versa: + + llist_t *my_b = NULL; + int verbose_level = 0; + bb_opt_complementally = "vv:b*:b-c:c-b"; + f = bb_getopt_ulflags(argc, argv, "vb:c", &my_b, &verbose_level); + if((f & 2)) // -c after -b unset this -b flag + while (my_b) { dosomething_with(my_b->data) ; my_b = my_b->link; } + if(my_b) // but llist stored always if -b found + free_llist(my_b); + if (verbose_level) bb_printf("verbose level is %d\n", verbose_level); Special characters: @@ -155,6 +170,16 @@ Special characters: if(opt & 4) printf("Detected odd -x usaging\n"); + "-" A minus as the first char in a bb_opt_complementally group means to + convert the arguments as option. + For example: + + bb_opt_complementally = "-:w-x:x-w"; + bb_getopt_ulflags(argc, argv, "wx"); + + Allows any arguments to be given without a dash (./program w x) + as well as with a dash (./program -x). Why unset -w see above. + "~" A tilde between two options, or between an option and a group of options, means that they are mutually exclusive. Unlike the "-" case above, an error will be forced if the options @@ -227,6 +252,9 @@ bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...) va_list p; const struct option *l_o; char flg_show_usage_if_error = 0; + char flg_argv_is_opts = 0; + unsigned long trigger; + char **pargv = NULL; va_start (p, applet_opts); @@ -294,6 +322,10 @@ bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...) flg_show_usage_if_error = '!'; continue; } + if(*s == '-') { + flg_argv_is_opts = '-'; + continue; + } for (on_off = complementally; on_off->opt; on_off++) if (on_off->opt == *s) break; @@ -304,17 +336,17 @@ bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...) } else if(*s == '*') { pair->list_flg++; } else { - unsigned long *pair_switch = &(pair->switch_on); - if(c) - pair_switch = c == '-' ? &(pair->switch_off) : &(pair->incongruously); - for (on_off = complementally; on_off->opt; on_off++) - if (on_off->opt == *s) { - if(pair_switch == &(on_off->switch_on)) - on_off->counter = va_arg (p, int *); - else - *pair_switch |= on_off->switch_on; - break; - } + unsigned long *pair_switch = &(pair->switch_on); + if(c) + pair_switch = c == '-' ? &(pair->switch_off) : &(pair->incongruously); + for (on_off = complementally; on_off->opt; on_off++) + if (on_off->opt == *s) { + if(pair_switch == &(on_off->switch_on)) + on_off->counter = va_arg (p, int *); + else + *pair_switch |= on_off->switch_on; + break; + } } } s--; @@ -322,8 +354,8 @@ bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...) while ((c = getopt_long (argc, argv, applet_opts, bb_applet_long_options, NULL)) > 0) { - unsigned long trigger; +loop_arg_is_opt: for (on_off = complementally; on_off->opt != c; on_off++) { if(!on_off->opt) bb_show_usage (); @@ -341,10 +373,28 @@ bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...) (*(on_off->counter))++; if(on_off->list_flg) { *(llist_t **)(on_off->optarg) = - llist_add_to(*(llist_t **)(on_off->optarg), optarg); + llist_add_to(*(llist_t **)(on_off->optarg), optarg); } else if (on_off->optarg) { *(char **)(on_off->optarg) = optarg; } + if(flg_argv_is_opts == 'p') + break; + } + if(flg_argv_is_opts) { + /* process argv is option, for example "ps" applet */ + if(flg_argv_is_opts == '-') { + flg_argv_is_opts = 'p'; + pargv = argv + optind; + } + while(*pargv) { + c = **pargv; + if(c == '\0') { + pargv++; + } else { + (*pargv)++; + goto loop_arg_is_opt; + } + } } return flags;