forsyth20121205-174063a80cc13 years agoHistory
1675 lines · 24.3 KB · C
RawDownload
#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.