commit b79a63cfb2cd56d47c30f9e8f219eb5a11350aa8
Author:     FRIGN <[email protected]>
AuthorDate: Wed May 25 10:55:33 2016 +0200
Commit:     FRIGN <[email protected]>
CommitDate: Wed May 25 10:55:33 2016 +0200

    [cc1] Add arg.h and refactor main.c
    
    There are three reasons for this:
    
    1) It greatly simplifies the main() code and makes it more
       maintainable
    2) arg.h is awesome. Thanks Christoph!
    3) the -I and -D flags only supported one way, the argument
       directly following the flag, e.g.
          -DBEANER
       However, gcc also supports the syntax
          -D BEANER
       Now, one might argue which one is better, but we must face
       the reality that scripts can break if used in the former
       case (and honestly, I see no reason to omit the space).
    
    While at it, I refactored the whole main() function to make it
    simpler and more readable.

diff --git a/cc1/arg.h b/cc1/arg.h
new file mode 100644
index 0000000..0b23c53
--- /dev/null
+++ b/cc1/arg.h
@@ -0,0 +1,65 @@
+/*
+ * Copy me if you can.
+ * by 20h
+ */
+
+#ifndef ARG_H__
+#define ARG_H__
+
+extern char *argv0;
+
+/* use main(int argc, char *argv[]) */
+#define ARGBEGIN       for (argv0 = *argv, argv++, argc--;\
+                                       argv[0] && argv[0][0] == '-'\
+                                       && argv[0][1];\
+                                       argc--, argv++) {\
+                               char argc_;\
+                               char **argv_;\
+                               int brk_;\
+                               if (argv[0][1] == '-' && argv[0][2] == '\0') {\
+                                       argv++;\
+                                       argc--;\
+                                       break;\
+                               }\
+                               for (brk_ = 0, argv[0]++, argv_ = argv;\
+                                               argv[0][0] && !brk_;\
+                                               argv[0]++) {\
+                                       if (argv_ != argv)\
+                                               break;\
+                                       argc_ = argv[0][0];\
+                                       switch (argc_)
+
+/* Handles obsolete -NUM syntax */
+#define ARGNUM                         case '0':\
+                                       case '1':\
+                                       case '2':\
+                                       case '3':\
+                                       case '4':\
+                                       case '5':\
+                                       case '6':\
+                                       case '7':\
+                                       case '8':\
+                                       case '9'
+
+#define ARGEND                 }\
+                       }
+
+#define ARGC()         argc_
+
+#define ARGNUMF()      (brk_ = 1, estrtonum(argv[0], 0, INT_MAX))
+
+#define EARGF(x)       ((argv[0][1] == '\0' && argv[1] == NULL)?\
+                               ((x), abort(), (char *)0) :\
+                               (brk_ = 1, (argv[0][1] != '\0')?\
+                                       (&argv[0][1]) :\
+                                       (argc--, argv++, argv[0])))
+
+#define ARGF()         ((argv[0][1] == '\0' && argv[1] == NULL)?\
+                               (char *)0 :\
+                               (brk_ = 1, (argv[0][1] != '\0')?\
+                                       (&argv[0][1]) :\
+                                       (argc--, argv++, argv[0])))
+
+#define LNGARG()       &argv[0][0]
+
+#endif
diff --git a/cc1/main.c b/cc1/main.c
index 9e53bd0..55517f5 100644
--- a/cc1/main.c
+++ b/cc1/main.c
@@ -7,12 +7,15 @@
 
 #include "../inc/cc.h"
 #include "arch.h"
+#include "arg.h"
 #include "cc1.h"
 
+char *argv0;
+
 int warnings;
 jmp_buf recover;
 
-static char *output, *arg0;
+static char *output;
 int onlycpp;
 
 static void
@@ -27,61 +30,51 @@ clean(void)
 static void
 usage(void)
 {
-       fprintf(stderr,
-               "usage: %s [-E] [-Dmacro[=value]] [-Idir] [-w] [-d] [-o output] 
[input]\n",
-               arg0);
-       exit(1);
+       die("usage: %s [-E] [-Dmacro[=value]] [-Idir] [-w] [-d] [-o output]"
+           "          [input]\n", argv0);
 }
 
 int
 main(int argc, char *argv[])
 {
-       char c, *cp;
+       char *base;
 
        atexit(clean);
 
-       arg0 = (cp = strrchr(*argv, '/')) ? cp+1 : *argv;
-       if (!strcmp(arg0, "cpp"))
+       ARGBEGIN {
+       case 'w':
+               warnings = 1;
+               break;
+       case 'E':
                onlycpp = 1;
+               break;
+       case 'D':
+               defmacro(EARGF(usage()));
+               break;
+       case 'd':
+               DBGON();
+               break;
+       case 'I':
+               incdir(EARGF(usage()));
+               break;
+       case 'o':
+               output = EARGF(usage());
+               break;
+       default:
+               usage();
+       } ARGEND
 
-       for (;;) {
-       nextiter:
-               --argc, ++argv;
-               if (!*argv || argv[0][0] != '-' || argv[0][1] == '-')
-                       break;
-               for (cp = &argv[0][1]; (c = *cp); cp++) {
-                       switch (c) {
-                       case 'w':
-                               warnings = 1;
-                               break;
-                       case 'E':
-                               onlycpp = 1;
-                               break;
-                       case 'D':
-                               defmacro(cp+1);
-                               goto nextiter;
-                       case 'd':
-                               DBGON();
-                               break;
-                       case 'I':
-                               incdir(cp+1);
-                               goto nextiter;
-                       case 'o':
-                               if (!*++argv || argv[0][0] == '-')
-                                       usage();
-                               --argc;
-                               output = *argv;
-                               break;
-                       default:
-                               usage();
-                       }
-               }
-       }
+       if (argc > 1)
+               usage();
+
+       /* if run as cpp, only run the preprocessor */
+       if (!(base = strrchr(argv0, '/')))
+               base = argv0;
+       if (!strcmp(base, "cpp"))
+               onlycpp = 1;
 
        if (output && !freopen(output, "w", stdout))
                die("error opening output: %s", strerror(errno));
-       if (argc > 1)
-               usage();
 
        icpp();
        ilex(*argv);
@@ -89,8 +82,10 @@ main(int argc, char *argv[])
        if (onlycpp) {
                outcpp();
        } else {
-               for (next(); yytoken != EOFTOK; decl())
-                       /* nothing */;
+               next();
+
+               while (yytoken != EOFTOK)
+                       decl();
        }
 
        return 0;

Reply via email to