shrink the code a bit
[oweals/busybox.git] / util-linux / getopt.c
index 032d0dc6be5146827ed0ae7174271113783d4e45..16dcbbca0fe0d897e7843c18251627a3116fa7d2 100644 (file)
@@ -63,15 +63,15 @@ typedef enum {BASH,TCSH} shell_t;
 
 /* Some global variables that tells us how to parse. */
 static shell_t shell=BASH; /* The shell we generate output for. */
-static int quiet_errors=0; /* 0 is not quiet. */
-static int quiet_output=0; /* 0 is not quiet. */
+static int quiet_errors; /* 0 is not quiet. */
+static int quiet_output; /* 0 is not quiet. */
 static int quote=1; /* 1 is do quote. */
-static int alternative=0; /* 0 is getopt_long, 1 is getopt_long_only */
+static int alternative; /* 0 is getopt_long, 1 is getopt_long_only */
 
 /* Function prototypes */
 static const char *normalize(const char *arg);
 static int generate_output(char * argv[],int argc,const char *optstr,
-                    const struct option *longopts);
+                   const struct option *longopts);
 static void add_long_options(char *options);
 static void add_longopt(const char *name,int has_arg);
 static void set_shell(const char *new_shell);
@@ -88,57 +88,57 @@ static void set_shell(const char *new_shell);
  */
 const char *normalize(const char *arg)
 {
-        static char *BUFFER=NULL;
-        const char *argptr=arg;
-        char *bufptr;
-
-        free(BUFFER);
-
-        if (!quote) { /* Just copy arg */
-               BUFFER=bb_xstrdup(arg);
-                return BUFFER;
-        }
-
-        /* Each character in arg may take up to four characters in the result:
-           For a quote we need a closing quote, a backslash, a quote and an
-           opening quote! We need also the global opening and closing quote,
-           and one extra character for '\0'. */
-        BUFFER=xmalloc(strlen(arg)*4+3);
-
-        bufptr=BUFFER;
-        *bufptr++='\'';
-
-        while (*argptr) {
-                if (*argptr == '\'') {
-                        /* Quote: replace it with: '\'' */
-                        *bufptr++='\'';
-                        *bufptr++='\\';
-                        *bufptr++='\'';
-                        *bufptr++='\'';
-                } else if (shell==TCSH && *argptr=='!') {
-                        /* Exclamation mark: replace it with: \! */
-                        *bufptr++='\'';
-                        *bufptr++='\\';
-                        *bufptr++='!';
-                        *bufptr++='\'';
-                } else if (shell==TCSH && *argptr=='\n') {
-                        /* Newline: replace it with: \n */
-                        *bufptr++='\\';
-                        *bufptr++='n';
-                } else if (shell==TCSH && isspace(*argptr)) {
-                        /* Non-newline whitespace: replace it with \<ws> */
-                        *bufptr++='\'';
-                        *bufptr++='\\';
-                        *bufptr++=*argptr;
-                        *bufptr++='\'';
-                } else
-                        /* Just copy */
-                        *bufptr++=*argptr;
-                argptr++;
-        }
-        *bufptr++='\'';
-        *bufptr++='\0';
-        return BUFFER;
+       static char *BUFFER=NULL;
+       const char *argptr=arg;
+       char *bufptr;
+
+       free(BUFFER);
+
+       if (!quote) { /* Just copy arg */
+              BUFFER=bb_xstrdup(arg);
+               return BUFFER;
+       }
+
+       /* Each character in arg may take up to four characters in the result:
+          For a quote we need a closing quote, a backslash, a quote and an
+          opening quote! We need also the global opening and closing quote,
+          and one extra character for '\0'. */
+       BUFFER=xmalloc(strlen(arg)*4+3);
+
+       bufptr=BUFFER;
+       *bufptr++='\'';
+
+       while (*argptr) {
+               if (*argptr == '\'') {
+                       /* Quote: replace it with: '\'' */
+                       *bufptr++='\'';
+                       *bufptr++='\\';
+                       *bufptr++='\'';
+                       *bufptr++='\'';
+               } else if (shell==TCSH && *argptr=='!') {
+                       /* Exclamation mark: replace it with: \! */
+                       *bufptr++='\'';
+                       *bufptr++='\\';
+                       *bufptr++='!';
+                       *bufptr++='\'';
+               } else if (shell==TCSH && *argptr=='\n') {
+                       /* Newline: replace it with: \n */
+                       *bufptr++='\\';
+                       *bufptr++='n';
+               } else if (shell==TCSH && isspace(*argptr)) {
+                       /* Non-newline whitespace: replace it with \<ws> */
+                       *bufptr++='\'';
+                       *bufptr++='\\';
+                       *bufptr++=*argptr;
+                       *bufptr++='\'';
+               } else
+                       /* Just copy */
+                       *bufptr++=*argptr;
+               argptr++;
+       }
+       *bufptr++='\'';
+       *bufptr++='\0';
+       return BUFFER;
 }
 
 /*
@@ -149,84 +149,84 @@ const char *normalize(const char *arg)
  * Other settings are found in global variables.
  */
 int generate_output(char * argv[],int argc,const char *optstr,
-                    const struct option *longopts)
+                   const struct option *longopts)
 {
-        int exit_code = 0; /* We assume everything will be OK */
-        int opt;
-        int longindex;
-        const char *charptr;
-
-        if (quiet_errors) /* No error reporting from getopt(3) */
-                opterr=0;
-        optind=0; /* Reset getopt(3) */
-
-        while ((opt = (alternative?
-                       getopt_long_only(argc,argv,optstr,longopts,&longindex):
-                       getopt_long(argc,argv,optstr,longopts,&longindex)))
-               != EOF)
-                if (opt == '?' || opt == ':' )
-                        exit_code = 1;
-                else if (!quiet_output) {
-                        if (opt == LONG_OPT) {
-                                printf(" --%s",longopts[longindex].name);
-                                if (longopts[longindex].has_arg)
-                                        printf(" %s",
-                                               normalize(optarg?optarg:""));
-                        } else if (opt == NON_OPT)
-                                printf(" %s",normalize(optarg));
-                        else {
-                                printf(" -%c",opt);
-                                charptr = strchr(optstr,opt);
-                                if (charptr != NULL && *++charptr == ':')
-                                        printf(" %s",
-                                               normalize(optarg?optarg:""));
-                        }
-                }
-
-        if (! quiet_output) {
-                printf(" --");
-                while (optind < argc)
-                        printf(" %s",normalize(argv[optind++]));
-                printf("\n");
-        }
-        return exit_code;
+       int exit_code = 0; /* We assume everything will be OK */
+       int opt;
+       int longindex;
+       const char *charptr;
+
+       if (quiet_errors) /* No error reporting from getopt(3) */
+               opterr=0;
+       optind=0; /* Reset getopt(3) */
+
+       while ((opt = (alternative?
+                      getopt_long_only(argc,argv,optstr,longopts,&longindex):
+                      getopt_long(argc,argv,optstr,longopts,&longindex)))
+              != EOF)
+               if (opt == '?' || opt == ':' )
+                       exit_code = 1;
+               else if (!quiet_output) {
+                       if (opt == LONG_OPT) {
+                               printf(" --%s",longopts[longindex].name);
+                               if (longopts[longindex].has_arg)
+                                       printf(" %s",
+                                              normalize(optarg?optarg:""));
+                       } else if (opt == NON_OPT)
+                               printf(" %s",normalize(optarg));
+                       else {
+                               printf(" -%c",opt);
+                               charptr = strchr(optstr,opt);
+                               if (charptr != NULL && *++charptr == ':')
+                                       printf(" %s",
+                                              normalize(optarg?optarg:""));
+                       }
+               }
+
+       if (! quiet_output) {
+               printf(" --");
+               while (optind < argc)
+                       printf(" %s",normalize(argv[optind++]));
+               printf("\n");
+       }
+       return exit_code;
 }
 
-static struct option *long_options=NULL;
-static int long_options_length=0; /* Length of array */
-static int long_options_nr=0; /* Nr of used elements in array */
+static struct option *long_options;
+static int long_options_length; /* Length of array */
+static int long_options_nr; /* Nr of used elements in array */
 static const int LONG_OPTIONS_INCR = 10;
 #define init_longopt() add_longopt(NULL,0)
 
 /* Register a long option. The contents of name is copied. */
 void add_longopt(const char *name,int has_arg)
 {
-        if (!name) { /* init */
-                free(long_options);
-                long_options=NULL;
-                long_options_length=0;
-                long_options_nr=0;
-        }
-
-        if (long_options_nr == long_options_length) {
-                long_options_length += LONG_OPTIONS_INCR;
-                long_options=xrealloc(long_options,
-                                         sizeof(struct option) *
-                                         long_options_length);
-        }
-
-        long_options[long_options_nr].name=NULL;
-        long_options[long_options_nr].has_arg=0;
-        long_options[long_options_nr].flag=NULL;
-        long_options[long_options_nr].val=0;
-
-        if (long_options_nr) { /* Not for init! */
-                long_options[long_options_nr-1].has_arg=has_arg;
-                long_options[long_options_nr-1].flag=NULL;
-                long_options[long_options_nr-1].val=LONG_OPT;
-               long_options[long_options_nr-1].name=bb_xstrdup(name);
-        }
-        long_options_nr++;
+       if (!name) { /* init */
+               free(long_options);
+               long_options=NULL;
+               long_options_length=0;
+               long_options_nr=0;
+       }
+
+       if (long_options_nr == long_options_length) {
+               long_options_length += LONG_OPTIONS_INCR;
+               long_options=xrealloc(long_options,
+                                        sizeof(struct option) *
+                                        long_options_length);
+       }
+
+       long_options[long_options_nr].name=NULL;
+       long_options[long_options_nr].has_arg=0;
+       long_options[long_options_nr].flag=NULL;
+       long_options[long_options_nr].val=0;
+
+       if (long_options_nr) { /* Not for init! */
+               long_options[long_options_nr-1].has_arg=has_arg;
+               long_options[long_options_nr-1].flag=NULL;
+               long_options[long_options_nr-1].val=LONG_OPT;
+              long_options[long_options_nr-1].name=bb_xstrdup(name);
+       }
+       long_options_nr++;
 }
 
 
@@ -237,43 +237,43 @@ void add_longopt(const char *name,int has_arg)
  */
 void add_long_options(char *options)
 {
-        int arg_opt, tlen;
-        char *tokptr=strtok(options,", \t\n");
-        while (tokptr) {
-                arg_opt=no_argument;
+       int arg_opt, tlen;
+       char *tokptr=strtok(options,", \t\n");
+       while (tokptr) {
+               arg_opt=no_argument;
                tlen=strlen(tokptr);
-                if (tlen > 0) {
-                        if (tokptr[tlen-1] == ':') {
-                                if (tlen > 1 && tokptr[tlen-2] == ':') {
-                                        tokptr[tlen-2]='\0';
+               if (tlen > 0) {
+                       if (tokptr[tlen-1] == ':') {
+                               if (tlen > 1 && tokptr[tlen-2] == ':') {
+                                       tokptr[tlen-2]='\0';
                                        tlen -= 2;
-                                        arg_opt=optional_argument;
-                                } else {
-                                        tokptr[tlen-1]='\0';
+                                       arg_opt=optional_argument;
+                               } else {
+                                       tokptr[tlen-1]='\0';
                                        tlen -= 1;
-                                        arg_opt=required_argument;
-                                }
-                                if (tlen == 0)
-                                        bb_error_msg("empty long option after -l or --long argument");
-                        }
-                        add_longopt(tokptr,arg_opt);
-                }
-                tokptr=strtok(NULL,", \t\n");
-        }
+                                       arg_opt=required_argument;
+                               }
+                               if (tlen == 0)
+                                       bb_error_msg("empty long option after -l or --long argument");
+                       }
+                       add_longopt(tokptr,arg_opt);
+               }
+               tokptr=strtok(NULL,", \t\n");
+       }
 }
 
 void set_shell(const char *new_shell)
 {
-        if (!strcmp(new_shell,"bash"))
-                shell=BASH;
-        else if (!strcmp(new_shell,"tcsh"))
-                shell=TCSH;
-        else if (!strcmp(new_shell,"sh"))
-                shell=BASH;
-        else if (!strcmp(new_shell,"csh"))
-                shell=TCSH;
-        else
-                bb_error_msg("unknown shell after -s or --shell argument");
+       if (!strcmp(new_shell,"bash"))
+               shell=BASH;
+       else if (!strcmp(new_shell,"tcsh"))
+               shell=TCSH;
+       else if (!strcmp(new_shell,"sh"))
+               shell=BASH;
+       else if (!strcmp(new_shell,"csh"))
+               shell=TCSH;
+       else
+               bb_error_msg("unknown shell after -s or --shell argument");
 }
 
 
@@ -285,100 +285,97 @@ void set_shell(const char *new_shell)
  *   4) Returned for -T
  */
 
-static struct option longopts[]=
+static const struct option longopts[]=
 {
-        {"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}
+       {"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";
+static const char shortopts[]="+ao:l:n:qQs:Tu";
 
 
 int getopt_main(int argc, char *argv[])
 {
-        const char *optstr = NULL;
-        const 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");
-                       return 0;
-                } else
-                        bb_error_msg_and_die("missing optstring argument");
-        }
-
-        if (argv[1][0] != '-' || compatible) {
-                quote=0;
-                optstr=xmalloc(strlen(argv[1])+1);
-                strcpy(optstr,argv[1]+strspn(argv[1],"-+"));
-                argv[1]=argv[0];
-               return (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':
-                       free(optstr);
-                       optstr = optarg;
-                        break;
-                case 'l':
-                        add_long_options(optarg);
-                        break;
-                case 'n':
-                       free(name);
-                       name = optarg;
-                        break;
-                case 'q':
-                        quiet_errors=1;
-                        break;
-                case 'Q':
-                        quiet_output=1;
-                        break;
-                case 's':
-                        set_shell(optarg);
-                        break;
-                case 'T':
-                       return 4;
-                case 'u':
-                        quote=0;
-                        break;
-                default:
-                        bb_show_usage();
-                }
-
-        if (!optstr) {
-                if (optind >= argc)
-                        bb_error_msg_and_die("missing optstring argument");
-                else {
-                       optstr=bb_xstrdup(argv[optind]);
-                        optind++;
-                }
-        }
-        if (name)
-                argv[optind-1]=name;
-        else
-                argv[optind-1]=argv[0];
+       const 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");
+                      return 0;
+               } else
+                       bb_error_msg_and_die("missing optstring argument");
+       }
+
+       if (argv[1][0] != '-' || compatible) {
+               char *s;
+
+               quote=0;
+               s=xmalloc(strlen(argv[1])+1);
+               strcpy(s,argv[1]+strspn(argv[1],"-+"));
+               argv[1]=argv[0];
+              return (generate_output(argv+1,argc-1,s,long_options));
+       }
+
+       while ((opt=getopt_long(argc,argv,shortopts,longopts,NULL)) != EOF)
+               switch (opt) {
+               case 'a':
+                       alternative=1;
+                       break;
+               case 'o':
+                      optstr = optarg;
+                       break;
+               case 'l':
+                       add_long_options(optarg);
+                       break;
+               case 'n':
+                      name = optarg;
+                       break;
+               case 'q':
+                       quiet_errors=1;
+                       break;
+               case 'Q':
+                       quiet_output=1;
+                       break;
+               case 's':
+                       set_shell(optarg);
+                       break;
+               case 'T':
+                      return 4;
+               case 'u':
+                       quote=0;
+                       break;
+               default:
+                       bb_show_usage();
+               }
+
+       if (!optstr) {
+               if (optind >= argc)
+                       bb_error_msg_and_die("missing optstring argument");
+               else optstr=argv[optind++];
+       }
+       if (name)
+               argv[optind-1]=name;
+       else
+               argv[optind-1]=argv[0];
        return (generate_output(argv+optind-1,argc-optind+1,optstr,long_options));
 }