#include "cc.h"#include "y.tab.h" #ifndef CPP#define CPP "/bin/cpp"#endif static int ansip; voidmain(int argc, char *argv[]){ char *defs[50], *p; int nproc, nout, status, i, c, ndef; tinit(); cinit(); ginit(); arginit(); tufield = simplet((1L<<tfield->etype) | BUNSIGNED); ndef = 0; include[ninclude++] = "."; strings = 1; passes = 1; ARGBEGIN { default: break; case 'p': ansip = 1; break; case 'D': p = ARGF(); if(p) { defs[ndef++] = p; dodefine(p); } break; case 'I': p = ARGF(); setinclude(p); break; case 'm': domod = 1; break; case 'i': doinc = 1; break; case 'l': doloc = 1; break; case 'c': justcode = 1; break; case 'v': comm = 1; break; case 's': strings = 0; break; case 'S': strings = 2; break; case 'M': inmain = 1; break; case 'q': passes = 0; break; case 'a': doaddr = 1; break; case 'A': doaddr = 1; doalladdr = 1; break; } ARGEND if(doinc) domod = doloc = 0; linit(); if(argc != 1) { print("usage: c2l [-options] file\n"); errorexit(); } if(argc > 1 && systemtype(Windows)){ print("can't compile multiple files on windows\n"); errorexit(); } if(argc > 1 && !systemtype(Windows)) { nproc = 1; if(p = getenv("NPROC")) nproc = atol(p); /* */ c = 0; nout = 0; for(;;) { while(nout < nproc && argc > 0) { i = myfork(); if(i < 0) { i = mywait(&status); if(i < 0) { print("cannot create a process\n"); errorexit(); } if(status) c++; nout--; continue; } if(i == 0) { fprint(2, "%s:\n", *argv); if (compile(*argv, defs, ndef)) errorexit(); exits(0); } nout++; argc--; argv++; } i = mywait(&status); if(i < 0) { if(c) errorexit(); exits(0); } if(status) c++; nout--; } } if(argc == 0) c = compile("stdin", defs, ndef); else c = compile(argv[0], defs, ndef); if(c) errorexit(); exits(0);} intcompile(char *file, char **defs, int ndef){ char ofile[200], incfile[20]; char *p, *av[100], opt[256]; int i, c, fd[2]; strcpy(ofile, file); p = utfrrune(ofile, pathchar()); if(p) { *p++ = 0; include[0] = strdup(ofile); } else p = ofile; USED(p); if(p = getenv("INCLUDE")) { setinclude(p); } else { if(systemtype(Plan9)) { sprint(incfile, "/%s/include", thestring); setinclude(strdup(incfile)); setinclude("/sys/include"); } } newio(); /* Use an ANSI preprocessor */ if(ansip) { if(systemtype(Windows)) { diag(Z, "-p option not supported on windows"); errorexit(); } if(mypipe(fd) < 0) { diag(Z, "pipe failed"); errorexit(); } switch(myfork()) { case -1: diag(Z, "fork failed"); errorexit(); case 0: close(fd[0]); mydup(fd[1], 1); close(fd[1]); av[0] = CPP; i = 1; for(c = 0; c < ndef; c++) { sprint(opt, "-D%s", defs[c]); av[i++] = strdup(opt); } for(c = 0; c < ninclude; c++) { sprint(opt, "-I%s", include[c]); av[i++] = strdup(opt); } if(strcmp(file, "stdin") != 0) av[i++] = file; av[i] = 0; if(0) { for(c = 0; c < i; c++) fprint(2, "%s ", av[c]); print("\n"); } myexec(av[0], av); fprint(2, "can't exec C preprocessor %s: %r\n", CPP); errorexit(); default: close(fd[1]); newfile(file, fd[0]); break; } } else { if(strcmp(file, "stdin") == 0) newfile(file, 0); else newfile(file, -1); } clbegin(); yyparse(); clend(); newsec(0); return nerrors;} voiderrorexit(void){ exits("error");} voidpushio(void){ Io *i; i = iostack; if(i == I) { yyerror("botch in pushio"); errorexit(); } i->p = fi.p; i->c = fi.c;} voidnewio(void){ Io *i; static pushdepth = 0; i = iofree; if(i == I) { pushdepth++; if(pushdepth > 1000) { yyerror("macro/io expansion too deep"); errorexit(); } i = alloc(sizeof(*i)); } else iofree = i->link; i->c = 0; i->f = -1; ionext = i;} voidnewfile(char *s, int f){ Io *i; if(0) print("%L: %s\n", lineno, s); i = ionext; i->link = iostack; iostack = i; i->f = f; if(f < 0) i->f = open(s, 0); if(i->f < 0) { yyerror("c2l: %r: %s", s); errorexit(); } fi.c = 0; linehist(s, 0); outpush(s);} Sym*slookup(char *s){ strcpy(symb, s); return lookup();} Sym*lookup(void){ static Sym zsym; Sym *s; ulong h; char *p; int c, n; h = 0; for(p=symb; *p;) { h = h * 3; h += *p++; } n = (p - symb) + 1; if((long)h < 0) h = ~h; h %= NHASH; c = symb[0]; for(s = hash[h]; s != S; s = s->link) { if(s->name[0] != c) continue; if(strcmp(s->name, symb) == 0) return s; } s = alloc(sizeof(*s)); *s = zsym; s->name = alloc(n); memmove(s->name, symb, n); strcpy(s->name, symb); s->link = hash[h]; hash[h] = s; syminit(s); return s;} voidsyminit(Sym *s){ s->lexical = LNAME; s->type = T; s->suetag = T; s->class = CXXX; s->lname = s->mod = nil; s->lineno = lineno; s->tenum = T;} #define EOF (-1)#define IGN (-2)#define ESC (1<<20)#define GETC() ((--fi.c < 0)? filbuf(): (*fi.p++ & 0xff)) enum{ Numdec = 1<<0, Numlong = 1<<1, Numuns = 1<<2, Numvlong = 1<<3, Numflt = 1<<4,}; static int ypeek = 0; longyylex(void){ vlong vv; long c, c1; char *cp; Rune rune; Sym *s; if(peekc != IGN) { c = peekc; peekc = IGN; goto l1; }l0: c = GETC(); l1: if(c >= Runeself) { /* * extension -- * all multibyte runes are alpha */ cp = symb; goto talph; } if(isspace(c)) { if(c == '\n') lineno++; goto l0; } if(isalpha(c)) { cp = symb; if(c != 'L') goto talph; *cp++ = c; c = GETC(); if(c == '\'') { /* L'x' */ c = escchar('\'', 1, 0); if(c == EOF) c = '\''; c1 = escchar('\'', 1, 0); if(c1 != EOF) { yyerror("missing '"); peekc = c1; } yylval.vval = convvtox(c, TUSHORT); return LUCONST; } if(c == '"') { goto caselq; } goto talph; } if(isdigit(c)) goto tnum; switch(c) { case EOF: peekc = EOF; return -1; case '_': cp = symb; goto talph; case '#': domacro(); goto l0; case '.': c1 = GETC(); if(isdigit(c1)) { cp = symb; *cp++ = c; c = c1; c1 = 0; goto casedot; } break; case '"': strcpy(symb, "\"<string>\""); cp = alloc(0); c1 = 0; /* "..." */ for(;;) { c = escchar('"', 0, 1); if(c == EOF) break; if(c & ESC) { cp = allocn(cp, c1, 1); cp[c1++] = c; } else { rune = c; c = runelen(rune); cp = allocn(cp, c1, c); runetochar(cp+c1, &rune); c1 += c; } } yylval.sval.l = c1; do { cp = allocn(cp, c1, 1); cp[c1++] = 0; } while(c1 & MAXALIGN); yylval.sval.s = cp; return LSTRING; caselq: /* L"..." */ strcpy(symb, "\"L<string>\""); cp = alloc(0); c1 = 0; for(;;) {Lines 1–500 of 1675. Load more
#include "cc.h" #include "y.tab.h" #ifndef CPP #define CPP "/bin/cpp" #endif static int ansip; void main(int argc, char *argv[]) { char *defs[50], *p; int nproc, nout, status, i, c, ndef; tinit(); cinit(); ginit(); arginit(); tufield = simplet((1L<<tfield->etype) | BUNSIGNED); ndef = 0; include[ninclude++] = "."; strings = 1; passes = 1; ARGBEGIN { default: break; case 'p': ansip = 1; break; case 'D': p = ARGF(); if(p) { defs[ndef++] = p; dodefine(p); } break; case 'I': p = ARGF(); setinclude(p); break; case 'm': domod = 1; break; case 'i': doinc = 1; break; case 'l': doloc = 1; break; case 'c': justcode = 1; break; case 'v': comm = 1; break; case 's': strings = 0; break; case 'S': strings = 2; break; case 'M': inmain = 1; break; case 'q': passes = 0; break; case 'a': doaddr = 1; break; case 'A': doaddr = 1; doalladdr = 1; break; } ARGEND if(doinc) domod = doloc = 0; linit(); if(argc != 1) { print("usage: c2l [-options] file\n"); errorexit(); } if(argc > 1 && systemtype(Windows)){ print("can't compile multiple files on windows\n"); errorexit(); } if(argc > 1 && !systemtype(Windows)) { nproc = 1; if(p = getenv("NPROC")) nproc = atol(p); /* */ c = 0; nout = 0; for(;;) { while(nout < nproc && argc > 0) { i = myfork(); if(i < 0) { i = mywait(&status); if(i < 0) { print("cannot create a process\n"); errorexit(); } if(status) c++; nout--; continue; } if(i == 0) { fprint(2, "%s:\n", *argv); if (compile(*argv, defs, ndef)) errorexit(); exits(0); } nout++; argc--; argv++; } i = mywait(&status); if(i < 0) { if(c) errorexit(); exits(0); } if(status) c++; nout--; } } if(argc == 0) c = compile("stdin", defs, ndef); else c = compile(argv[0], defs, ndef); if(c) errorexit(); exits(0); } int compile(char *file, char **defs, int ndef) { char ofile[200], incfile[20]; char *p, *av[100], opt[256]; int i, c, fd[2]; strcpy(ofile, file); p = utfrrune(ofile, pathchar()); if(p) { *p++ = 0; include[0] = strdup(ofile); } else p = ofile; USED(p); if(p = getenv("INCLUDE")) { setinclude(p); } else { if(systemtype(Plan9)) { sprint(incfile, "/%s/include", thestring); setinclude(strdup(incfile)); setinclude("/sys/include"); } } newio(); /* Use an ANSI preprocessor */ if(ansip) { if(systemtype(Windows)) { diag(Z, "-p option not supported on windows"); errorexit(); } if(mypipe(fd) < 0) { diag(Z, "pipe failed"); errorexit(); } switch(myfork()) { case -1: diag(Z, "fork failed"); errorexit(); case 0: close(fd[0]); mydup(fd[1], 1); close(fd[1]); av[0] = CPP; i = 1; for(c = 0; c < ndef; c++) { sprint(opt, "-D%s", defs[c]); av[i++] = strdup(opt); } for(c = 0; c < ninclude; c++) { sprint(opt, "-I%s", include[c]); av[i++] = strdup(opt); } if(strcmp(file, "stdin") != 0) av[i++] = file; av[i] = 0; if(0) { for(c = 0; c < i; c++) fprint(2, "%s ", av[c]); print("\n"); } myexec(av[0], av); fprint(2, "can't exec C preprocessor %s: %r\n", CPP); errorexit(); default: close(fd[1]); newfile(file, fd[0]); break; } } else { if(strcmp(file, "stdin") == 0) newfile(file, 0); else newfile(file, -1); } clbegin(); yyparse(); clend(); newsec(0); return nerrors; } void errorexit(void) { exits("error"); } void pushio(void) { Io *i; i = iostack; if(i == I) { yyerror("botch in pushio"); errorexit(); } i->p = fi.p; i->c = fi.c; } void newio(void) { Io *i; static pushdepth = 0; i = iofree; if(i == I) { pushdepth++; if(pushdepth > 1000) { yyerror("macro/io expansion too deep"); errorexit(); } i = alloc(sizeof(*i)); } else iofree = i->link; i->c = 0; i->f = -1; ionext = i; } void newfile(char *s, int f) { Io *i; if(0) print("%L: %s\n", lineno, s); i = ionext; i->link = iostack; iostack = i; i->f = f; if(f < 0) i->f = open(s, 0); if(i->f < 0) { yyerror("c2l: %r: %s", s); errorexit(); } fi.c = 0; linehist(s, 0); outpush(s); } Sym* slookup(char *s) { strcpy(symb, s); return lookup(); } Sym* lookup(void) { static Sym zsym; Sym *s; ulong h; char *p; int c, n; h = 0; for(p=symb; *p;) { h = h * 3; h += *p++; } n = (p - symb) + 1; if((long)h < 0) h = ~h; h %= NHASH; c = symb[0]; for(s = hash[h]; s != S; s = s->link) { if(s->name[0] != c) continue; if(strcmp(s->name, symb) == 0) return s; } s = alloc(sizeof(*s)); *s = zsym; s->name = alloc(n); memmove(s->name, symb, n); strcpy(s->name, symb); s->link = hash[h]; hash[h] = s; syminit(s); return s; } void syminit(Sym *s) { s->lexical = LNAME; s->type = T; s->suetag = T; s->class = CXXX; s->lname = s->mod = nil; s->lineno = lineno; s->tenum = T; } #define EOF (-1) #define IGN (-2) #define ESC (1<<20) #define GETC() ((--fi.c < 0)? filbuf(): (*fi.p++ & 0xff)) enum { Numdec = 1<<0, Numlong = 1<<1, Numuns = 1<<2, Numvlong = 1<<3, Numflt = 1<<4, }; static int ypeek = 0; long yylex(void) { vlong vv; long c, c1; char *cp; Rune rune; Sym *s; if(peekc != IGN) { c = peekc; peekc = IGN; goto l1; } l0: c = GETC(); l1: if(c >= Runeself) { /* * extension -- * all multibyte runes are alpha */ cp = symb; goto talph; } if(isspace(c)) { if(c == '\n') lineno++; goto l0; } if(isalpha(c)) { cp = symb; if(c != 'L') goto talph; *cp++ = c; c = GETC(); if(c == '\'') { /* L'x' */ c = escchar('\'', 1, 0); if(c == EOF) c = '\''; c1 = escchar('\'', 1, 0); if(c1 != EOF) { yyerror("missing '"); peekc = c1; } yylval.vval = convvtox(c, TUSHORT); return LUCONST; } if(c == '"') { goto caselq; } goto talph; } if(isdigit(c)) goto tnum; switch(c) { case EOF: peekc = EOF; return -1; case '_': cp = symb; goto talph; case '#': domacro(); goto l0; case '.': c1 = GETC(); if(isdigit(c1)) { cp = symb; *cp++ = c; c = c1; c1 = 0; goto casedot; } break; case '"': strcpy(symb, "\"<string>\""); cp = alloc(0); c1 = 0; /* "..." */ for(;;) { c = escchar('"', 0, 1); if(c == EOF) break; if(c & ESC) { cp = allocn(cp, c1, 1); cp[c1++] = c; } else { rune = c; c = runelen(rune); cp = allocn(cp, c1, c); runetochar(cp+c1, &rune); c1 += c; } } yylval.sval.l = c1; do { cp = allocn(cp, c1, 1); cp[c1++] = 0; } while(c1 & MAXALIGN); yylval.sval.s = cp; return LSTRING; caselq: /* L"..." */ strcpy(symb, "\"L<string>\""); cp = alloc(0); c1 = 0; for(;;) {