* Use getopt_long_only().
* Mark handle_* functions as static.
* Support for easy adding new command line options rests in place.

--- 1.1233/lib.c        2005-01-16 01:09:02.000000000 +0200
+++ 1.1233-getopt/lib.c 2005-01-18 02:26:45.000000000 +0200
@@ -15,6 +15,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <assert.h>
+#include <getopt.h>
 
 #include <sys/types.h>
 
@@ -389,218 +390,81 @@ void add_pre_buffer(const char *fmt, ...
        va_end(args);
 }
 
-char **handle_switch_D(char *arg, char **next)
+static void handle_switch_D(char *name)
 {
-       const char *name = arg + 1;
-       const char *value = "1";
-       for (;;) {
-               char c;
-               c = *++arg;
-               if (!c)
-                       break;
-               if (isspace((unsigned char)c) || c == '=') {
-                       *arg = '\0';
-                       value = arg + 1;
-                       break;
-               }
-       }
-       add_pre_buffer("#define %s %s\n", name, value);
-       return next;
-}
+       char *p, *value, one[2] = {'1', '\0'};
 
-char **handle_switch_E(char *arg, char **next)
-{
-       preprocess_only = 1;
-       return next;
+       p = strchr(name, '=');
+       if (p) {
+               *p = '\0';
+               value = p + 1;
+       } else
+               value = &one[0];
+       add_pre_buffer("#define %s %s\n", name, value);
 }
 
-char **handle_switch_v(char *arg, char **next)
+static void handle_switch_I(char *path)
 {
-       do {
-               verbose++;
-       } while (*++arg == 'v');
-       return next;
+       /* Explaining '-I-' with a google search:
+        *
+        *      "Specifying -I after -I- searches for #include directories.
+        *       If -I- is specified before, it searches for #include "file"
+        *       and not #include ."
+        *
+        * Which didn't explain it at all to me. Maybe somebody else can
+        * explain it properly. We ignore it for now.
+        */
+       add_pre_buffer("#add_include \"%s/\"\n", path);
 }
 
-char **handle_switch_I(char *arg, char **next)
+static void handle_include(char *name)
 {
-       char *path = arg+1;
+       int fd = open(name, O_RDONLY);
 
-       switch (arg[1]) {
-       case '-':
-               /* Explaining '-I-' with a google search:
-                *
-                *      "Specifying -I after -I- searches for #include 
directories.
-                *       If -I- is specified before, it searches for #include 
"file"
-                *       and not #include ."
-                *
-                * Which didn't explain it at all to me. Maybe somebody else can
-                * explain it properly. We ignore it for now.
-                */
-               return next;
+       if (fd < 0)
+               perror(name);
 
-       case '\0':      /* Plain "-I" */
-               path = *++next;
-               if (!path)
-                       die("missing argument for -I option");
-               /* Fallthrough */
-       default:
-               add_pre_buffer("#add_include \"%s/\"\n", path);
-       }
-       return next;
+       include_fd = fd;
+       include = name;
 }
 
-char **handle_switch_i(char *arg, char **next)
+static void handle_isystem(char *path)
 {
-       if (*next && !strcmp(arg, "include")) {
-               char *name = *++next;
-               int fd = open(name, O_RDONLY);
-
-               include_fd = fd;
-               include = name;
-               if (fd < 0)
-                       perror(name);
-       }
-       else if (*next && !strcmp(arg, "isystem")) {
-               char *path = *++next;
-               if (!path)
-                       die("missing argument for -isystem option");
-               add_pre_buffer("#add_include \"%s/\"\n", path);
-       }
-       return next;
+       add_pre_buffer("#add_include \"%s/\"\n", path);
 }
 
-char **handle_switch_M(char *arg, char **next)
+static void handle_MF(char *file)
 {
-       if (!strcmp(arg, "MF") || !strcmp(arg,"MQ") || !strcmp(arg,"MT")) {
-               if (!*next)
-                       die("missing argument for -%s option", arg);
-               return next + 1;
-       }
-       return next;
 }
 
-char **handle_switch_m(char *arg, char **next)
+static void handle_MT(char *target)
 {
-       if (!strcmp(arg, "m64")) {
-               bits_in_long = 64;
-               max_int_alignment = 8;
-               bits_in_pointer = 64;
-               pointer_alignment = 8;
-       }
-       return next;
 }
 
-char **handle_switch_o(char *arg, char **next)
+static void handle_MQ(char *target)
 {
-       if (!strcmp (arg, "o") && *next)
-               return next + 1; // "-o foo"
-       else
-               return next;     // "-ofoo" or (bogus) terminal "-o"
 }
 
-const struct warning {
-       const char *name;
-       int *flag;
-} warnings[] = {
-       { "ptr-subtraction-blows", &Wptr_subtraction_blows },
-       { "default-bitfield-sign", &Wdefault_bitfield_sign },
-       { "undef", &Wundefined_preprocessor },
-       { "bitwise", &Wbitwise },
-       { "typesign", &Wtypesign },
-       { "context", &Wcontext },
-};
-
-
-char **handle_switch_W(char *arg, char **next)
+static void handle_m64(void)
 {
-       int no = 0;
-       char *p = arg + 1;
-       unsigned i;
-
-       // Prefixes "no" and "no-" mean to turn warning off.
-       if (p[0] == 'n' && p[1] == 'o') {
-               p += 2;
-               if (p[0] == '-')
-                       p++;
-               no = 1;
-       }
-
-       for (i = 0; i < sizeof(warnings) / sizeof(warnings[0]); i++) {
-               if (!strcmp(p,warnings[i].name)) {
-                       *warnings[i].flag = !no;
-                       return next;
-               }
-       }
-
-       // Unknown.
-       return next;
+       bits_in_long = 64;
+       max_int_alignment = 8;
+       bits_in_pointer = 64;
+       pointer_alignment = 8;
 }
 
-char **handle_switch_U(char *arg, char **next)
+static void handle_switch_o(char *outfile)
 {
-       const char *name = arg + 1;
-       add_pre_buffer ("#undef %s\n", name);
-       return next;
 }
 
-char **handle_switch_O(char *arg, char **next)
+static void handle_switch_U(char *name)
 {
-       int level = 1;
-       if (arg[1] >= '0' && arg[1] <= '9')
-               level = arg[1] - '0';
-       optimize = level;
-       return next;
+       add_pre_buffer("#undef %s\n", name);
 }
 
-char **handle_nostdinc(char *arg, char **next)
+static void handle_nostdinc(void)
 {
        add_pre_buffer("#nostdinc\n");
-       return next;
-}
-
-struct switches {
-       const char *name;
-       char **(*fn)(char *, char**);
-};
-
-char **handle_switch(char *arg, char **next)
-{
-       char **rc = next;
-       static struct switches cmd[] = {
-               { "nostdinc", handle_nostdinc },
-               { NULL, NULL }
-       };
-       struct switches *s;
-
-       switch (*arg) {
-       case 'D': rc = handle_switch_D(arg, next); break;
-       case 'E': rc = handle_switch_E(arg, next); break;
-       case 'I': rc = handle_switch_I(arg, next); break;
-       case 'i': rc = handle_switch_i(arg, next); break;
-       case 'M': rc = handle_switch_M(arg, next); break;
-       case 'm': rc = handle_switch_m(arg, next); break;
-       case 'o': rc = handle_switch_o(arg, next); break;
-       case 'U': rc = handle_switch_U(arg, next); break;
-       case 'v': rc = handle_switch_v(arg, next); break;
-       case 'W': rc = handle_switch_W(arg, next); break;
-       case 'O': rc = handle_switch_O(arg, next); break;
-       default:
-               break;
-       }
-
-       s = cmd;
-       while (s->name) {
-               if (!strcmp(s->name, arg))
-                       return s->fn(arg, next);
-               s++;
-       }
-
-       /*
-        * Ignore unknown command line options:
-        * they're probably gcc switches
-        */
-       return rc;
 }
 
 void declare_builtin_functions(void)
@@ -644,27 +508,93 @@ static void do_predefined(char *filename
        add_pre_buffer("#define __TIME__ \"??:??:??\"\n");
 }
 
+static struct option long_options[] = {
+       {"nostdinc", no_argument, NULL, 0x100},
+       {"include", required_argument, NULL, 0x101},
+       {"isystem", required_argument, NULL, 0x102},
+       {"MF", required_argument, NULL, 0x103},
+       {"MT", required_argument, NULL, 0x104},
+       {"MQ", required_argument, NULL, 0x105},
+       {"m64", no_argument, NULL, 0x106},
+       {"O0", no_argument, &optimize, 0},
+       {"O", no_argument, &optimize, 1},
+       {"O1", no_argument, &optimize, 1},
+       {"O2", no_argument, &optimize, 2},
+       {"O3", no_argument, &optimize, 3},
+       {"E", no_argument, &preprocess_only, 1},
+       {"v", no_argument, &verbose, 1},
+       {"Wcontext", no_argument, &Wcontext, 1},
+       {"Wnocontext", no_argument, &Wcontext, 0},
+       {"Wno-context", no_argument, &Wcontext, 0},
+       {"Wtypesign", no_argument, &Wtypesign, 1},
+       {"Wnotypesign", no_argument, &Wtypesign, 0},
+       {"Wno-typesign", no_argument, &Wtypesign, 0},
+       {"Wbitwise", no_argument, &Wbitwise, 1},
+       {"Wnobitwise", no_argument, &Wbitwise, 0},
+       {"Wno-bitwise", no_argument, &Wbitwise, 0},
+       {"Wundef", no_argument, &Wundefined_preprocessor, 1},
+       {"Wnoundef", no_argument, &Wundefined_preprocessor, 0},
+       {"Wno-undef", no_argument, &Wundefined_preprocessor, 0},
+       {"Wdefault-bitfield-sign", no_argument, &Wdefault_bitfield_sign, 1},
+       {"Wnodefault-bitfield-sign", no_argument, &Wdefault_bitfield_sign, 0},
+       {"Wno-default-bitfield-sign", no_argument, &Wdefault_bitfield_sign, 0},
+       {"Wptr-subtraction-blows", no_argument, &Wptr_subtraction_blows, 1},
+       {"Wnoptr-subtraction-blows", no_argument, &Wptr_subtraction_blows, 0},
+       {"Wno-ptr-subtraction-blows", no_argument, &Wptr_subtraction_blows, 0},
+       {NULL, 0, NULL, 0}
+};
+
 struct symbol_list *sparse(int argc, char **argv)
 {
        int fd;
-       char *filename = NULL, **args;
+       char *filename = NULL;
        struct token *token;
+       int c;
 
        // Initialize symbol stream first, so that we can add defines etc
        init_symbols();
 
-       args = argv;
-       for (;;) {
-               char *arg = *++args;
-               if (!arg)
-                       break;
-               if (arg[0] == '-' && arg[1]) {
-                       args = handle_switch(arg+1, args);
-                       continue;
+       while ((c = getopt_long_only(argc, argv, "D:I:o:U:",
+                                       long_options, NULL)) != -1)
+               switch (c) {
+               case 'D':
+                       handle_switch_D(optarg);
+                       break;
+               case 'I':
+                       handle_switch_I(optarg);
+                       break;
+               case 'o':
+                       handle_switch_o(optarg);
+                       break;
+               case 'U':
+                       handle_switch_U(optarg);
+                       break;
+               case 0x100:
+                       handle_nostdinc();
+                       break;
+               case 0x101:
+                       handle_include(optarg);
+                       break;
+               case 0x102:
+                       handle_isystem(optarg);
+                       break;
+               case 0x103:
+                       handle_MF(optarg);
+                       break;
+               case 0x104:
+                       handle_MT(optarg);
+                       break;
+               case 0x105:
+                       handle_MQ(optarg);
+                       break;
+               case 0x106:
+                       handle_m64();
+                       break;
+               default:
+                       break;
                }
-               filename = arg;
-       }
 
+       filename = argv[optind];
        if (!filename)
                die("no input files given");
 
-
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to