aboutsummaryrefslogtreecommitdiff
path: root/code/tools/lcc/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'code/tools/lcc/src/main.c')
-rw-r--r--code/tools/lcc/src/main.c225
1 files changed, 225 insertions, 0 deletions
diff --git a/code/tools/lcc/src/main.c b/code/tools/lcc/src/main.c
new file mode 100644
index 0000000..63b85f2
--- /dev/null
+++ b/code/tools/lcc/src/main.c
@@ -0,0 +1,225 @@
+#include "c.h"
+
+static char rcsid[] = "main.c - faked rcsid";
+
+static void typestab(Symbol, void *);
+
+static void stabline(Coordinate *);
+static void stabend(Coordinate *, Symbol, Coordinate **, Symbol *, Symbol *);
+Interface *IR = NULL;
+
+int Aflag; /* >= 0 if -A specified */
+int Pflag; /* != 0 if -P specified */
+int glevel; /* == [0-9] if -g[0-9] specified */
+int xref; /* != 0 for cross-reference data */
+Symbol YYnull; /* _YYnull symbol if -n or -nvalidate specified */
+Symbol YYcheck; /* _YYcheck symbol if -nvalidate,check specified */
+
+static char *comment;
+static Interface stabIR;
+static char *currentfile; /* current file name */
+static int currentline; /* current line number */
+static FILE *srcfp; /* stream for current file, if non-NULL */
+static int srcpos; /* position of srcfp, if srcfp is non-NULL */
+int main(int argc, char *argv[]) {
+ int i, j;
+ for (i = argc - 1; i > 0; i--)
+ if (strncmp(argv[i], "-target=", 8) == 0)
+ break;
+ if (i > 0) {
+ char *s = strchr(argv[i], '\\');
+ if (s != NULL)
+ *s = '/';
+ for (j = 0; bindings[j].name && bindings[j].ir; j++)
+ if (strcmp(&argv[i][8], bindings[j].name) == 0) {
+ IR = bindings[j].ir;
+ break;
+ }
+ if (s != NULL)
+ *s = '\\';
+ }
+ if (!IR) {
+ fprint(stderr, "%s: unknown target", argv[0]);
+ if (i > 0)
+ fprint(stderr, " `%s'", &argv[i][8]);
+ fprint(stderr, "; must specify one of\n");
+ for (i = 0; bindings[i].name; i++)
+ fprint(stderr, "\t-target=%s\n", bindings[i].name);
+ exit(EXIT_FAILURE);
+ }
+ init(argc, argv);
+ t = gettok();
+ (*IR->progbeg)(argc, argv);
+ if (glevel && IR->stabinit)
+ (*IR->stabinit)(firstfile, argc, argv);
+ program();
+ if (events.end)
+ apply(events.end, NULL, NULL);
+ memset(&events, 0, sizeof events);
+ if (glevel || xref) {
+ Symbol symroot = NULL;
+ Coordinate src;
+ foreach(types, GLOBAL, typestab, &symroot);
+ foreach(identifiers, GLOBAL, typestab, &symroot);
+ src.file = firstfile;
+ src.x = 0;
+ src.y = lineno;
+ if ((glevel > 2 || xref) && IR->stabend)
+ (*IR->stabend)(&src, symroot,
+ ltov(&loci, PERM),
+ ltov(&symbols, PERM), NULL);
+ else if (IR->stabend)
+ (*IR->stabend)(&src, NULL, NULL, NULL, NULL);
+ }
+ finalize();
+ (*IR->progend)();
+ deallocate(PERM);
+ return errcnt > 0;
+}
+/* main_init - process program arguments */
+void main_init(int argc, char *argv[]) {
+ char *infile = NULL, *outfile = NULL;
+ int i;
+ static int inited;
+
+ if (inited)
+ return;
+ inited = 1;
+ type_init(argc, argv);
+ for (i = 1; i < argc; i++)
+ if (strcmp(argv[i], "-g") == 0 || strcmp(argv[i], "-g2") == 0)
+ glevel = 2;
+ else if (strncmp(argv[i], "-g", 2) == 0) { /* -gn[,x] */
+ char *p = strchr(argv[i], ',');
+ glevel = atoi(argv[i]+2);
+ if (p) {
+ comment = p + 1;
+ if (glevel == 0)
+ glevel = 1;
+ if (stabIR.stabline == NULL) {
+ stabIR.stabline = IR->stabline;
+ stabIR.stabend = IR->stabend;
+ IR->stabline = stabline;
+ IR->stabend = stabend;
+ }
+ }
+ } else if (strcmp(argv[i], "-x") == 0)
+ xref++;
+ else if (strcmp(argv[i], "-A") == 0) {
+ ++Aflag;
+ } else if (strcmp(argv[i], "-P") == 0)
+ Pflag++;
+ else if (strcmp(argv[i], "-w") == 0)
+ wflag++;
+ else if (strcmp(argv[i], "-n") == 0) {
+ if (!YYnull) {
+ YYnull = install(string("_YYnull"), &globals, GLOBAL, PERM);
+ YYnull->type = func(voidptype, NULL, 1);
+ YYnull->sclass = EXTERN;
+ (*IR->defsymbol)(YYnull);
+ }
+ } else if (strncmp(argv[i], "-n", 2) == 0) { /* -nvalid[,check] */
+ char *p = strchr(argv[i], ',');
+ if (p) {
+ YYcheck = install(string(p+1), &globals, GLOBAL, PERM);
+ YYcheck->type = func(voidptype, NULL, 1);
+ YYcheck->sclass = EXTERN;
+ (*IR->defsymbol)(YYcheck);
+ p = stringn(argv[i]+2, p - (argv[i]+2));
+ } else
+ p = string(argv[i]+2);
+ YYnull = install(p, &globals, GLOBAL, PERM);
+ YYnull->type = func(voidptype, NULL, 1);
+ YYnull->sclass = EXTERN;
+ (*IR->defsymbol)(YYnull);
+ } else if (strcmp(argv[i], "-v") == 0)
+ fprint(stderr, "%s %s\n", argv[0], rcsid);
+ else if (strncmp(argv[i], "-s", 2) == 0)
+ density = strtod(&argv[i][2], NULL);
+ else if (strncmp(argv[i], "-errout=", 8) == 0) {
+ FILE *f = fopen(argv[i]+8, "w");
+ if (f == NULL) {
+ fprint(stderr, "%s: can't write errors to `%s'\n", argv[0], argv[i]+8);
+ exit(EXIT_FAILURE);
+ }
+ fclose(f);
+ f = freopen(argv[i]+8, "w", stderr);
+ assert(f);
+ } else if (strncmp(argv[i], "-e", 2) == 0) {
+ int x;
+ if ((x = strtol(&argv[i][2], NULL, 0)) > 0)
+ errlimit = x;
+ } else if (strncmp(argv[i], "-little_endian=", 15) == 0)
+ IR->little_endian = argv[i][15] - '0';
+ else if (strncmp(argv[i], "-mulops_calls=", 18) == 0)
+ IR->mulops_calls = argv[i][18] - '0';
+ else if (strncmp(argv[i], "-wants_callb=", 13) == 0)
+ IR->wants_callb = argv[i][13] - '0';
+ else if (strncmp(argv[i], "-wants_argb=", 12) == 0)
+ IR->wants_argb = argv[i][12] - '0';
+ else if (strncmp(argv[i], "-left_to_right=", 15) == 0)
+ IR->left_to_right = argv[i][15] - '0';
+ else if (strncmp(argv[i], "-wants_dag=", 11) == 0)
+ IR->wants_dag = argv[i][11] - '0';
+ else if (*argv[i] != '-' || strcmp(argv[i], "-") == 0) {
+ if (infile == NULL)
+ infile = argv[i];
+ else if (outfile == NULL)
+ outfile = argv[i];
+ }
+
+ if (infile != NULL && strcmp(infile, "-") != 0
+ && freopen(infile, "r", stdin) == NULL) {
+ fprint(stderr, "%s: can't read `%s'\n", argv[0], infile);
+ exit(EXIT_FAILURE);
+ }
+ if (outfile != NULL && strcmp(outfile, "-") != 0
+ && freopen(outfile, "w", stdout) == NULL) {
+ fprint(stderr, "%s: can't write `%s'\n", argv[0], outfile);
+ exit(EXIT_FAILURE);
+ }
+}
+/* typestab - emit stab entries for p */
+static void typestab(Symbol p, void *cl) {
+ if (*(Symbol *)cl == 0 && p->sclass && p->sclass != TYPEDEF)
+ *(Symbol *)cl = p;
+ if ((p->sclass == TYPEDEF || p->sclass == 0) && IR->stabtype)
+ (*IR->stabtype)(p);
+}
+
+/* stabline - emit source code for source coordinate *cp */
+static void stabline(Coordinate *cp) {
+ if (cp->file && cp->file != currentfile) {
+ if (srcfp)
+ fclose(srcfp);
+ currentfile = cp->file;
+ srcfp = fopen(currentfile, "r");
+ srcpos = 0;
+ currentline = 0;
+ }
+ if (currentline != cp->y && srcfp) {
+ char buf[512];
+ if (srcpos > cp->y) {
+ rewind(srcfp);
+ srcpos = 0;
+ }
+ for ( ; srcpos < cp->y; srcpos++)
+ if (fgets(buf, sizeof buf, srcfp) == NULL) {
+ fclose(srcfp);
+ srcfp = NULL;
+ break;
+ }
+ if (srcfp && srcpos == cp->y)
+ print("%s%s", comment, buf);
+ }
+ currentline = cp->y;
+ if (stabIR.stabline)
+ (*stabIR.stabline)(cp);
+}
+
+static void stabend(Coordinate *cp, Symbol p, Coordinate **cpp, Symbol *sp, Symbol *stab) {
+ if (stabIR.stabend)
+ (*stabIR.stabend)(cp, p, cpp, sp, stab);
+ if (srcfp)
+ fclose(srcfp);
+}