- {"options",required_argument,NULL,'o'},
- {"longoptions",required_argument,NULL,'l'},
- {"quiet",no_argument,NULL,'q'},
- {"quiet-output",no_argument,NULL,'Q'},
- {"shell",required_argument,NULL,'s'},
- {"test",no_argument,NULL,'T'},
- {"unquoted",no_argument,NULL,'u'},
- {"alternative",no_argument,NULL,'a'},
- {"name",required_argument,NULL,'n'},
- {NULL,0,NULL,0}
-};
-
-/* Stop scanning as soon as a non-option argument is found! */
-static const char *shortopts="+ao:l:n:qQs:Tu";
-
-
-int getopt_main(int argc, char *argv[])
-{
- char *optstr=NULL;
- char *name=NULL;
- int opt;
- int compatible=0;
-
- init_longopt();
-
- if (getenv("GETOPT_COMPATIBLE"))
- compatible=1;
-
- if (argc == 1) {
- if (compatible) {
- /* For some reason, the original getopt gave no error
- when there were no arguments. */
- printf(" --\n");
- exit(0);
- } else
- fatalError("missing optstring argument\n");
- }
-
- if (argv[1][0] != '-' || compatible) {
- quote=0;
- optstr=xmalloc(strlen(argv[1])+1);
- strcpy(optstr,argv[1]+strspn(argv[1],"-+"));
- argv[1]=argv[0];
- exit(generate_output(argv+1,argc-1,optstr,long_options));
- }
-
- while ((opt=getopt_long(argc,argv,shortopts,longopts,NULL)) != EOF)
- switch (opt) {
- case 'a':
- alternative=1;
- break;
- case 'o':
- if (optstr)
- free(optstr);
- optstr=xmalloc(strlen(optarg)+1);
- strcpy(optstr,optarg);
- break;
- case 'l':
- add_long_options(optarg);
- break;
- case 'n':
- if (name)
- free(name);
- name=xmalloc(strlen(optarg)+1);
- strcpy(name,optarg);
- break;
- case 'q':
- quiet_errors=1;
- break;
- case 'Q':
- quiet_output=1;
- break;
- case 's':
- set_shell(optarg);
- break;
- case 'T':
- exit(4);
- case 'u':
- quote=0;
- break;
- default:
- usage(getopt_usage);
- }
-
- if (!optstr) {
- if (optind >= argc)
- fatalError("missing optstring argument\n");
- else {
- optstr=xmalloc(strlen(argv[optind])+1);
- strcpy(optstr,argv[optind]);
- optind++;
- }
- }
- if (name)
- argv[optind-1]=name;
- else
- argv[optind-1]=argv[0];
- exit(generate_output(argv+optind-1,argc-optind+1,optstr,long_options));
+ char *optstr = NULL;
+ char *name = NULL;
+ unsigned opt;
+ const char *compatible;
+ char *s_arg;
+#if ENABLE_FEATURE_GETOPT_LONG
+ struct option *long_options = NULL;
+ llist_t *l_arg = NULL;
+#endif
+
+ compatible = getenv("GETOPT_COMPATIBLE"); /* used as yes/no flag */
+
+ if (argc == 1) {
+ if (compatible) {
+ /* For some reason, the original getopt gave no error
+ when there were no arguments. */
+ printf(" --\n");
+ return 0;
+ }
+ bb_error_msg_and_die("missing optstring argument");
+ }
+
+ if (argv[1][0] != '-' || compatible) {
+ char *s;
+
+ option_mask32 |= OPT_u; /* quoting off */
+ s = xstrdup(argv[1] + strspn(argv[1], "-+"));
+ argv[1] = argv[0];
+ return generate_output(argv+1, argc-1, s, long_options);
+ }
+
+#if !ENABLE_FEATURE_GETOPT_LONG
+ opt = getopt32(argv, "+o:n:qQs:Tu", &optstr, &name, &s_arg);
+#else
+ applet_long_options = getopt_longopts;
+ opt_complementary = "l::";
+ opt = getopt32(argv, "+o:n:qQs:Tual:",
+ &optstr, &name, &s_arg, &l_arg);
+ /* Effectuate the read options for the applet itself */
+ while (l_arg) {
+ long_options = add_long_options(long_options, llist_pop(&l_arg));
+ }
+#endif
+
+ if (opt & OPT_s) {
+ set_shell(s_arg);
+ }
+
+ if (opt & OPT_T) {
+ return 4;
+ }
+
+ /* All options controlling the applet have now been parsed */
+ if (!optstr) {
+ if (optind >= argc)
+ bb_error_msg_and_die("missing optstring argument");
+ optstr = argv[optind++];
+ }
+
+ argv[optind-1] = name ? name : argv[0];
+ return generate_output(argv+optind-1, argc-optind+1, optstr, long_options);