xref: /plan9-contrib/sys/src/cmd/cc/lex.c (revision 40d015479ed36701ae6dcfd8814f849fc6285e8d)
13e12c5d1SDavid du Colombier #include	"cc.h"
23e12c5d1SDavid du Colombier #include	"y.tab.h"
33e12c5d1SDavid du Colombier 
47dd7cddfSDavid du Colombier #ifndef	CPP
57dd7cddfSDavid du Colombier #define	CPP	"/bin/cpp"
67dd7cddfSDavid du Colombier #endif
77dd7cddfSDavid du Colombier 
83e12c5d1SDavid du Colombier /*
93e12c5d1SDavid du Colombier  * known debug flags
10219b2ee8SDavid du Colombier  *	-a		acid declaration output
11219b2ee8SDavid du Colombier  *	-A		!B
1291178603SDavid du Colombier  *	-B		non ANSI
13219b2ee8SDavid du Colombier  *	-d		print declarations
1491178603SDavid du Colombier  *	-D name		define
157dd7cddfSDavid du Colombier  *	-F		format specification check
1691178603SDavid du Colombier  *	-i		print initialization
1791178603SDavid du Colombier  *	-I path		include
1891178603SDavid du Colombier  *	-l		generate little-endian code
1991178603SDavid du Colombier  *	-L		print every NAME symbol
2091178603SDavid du Colombier  *	-M		constant multiplication
21219b2ee8SDavid du Colombier  *	-m		print add/sub/mul trees
227dd7cddfSDavid du Colombier  *	-n		print acid to file (%.c=%.acid) (with -a or -aa)
2391178603SDavid du Colombier  *	-o file		output file
247dd7cddfSDavid du Colombier  *	-p		use standard cpp ANSI preprocessor (not on windows)
2591178603SDavid du Colombier  *	-r		print registerization
2691178603SDavid du Colombier  *	-s		print structure offsets (with -a or -aa)
27eed6406fSDavid du Colombier  *	-S		print assembly
2891178603SDavid du Colombier  *	-t		print type trees
297dd7cddfSDavid du Colombier  *	-V		enable void* conversion warnings
3091178603SDavid du Colombier  *	-v		verbose printing
3191178603SDavid du Colombier  *	-w		print warnings
3291178603SDavid du Colombier  *	-X		abort on error
338deabd96SDavid du Colombier  *	-.		Inhibit search for includes in source directory
343e12c5d1SDavid du Colombier  */
353e12c5d1SDavid du Colombier 
363e12c5d1SDavid du Colombier void
main(int argc,char * argv[])373e12c5d1SDavid du Colombier main(int argc, char *argv[])
383e12c5d1SDavid du Colombier {
396bbfed0dSDavid du Colombier 	char **defs, **np, *p;
406bbfed0dSDavid du Colombier 	int nproc, nout, status, i, c, ndef, maxdef;
413e12c5d1SDavid du Colombier 
423e12c5d1SDavid du Colombier 	memset(debug, 0, sizeof(debug));
437dd7cddfSDavid du Colombier 	tinit();
443e12c5d1SDavid du Colombier 	cinit();
453e12c5d1SDavid du Colombier 	ginit();
467dd7cddfSDavid du Colombier 	arginit();
473e12c5d1SDavid du Colombier 
48e288d156SDavid du Colombier 	profileflg = 1;	/* #pragma can turn it off */
497dd7cddfSDavid du Colombier 	tufield = simplet((1L<<tfield->etype) | BUNSIGNED);
506bbfed0dSDavid du Colombier 	maxdef = 0;
517dd7cddfSDavid du Colombier 	ndef = 0;
523e12c5d1SDavid du Colombier 	outfile = 0;
536bbfed0dSDavid du Colombier 	defs = nil;
546bbfed0dSDavid du Colombier 	setinclude(".");
553e12c5d1SDavid du Colombier 	ARGBEGIN {
563e12c5d1SDavid du Colombier 	default:
573e12c5d1SDavid du Colombier 		c = ARGC();
583e12c5d1SDavid du Colombier 		if(c >= 0 && c < sizeof(debug))
593e12c5d1SDavid du Colombier 			debug[c]++;
603e12c5d1SDavid du Colombier 		break;
613e12c5d1SDavid du Colombier 
6291178603SDavid du Colombier 	case 'l':			/* for little-endian mips */
6391178603SDavid du Colombier 		if(thechar != 'v'){
6491178603SDavid du Colombier 			print("can only use -l with vc");
6591178603SDavid du Colombier 			errorexit();
6691178603SDavid du Colombier 		}
6791178603SDavid du Colombier 		thechar = '0';
6891178603SDavid du Colombier 		thestring = "spim";
6991178603SDavid du Colombier 		break;
7091178603SDavid du Colombier 
713e12c5d1SDavid du Colombier 	case 'o':
723e12c5d1SDavid du Colombier 		outfile = ARGF();
733e12c5d1SDavid du Colombier 		break;
743e12c5d1SDavid du Colombier 
753e12c5d1SDavid du Colombier 	case 'D':
763e12c5d1SDavid du Colombier 		p = ARGF();
777dd7cddfSDavid du Colombier 		if(p) {
786bbfed0dSDavid du Colombier 			if(ndef >= maxdef){
796bbfed0dSDavid du Colombier 				maxdef += 50;
806bbfed0dSDavid du Colombier 				np = alloc(maxdef * sizeof *np);
816bbfed0dSDavid du Colombier 				if(defs != nil)
826bbfed0dSDavid du Colombier 					memmove(np, defs, (maxdef - 50) * sizeof *np);
836bbfed0dSDavid du Colombier 				defs = np;
846bbfed0dSDavid du Colombier 			}
857dd7cddfSDavid du Colombier 			defs[ndef++] = p;
863e12c5d1SDavid du Colombier 			dodefine(p);
877dd7cddfSDavid du Colombier 		}
883e12c5d1SDavid du Colombier 		break;
893e12c5d1SDavid du Colombier 
903e12c5d1SDavid du Colombier 	case 'I':
913e12c5d1SDavid du Colombier 		p = ARGF();
9282726826SDavid du Colombier 		if(p)
937dd7cddfSDavid du Colombier 			setinclude(p);
943e12c5d1SDavid du Colombier 		break;
953e12c5d1SDavid du Colombier 	} ARGEND
963e12c5d1SDavid du Colombier 	if(argc < 1 && outfile == 0) {
973e12c5d1SDavid du Colombier 		print("usage: %cc [-options] files\n", thechar);
983e12c5d1SDavid du Colombier 		errorexit();
993e12c5d1SDavid du Colombier 	}
1007dd7cddfSDavid du Colombier 	if(argc > 1 && systemtype(Windows)){
1017dd7cddfSDavid du Colombier 		print("can't compile multiple files on windows\n");
1027dd7cddfSDavid du Colombier 		errorexit();
1037dd7cddfSDavid du Colombier 	}
1047dd7cddfSDavid du Colombier 	if(argc > 1 && !systemtype(Windows)) {
1053e12c5d1SDavid du Colombier 		nproc = 1;
106aedc1c01SDavid du Colombier 		/*
107aedc1c01SDavid du Colombier 		 * if we're writing acid to standard output, don't compile
108aedc1c01SDavid du Colombier 		 * concurrently, to avoid interleaving output.
109aedc1c01SDavid du Colombier 		 */
110aedc1c01SDavid du Colombier 		if(((!debug['a'] && !debug['Z']) || debug['n']) &&
111aedc1c01SDavid du Colombier 		    (p = getenv("NPROC")) != nil)
1123e12c5d1SDavid du Colombier 			nproc = atol(p);	/* */
1133e12c5d1SDavid du Colombier 		c = 0;
1143e12c5d1SDavid du Colombier 		nout = 0;
1153e12c5d1SDavid du Colombier 		for(;;) {
1163e12c5d1SDavid du Colombier 			while(nout < nproc && argc > 0) {
1177dd7cddfSDavid du Colombier 				i = myfork();
1183e12c5d1SDavid du Colombier 				if(i < 0) {
1193e12c5d1SDavid du Colombier 					i = mywait(&status);
1203e12c5d1SDavid du Colombier 					if(i < 0) {
1213e12c5d1SDavid du Colombier 						print("cannot create a process\n");
1223e12c5d1SDavid du Colombier 						errorexit();
1233e12c5d1SDavid du Colombier 					}
1243e12c5d1SDavid du Colombier 					if(status)
1253e12c5d1SDavid du Colombier 						c++;
1263e12c5d1SDavid du Colombier 					nout--;
1273e12c5d1SDavid du Colombier 					continue;
1283e12c5d1SDavid du Colombier 				}
129219b2ee8SDavid du Colombier 				if(i == 0) {
1307dd7cddfSDavid du Colombier 					fprint(2, "%s:\n", *argv);
1317dd7cddfSDavid du Colombier 					if (compile(*argv, defs, ndef))
1327dd7cddfSDavid du Colombier 						errorexit();
1337dd7cddfSDavid du Colombier 					exits(0);
134219b2ee8SDavid du Colombier 				}
1353e12c5d1SDavid du Colombier 				nout++;
1363e12c5d1SDavid du Colombier 				argc--;
1373e12c5d1SDavid du Colombier 				argv++;
1383e12c5d1SDavid du Colombier 			}
1393e12c5d1SDavid du Colombier 			i = mywait(&status);
1403e12c5d1SDavid du Colombier 			if(i < 0) {
1413e12c5d1SDavid du Colombier 				if(c)
1423e12c5d1SDavid du Colombier 					errorexit();
1433e12c5d1SDavid du Colombier 				exits(0);
1443e12c5d1SDavid du Colombier 			}
1453e12c5d1SDavid du Colombier 			if(status)
1463e12c5d1SDavid du Colombier 				c++;
1473e12c5d1SDavid du Colombier 			nout--;
1483e12c5d1SDavid du Colombier 		}
1493e12c5d1SDavid du Colombier 	}
1503e12c5d1SDavid du Colombier 
1517dd7cddfSDavid du Colombier 	if(argc == 0)
1527dd7cddfSDavid du Colombier 		c = compile("stdin", defs, ndef);
1533e12c5d1SDavid du Colombier 	else
1547dd7cddfSDavid du Colombier 		c = compile(argv[0], defs, ndef);
1557dd7cddfSDavid du Colombier 
1567dd7cddfSDavid du Colombier 	if(c)
1577dd7cddfSDavid du Colombier 		errorexit();
1587dd7cddfSDavid du Colombier 	exits(0);
1597dd7cddfSDavid du Colombier }
1607dd7cddfSDavid du Colombier 
1617dd7cddfSDavid du Colombier int
compile(char * file,char ** defs,int ndef)1627dd7cddfSDavid du Colombier compile(char *file, char **defs, int ndef)
1637dd7cddfSDavid du Colombier {
164*40d01547SDavid du Colombier 	char ofile[400], incfile[200];
1656bbfed0dSDavid du Colombier 	char *p, **av, opt[256];
1667dd7cddfSDavid du Colombier 	int i, c, fd[2];
167aedc1c01SDavid du Colombier 	static int first = 1;
1687dd7cddfSDavid du Colombier 
1697dd7cddfSDavid du Colombier 	strcpy(ofile, file);
1707dd7cddfSDavid du Colombier 	p = utfrrune(ofile, pathchar());
1717dd7cddfSDavid du Colombier 	if(p) {
1723e12c5d1SDavid du Colombier 		*p++ = 0;
173810832d3SDavid du Colombier 		if(!debug['.'])
174375daca8SDavid du Colombier 			include[0] = strdup(ofile);
1753e12c5d1SDavid du Colombier 	} else
1763e12c5d1SDavid du Colombier 		p = ofile;
177314a20f0SDavid du Colombier 
1783e12c5d1SDavid du Colombier 	if(outfile == 0) {
1793e12c5d1SDavid du Colombier 		outfile = p;
1807dd7cddfSDavid du Colombier 		if(outfile) {
1813e12c5d1SDavid du Colombier 			if(p = utfrrune(outfile, '.'))
1823e12c5d1SDavid du Colombier 				if(p[1] == 'c' && p[2] == 0)
1833e12c5d1SDavid du Colombier 					p[0] = 0;
1843e12c5d1SDavid du Colombier 			p = utfrune(outfile, 0);
1857dd7cddfSDavid du Colombier 			if(debug['a'] && debug['n'])
1867dd7cddfSDavid du Colombier 				strcat(p, ".acid");
187fc375d71SDavid du Colombier 			else if(debug['Z'] && debug['n'])
18880ee5cbfSDavid du Colombier 				strcat(p, "_pickle.c");
1897dd7cddfSDavid du Colombier 			else {
1903e12c5d1SDavid du Colombier 				p[0] = '.';
1913e12c5d1SDavid du Colombier 				p[1] = thechar;
1923e12c5d1SDavid du Colombier 				p[2] = 0;
1933e12c5d1SDavid du Colombier 			}
1947dd7cddfSDavid du Colombier 		} else
1957dd7cddfSDavid du Colombier 			outfile = "/dev/null";
1963e12c5d1SDavid du Colombier 	}
1977dd7cddfSDavid du Colombier 
1983e12c5d1SDavid du Colombier 	if(p = getenv("INCLUDE")) {
1997dd7cddfSDavid du Colombier 		setinclude(p);
2003e12c5d1SDavid du Colombier 	} else {
2017dd7cddfSDavid du Colombier 		if(systemtype(Plan9)) {
202*40d01547SDavid du Colombier 			p = getenv("ccroot");
203*40d01547SDavid du Colombier 			if(p == nil)
204*40d01547SDavid du Colombier 				p = "";
205*40d01547SDavid du Colombier 			snprint(incfile, sizeof(incfile), "%s/%s/include", p, thestring);
2067dd7cddfSDavid du Colombier 			setinclude(strdup(incfile));
207*40d01547SDavid du Colombier 			snprint(incfile, sizeof(incfile), "%s/sys/include", p);
208*40d01547SDavid du Colombier 			setinclude(strdup(incfile));
209*40d01547SDavid du Colombier 			if(*p != '\0') {
210*40d01547SDavid du Colombier 				snprint(incfile, sizeof(incfile), "%s/include", p);
211*40d01547SDavid du Colombier 				if(myaccess(incfile) >= 0)
212*40d01547SDavid du Colombier 					setinclude(strdup(incfile));
213*40d01547SDavid du Colombier 			}
2143e12c5d1SDavid du Colombier 		}
2157dd7cddfSDavid du Colombier 	}
216aedc1c01SDavid du Colombier 	if (first)
217314a20f0SDavid du Colombier 		Binit(&diagbuf, 1, OWRITE);
218aedc1c01SDavid du Colombier 	/*
219aedc1c01SDavid du Colombier 	 * if we're writing acid to standard output, don't keep scratching
220aedc1c01SDavid du Colombier 	 * outbuf.
221aedc1c01SDavid du Colombier 	 */
222fc375d71SDavid du Colombier 	if((debug['a'] || debug['Z']) && !debug['n']) {
223aedc1c01SDavid du Colombier 		if (first) {
2243e12c5d1SDavid du Colombier 			outfile = 0;
225e059317eSDavid du Colombier 			Binit(&outbuf, dup(1, -1), OWRITE);
226e059317eSDavid du Colombier 			dup(2, 1);
227aedc1c01SDavid du Colombier 		}
228219b2ee8SDavid du Colombier 	} else {
229219b2ee8SDavid du Colombier 		c = mycreat(outfile, 0664);
230219b2ee8SDavid du Colombier 		if(c < 0) {
231314a20f0SDavid du Colombier 			diag(Z, "cannot open %s - %r", outfile);
232219b2ee8SDavid du Colombier 			outfile = 0;
233219b2ee8SDavid du Colombier 			errorexit();
234219b2ee8SDavid du Colombier 		}
235219b2ee8SDavid du Colombier 		Binit(&outbuf, c, OWRITE);
236219b2ee8SDavid du Colombier 	}
2373e12c5d1SDavid du Colombier 	newio();
238aedc1c01SDavid du Colombier 	first = 0;
2397dd7cddfSDavid du Colombier 
2407dd7cddfSDavid du Colombier 	/* Use an ANSI preprocessor */
2417dd7cddfSDavid du Colombier 	if(debug['p']) {
2427dd7cddfSDavid du Colombier 		if(systemtype(Windows)) {
2437dd7cddfSDavid du Colombier 			diag(Z, "-p option not supported on windows");
2447dd7cddfSDavid du Colombier 			errorexit();
2457dd7cddfSDavid du Colombier 		}
24680ee5cbfSDavid du Colombier 		if(myaccess(file) < 0) {
24780ee5cbfSDavid du Colombier 			diag(Z, "%s does not exist", file);
24880ee5cbfSDavid du Colombier 			errorexit();
24980ee5cbfSDavid du Colombier 		}
2507dd7cddfSDavid du Colombier 		if(mypipe(fd) < 0) {
2517dd7cddfSDavid du Colombier 			diag(Z, "pipe failed");
2527dd7cddfSDavid du Colombier 			errorexit();
2537dd7cddfSDavid du Colombier 		}
2547dd7cddfSDavid du Colombier 		switch(myfork()) {
2557dd7cddfSDavid du Colombier 		case -1:
2567dd7cddfSDavid du Colombier 			diag(Z, "fork failed");
2577dd7cddfSDavid du Colombier 			errorexit();
2587dd7cddfSDavid du Colombier 		case 0:
2597dd7cddfSDavid du Colombier 			close(fd[0]);
2607dd7cddfSDavid du Colombier 			mydup(fd[1], 1);
2617dd7cddfSDavid du Colombier 			close(fd[1]);
2626bbfed0dSDavid du Colombier 			av = alloc((3 + ndef + ninclude + 2) * sizeof *av);
2637dd7cddfSDavid du Colombier 			av[0] = CPP;
2647dd7cddfSDavid du Colombier 			i = 1;
2657ee275a1SDavid du Colombier 			if(debug['.'])
2667ee275a1SDavid du Colombier 				av[i++] = strdup("-.");
2677ee275a1SDavid du Colombier 			/* 1999 ANSI C requires recognising // comments */
2687ee275a1SDavid du Colombier 			av[i++] = strdup("-+");
2697dd7cddfSDavid du Colombier 			for(c = 0; c < ndef; c++) {
27057cfc11bSDavid du Colombier 				snprint(opt, sizeof opt, "-D%s", defs[c]);
2717dd7cddfSDavid du Colombier 				av[i++] = strdup(opt);
2727dd7cddfSDavid du Colombier 			}
2737dd7cddfSDavid du Colombier 			for(c = 0; c < ninclude; c++) {
27457cfc11bSDavid du Colombier 				snprint(opt, sizeof opt, "-I%s", include[c]);
2757dd7cddfSDavid du Colombier 				av[i++] = strdup(opt);
2767dd7cddfSDavid du Colombier 			}
2777dd7cddfSDavid du Colombier 			if(strcmp(file, "stdin") != 0)
2787dd7cddfSDavid du Colombier 				av[i++] = file;
2797dd7cddfSDavid du Colombier 			av[i] = 0;
2807dd7cddfSDavid du Colombier 			if(debug['p'] > 1) {
2817dd7cddfSDavid du Colombier 				for(c = 0; c < i; c++)
2827dd7cddfSDavid du Colombier 					fprint(2, "%s ", av[c]);
2834de34a7eSDavid du Colombier 				fprint(2, "\n");
2847dd7cddfSDavid du Colombier 			}
2857dd7cddfSDavid du Colombier 			myexec(av[0], av);
2867dd7cddfSDavid du Colombier 			fprint(2, "can't exec C preprocessor %s: %r\n", CPP);
2877dd7cddfSDavid du Colombier 			errorexit();
2887dd7cddfSDavid du Colombier 		default:
2897dd7cddfSDavid du Colombier 			close(fd[1]);
2907dd7cddfSDavid du Colombier 			newfile(file, fd[0]);
2917dd7cddfSDavid du Colombier 			break;
2927dd7cddfSDavid du Colombier 		}
2937dd7cddfSDavid du Colombier 	} else {
2947dd7cddfSDavid du Colombier 		if(strcmp(file, "stdin") == 0)
2957dd7cddfSDavid du Colombier 			newfile(file, 0);
2963e12c5d1SDavid du Colombier 		else
2977dd7cddfSDavid du Colombier 			newfile(file, -1);
2987dd7cddfSDavid du Colombier 	}
2993e12c5d1SDavid du Colombier 	yyparse();
300fc375d71SDavid du Colombier 	if(!debug['a'] && !debug['Z'])
3013e12c5d1SDavid du Colombier 		gclean();
3027dd7cddfSDavid du Colombier 	return nerrors;
3033e12c5d1SDavid du Colombier }
3043e12c5d1SDavid du Colombier 
3053e12c5d1SDavid du Colombier void
errorexit(void)3063e12c5d1SDavid du Colombier errorexit(void)
3073e12c5d1SDavid du Colombier {
3083e12c5d1SDavid du Colombier 	if(outfile)
3093e12c5d1SDavid du Colombier 		remove(outfile);
3103e12c5d1SDavid du Colombier 	exits("error");
3113e12c5d1SDavid du Colombier }
3123e12c5d1SDavid du Colombier 
3133e12c5d1SDavid du Colombier void
pushio(void)3143e12c5d1SDavid du Colombier pushio(void)
3153e12c5d1SDavid du Colombier {
3163e12c5d1SDavid du Colombier 	Io *i;
3173e12c5d1SDavid du Colombier 
3183e12c5d1SDavid du Colombier 	i = iostack;
3193e12c5d1SDavid du Colombier 	if(i == I) {
3203e12c5d1SDavid du Colombier 		yyerror("botch in pushio");
3213e12c5d1SDavid du Colombier 		errorexit();
3223e12c5d1SDavid du Colombier 	}
3233e12c5d1SDavid du Colombier 	i->p = fi.p;
3243e12c5d1SDavid du Colombier 	i->c = fi.c;
3253e12c5d1SDavid du Colombier }
3263e12c5d1SDavid du Colombier 
3273e12c5d1SDavid du Colombier void
newio(void)3283e12c5d1SDavid du Colombier newio(void)
3293e12c5d1SDavid du Colombier {
3303e12c5d1SDavid du Colombier 	Io *i;
331375daca8SDavid du Colombier 	static int pushdepth = 0;
3323e12c5d1SDavid du Colombier 
3333e12c5d1SDavid du Colombier 	i = iofree;
3343e12c5d1SDavid du Colombier 	if(i == I) {
3353e12c5d1SDavid du Colombier 		pushdepth++;
3363e12c5d1SDavid du Colombier 		if(pushdepth > 1000) {
3373e12c5d1SDavid du Colombier 			yyerror("macro/io expansion too deep");
3383e12c5d1SDavid du Colombier 			errorexit();
3393e12c5d1SDavid du Colombier 		}
3407dd7cddfSDavid du Colombier 		i = alloc(sizeof(*i));
3413e12c5d1SDavid du Colombier 	} else
3423e12c5d1SDavid du Colombier 		iofree = i->link;
3433e12c5d1SDavid du Colombier 	i->c = 0;
3443e12c5d1SDavid du Colombier 	i->f = -1;
3453e12c5d1SDavid du Colombier 	ionext = i;
3463e12c5d1SDavid du Colombier }
3473e12c5d1SDavid du Colombier 
3483e12c5d1SDavid du Colombier void
newfile(char * s,int f)3493e12c5d1SDavid du Colombier newfile(char *s, int f)
3503e12c5d1SDavid du Colombier {
3513e12c5d1SDavid du Colombier 	Io *i;
3523e12c5d1SDavid du Colombier 
3537dd7cddfSDavid du Colombier 	if(debug['e'])
3547dd7cddfSDavid du Colombier 		print("%L: %s\n", lineno, s);
3557dd7cddfSDavid du Colombier 
3563e12c5d1SDavid du Colombier 	i = ionext;
3573e12c5d1SDavid du Colombier 	i->link = iostack;
3583e12c5d1SDavid du Colombier 	iostack = i;
3593e12c5d1SDavid du Colombier 	i->f = f;
3603e12c5d1SDavid du Colombier 	if(f < 0)
3613e12c5d1SDavid du Colombier 		i->f = open(s, 0);
3623e12c5d1SDavid du Colombier 	if(i->f < 0) {
3637dd7cddfSDavid du Colombier 		yyerror("%cc: %r: %s", thechar, s);
3643e12c5d1SDavid du Colombier 		errorexit();
3653e12c5d1SDavid du Colombier 	}
3663e12c5d1SDavid du Colombier 	fi.c = 0;
3673e12c5d1SDavid du Colombier 	linehist(s, 0);
3683e12c5d1SDavid du Colombier }
3693e12c5d1SDavid du Colombier 
3703e12c5d1SDavid du Colombier Sym*
slookup(char * s)3713e12c5d1SDavid du Colombier slookup(char *s)
3723e12c5d1SDavid du Colombier {
3733e12c5d1SDavid du Colombier 
3743e12c5d1SDavid du Colombier 	strcpy(symb, s);
3753e12c5d1SDavid du Colombier 	return lookup();
3763e12c5d1SDavid du Colombier }
3773e12c5d1SDavid du Colombier 
3783e12c5d1SDavid du Colombier Sym*
lookup(void)3793e12c5d1SDavid du Colombier lookup(void)
3803e12c5d1SDavid du Colombier {
3813e12c5d1SDavid du Colombier 	Sym *s;
3823e12c5d1SDavid du Colombier 	ulong h;
383219b2ee8SDavid du Colombier 	char *p;
384219b2ee8SDavid du Colombier 	int c, n;
3853e12c5d1SDavid du Colombier 
386219b2ee8SDavid du Colombier 	h = 0;
3873e12c5d1SDavid du Colombier 	for(p=symb; *p;) {
388219b2ee8SDavid du Colombier 		h = h * 3;
389219b2ee8SDavid du Colombier 		h += *p++;
3903e12c5d1SDavid du Colombier 	}
391219b2ee8SDavid du Colombier 	n = (p - symb) + 1;
392219b2ee8SDavid du Colombier 	if((long)h < 0)
393219b2ee8SDavid du Colombier 		h = ~h;
3943e12c5d1SDavid du Colombier 	h %= NHASH;
395219b2ee8SDavid du Colombier 	c = symb[0];
3963e12c5d1SDavid du Colombier 	for(s = hash[h]; s != S; s = s->link) {
397219b2ee8SDavid du Colombier 		if(s->name[0] != c)
3983e12c5d1SDavid du Colombier 			continue;
399219b2ee8SDavid du Colombier 		if(strcmp(s->name, symb) == 0)
4003e12c5d1SDavid du Colombier 			return s;
4013e12c5d1SDavid du Colombier 	}
4027dd7cddfSDavid du Colombier 	s = alloc(sizeof(*s));
4037dd7cddfSDavid du Colombier 	s->name = alloc(n);
404219b2ee8SDavid du Colombier 	memmove(s->name, symb, n);
405219b2ee8SDavid du Colombier 
4063e12c5d1SDavid du Colombier 	strcpy(s->name, symb);
4073e12c5d1SDavid du Colombier 	s->link = hash[h];
4083e12c5d1SDavid du Colombier 	hash[h] = s;
4093e12c5d1SDavid du Colombier 	syminit(s);
4103e12c5d1SDavid du Colombier 
4113e12c5d1SDavid du Colombier 	return s;
4123e12c5d1SDavid du Colombier }
4133e12c5d1SDavid du Colombier 
4143e12c5d1SDavid du Colombier void
syminit(Sym * s)4153e12c5d1SDavid du Colombier syminit(Sym *s)
4163e12c5d1SDavid du Colombier {
4173e12c5d1SDavid du Colombier 	s->lexical = LNAME;
4183e12c5d1SDavid du Colombier 	s->block = 0;
4193e12c5d1SDavid du Colombier 	s->offset = 0;
4203e12c5d1SDavid du Colombier 	s->type = T;
4213e12c5d1SDavid du Colombier 	s->suetag = T;
4223e12c5d1SDavid du Colombier 	s->class = CXXX;
4233e12c5d1SDavid du Colombier 	s->aused = 0;
424375daca8SDavid du Colombier 	s->sig = SIGNONE;
4253e12c5d1SDavid du Colombier }
4263e12c5d1SDavid du Colombier 
4273e12c5d1SDavid du Colombier #define	EOF	(-1)
4283e12c5d1SDavid du Colombier #define	IGN	(-2)
429905f70e7SDavid du Colombier #define	ESC	(Runemask+1)		/* Rune flag: a literal byte */
4303e12c5d1SDavid du Colombier #define	GETC()	((--fi.c < 0)? filbuf(): (*fi.p++ & 0xff))
4313e12c5d1SDavid du Colombier 
4323e12c5d1SDavid du Colombier enum
4333e12c5d1SDavid du Colombier {
4343e12c5d1SDavid du Colombier 	Numdec		= 1<<0,
4353e12c5d1SDavid du Colombier 	Numlong		= 1<<1,
4363e12c5d1SDavid du Colombier 	Numuns		= 1<<2,
4373e12c5d1SDavid du Colombier 	Numvlong	= 1<<3,
4383e12c5d1SDavid du Colombier 	Numflt		= 1<<4,
4393e12c5d1SDavid du Colombier };
4403e12c5d1SDavid du Colombier 
4413e12c5d1SDavid du Colombier long
yylex(void)4423e12c5d1SDavid du Colombier yylex(void)
4433e12c5d1SDavid du Colombier {
444219b2ee8SDavid du Colombier 	vlong vv;
44522a127bbSDavid du Colombier 	long c, c1, t;
4463e12c5d1SDavid du Colombier 	char *cp;
4473e12c5d1SDavid du Colombier 	Rune rune;
4483e12c5d1SDavid du Colombier 	Sym *s;
4493e12c5d1SDavid du Colombier 
4503e12c5d1SDavid du Colombier 	if(peekc != IGN) {
4513e12c5d1SDavid du Colombier 		c = peekc;
4523e12c5d1SDavid du Colombier 		peekc = IGN;
4533e12c5d1SDavid du Colombier 		goto l1;
4543e12c5d1SDavid du Colombier 	}
4553e12c5d1SDavid du Colombier l0:
4563e12c5d1SDavid du Colombier 	c = GETC();
4573e12c5d1SDavid du Colombier 
4583e12c5d1SDavid du Colombier l1:
4593e12c5d1SDavid du Colombier 	if(c >= Runeself) {
4603e12c5d1SDavid du Colombier 		/*
4613e12c5d1SDavid du Colombier 		 * extension --
4623e12c5d1SDavid du Colombier 		 *	all multibyte runes are alpha
4633e12c5d1SDavid du Colombier 		 */
4643e12c5d1SDavid du Colombier 		cp = symb;
4653e12c5d1SDavid du Colombier 		goto talph;
4663e12c5d1SDavid du Colombier 	}
4673e12c5d1SDavid du Colombier 	if(isspace(c)) {
4683e12c5d1SDavid du Colombier 		if(c == '\n')
4693e12c5d1SDavid du Colombier 			lineno++;
4703e12c5d1SDavid du Colombier 		goto l0;
4713e12c5d1SDavid du Colombier 	}
4723e12c5d1SDavid du Colombier 	if(isalpha(c)) {
4733e12c5d1SDavid du Colombier 		cp = symb;
4743e12c5d1SDavid du Colombier 		if(c != 'L')
4753e12c5d1SDavid du Colombier 			goto talph;
4763e12c5d1SDavid du Colombier 		*cp++ = c;
4773e12c5d1SDavid du Colombier 		c = GETC();
4783e12c5d1SDavid du Colombier 		if(c == '\'') {
4793e12c5d1SDavid du Colombier 			/* L'x' */
4803e12c5d1SDavid du Colombier 			c = escchar('\'', 1, 0);
4813e12c5d1SDavid du Colombier 			if(c == EOF)
4823e12c5d1SDavid du Colombier 				c = '\'';
4833e12c5d1SDavid du Colombier 			c1 = escchar('\'', 1, 0);
4843e12c5d1SDavid du Colombier 			if(c1 != EOF) {
4853e12c5d1SDavid du Colombier 				yyerror("missing '");
4863e12c5d1SDavid du Colombier 				peekc = c1;
4873e12c5d1SDavid du Colombier 			}
48882726826SDavid du Colombier 			yylval.vval = convvtox(c, TRUNE);
4893e12c5d1SDavid du Colombier 			return LUCONST;
4903e12c5d1SDavid du Colombier 		}
4913e12c5d1SDavid du Colombier 		if(c == '"') {
4923e12c5d1SDavid du Colombier 			goto caselq;
4933e12c5d1SDavid du Colombier 		}
4943e12c5d1SDavid du Colombier 		goto talph;
4953e12c5d1SDavid du Colombier 	}
4963e12c5d1SDavid du Colombier 	if(isdigit(c))
4973e12c5d1SDavid du Colombier 		goto tnum;
4983e12c5d1SDavid du Colombier 	switch(c)
4993e12c5d1SDavid du Colombier 	{
5003e12c5d1SDavid du Colombier 
5013e12c5d1SDavid du Colombier 	case EOF:
5023e12c5d1SDavid du Colombier 		peekc = EOF;
5033e12c5d1SDavid du Colombier 		return -1;
5043e12c5d1SDavid du Colombier 
5053e12c5d1SDavid du Colombier 	case '_':
5063e12c5d1SDavid du Colombier 		cp = symb;
5073e12c5d1SDavid du Colombier 		goto talph;
5083e12c5d1SDavid du Colombier 
5093e12c5d1SDavid du Colombier 	case '#':
5103e12c5d1SDavid du Colombier 		domacro();
5113e12c5d1SDavid du Colombier 		goto l0;
5123e12c5d1SDavid du Colombier 
5133e12c5d1SDavid du Colombier 	case '.':
5143e12c5d1SDavid du Colombier 		c1 = GETC();
5153e12c5d1SDavid du Colombier 		if(isdigit(c1)) {
5163e12c5d1SDavid du Colombier 			cp = symb;
5173e12c5d1SDavid du Colombier 			*cp++ = c;
5183e12c5d1SDavid du Colombier 			c = c1;
5193e12c5d1SDavid du Colombier 			c1 = 0;
5203e12c5d1SDavid du Colombier 			goto casedot;
5213e12c5d1SDavid du Colombier 		}
5223e12c5d1SDavid du Colombier 		break;
5233e12c5d1SDavid du Colombier 
5243e12c5d1SDavid du Colombier 	case '"':
5257dd7cddfSDavid du Colombier 		strcpy(symb, "\"<string>\"");
5267dd7cddfSDavid du Colombier 		cp = alloc(0);
5273e12c5d1SDavid du Colombier 		c1 = 0;
5283e12c5d1SDavid du Colombier 
5293e12c5d1SDavid du Colombier 		/* "..." */
5303e12c5d1SDavid du Colombier 		for(;;) {
5313e12c5d1SDavid du Colombier 			c = escchar('"', 0, 1);
5323e12c5d1SDavid du Colombier 			if(c == EOF)
5333e12c5d1SDavid du Colombier 				break;
5343e12c5d1SDavid du Colombier 			if(c & ESC) {
5357dd7cddfSDavid du Colombier 				cp = allocn(cp, c1, 1);
5367dd7cddfSDavid du Colombier 				cp[c1++] = c;
5373e12c5d1SDavid du Colombier 			} else {
5383e12c5d1SDavid du Colombier 				rune = c;
5393e12c5d1SDavid du Colombier 				c = runelen(rune);
5407dd7cddfSDavid du Colombier 				cp = allocn(cp, c1, c);
5413e12c5d1SDavid du Colombier 				runetochar(cp+c1, &rune);
5423e12c5d1SDavid du Colombier 				c1 += c;
5433e12c5d1SDavid du Colombier 			}
5443e12c5d1SDavid du Colombier 		}
5457dd7cddfSDavid du Colombier 		yylval.sval.l = c1;
5463e12c5d1SDavid du Colombier 		do {
5477dd7cddfSDavid du Colombier 			cp = allocn(cp, c1, 1);
5483e12c5d1SDavid du Colombier 			cp[c1++] = 0;
5497dd7cddfSDavid du Colombier 		} while(c1 & MAXALIGN);
5507dd7cddfSDavid du Colombier 		yylval.sval.s = cp;
5513e12c5d1SDavid du Colombier 		return LSTRING;
5523e12c5d1SDavid du Colombier 
5533e12c5d1SDavid du Colombier 	caselq:
5543e12c5d1SDavid du Colombier 		/* L"..." */
5557dd7cddfSDavid du Colombier 		strcpy(symb, "\"L<string>\"");
5567dd7cddfSDavid du Colombier 		cp = alloc(0);
5577dd7cddfSDavid du Colombier 		c1 = 0;
5583e12c5d1SDavid du Colombier 		for(;;) {
5593e12c5d1SDavid du Colombier 			c = escchar('"', 1, 0);
5603e12c5d1SDavid du Colombier 			if(c == EOF)
5613e12c5d1SDavid du Colombier 				break;
56282726826SDavid du Colombier 			cp = allocn(cp, c1, sizeof(TRune));
56382726826SDavid du Colombier 			*(TRune*)(cp + c1) = c;
56482726826SDavid du Colombier 			c1 += sizeof(TRune);
5653e12c5d1SDavid du Colombier 		}
5667dd7cddfSDavid du Colombier 		yylval.sval.l = c1;
5673e12c5d1SDavid du Colombier 		do {
56882726826SDavid du Colombier 			cp = allocn(cp, c1, sizeof(TRune));
56982726826SDavid du Colombier 			*(TRune*)(cp + c1) = 0;
57082726826SDavid du Colombier 			c1 += sizeof(TRune);
5717dd7cddfSDavid du Colombier 		} while(c1 & MAXALIGN);
5727dd7cddfSDavid du Colombier 		yylval.sval.s = cp;
5733e12c5d1SDavid du Colombier 		return LLSTRING;
5743e12c5d1SDavid du Colombier 
5753e12c5d1SDavid du Colombier 	case '\'':
5763e12c5d1SDavid du Colombier 		/* '.' */
5773e12c5d1SDavid du Colombier 		c = escchar('\'', 0, 0);
5783e12c5d1SDavid du Colombier 		if(c == EOF)
5793e12c5d1SDavid du Colombier 			c = '\'';
5803e12c5d1SDavid du Colombier 		c1 = escchar('\'', 0, 0);
5813e12c5d1SDavid du Colombier 		if(c1 != EOF) {
5823e12c5d1SDavid du Colombier 			yyerror("missing '");
5833e12c5d1SDavid du Colombier 			peekc = c1;
5843e12c5d1SDavid du Colombier 		}
585219b2ee8SDavid du Colombier 		vv = c;
586219b2ee8SDavid du Colombier 		yylval.vval = convvtox(vv, TUCHAR);
587219b2ee8SDavid du Colombier 		if(yylval.vval != vv)
5887dd7cddfSDavid du Colombier 			yyerror("overflow in character constant: 0x%lx", c);
5897dd7cddfSDavid du Colombier 		else
59022a127bbSDavid du Colombier 		if(c & 0x80){
59122a127bbSDavid du Colombier 			nearln = lineno;
5927dd7cddfSDavid du Colombier 			warn(Z, "sign-extended character constant");
59322a127bbSDavid du Colombier 		}
594219b2ee8SDavid du Colombier 		yylval.vval = convvtox(vv, TCHAR);
5953e12c5d1SDavid du Colombier 		return LCONST;
5963e12c5d1SDavid du Colombier 
5973e12c5d1SDavid du Colombier 	case '/':
5983e12c5d1SDavid du Colombier 		c1 = GETC();
5993e12c5d1SDavid du Colombier 		if(c1 == '*') {
6003e12c5d1SDavid du Colombier 			for(;;) {
6013e12c5d1SDavid du Colombier 				c = getr();
6023e12c5d1SDavid du Colombier 				while(c == '*') {
6033e12c5d1SDavid du Colombier 					c = getr();
6043e12c5d1SDavid du Colombier 					if(c == '/')
6053e12c5d1SDavid du Colombier 						goto l0;
6063e12c5d1SDavid du Colombier 				}
6073e12c5d1SDavid du Colombier 				if(c == EOF) {
6083e12c5d1SDavid du Colombier 					yyerror("eof in comment");
6093e12c5d1SDavid du Colombier 					errorexit();
6103e12c5d1SDavid du Colombier 				}
6113e12c5d1SDavid du Colombier 			}
6123e12c5d1SDavid du Colombier 		}
613219b2ee8SDavid du Colombier 		if(c1 == '/') {
614219b2ee8SDavid du Colombier 			for(;;) {
615219b2ee8SDavid du Colombier 				c = getr();
616219b2ee8SDavid du Colombier 				if(c == '\n')
617219b2ee8SDavid du Colombier 					goto l0;
618219b2ee8SDavid du Colombier 				if(c == EOF) {
619219b2ee8SDavid du Colombier 					yyerror("eof in comment");
620219b2ee8SDavid du Colombier 					errorexit();
621219b2ee8SDavid du Colombier 				}
622219b2ee8SDavid du Colombier 			}
623219b2ee8SDavid du Colombier 		}
6243e12c5d1SDavid du Colombier 		if(c1 == '=')
6253e12c5d1SDavid du Colombier 			return LDVE;
6263e12c5d1SDavid du Colombier 		break;
6273e12c5d1SDavid du Colombier 
6283e12c5d1SDavid du Colombier 	case '*':
6293e12c5d1SDavid du Colombier 		c1 = GETC();
6303e12c5d1SDavid du Colombier 		if(c1 == '=')
6313e12c5d1SDavid du Colombier 			return LMLE;
6323e12c5d1SDavid du Colombier 		break;
6333e12c5d1SDavid du Colombier 
6343e12c5d1SDavid du Colombier 	case '%':
6353e12c5d1SDavid du Colombier 		c1 = GETC();
6363e12c5d1SDavid du Colombier 		if(c1 == '=')
6373e12c5d1SDavid du Colombier 			return LMDE;
6383e12c5d1SDavid du Colombier 		break;
6393e12c5d1SDavid du Colombier 
6403e12c5d1SDavid du Colombier 	case '+':
6413e12c5d1SDavid du Colombier 		c1 = GETC();
6423e12c5d1SDavid du Colombier 		if(c1 == '+')
6433e12c5d1SDavid du Colombier 			return LPP;
6443e12c5d1SDavid du Colombier 		if(c1 == '=')
6453e12c5d1SDavid du Colombier 			return LPE;
6463e12c5d1SDavid du Colombier 		break;
6473e12c5d1SDavid du Colombier 
6483e12c5d1SDavid du Colombier 	case '-':
6493e12c5d1SDavid du Colombier 		c1 = GETC();
6503e12c5d1SDavid du Colombier 		if(c1 == '-')
6513e12c5d1SDavid du Colombier 			return LMM;
6523e12c5d1SDavid du Colombier 		if(c1 == '=')
6533e12c5d1SDavid du Colombier 			return LME;
6543e12c5d1SDavid du Colombier 		if(c1 == '>')
6553e12c5d1SDavid du Colombier 			return LMG;
6563e12c5d1SDavid du Colombier 		break;
6573e12c5d1SDavid du Colombier 
6583e12c5d1SDavid du Colombier 	case '>':
6593e12c5d1SDavid du Colombier 		c1 = GETC();
6603e12c5d1SDavid du Colombier 		if(c1 == '>') {
6613e12c5d1SDavid du Colombier 			c = LRSH;
6623e12c5d1SDavid du Colombier 			c1 = GETC();
6633e12c5d1SDavid du Colombier 			if(c1 == '=')
6643e12c5d1SDavid du Colombier 				return LRSHE;
6653e12c5d1SDavid du Colombier 			break;
6663e12c5d1SDavid du Colombier 		}
6673e12c5d1SDavid du Colombier 		if(c1 == '=')
6683e12c5d1SDavid du Colombier 			return LGE;
6693e12c5d1SDavid du Colombier 		break;
6703e12c5d1SDavid du Colombier 
6713e12c5d1SDavid du Colombier 	case '<':
6723e12c5d1SDavid du Colombier 		c1 = GETC();
6733e12c5d1SDavid du Colombier 		if(c1 == '<') {
6743e12c5d1SDavid du Colombier 			c = LLSH;
6753e12c5d1SDavid du Colombier 			c1 = GETC();
6763e12c5d1SDavid du Colombier 			if(c1 == '=')
6773e12c5d1SDavid du Colombier 				return LLSHE;
6783e12c5d1SDavid du Colombier 			break;
6793e12c5d1SDavid du Colombier 		}
6803e12c5d1SDavid du Colombier 		if(c1 == '=')
6813e12c5d1SDavid du Colombier 			return LLE;
6823e12c5d1SDavid du Colombier 		break;
6833e12c5d1SDavid du Colombier 
6843e12c5d1SDavid du Colombier 	case '=':
6853e12c5d1SDavid du Colombier 		c1 = GETC();
6863e12c5d1SDavid du Colombier 		if(c1 == '=')
6873e12c5d1SDavid du Colombier 			return LEQ;
6883e12c5d1SDavid du Colombier 		break;
6893e12c5d1SDavid du Colombier 
6903e12c5d1SDavid du Colombier 	case '!':
6913e12c5d1SDavid du Colombier 		c1 = GETC();
6923e12c5d1SDavid du Colombier 		if(c1 == '=')
6933e12c5d1SDavid du Colombier 			return LNE;
6943e12c5d1SDavid du Colombier 		break;
6953e12c5d1SDavid du Colombier 
6963e12c5d1SDavid du Colombier 	case '&':
6973e12c5d1SDavid du Colombier 		c1 = GETC();
6983e12c5d1SDavid du Colombier 		if(c1 == '&')
6993e12c5d1SDavid du Colombier 			return LANDAND;
7003e12c5d1SDavid du Colombier 		if(c1 == '=')
7013e12c5d1SDavid du Colombier 			return LANDE;
7023e12c5d1SDavid du Colombier 		break;
7033e12c5d1SDavid du Colombier 
7043e12c5d1SDavid du Colombier 	case '|':
7053e12c5d1SDavid du Colombier 		c1 = GETC();
7063e12c5d1SDavid du Colombier 		if(c1 == '|')
7073e12c5d1SDavid du Colombier 			return LOROR;
7083e12c5d1SDavid du Colombier 		if(c1 == '=')
7093e12c5d1SDavid du Colombier 			return LORE;
7103e12c5d1SDavid du Colombier 		break;
7113e12c5d1SDavid du Colombier 
7123e12c5d1SDavid du Colombier 	case '^':
7133e12c5d1SDavid du Colombier 		c1 = GETC();
7143e12c5d1SDavid du Colombier 		if(c1 == '=')
7153e12c5d1SDavid du Colombier 			return LXORE;
7163e12c5d1SDavid du Colombier 		break;
7173e12c5d1SDavid du Colombier 
7183e12c5d1SDavid du Colombier 	default:
7193e12c5d1SDavid du Colombier 		return c;
7203e12c5d1SDavid du Colombier 	}
7213e12c5d1SDavid du Colombier 	peekc = c1;
7223e12c5d1SDavid du Colombier 	return c;
7233e12c5d1SDavid du Colombier 
7243e12c5d1SDavid du Colombier talph:
7253e12c5d1SDavid du Colombier 	/*
7263e12c5d1SDavid du Colombier 	 * cp is set to symb and some
7273e12c5d1SDavid du Colombier 	 * prefix has been stored
7283e12c5d1SDavid du Colombier 	 */
7293e12c5d1SDavid du Colombier 	for(;;) {
7303e12c5d1SDavid du Colombier 		if(c >= Runeself) {
7313e12c5d1SDavid du Colombier 			for(c1=0;;) {
7323e12c5d1SDavid du Colombier 				cp[c1++] = c;
7333e12c5d1SDavid du Colombier 				if(fullrune(cp, c1))
7343e12c5d1SDavid du Colombier 					break;
7353e12c5d1SDavid du Colombier 				c = GETC();
7363e12c5d1SDavid du Colombier 			}
7373e12c5d1SDavid du Colombier 			cp += c1;
7383e12c5d1SDavid du Colombier 			c = GETC();
7393e12c5d1SDavid du Colombier 			continue;
7403e12c5d1SDavid du Colombier 		}
7413e12c5d1SDavid du Colombier 		if(!isalnum(c) && c != '_')
7423e12c5d1SDavid du Colombier 			break;
7433e12c5d1SDavid du Colombier 		*cp++ = c;
7443e12c5d1SDavid du Colombier 		c = GETC();
7453e12c5d1SDavid du Colombier 	}
7463e12c5d1SDavid du Colombier 	*cp = 0;
7473e12c5d1SDavid du Colombier 	if(debug['L'])
748219b2ee8SDavid du Colombier 		print("%L: %s\n", lineno, symb);
7493e12c5d1SDavid du Colombier 	peekc = c;
7503e12c5d1SDavid du Colombier 	s = lookup();
7513e12c5d1SDavid du Colombier 	if(s->macro) {
7523e12c5d1SDavid du Colombier 		newio();
7533e12c5d1SDavid du Colombier 		cp = ionext->b;
7543e12c5d1SDavid du Colombier 		macexpand(s, cp);
7553e12c5d1SDavid du Colombier 		pushio();
7563e12c5d1SDavid du Colombier 		ionext->link = iostack;
7573e12c5d1SDavid du Colombier 		iostack = ionext;
7583e12c5d1SDavid du Colombier 		fi.p = cp;
7593e12c5d1SDavid du Colombier 		fi.c = strlen(cp);
7603e12c5d1SDavid du Colombier 		if(peekc != IGN) {
7613e12c5d1SDavid du Colombier 			cp[fi.c++] = peekc;
7623e12c5d1SDavid du Colombier 			cp[fi.c] = 0;
7633e12c5d1SDavid du Colombier 			peekc = IGN;
7643e12c5d1SDavid du Colombier 		}
7653e12c5d1SDavid du Colombier 		goto l0;
7663e12c5d1SDavid du Colombier 	}
7673e12c5d1SDavid du Colombier 	yylval.sym = s;
76880ee5cbfSDavid du Colombier 	if(s->class == CTYPEDEF || s->class == CTYPESTR)
76980ee5cbfSDavid du Colombier 		return LTYPE;
7703e12c5d1SDavid du Colombier 	return s->lexical;
7713e12c5d1SDavid du Colombier 
7723e12c5d1SDavid du Colombier tnum:
7733e12c5d1SDavid du Colombier 	c1 = 0;
7743e12c5d1SDavid du Colombier 	cp = symb;
7753e12c5d1SDavid du Colombier 	if(c != '0') {
7763e12c5d1SDavid du Colombier 		c1 |= Numdec;
7773e12c5d1SDavid du Colombier 		for(;;) {
7783e12c5d1SDavid du Colombier 			*cp++ = c;
7793e12c5d1SDavid du Colombier 			c = GETC();
7803e12c5d1SDavid du Colombier 			if(isdigit(c))
7813e12c5d1SDavid du Colombier 				continue;
7823e12c5d1SDavid du Colombier 			goto dc;
7833e12c5d1SDavid du Colombier 		}
7843e12c5d1SDavid du Colombier 	}
7853e12c5d1SDavid du Colombier 	*cp++ = c;
7863e12c5d1SDavid du Colombier 	c = GETC();
7873e12c5d1SDavid du Colombier 	if(c == 'x' || c == 'X')
7883e12c5d1SDavid du Colombier 		for(;;) {
7893e12c5d1SDavid du Colombier 			*cp++ = c;
7903e12c5d1SDavid du Colombier 			c = GETC();
7913e12c5d1SDavid du Colombier 			if(isdigit(c))
7923e12c5d1SDavid du Colombier 				continue;
7933e12c5d1SDavid du Colombier 			if(c >= 'a' && c <= 'f')
7943e12c5d1SDavid du Colombier 				continue;
7953e12c5d1SDavid du Colombier 			if(c >= 'A' && c <= 'F')
7963e12c5d1SDavid du Colombier 				continue;
7973e12c5d1SDavid du Colombier 			if(cp == symb+2)
7983e12c5d1SDavid du Colombier 				yyerror("malformed hex constant");
7993e12c5d1SDavid du Colombier 			goto ncu;
8003e12c5d1SDavid du Colombier 		}
8013e12c5d1SDavid du Colombier 	if(c < '0' || c > '7')
8023e12c5d1SDavid du Colombier 		goto dc;
8033e12c5d1SDavid du Colombier 	for(;;) {
8043e12c5d1SDavid du Colombier 		if(c >= '0' && c <= '7') {
8053e12c5d1SDavid du Colombier 			*cp++ = c;
8063e12c5d1SDavid du Colombier 			c = GETC();
8073e12c5d1SDavid du Colombier 			continue;
8083e12c5d1SDavid du Colombier 		}
8093e12c5d1SDavid du Colombier 		goto ncu;
8103e12c5d1SDavid du Colombier 	}
8113e12c5d1SDavid du Colombier 
8123e12c5d1SDavid du Colombier dc:
8133e12c5d1SDavid du Colombier 	if(c == '.')
8143e12c5d1SDavid du Colombier 		goto casedot;
8153e12c5d1SDavid du Colombier 	if(c == 'e' || c == 'E')
8163e12c5d1SDavid du Colombier 		goto casee;
8173e12c5d1SDavid du Colombier 
8183e12c5d1SDavid du Colombier ncu:
8197dd7cddfSDavid du Colombier 	if((c == 'U' || c == 'u') && !(c1 & Numuns)) {
8203e12c5d1SDavid du Colombier 		c = GETC();
8213e12c5d1SDavid du Colombier 		c1 |= Numuns;
8227dd7cddfSDavid du Colombier 		goto ncu;
8233e12c5d1SDavid du Colombier 	}
8247dd7cddfSDavid du Colombier 	if((c == 'L' || c == 'l') && !(c1 & Numvlong)) {
8253e12c5d1SDavid du Colombier 		c = GETC();
8267dd7cddfSDavid du Colombier 		if(c1 & Numlong)
8273e12c5d1SDavid du Colombier 			c1 |= Numvlong;
8287dd7cddfSDavid du Colombier 		c1 |= Numlong;
8297dd7cddfSDavid du Colombier 		goto ncu;
8303e12c5d1SDavid du Colombier 	}
8317dd7cddfSDavid du Colombier 	*cp = 0;
8323e12c5d1SDavid du Colombier 	peekc = c;
833219b2ee8SDavid du Colombier 	if(mpatov(symb, &yylval.vval))
834219b2ee8SDavid du Colombier 		yyerror("overflow in constant");
835219b2ee8SDavid du Colombier 
83622a127bbSDavid du Colombier 	vv = yylval.vval;
8373e12c5d1SDavid du Colombier 	if(c1 & Numvlong) {
83822a127bbSDavid du Colombier 		if((c1 & Numuns) || convvtox(vv, TVLONG) < 0) {
839219b2ee8SDavid du Colombier 			c = LUVLCONST;
84022a127bbSDavid du Colombier 			t = TUVLONG;
8413e12c5d1SDavid du Colombier 			goto nret;
8423e12c5d1SDavid du Colombier 		}
843219b2ee8SDavid du Colombier 		c = LVLCONST;
84422a127bbSDavid du Colombier 		t = TVLONG;
845219b2ee8SDavid du Colombier 		goto nret;
846219b2ee8SDavid du Colombier 	}
8473e12c5d1SDavid du Colombier 	if(c1 & Numlong) {
84822a127bbSDavid du Colombier 		if((c1 & Numuns) || convvtox(vv, TLONG) < 0) {
849219b2ee8SDavid du Colombier 			c = LULCONST;
85022a127bbSDavid du Colombier 			t = TULONG;
851219b2ee8SDavid du Colombier 			goto nret;
8523e12c5d1SDavid du Colombier 		}
853219b2ee8SDavid du Colombier 		c = LLCONST;
85422a127bbSDavid du Colombier 		t = TLONG;
8553e12c5d1SDavid du Colombier 		goto nret;
856219b2ee8SDavid du Colombier 	}
85722a127bbSDavid du Colombier 	if((c1 & Numuns) || convvtox(vv, TINT) < 0) {
858219b2ee8SDavid du Colombier 		c = LUCONST;
85922a127bbSDavid du Colombier 		t = TUINT;
8603e12c5d1SDavid du Colombier 		goto nret;
861219b2ee8SDavid du Colombier 	}
862219b2ee8SDavid du Colombier 	c = LCONST;
86322a127bbSDavid du Colombier 	t = TINT;
864219b2ee8SDavid du Colombier 	goto nret;
865219b2ee8SDavid du Colombier 
866219b2ee8SDavid du Colombier nret:
86722a127bbSDavid du Colombier 	yylval.vval = convvtox(vv, t);
86822a127bbSDavid du Colombier 	if(yylval.vval != vv){
86922a127bbSDavid du Colombier 		nearln = lineno;
87022a127bbSDavid du Colombier 		warn(Z, "truncated constant: %T %s", types[t], symb);
87122a127bbSDavid du Colombier 	}
872219b2ee8SDavid du Colombier 	return c;
8733e12c5d1SDavid du Colombier 
8743e12c5d1SDavid du Colombier casedot:
8753e12c5d1SDavid du Colombier 	for(;;) {
8763e12c5d1SDavid du Colombier 		*cp++ = c;
8773e12c5d1SDavid du Colombier 		c = GETC();
8783e12c5d1SDavid du Colombier 		if(!isdigit(c))
8793e12c5d1SDavid du Colombier 			break;
8803e12c5d1SDavid du Colombier 	}
8813e12c5d1SDavid du Colombier 	if(c != 'e' && c != 'E')
8823e12c5d1SDavid du Colombier 		goto caseout;
8833e12c5d1SDavid du Colombier 
8843e12c5d1SDavid du Colombier casee:
8853e12c5d1SDavid du Colombier 	*cp++ = 'e';
8863e12c5d1SDavid du Colombier 	c = GETC();
8873e12c5d1SDavid du Colombier 	if(c == '+' || c == '-') {
8883e12c5d1SDavid du Colombier 		*cp++ = c;
8893e12c5d1SDavid du Colombier 		c = GETC();
8903e12c5d1SDavid du Colombier 	}
8913e12c5d1SDavid du Colombier 	if(!isdigit(c))
8923e12c5d1SDavid du Colombier 		yyerror("malformed fp constant exponent");
8933e12c5d1SDavid du Colombier 	while(isdigit(c)) {
8943e12c5d1SDavid du Colombier 		*cp++ = c;
8953e12c5d1SDavid du Colombier 		c = GETC();
8963e12c5d1SDavid du Colombier 	}
8973e12c5d1SDavid du Colombier 
8983e12c5d1SDavid du Colombier caseout:
8993e12c5d1SDavid du Colombier 	if(c == 'L' || c == 'l') {
9003e12c5d1SDavid du Colombier 		c = GETC();
9013e12c5d1SDavid du Colombier 		c1 |= Numlong;
9023e12c5d1SDavid du Colombier 	} else
9033e12c5d1SDavid du Colombier 	if(c == 'F' || c == 'f') {
9043e12c5d1SDavid du Colombier 		c = GETC();
9053e12c5d1SDavid du Colombier 		c1 |= Numflt;
9063e12c5d1SDavid du Colombier 	}
9073e12c5d1SDavid du Colombier 	*cp = 0;
9083e12c5d1SDavid du Colombier 	peekc = c;
90959cc4ca5SDavid du Colombier 	yylval.dval = strtod(symb, nil);
91059cc4ca5SDavid du Colombier 	if(isInf(yylval.dval, 1) || isInf(yylval.dval, -1)) {
9113e12c5d1SDavid du Colombier 		yyerror("overflow in float constant");
9123e12c5d1SDavid du Colombier 		yylval.dval = 0;
9133e12c5d1SDavid du Colombier 	}
9143e12c5d1SDavid du Colombier 	if(c1 & Numflt)
9153e12c5d1SDavid du Colombier 		return LFCONST;
9163e12c5d1SDavid du Colombier 	return LDCONST;
9173e12c5d1SDavid du Colombier }
9183e12c5d1SDavid du Colombier 
91959cc4ca5SDavid du Colombier /*
92059cc4ca5SDavid du Colombier  * convert a string, s, to vlong in *v
92159cc4ca5SDavid du Colombier  * return conversion overflow.
92259cc4ca5SDavid du Colombier  * required syntax is [0[x]]d*
92359cc4ca5SDavid du Colombier  */
92459cc4ca5SDavid du Colombier int
mpatov(char * s,vlong * v)92559cc4ca5SDavid du Colombier mpatov(char *s, vlong *v)
92659cc4ca5SDavid du Colombier {
92759cc4ca5SDavid du Colombier 	vlong n, nn;
92859cc4ca5SDavid du Colombier 	int c;
92959cc4ca5SDavid du Colombier 
93059cc4ca5SDavid du Colombier 	n = 0;
93159cc4ca5SDavid du Colombier 	c = *s;
93259cc4ca5SDavid du Colombier 	if(c == '0')
93359cc4ca5SDavid du Colombier 		goto oct;
93459cc4ca5SDavid du Colombier 	while(c = *s++) {
93559cc4ca5SDavid du Colombier 		if(c >= '0' && c <= '9')
93659cc4ca5SDavid du Colombier 			nn = n*10 + c-'0';
93759cc4ca5SDavid du Colombier 		else
93859cc4ca5SDavid du Colombier 			goto bad;
93959cc4ca5SDavid du Colombier 		if(n < 0 && nn >= 0)
94059cc4ca5SDavid du Colombier 			goto bad;
94159cc4ca5SDavid du Colombier 		n = nn;
94259cc4ca5SDavid du Colombier 	}
94359cc4ca5SDavid du Colombier 	goto out;
94459cc4ca5SDavid du Colombier 
94559cc4ca5SDavid du Colombier oct:
94659cc4ca5SDavid du Colombier 	s++;
94759cc4ca5SDavid du Colombier 	c = *s;
94859cc4ca5SDavid du Colombier 	if(c == 'x' || c == 'X')
94959cc4ca5SDavid du Colombier 		goto hex;
95059cc4ca5SDavid du Colombier 	while(c = *s++) {
95159cc4ca5SDavid du Colombier 		if(c >= '0' || c <= '7')
95259cc4ca5SDavid du Colombier 			nn = n*8 + c-'0';
95359cc4ca5SDavid du Colombier 		else
95459cc4ca5SDavid du Colombier 			goto bad;
95559cc4ca5SDavid du Colombier 		if(n < 0 && nn >= 0)
95659cc4ca5SDavid du Colombier 			goto bad;
95759cc4ca5SDavid du Colombier 		n = nn;
95859cc4ca5SDavid du Colombier 	}
95959cc4ca5SDavid du Colombier 	goto out;
96059cc4ca5SDavid du Colombier 
96159cc4ca5SDavid du Colombier hex:
96259cc4ca5SDavid du Colombier 	s++;
96359cc4ca5SDavid du Colombier 	while(c = *s++) {
96459cc4ca5SDavid du Colombier 		if(c >= '0' && c <= '9')
96559cc4ca5SDavid du Colombier 			c += 0-'0';
96659cc4ca5SDavid du Colombier 		else
96759cc4ca5SDavid du Colombier 		if(c >= 'a' && c <= 'f')
96859cc4ca5SDavid du Colombier 			c += 10-'a';
96959cc4ca5SDavid du Colombier 		else
97059cc4ca5SDavid du Colombier 		if(c >= 'A' && c <= 'F')
97159cc4ca5SDavid du Colombier 			c += 10-'A';
97259cc4ca5SDavid du Colombier 		else
97359cc4ca5SDavid du Colombier 			goto bad;
97459cc4ca5SDavid du Colombier 		nn = n*16 + c;
97559cc4ca5SDavid du Colombier 		if(n < 0 && nn >= 0)
97659cc4ca5SDavid du Colombier 			goto bad;
97759cc4ca5SDavid du Colombier 		n = nn;
97859cc4ca5SDavid du Colombier 	}
97959cc4ca5SDavid du Colombier out:
98059cc4ca5SDavid du Colombier 	*v = n;
98159cc4ca5SDavid du Colombier 	return 0;
98259cc4ca5SDavid du Colombier 
98359cc4ca5SDavid du Colombier bad:
98459cc4ca5SDavid du Colombier 	*v = ~0;
98559cc4ca5SDavid du Colombier 	return 1;
98659cc4ca5SDavid du Colombier }
98759cc4ca5SDavid du Colombier 
9883e12c5d1SDavid du Colombier int
getc(void)9893e12c5d1SDavid du Colombier getc(void)
9903e12c5d1SDavid du Colombier {
9913e12c5d1SDavid du Colombier 	int c;
9923e12c5d1SDavid du Colombier 
9933e12c5d1SDavid du Colombier 	if(peekc != IGN) {
9943e12c5d1SDavid du Colombier 		c = peekc;
9953e12c5d1SDavid du Colombier 		peekc = IGN;
9963e12c5d1SDavid du Colombier 	} else
9973e12c5d1SDavid du Colombier 		c = GETC();
9983e12c5d1SDavid du Colombier 	if(c == '\n')
9993e12c5d1SDavid du Colombier 		lineno++;
10003e12c5d1SDavid du Colombier 	if(c == EOF) {
10013e12c5d1SDavid du Colombier 		yyerror("End of file");
10023e12c5d1SDavid du Colombier 		errorexit();
10033e12c5d1SDavid du Colombier 	}
10043e12c5d1SDavid du Colombier 	return c;
10053e12c5d1SDavid du Colombier }
10063e12c5d1SDavid du Colombier 
10073e12c5d1SDavid du Colombier long
getr(void)10083e12c5d1SDavid du Colombier getr(void)
10093e12c5d1SDavid du Colombier {
10103e12c5d1SDavid du Colombier 	int c, i;
10113e12c5d1SDavid du Colombier 	char str[UTFmax+1];
10123e12c5d1SDavid du Colombier 	Rune rune;
10133e12c5d1SDavid du Colombier 
10143e12c5d1SDavid du Colombier 
10153e12c5d1SDavid du Colombier 	c = getc();
10163e12c5d1SDavid du Colombier 	if(c < Runeself)
10173e12c5d1SDavid du Colombier 		return c;
10183e12c5d1SDavid du Colombier 	i = 0;
10193e12c5d1SDavid du Colombier 	str[i++] = c;
10203e12c5d1SDavid du Colombier 
10213e12c5d1SDavid du Colombier loop:
10223e12c5d1SDavid du Colombier 	c = getc();
10233e12c5d1SDavid du Colombier 	str[i++] = c;
10243e12c5d1SDavid du Colombier 	if(!fullrune(str, i))
10253e12c5d1SDavid du Colombier 		goto loop;
10263e12c5d1SDavid du Colombier 	c = chartorune(&rune, str);
10273e12c5d1SDavid du Colombier 	if(rune == Runeerror && c == 1) {
10283e12c5d1SDavid du Colombier 		nearln = lineno;
10293e12c5d1SDavid du Colombier 		diag(Z, "illegal rune in string");
10303e12c5d1SDavid du Colombier 		for(c=0; c<i; c++)
10313e12c5d1SDavid du Colombier 			print(" %.2x", *(uchar*)(str+c));
10323e12c5d1SDavid du Colombier 		print("\n");
10333e12c5d1SDavid du Colombier 	}
10343e12c5d1SDavid du Colombier 	return rune;
10353e12c5d1SDavid du Colombier }
10363e12c5d1SDavid du Colombier 
10373e12c5d1SDavid du Colombier int
getnsc(void)10383e12c5d1SDavid du Colombier getnsc(void)
10393e12c5d1SDavid du Colombier {
10403e12c5d1SDavid du Colombier 	int c;
10413e12c5d1SDavid du Colombier 
10423e12c5d1SDavid du Colombier 	if(peekc != IGN) {
10433e12c5d1SDavid du Colombier 		c = peekc;
10443e12c5d1SDavid du Colombier 		peekc = IGN;
10453e12c5d1SDavid du Colombier 	} else
10463e12c5d1SDavid du Colombier 		c = GETC();
10473e12c5d1SDavid du Colombier 	for(;;) {
104882726826SDavid du Colombier 		if(c >= Runeself || !isspace(c))
10493e12c5d1SDavid du Colombier 			return c;
10503e12c5d1SDavid du Colombier 		if(c == '\n') {
10513e12c5d1SDavid du Colombier 			lineno++;
10523e12c5d1SDavid du Colombier 			return c;
10533e12c5d1SDavid du Colombier 		}
10543e12c5d1SDavid du Colombier 		c = GETC();
10553e12c5d1SDavid du Colombier 	}
10563e12c5d1SDavid du Colombier }
10573e12c5d1SDavid du Colombier 
10583e12c5d1SDavid du Colombier void
unget(int c)10593e12c5d1SDavid du Colombier unget(int c)
10603e12c5d1SDavid du Colombier {
10613e12c5d1SDavid du Colombier 
10623e12c5d1SDavid du Colombier 	peekc = c;
10633e12c5d1SDavid du Colombier 	if(c == '\n')
10643e12c5d1SDavid du Colombier 		lineno--;
10653e12c5d1SDavid du Colombier }
10663e12c5d1SDavid du Colombier 
10673e12c5d1SDavid du Colombier long
escchar(long e,int longflg,int escflg)10683e12c5d1SDavid du Colombier escchar(long e, int longflg, int escflg)
10693e12c5d1SDavid du Colombier {
10703e12c5d1SDavid du Colombier 	long c, l;
10713e12c5d1SDavid du Colombier 	int i;
10723e12c5d1SDavid du Colombier 
10733e12c5d1SDavid du Colombier loop:
10743e12c5d1SDavid du Colombier 	c = getr();
10753e12c5d1SDavid du Colombier 	if(c == '\n') {
10763e12c5d1SDavid du Colombier 		yyerror("newline in string");
10773e12c5d1SDavid du Colombier 		return EOF;
10783e12c5d1SDavid du Colombier 	}
10793e12c5d1SDavid du Colombier 	if(c != '\\') {
10803e12c5d1SDavid du Colombier 		if(c == e)
10813e12c5d1SDavid du Colombier 			c = EOF;
10823e12c5d1SDavid du Colombier 		return c;
10833e12c5d1SDavid du Colombier 	}
10843e12c5d1SDavid du Colombier 	c = getr();
10853e12c5d1SDavid du Colombier 	if(c == 'x') {
10863e12c5d1SDavid du Colombier 		/*
10873e12c5d1SDavid du Colombier 		 * note this is not ansi,
10883e12c5d1SDavid du Colombier 		 * supposed to only accept 2 hex
10893e12c5d1SDavid du Colombier 		 */
10903e12c5d1SDavid du Colombier 		i = 2;
10913e12c5d1SDavid du Colombier 		if(longflg)
1092e94a8e9bSDavid du Colombier 			i = 6;
10933e12c5d1SDavid du Colombier 		l = 0;
10943e12c5d1SDavid du Colombier 		for(; i>0; i--) {
10953e12c5d1SDavid du Colombier 			c = getc();
1096219b2ee8SDavid du Colombier 			if(c >= '0' && c <= '9') {
10973e12c5d1SDavid du Colombier 				l = l*16 + c-'0';
10983e12c5d1SDavid du Colombier 				continue;
10993e12c5d1SDavid du Colombier 			}
11003e12c5d1SDavid du Colombier 			if(c >= 'a' && c <= 'f') {
11013e12c5d1SDavid du Colombier 				l = l*16 + c-'a' + 10;
11023e12c5d1SDavid du Colombier 				continue;
11033e12c5d1SDavid du Colombier 			}
11043e12c5d1SDavid du Colombier 			if(c >= 'A' && c <= 'F') {
11053e12c5d1SDavid du Colombier 				l = l*16 + c-'A' + 10;
11063e12c5d1SDavid du Colombier 				continue;
11073e12c5d1SDavid du Colombier 			}
11083e12c5d1SDavid du Colombier 			unget(c);
11093e12c5d1SDavid du Colombier 			break;
11103e12c5d1SDavid du Colombier 		}
11113e12c5d1SDavid du Colombier 		if(escflg)
11123e12c5d1SDavid du Colombier 			l |= ESC;
11133e12c5d1SDavid du Colombier 		return l;
11143e12c5d1SDavid du Colombier 	}
11153e12c5d1SDavid du Colombier 	if(c >= '0' && c <= '7') {
11163e12c5d1SDavid du Colombier 		/*
11173e12c5d1SDavid du Colombier 		 * note this is not ansi,
11183e12c5d1SDavid du Colombier 		 * supposed to only accept 3 oct
11193e12c5d1SDavid du Colombier 		 */
11203e12c5d1SDavid du Colombier 		i = 2;
11213e12c5d1SDavid du Colombier 		if(longflg)
1122e94a8e9bSDavid du Colombier 			i = 8;
11233e12c5d1SDavid du Colombier 		l = c - '0';
11243e12c5d1SDavid du Colombier 		for(; i>0; i--) {
11253e12c5d1SDavid du Colombier 			c = getc();
11263e12c5d1SDavid du Colombier 			if(c >= '0' && c <= '7') {
11273e12c5d1SDavid du Colombier 				l = l*8 + c-'0';
11283e12c5d1SDavid du Colombier 				continue;
11293e12c5d1SDavid du Colombier 			}
11303e12c5d1SDavid du Colombier 			unget(c);
11313e12c5d1SDavid du Colombier 		}
11323e12c5d1SDavid du Colombier 		if(escflg)
11333e12c5d1SDavid du Colombier 			l |= ESC;
11343e12c5d1SDavid du Colombier 		return l;
11353e12c5d1SDavid du Colombier 	}
11363e12c5d1SDavid du Colombier 	switch(c)
11373e12c5d1SDavid du Colombier 	{
11383e12c5d1SDavid du Colombier 	case '\n':	goto loop;
11393e12c5d1SDavid du Colombier 	case 'n':	return '\n';
11403e12c5d1SDavid du Colombier 	case 't':	return '\t';
11413e12c5d1SDavid du Colombier 	case 'b':	return '\b';
11423e12c5d1SDavid du Colombier 	case 'r':	return '\r';
11433e12c5d1SDavid du Colombier 	case 'f':	return '\f';
11443e12c5d1SDavid du Colombier 	case 'a':	return '\a';
11453e12c5d1SDavid du Colombier 	case 'v':	return '\v';
11463e12c5d1SDavid du Colombier 	}
11473e12c5d1SDavid du Colombier 	return c;
11483e12c5d1SDavid du Colombier }
11493e12c5d1SDavid du Colombier 
11503e12c5d1SDavid du Colombier struct
11513e12c5d1SDavid du Colombier {
11523e12c5d1SDavid du Colombier 	char	*name;
11533e12c5d1SDavid du Colombier 	ushort	lexical;
11547dd7cddfSDavid du Colombier 	ushort	type;
11553e12c5d1SDavid du Colombier } itab[] =
11563e12c5d1SDavid du Colombier {
11577dd7cddfSDavid du Colombier 	"auto",		LAUTO,		0,
11587dd7cddfSDavid du Colombier 	"break",	LBREAK,		0,
11597dd7cddfSDavid du Colombier 	"case",		LCASE,		0,
11607dd7cddfSDavid du Colombier 	"char",		LCHAR,		TCHAR,
11617dd7cddfSDavid du Colombier 	"const",	LCONSTNT,	0,
11627dd7cddfSDavid du Colombier 	"continue",	LCONTINUE,	0,
11637dd7cddfSDavid du Colombier 	"default",	LDEFAULT,	0,
11647dd7cddfSDavid du Colombier 	"do",		LDO,		0,
11657dd7cddfSDavid du Colombier 	"double",	LDOUBLE,	TDOUBLE,
11667dd7cddfSDavid du Colombier 	"else",		LELSE,		0,
11677dd7cddfSDavid du Colombier 	"enum",		LENUM,		0,
11687dd7cddfSDavid du Colombier 	"extern",	LEXTERN,	0,
11697dd7cddfSDavid du Colombier 	"float",	LFLOAT,		TFLOAT,
11707dd7cddfSDavid du Colombier 	"for",		LFOR,		0,
11717dd7cddfSDavid du Colombier 	"goto",		LGOTO,		0,
11727dd7cddfSDavid du Colombier 	"if",		LIF,		0,
11734bada075SDavid du Colombier 	"inline",	LINLINE,	0,
11747dd7cddfSDavid du Colombier 	"int",		LINT,		TINT,
11757dd7cddfSDavid du Colombier 	"long",		LLONG,		TLONG,
11767dd7cddfSDavid du Colombier 	"register",	LREGISTER,	0,
11774bada075SDavid du Colombier 	"restrict",	LRESTRICT,	0,
11787dd7cddfSDavid du Colombier 	"return",	LRETURN,	0,
11797dd7cddfSDavid du Colombier 	"SET",		LSET,		0,
11807dd7cddfSDavid du Colombier 	"short",	LSHORT,		TSHORT,
11817dd7cddfSDavid du Colombier 	"signed",	LSIGNED,	0,
11827dd7cddfSDavid du Colombier 	"signof",	LSIGNOF,	0,
11837dd7cddfSDavid du Colombier 	"sizeof",	LSIZEOF,	0,
11847dd7cddfSDavid du Colombier 	"static",	LSTATIC,	0,
11857dd7cddfSDavid du Colombier 	"struct",	LSTRUCT,	0,
11867dd7cddfSDavid du Colombier 	"switch",	LSWITCH,	0,
11877dd7cddfSDavid du Colombier 	"typedef",	LTYPEDEF,	0,
118880ee5cbfSDavid du Colombier 	"typestr",	LTYPESTR,	0,
11897dd7cddfSDavid du Colombier 	"union",	LUNION,		0,
11907dd7cddfSDavid du Colombier 	"unsigned",	LUNSIGNED,	0,
11917dd7cddfSDavid du Colombier 	"USED",		LUSED,		0,
11927dd7cddfSDavid du Colombier 	"void",		LVOID,		TVOID,
11937dd7cddfSDavid du Colombier 	"volatile",	LVOLATILE,	0,
11947dd7cddfSDavid du Colombier 	"while",	LWHILE,		0,
11953e12c5d1SDavid du Colombier 	0
11963e12c5d1SDavid du Colombier };
11973e12c5d1SDavid du Colombier 
11983e12c5d1SDavid du Colombier void
cinit(void)11993e12c5d1SDavid du Colombier cinit(void)
12003e12c5d1SDavid du Colombier {
12013e12c5d1SDavid du Colombier 	Sym *s;
12023e12c5d1SDavid du Colombier 	int i;
12033e12c5d1SDavid du Colombier 	Type *t;
12043e12c5d1SDavid du Colombier 
12053e12c5d1SDavid du Colombier 	nerrors = 0;
12063e12c5d1SDavid du Colombier 	lineno = 1;
12073e12c5d1SDavid du Colombier 	iostack = I;
12083e12c5d1SDavid du Colombier 	iofree = I;
12093e12c5d1SDavid du Colombier 	peekc = IGN;
12103e12c5d1SDavid du Colombier 	nhunk = 0;
12113e12c5d1SDavid du Colombier 
12123e12c5d1SDavid du Colombier 	types[TXXX] = T;
12133e12c5d1SDavid du Colombier 	types[TCHAR] = typ(TCHAR, T);
12143e12c5d1SDavid du Colombier 	types[TUCHAR] = typ(TUCHAR, T);
12153e12c5d1SDavid du Colombier 	types[TSHORT] = typ(TSHORT, T);
12163e12c5d1SDavid du Colombier 	types[TUSHORT] = typ(TUSHORT, T);
12177dd7cddfSDavid du Colombier 	types[TINT] = typ(TINT, T);
12187dd7cddfSDavid du Colombier 	types[TUINT] = typ(TUINT, T);
12193e12c5d1SDavid du Colombier 	types[TLONG] = typ(TLONG, T);
12203e12c5d1SDavid du Colombier 	types[TULONG] = typ(TULONG, T);
12213e12c5d1SDavid du Colombier 	types[TVLONG] = typ(TVLONG, T);
1222219b2ee8SDavid du Colombier 	types[TUVLONG] = typ(TUVLONG, T);
12233e12c5d1SDavid du Colombier 	types[TFLOAT] = typ(TFLOAT, T);
12243e12c5d1SDavid du Colombier 	types[TDOUBLE] = typ(TDOUBLE, T);
12253e12c5d1SDavid du Colombier 	types[TVOID] = typ(TVOID, T);
12263e12c5d1SDavid du Colombier 	types[TENUM] = typ(TENUM, T);
12277dd7cddfSDavid du Colombier 	types[TFUNC] = typ(TFUNC, types[TINT]);
12283e12c5d1SDavid du Colombier 	types[TIND] = typ(TIND, types[TVOID]);
12293e12c5d1SDavid du Colombier 
12307dd7cddfSDavid du Colombier 	for(i=0; i<NHASH; i++)
12317dd7cddfSDavid du Colombier 		hash[i] = S;
12327dd7cddfSDavid du Colombier 	for(i=0; itab[i].name; i++) {
12337dd7cddfSDavid du Colombier 		s = slookup(itab[i].name);
12347dd7cddfSDavid du Colombier 		s->lexical = itab[i].lexical;
12357dd7cddfSDavid du Colombier 		if(itab[i].type != 0)
12367dd7cddfSDavid du Colombier 			s->type = types[itab[i].type];
12377dd7cddfSDavid du Colombier 	}
12387dd7cddfSDavid du Colombier 	blockno = 0;
12397dd7cddfSDavid du Colombier 	autobn = 0;
12407dd7cddfSDavid du Colombier 	autoffset = 0;
12413e12c5d1SDavid du Colombier 
12423e12c5d1SDavid du Colombier 	t = typ(TARRAY, types[TCHAR]);
12433e12c5d1SDavid du Colombier 	t->width = 0;
12443e12c5d1SDavid du Colombier 	symstring = slookup(".string");
12453e12c5d1SDavid du Colombier 	symstring->class = CSTATIC;
12463e12c5d1SDavid du Colombier 	symstring->type = t;
12473e12c5d1SDavid du Colombier 
12483e12c5d1SDavid du Colombier 	t = typ(TARRAY, types[TCHAR]);
12493e12c5d1SDavid du Colombier 	t->width = 0;
12503e12c5d1SDavid du Colombier 
12513e12c5d1SDavid du Colombier 	nodproto = new(OPROTO, Z, Z);
12523e12c5d1SDavid du Colombier 	dclstack = D;
12533e12c5d1SDavid du Colombier 
12547dd7cddfSDavid du Colombier 	pathname = allocn(pathname, 0, 100);
12557dd7cddfSDavid du Colombier 	if(mygetwd(pathname, 99) == 0) {
12567dd7cddfSDavid du Colombier 		pathname = allocn(pathname, 100, 900);
12577dd7cddfSDavid du Colombier 		if(mygetwd(pathname, 999) == 0)
1258219b2ee8SDavid du Colombier 			strcpy(pathname, "/???");
1259219b2ee8SDavid du Colombier 	}
1260219b2ee8SDavid du Colombier 
12613e12c5d1SDavid du Colombier 	fmtinstall('O', Oconv);
12623e12c5d1SDavid du Colombier 	fmtinstall('T', Tconv);
1263bd389b36SDavid du Colombier 	fmtinstall('F', FNconv);
12643e12c5d1SDavid du Colombier 	fmtinstall('L', Lconv);
12653e12c5d1SDavid du Colombier 	fmtinstall('Q', Qconv);
12663e12c5d1SDavid du Colombier 	fmtinstall('|', VBconv);
12673e12c5d1SDavid du Colombier }
12683e12c5d1SDavid du Colombier 
12693e12c5d1SDavid du Colombier int
filbuf(void)12703e12c5d1SDavid du Colombier filbuf(void)
12713e12c5d1SDavid du Colombier {
12723e12c5d1SDavid du Colombier 	Io *i;
12733e12c5d1SDavid du Colombier 
12743e12c5d1SDavid du Colombier loop:
12753e12c5d1SDavid du Colombier 	i = iostack;
12763e12c5d1SDavid du Colombier 	if(i == I)
12773e12c5d1SDavid du Colombier 		return EOF;
12783e12c5d1SDavid du Colombier 	if(i->f < 0)
12793e12c5d1SDavid du Colombier 		goto pop;
12803e12c5d1SDavid du Colombier 	fi.c = read(i->f, i->b, BUFSIZ) - 1;
12813e12c5d1SDavid du Colombier 	if(fi.c < 0) {
12823e12c5d1SDavid du Colombier 		close(i->f);
12833e12c5d1SDavid du Colombier 		linehist(0, 0);
12843e12c5d1SDavid du Colombier 		goto pop;
12853e12c5d1SDavid du Colombier 	}
12863e12c5d1SDavid du Colombier 	fi.p = i->b + 1;
12873e12c5d1SDavid du Colombier 	return i->b[0] & 0xff;
12883e12c5d1SDavid du Colombier 
12893e12c5d1SDavid du Colombier pop:
12903e12c5d1SDavid du Colombier 	iostack = i->link;
12913e12c5d1SDavid du Colombier 	i->link = iofree;
12923e12c5d1SDavid du Colombier 	iofree = i;
12933e12c5d1SDavid du Colombier 	i = iostack;
12943e12c5d1SDavid du Colombier 	if(i == I)
12953e12c5d1SDavid du Colombier 		return EOF;
12963e12c5d1SDavid du Colombier 	fi.p = i->p;
12973e12c5d1SDavid du Colombier 	fi.c = i->c;
12983e12c5d1SDavid du Colombier 	if(--fi.c < 0)
12993e12c5d1SDavid du Colombier 		goto loop;
13003e12c5d1SDavid du Colombier 	return *fi.p++ & 0xff;
13013e12c5d1SDavid du Colombier }
13023e12c5d1SDavid du Colombier 
13033e12c5d1SDavid du Colombier int
Oconv(Fmt * fp)13049a747e4fSDavid du Colombier Oconv(Fmt *fp)
13053e12c5d1SDavid du Colombier {
13063e12c5d1SDavid du Colombier 	int a;
13073e12c5d1SDavid du Colombier 
13089a747e4fSDavid du Colombier 	a = va_arg(fp->args, int);
13099a747e4fSDavid du Colombier 	if(a < OXXX || a > OEND)
13109a747e4fSDavid du Colombier 		return fmtprint(fp, "***badO %d***", a);
13119a747e4fSDavid du Colombier 
13129a747e4fSDavid du Colombier 	return fmtstrcpy(fp, onames[a]);
13133e12c5d1SDavid du Colombier }
13143e12c5d1SDavid du Colombier 
13153e12c5d1SDavid du Colombier int
Lconv(Fmt * fp)13169a747e4fSDavid du Colombier Lconv(Fmt *fp)
13173e12c5d1SDavid du Colombier {
13183e12c5d1SDavid du Colombier 	char str[STRINGSZ], s[STRINGSZ];
13193e12c5d1SDavid du Colombier 	Hist *h;
13203e12c5d1SDavid du Colombier 	struct
13213e12c5d1SDavid du Colombier 	{
13223e12c5d1SDavid du Colombier 		Hist*	incl;	/* start of this include file */
13233e12c5d1SDavid du Colombier 		long	idel;	/* delta line number to apply to include */
13243e12c5d1SDavid du Colombier 		Hist*	line;	/* start of this #line directive */
13253e12c5d1SDavid du Colombier 		long	ldel;	/* delta line number to apply to #line */
13263e12c5d1SDavid du Colombier 	} a[HISTSZ];
13273e12c5d1SDavid du Colombier 	long l, d;
13283e12c5d1SDavid du Colombier 	int i, n;
13293e12c5d1SDavid du Colombier 
13309a747e4fSDavid du Colombier 	l = va_arg(fp->args, long);
13313e12c5d1SDavid du Colombier 	n = 0;
13323e12c5d1SDavid du Colombier 	for(h = hist; h != H; h = h->link) {
13333e12c5d1SDavid du Colombier 		if(l < h->line)
13343e12c5d1SDavid du Colombier 			break;
13353e12c5d1SDavid du Colombier 		if(h->name) {
13363e12c5d1SDavid du Colombier 			if(h->offset != 0) {		/* #line directive, not #pragma */
13373e12c5d1SDavid du Colombier 				if(n > 0 && n < HISTSZ && h->offset >= 0) {
13383e12c5d1SDavid du Colombier 					a[n-1].line = h;
13393e12c5d1SDavid du Colombier 					a[n-1].ldel = h->line - h->offset + 1;
13403e12c5d1SDavid du Colombier 				}
13413e12c5d1SDavid du Colombier 			} else {
13423e12c5d1SDavid du Colombier 				if(n < HISTSZ) {	/* beginning of file */
13433e12c5d1SDavid du Colombier 					a[n].incl = h;
13443e12c5d1SDavid du Colombier 					a[n].idel = h->line;
13453e12c5d1SDavid du Colombier 					a[n].line = 0;
13463e12c5d1SDavid du Colombier 				}
13473e12c5d1SDavid du Colombier 				n++;
13483e12c5d1SDavid du Colombier 			}
13493e12c5d1SDavid du Colombier 			continue;
13503e12c5d1SDavid du Colombier 		}
13513e12c5d1SDavid du Colombier 		n--;
13523e12c5d1SDavid du Colombier 		if(n > 0 && n < HISTSZ) {
13533e12c5d1SDavid du Colombier 			d = h->line - a[n].incl->line;
13543e12c5d1SDavid du Colombier 			a[n-1].ldel += d;
13553e12c5d1SDavid du Colombier 			a[n-1].idel += d;
13563e12c5d1SDavid du Colombier 		}
13573e12c5d1SDavid du Colombier 	}
13583e12c5d1SDavid du Colombier 	if(n > HISTSZ)
13593e12c5d1SDavid du Colombier 		n = HISTSZ;
13603e12c5d1SDavid du Colombier 	str[0] = 0;
13613e12c5d1SDavid du Colombier 	for(i=n-1; i>=0; i--) {
13623e12c5d1SDavid du Colombier 		if(i != n-1) {
13639a747e4fSDavid du Colombier 			if(fp->flags & ~(FmtWidth|FmtPrec))	/* BUG ROB - was f3 */
13643e12c5d1SDavid du Colombier 				break;
13653e12c5d1SDavid du Colombier 			strcat(str, " ");
13663e12c5d1SDavid du Colombier 		}
13673e12c5d1SDavid du Colombier 		if(a[i].line)
1368219b2ee8SDavid du Colombier 			snprint(s, STRINGSZ, "%s:%ld[%s:%ld]",
13693e12c5d1SDavid du Colombier 				a[i].line->name, l-a[i].ldel+1,
13703e12c5d1SDavid du Colombier 				a[i].incl->name, l-a[i].idel+1);
13713e12c5d1SDavid du Colombier 		else
1372219b2ee8SDavid du Colombier 			snprint(s, STRINGSZ, "%s:%ld",
13733e12c5d1SDavid du Colombier 				a[i].incl->name, l-a[i].idel+1);
13743e12c5d1SDavid du Colombier 		if(strlen(s)+strlen(str) >= STRINGSZ-10)
13753e12c5d1SDavid du Colombier 			break;
13763e12c5d1SDavid du Colombier 		strcat(str, s);
13773e12c5d1SDavid du Colombier 		l = a[i].incl->line - 1;	/* now print out start of this file */
13783e12c5d1SDavid du Colombier 	}
13793e12c5d1SDavid du Colombier 	if(n == 0)
13803e12c5d1SDavid du Colombier 		strcat(str, "<eof>");
13819a747e4fSDavid du Colombier 	return fmtstrcpy(fp, str);
13823e12c5d1SDavid du Colombier }
13833e12c5d1SDavid du Colombier 
13843e12c5d1SDavid du Colombier int
Tconv(Fmt * fp)13859a747e4fSDavid du Colombier Tconv(Fmt *fp)
13863e12c5d1SDavid du Colombier {
1387219b2ee8SDavid du Colombier 	char str[STRINGSZ+20], s[STRINGSZ+20];
13883e12c5d1SDavid du Colombier 	Type *t, *t1;
13893e12c5d1SDavid du Colombier 	int et;
13907dd7cddfSDavid du Colombier 	long n;
13913e12c5d1SDavid du Colombier 
13923e12c5d1SDavid du Colombier 	str[0] = 0;
13939a747e4fSDavid du Colombier 	for(t = va_arg(fp->args, Type*); t != T; t = t->link) {
13943e12c5d1SDavid du Colombier 		et = t->etype;
13953e12c5d1SDavid du Colombier 		if(str[0])
13963e12c5d1SDavid du Colombier 			strcat(str, " ");
1397375daca8SDavid du Colombier 		if(t->garb&~GINCOMPLETE) {
139857cfc11bSDavid du Colombier 			snprint(s, sizeof s, "%s ", gnames[t->garb&~GINCOMPLETE]);
13997dd7cddfSDavid du Colombier 			if(strlen(str) + strlen(s) < STRINGSZ)
14007dd7cddfSDavid du Colombier 				strcat(str, s);
14017dd7cddfSDavid du Colombier 		}
140257cfc11bSDavid du Colombier 		snprint(s, sizeof s, "%s", tnames[et]);
14033e12c5d1SDavid du Colombier 		if(strlen(str) + strlen(s) < STRINGSZ)
14043e12c5d1SDavid du Colombier 			strcat(str, s);
14053e12c5d1SDavid du Colombier 		if(et == TFUNC && (t1 = t->down)) {
140657cfc11bSDavid du Colombier 			snprint(s, sizeof s, "(%T", t1);
1407219b2ee8SDavid du Colombier 			if(strlen(str) + strlen(s) < STRINGSZ)
14083e12c5d1SDavid du Colombier 				strcat(str, s);
14093e12c5d1SDavid du Colombier 			while(t1 = t1->down) {
141057cfc11bSDavid du Colombier 				snprint(s, sizeof s, ", %T", t1);
1411219b2ee8SDavid du Colombier 				if(strlen(str) + strlen(s) < STRINGSZ)
14123e12c5d1SDavid du Colombier 					strcat(str, s);
14133e12c5d1SDavid du Colombier 			}
1414219b2ee8SDavid du Colombier 			if(strlen(str) + strlen(s) < STRINGSZ)
14153e12c5d1SDavid du Colombier 				strcat(str, ")");
14163e12c5d1SDavid du Colombier 		}
14173e12c5d1SDavid du Colombier 		if(et == TARRAY) {
14187dd7cddfSDavid du Colombier 			n = t->width;
14197dd7cddfSDavid du Colombier 			if(t->link && t->link->width)
14207dd7cddfSDavid du Colombier 				n /= t->link->width;
142157cfc11bSDavid du Colombier 			snprint(s, sizeof s, "[%ld]", n);
1422219b2ee8SDavid du Colombier 			if(strlen(str) + strlen(s) < STRINGSZ)
14233e12c5d1SDavid du Colombier 				strcat(str, s);
14243e12c5d1SDavid du Colombier 		}
14253e12c5d1SDavid du Colombier 		if(t->nbits) {
142657cfc11bSDavid du Colombier 			snprint(s, sizeof s, " %d:%d", t->shift, t->nbits);
14273e12c5d1SDavid du Colombier 			if(strlen(str) + strlen(s) < STRINGSZ)
14283e12c5d1SDavid du Colombier 				strcat(str, s);
14293e12c5d1SDavid du Colombier 		}
14303e12c5d1SDavid du Colombier 		if(typesu[et]) {
14313e12c5d1SDavid du Colombier 			if(t->tag) {
14323e12c5d1SDavid du Colombier 				strcat(str, " ");
1433219b2ee8SDavid du Colombier 				if(strlen(str) + strlen(t->tag->name) < STRINGSZ)
14343e12c5d1SDavid du Colombier 					strcat(str, t->tag->name);
14353e12c5d1SDavid du Colombier 			} else
14363e12c5d1SDavid du Colombier 				strcat(str, " {}");
14373e12c5d1SDavid du Colombier 			break;
14383e12c5d1SDavid du Colombier 		}
14393e12c5d1SDavid du Colombier 	}
14409a747e4fSDavid du Colombier 	return fmtstrcpy(fp, str);
14413e12c5d1SDavid du Colombier }
14423e12c5d1SDavid du Colombier 
14433e12c5d1SDavid du Colombier int
FNconv(Fmt * fp)14449a747e4fSDavid du Colombier FNconv(Fmt *fp)
14453e12c5d1SDavid du Colombier {
1446219b2ee8SDavid du Colombier 	char *str;
14473e12c5d1SDavid du Colombier 	Node *n;
14483e12c5d1SDavid du Colombier 
14499a747e4fSDavid du Colombier 	n = va_arg(fp->args, Node*);
1450219b2ee8SDavid du Colombier 	str = "<indirect>";
1451219b2ee8SDavid du Colombier 	if(n != Z && (n->op == ONAME || n->op == ODOT || n->op == OELEM))
1452219b2ee8SDavid du Colombier 		str = n->sym->name;
14539a747e4fSDavid du Colombier 	return fmtstrcpy(fp, str);
14543e12c5d1SDavid du Colombier }
14553e12c5d1SDavid du Colombier 
14563e12c5d1SDavid du Colombier int
Qconv(Fmt * fp)14579a747e4fSDavid du Colombier Qconv(Fmt *fp)
14583e12c5d1SDavid du Colombier {
1459219b2ee8SDavid du Colombier 	char str[STRINGSZ+20], *s;
14603e12c5d1SDavid du Colombier 	long b;
14613e12c5d1SDavid du Colombier 	int i;
14623e12c5d1SDavid du Colombier 
14633e12c5d1SDavid du Colombier 	str[0] = 0;
14649a747e4fSDavid du Colombier 	for(b = va_arg(fp->args, long); b;) {
14653e12c5d1SDavid du Colombier 		i = bitno(b);
14663e12c5d1SDavid du Colombier 		if(str[0])
14673e12c5d1SDavid du Colombier 			strcat(str, " ");
14683e12c5d1SDavid du Colombier 		s = qnames[i];
1469219b2ee8SDavid du Colombier 		if(strlen(str) + strlen(s) >= STRINGSZ)
14703e12c5d1SDavid du Colombier 			break;
14713e12c5d1SDavid du Colombier 		strcat(str, s);
14723e12c5d1SDavid du Colombier 		b &= ~(1L << i);
14733e12c5d1SDavid du Colombier 	}
14749a747e4fSDavid du Colombier 	return fmtstrcpy(fp, str);
14753e12c5d1SDavid du Colombier }
14763e12c5d1SDavid du Colombier 
14773e12c5d1SDavid du Colombier int
VBconv(Fmt * fp)14789a747e4fSDavid du Colombier VBconv(Fmt *fp)
14793e12c5d1SDavid du Colombier {
14803e12c5d1SDavid du Colombier 	char str[STRINGSZ];
14813e12c5d1SDavid du Colombier 	int i, n, t, pc;
14823e12c5d1SDavid du Colombier 
14839a747e4fSDavid du Colombier 	n = va_arg(fp->args, int);
14849a747e4fSDavid du Colombier 	pc = 0;	/* BUG: was printcol */
14853e12c5d1SDavid du Colombier 	i = 0;
14863e12c5d1SDavid du Colombier 	while(pc < n) {
14879a747e4fSDavid du Colombier 		t = (pc+4) & ~3;
14883e12c5d1SDavid du Colombier 		if(t <= n) {
14893e12c5d1SDavid du Colombier 			str[i++] = '\t';
14903e12c5d1SDavid du Colombier 			pc = t;
14913e12c5d1SDavid du Colombier 			continue;
14923e12c5d1SDavid du Colombier 		}
14933e12c5d1SDavid du Colombier 		str[i++] = ' ';
14943e12c5d1SDavid du Colombier 		pc++;
14953e12c5d1SDavid du Colombier 	}
14963e12c5d1SDavid du Colombier 	str[i] = 0;
14979a747e4fSDavid du Colombier 
14989a747e4fSDavid du Colombier 	return fmtstrcpy(fp, str);
14993e12c5d1SDavid du Colombier }
15003e12c5d1SDavid du Colombier 
15013e12c5d1SDavid du Colombier /*
15027dd7cddfSDavid du Colombier  * real allocs
15033e12c5d1SDavid du Colombier  */
15043e12c5d1SDavid du Colombier void*
alloc(long n)15057dd7cddfSDavid du Colombier alloc(long n)
15063e12c5d1SDavid du Colombier {
15073e12c5d1SDavid du Colombier 	void *p;
15083e12c5d1SDavid du Colombier 
15094de34a7eSDavid du Colombier 	while((uintptr)hunk & MAXALIGN) {
15107dd7cddfSDavid du Colombier 		hunk++;
15117dd7cddfSDavid du Colombier 		nhunk--;
15127dd7cddfSDavid du Colombier 	}
15133e12c5d1SDavid du Colombier 	while(nhunk < n)
15143e12c5d1SDavid du Colombier 		gethunk();
15153e12c5d1SDavid du Colombier 	p = hunk;
15163e12c5d1SDavid du Colombier 	nhunk -= n;
15173e12c5d1SDavid du Colombier 	hunk += n;
15183e12c5d1SDavid du Colombier 	return p;
15193e12c5d1SDavid du Colombier }
15203e12c5d1SDavid du Colombier 
15213e12c5d1SDavid du Colombier void*
allocn(void * p,long on,long n)15227dd7cddfSDavid du Colombier allocn(void *p, long on, long n)
15233e12c5d1SDavid du Colombier {
15247dd7cddfSDavid du Colombier 	void *q;
15253e12c5d1SDavid du Colombier 
15267dd7cddfSDavid du Colombier 	q = (uchar*)p + on;
15277dd7cddfSDavid du Colombier 	if(q != hunk || nhunk < n) {
15287dd7cddfSDavid du Colombier 		while(nhunk < on+n)
15297dd7cddfSDavid du Colombier 			gethunk();
15307dd7cddfSDavid du Colombier 		memmove(hunk, p, on);
15317dd7cddfSDavid du Colombier 		p = hunk;
15327dd7cddfSDavid du Colombier 		hunk += on;
15337dd7cddfSDavid du Colombier 		nhunk -= on;
15347dd7cddfSDavid du Colombier 	}
15357dd7cddfSDavid du Colombier 	hunk += n;
15367dd7cddfSDavid du Colombier 	nhunk -= n;
15373e12c5d1SDavid du Colombier 	return p;
15383e12c5d1SDavid du Colombier }
15393e12c5d1SDavid du Colombier 
15407dd7cddfSDavid du Colombier void
setinclude(char * p)15417dd7cddfSDavid du Colombier setinclude(char *p)
15423e12c5d1SDavid du Colombier {
15437dd7cddfSDavid du Colombier 	int i;
15446bbfed0dSDavid du Colombier 	char *e, **np;
15453e12c5d1SDavid du Colombier 
15467dd7cddfSDavid du Colombier 	while(*p != 0) {
15477dd7cddfSDavid du Colombier 		e = strchr(p, ' ');
15487dd7cddfSDavid du Colombier 		if(e != 0)
15497dd7cddfSDavid du Colombier 			*e = '\0';
15507dd7cddfSDavid du Colombier 
15516bbfed0dSDavid du Colombier 		for(i=0; i < ninclude; i++)
15527dd7cddfSDavid du Colombier 			if(strcmp(p, include[i]) == 0)
15537dd7cddfSDavid du Colombier 				break;
15547dd7cddfSDavid du Colombier 
15556bbfed0dSDavid du Colombier 		if(i >= ninclude){
15566bbfed0dSDavid du Colombier 			if(i >= maxinclude){
15576bbfed0dSDavid du Colombier 				maxinclude += 20;
15586bbfed0dSDavid du Colombier 				np = alloc(maxinclude * sizeof *np);
15596bbfed0dSDavid du Colombier 				if(include != nil)
15606bbfed0dSDavid du Colombier 					memmove(np, include, (maxinclude - 20) * sizeof *np);
15616bbfed0dSDavid du Colombier 				include = np;
15626bbfed0dSDavid du Colombier 			}
15637dd7cddfSDavid du Colombier 			include[ninclude++] = p;
15647dd7cddfSDavid du Colombier 		}
15657dd7cddfSDavid du Colombier 
15667dd7cddfSDavid du Colombier 		if(e == 0)
15677dd7cddfSDavid du Colombier 			break;
15687dd7cddfSDavid du Colombier 		p = e+1;
15697dd7cddfSDavid du Colombier 	}
15703e12c5d1SDavid du Colombier }
1571