scc

Simple C99 Compiler
Log | Files | Refs | README | LICENSE

commit b79a63cfb2cd56d47c30f9e8f219eb5a11350aa8
parent 5bc9511fcaa1b5906607d25c747ab28c1b25b4eb
Author: FRIGN <dev@frign.de>
Date:   Wed, 25 May 2016 10:55:33 +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.

Diffstat:
cc1/arg.h | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
cc1/main.c | 85+++++++++++++++++++++++++++++++++++++------------------------------------------
2 files changed, 105 insertions(+), 45 deletions(-)

diff --git a/cc1/arg.h 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 @@ -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;