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 {
39*6bbfed0dSDavid du Colombier char **defs, **np, *p;
40*6bbfed0dSDavid 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);
50*6bbfed0dSDavid du Colombier maxdef = 0;
517dd7cddfSDavid du Colombier ndef = 0;
523e12c5d1SDavid du Colombier outfile = 0;
53*6bbfed0dSDavid du Colombier defs = nil;
54*6bbfed0dSDavid 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) {
78*6bbfed0dSDavid du Colombier if(ndef >= maxdef){
79*6bbfed0dSDavid du Colombier maxdef += 50;
80*6bbfed0dSDavid du Colombier np = alloc(maxdef * sizeof *np);
81*6bbfed0dSDavid du Colombier if(defs != nil)
82*6bbfed0dSDavid du Colombier memmove(np, defs, (maxdef - 50) * sizeof *np);
83*6bbfed0dSDavid du Colombier defs = np;
84*6bbfed0dSDavid 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 {
164375daca8SDavid du Colombier char ofile[400], incfile[20];
165*6bbfed0dSDavid 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)) {
2027dd7cddfSDavid du Colombier sprint(incfile, "/%s/include", thestring);
2037dd7cddfSDavid du Colombier setinclude(strdup(incfile));
2047dd7cddfSDavid du Colombier setinclude("/sys/include");
2053e12c5d1SDavid du Colombier }
2067dd7cddfSDavid du Colombier }
207aedc1c01SDavid du Colombier if (first)
208314a20f0SDavid du Colombier Binit(&diagbuf, 1, OWRITE);
209aedc1c01SDavid du Colombier /*
210aedc1c01SDavid du Colombier * if we're writing acid to standard output, don't keep scratching
211aedc1c01SDavid du Colombier * outbuf.
212aedc1c01SDavid du Colombier */
213fc375d71SDavid du Colombier if((debug['a'] || debug['Z']) && !debug['n']) {
214aedc1c01SDavid du Colombier if (first) {
2153e12c5d1SDavid du Colombier outfile = 0;
216e059317eSDavid du Colombier Binit(&outbuf, dup(1, -1), OWRITE);
217e059317eSDavid du Colombier dup(2, 1);
218aedc1c01SDavid du Colombier }
219219b2ee8SDavid du Colombier } else {
220219b2ee8SDavid du Colombier c = mycreat(outfile, 0664);
221219b2ee8SDavid du Colombier if(c < 0) {
222314a20f0SDavid du Colombier diag(Z, "cannot open %s - %r", outfile);
223219b2ee8SDavid du Colombier outfile = 0;
224219b2ee8SDavid du Colombier errorexit();
225219b2ee8SDavid du Colombier }
226219b2ee8SDavid du Colombier Binit(&outbuf, c, OWRITE);
227219b2ee8SDavid du Colombier }
2283e12c5d1SDavid du Colombier newio();
229aedc1c01SDavid du Colombier first = 0;
2307dd7cddfSDavid du Colombier
2317dd7cddfSDavid du Colombier /* Use an ANSI preprocessor */
2327dd7cddfSDavid du Colombier if(debug['p']) {
2337dd7cddfSDavid du Colombier if(systemtype(Windows)) {
2347dd7cddfSDavid du Colombier diag(Z, "-p option not supported on windows");
2357dd7cddfSDavid du Colombier errorexit();
2367dd7cddfSDavid du Colombier }
23780ee5cbfSDavid du Colombier if(myaccess(file) < 0) {
23880ee5cbfSDavid du Colombier diag(Z, "%s does not exist", file);
23980ee5cbfSDavid du Colombier errorexit();
24080ee5cbfSDavid du Colombier }
2417dd7cddfSDavid du Colombier if(mypipe(fd) < 0) {
2427dd7cddfSDavid du Colombier diag(Z, "pipe failed");
2437dd7cddfSDavid du Colombier errorexit();
2447dd7cddfSDavid du Colombier }
2457dd7cddfSDavid du Colombier switch(myfork()) {
2467dd7cddfSDavid du Colombier case -1:
2477dd7cddfSDavid du Colombier diag(Z, "fork failed");
2487dd7cddfSDavid du Colombier errorexit();
2497dd7cddfSDavid du Colombier case 0:
2507dd7cddfSDavid du Colombier close(fd[0]);
2517dd7cddfSDavid du Colombier mydup(fd[1], 1);
2527dd7cddfSDavid du Colombier close(fd[1]);
253*6bbfed0dSDavid du Colombier av = alloc((3 + ndef + ninclude + 2) * sizeof *av);
2547dd7cddfSDavid du Colombier av[0] = CPP;
2557dd7cddfSDavid du Colombier i = 1;
2567ee275a1SDavid du Colombier if(debug['.'])
2577ee275a1SDavid du Colombier av[i++] = strdup("-.");
2587ee275a1SDavid du Colombier /* 1999 ANSI C requires recognising // comments */
2597ee275a1SDavid du Colombier av[i++] = strdup("-+");
2607dd7cddfSDavid du Colombier for(c = 0; c < ndef; c++) {
2617dd7cddfSDavid du Colombier sprint(opt, "-D%s", defs[c]);
2627dd7cddfSDavid du Colombier av[i++] = strdup(opt);
2637dd7cddfSDavid du Colombier }
2647dd7cddfSDavid du Colombier for(c = 0; c < ninclude; c++) {
2657dd7cddfSDavid du Colombier sprint(opt, "-I%s", include[c]);
2667dd7cddfSDavid du Colombier av[i++] = strdup(opt);
2677dd7cddfSDavid du Colombier }
2687dd7cddfSDavid du Colombier if(strcmp(file, "stdin") != 0)
2697dd7cddfSDavid du Colombier av[i++] = file;
2707dd7cddfSDavid du Colombier av[i] = 0;
2717dd7cddfSDavid du Colombier if(debug['p'] > 1) {
2727dd7cddfSDavid du Colombier for(c = 0; c < i; c++)
2737dd7cddfSDavid du Colombier fprint(2, "%s ", av[c]);
2744de34a7eSDavid du Colombier fprint(2, "\n");
2757dd7cddfSDavid du Colombier }
2767dd7cddfSDavid du Colombier myexec(av[0], av);
2777dd7cddfSDavid du Colombier fprint(2, "can't exec C preprocessor %s: %r\n", CPP);
2787dd7cddfSDavid du Colombier errorexit();
2797dd7cddfSDavid du Colombier default:
2807dd7cddfSDavid du Colombier close(fd[1]);
2817dd7cddfSDavid du Colombier newfile(file, fd[0]);
2827dd7cddfSDavid du Colombier break;
2837dd7cddfSDavid du Colombier }
2847dd7cddfSDavid du Colombier } else {
2857dd7cddfSDavid du Colombier if(strcmp(file, "stdin") == 0)
2867dd7cddfSDavid du Colombier newfile(file, 0);
2873e12c5d1SDavid du Colombier else
2887dd7cddfSDavid du Colombier newfile(file, -1);
2897dd7cddfSDavid du Colombier }
2903e12c5d1SDavid du Colombier yyparse();
291fc375d71SDavid du Colombier if(!debug['a'] && !debug['Z'])
2923e12c5d1SDavid du Colombier gclean();
2937dd7cddfSDavid du Colombier return nerrors;
2943e12c5d1SDavid du Colombier }
2953e12c5d1SDavid du Colombier
2963e12c5d1SDavid du Colombier void
errorexit(void)2973e12c5d1SDavid du Colombier errorexit(void)
2983e12c5d1SDavid du Colombier {
2993e12c5d1SDavid du Colombier if(outfile)
3003e12c5d1SDavid du Colombier remove(outfile);
3013e12c5d1SDavid du Colombier exits("error");
3023e12c5d1SDavid du Colombier }
3033e12c5d1SDavid du Colombier
3043e12c5d1SDavid du Colombier void
pushio(void)3053e12c5d1SDavid du Colombier pushio(void)
3063e12c5d1SDavid du Colombier {
3073e12c5d1SDavid du Colombier Io *i;
3083e12c5d1SDavid du Colombier
3093e12c5d1SDavid du Colombier i = iostack;
3103e12c5d1SDavid du Colombier if(i == I) {
3113e12c5d1SDavid du Colombier yyerror("botch in pushio");
3123e12c5d1SDavid du Colombier errorexit();
3133e12c5d1SDavid du Colombier }
3143e12c5d1SDavid du Colombier i->p = fi.p;
3153e12c5d1SDavid du Colombier i->c = fi.c;
3163e12c5d1SDavid du Colombier }
3173e12c5d1SDavid du Colombier
3183e12c5d1SDavid du Colombier void
newio(void)3193e12c5d1SDavid du Colombier newio(void)
3203e12c5d1SDavid du Colombier {
3213e12c5d1SDavid du Colombier Io *i;
322375daca8SDavid du Colombier static int pushdepth = 0;
3233e12c5d1SDavid du Colombier
3243e12c5d1SDavid du Colombier i = iofree;
3253e12c5d1SDavid du Colombier if(i == I) {
3263e12c5d1SDavid du Colombier pushdepth++;
3273e12c5d1SDavid du Colombier if(pushdepth > 1000) {
3283e12c5d1SDavid du Colombier yyerror("macro/io expansion too deep");
3293e12c5d1SDavid du Colombier errorexit();
3303e12c5d1SDavid du Colombier }
3317dd7cddfSDavid du Colombier i = alloc(sizeof(*i));
3323e12c5d1SDavid du Colombier } else
3333e12c5d1SDavid du Colombier iofree = i->link;
3343e12c5d1SDavid du Colombier i->c = 0;
3353e12c5d1SDavid du Colombier i->f = -1;
3363e12c5d1SDavid du Colombier ionext = i;
3373e12c5d1SDavid du Colombier }
3383e12c5d1SDavid du Colombier
3393e12c5d1SDavid du Colombier void
newfile(char * s,int f)3403e12c5d1SDavid du Colombier newfile(char *s, int f)
3413e12c5d1SDavid du Colombier {
3423e12c5d1SDavid du Colombier Io *i;
3433e12c5d1SDavid du Colombier
3447dd7cddfSDavid du Colombier if(debug['e'])
3457dd7cddfSDavid du Colombier print("%L: %s\n", lineno, s);
3467dd7cddfSDavid du Colombier
3473e12c5d1SDavid du Colombier i = ionext;
3483e12c5d1SDavid du Colombier i->link = iostack;
3493e12c5d1SDavid du Colombier iostack = i;
3503e12c5d1SDavid du Colombier i->f = f;
3513e12c5d1SDavid du Colombier if(f < 0)
3523e12c5d1SDavid du Colombier i->f = open(s, 0);
3533e12c5d1SDavid du Colombier if(i->f < 0) {
3547dd7cddfSDavid du Colombier yyerror("%cc: %r: %s", thechar, s);
3553e12c5d1SDavid du Colombier errorexit();
3563e12c5d1SDavid du Colombier }
3573e12c5d1SDavid du Colombier fi.c = 0;
3583e12c5d1SDavid du Colombier linehist(s, 0);
3593e12c5d1SDavid du Colombier }
3603e12c5d1SDavid du Colombier
3613e12c5d1SDavid du Colombier Sym*
slookup(char * s)3623e12c5d1SDavid du Colombier slookup(char *s)
3633e12c5d1SDavid du Colombier {
3643e12c5d1SDavid du Colombier
3653e12c5d1SDavid du Colombier strcpy(symb, s);
3663e12c5d1SDavid du Colombier return lookup();
3673e12c5d1SDavid du Colombier }
3683e12c5d1SDavid du Colombier
3693e12c5d1SDavid du Colombier Sym*
lookup(void)3703e12c5d1SDavid du Colombier lookup(void)
3713e12c5d1SDavid du Colombier {
3723e12c5d1SDavid du Colombier Sym *s;
3733e12c5d1SDavid du Colombier ulong h;
374219b2ee8SDavid du Colombier char *p;
375219b2ee8SDavid du Colombier int c, n;
3763e12c5d1SDavid du Colombier
377219b2ee8SDavid du Colombier h = 0;
3783e12c5d1SDavid du Colombier for(p=symb; *p;) {
379219b2ee8SDavid du Colombier h = h * 3;
380219b2ee8SDavid du Colombier h += *p++;
3813e12c5d1SDavid du Colombier }
382219b2ee8SDavid du Colombier n = (p - symb) + 1;
383219b2ee8SDavid du Colombier if((long)h < 0)
384219b2ee8SDavid du Colombier h = ~h;
3853e12c5d1SDavid du Colombier h %= NHASH;
386219b2ee8SDavid du Colombier c = symb[0];
3873e12c5d1SDavid du Colombier for(s = hash[h]; s != S; s = s->link) {
388219b2ee8SDavid du Colombier if(s->name[0] != c)
3893e12c5d1SDavid du Colombier continue;
390219b2ee8SDavid du Colombier if(strcmp(s->name, symb) == 0)
3913e12c5d1SDavid du Colombier return s;
3923e12c5d1SDavid du Colombier }
3937dd7cddfSDavid du Colombier s = alloc(sizeof(*s));
3947dd7cddfSDavid du Colombier s->name = alloc(n);
395219b2ee8SDavid du Colombier memmove(s->name, symb, n);
396219b2ee8SDavid du Colombier
3973e12c5d1SDavid du Colombier strcpy(s->name, symb);
3983e12c5d1SDavid du Colombier s->link = hash[h];
3993e12c5d1SDavid du Colombier hash[h] = s;
4003e12c5d1SDavid du Colombier syminit(s);
4013e12c5d1SDavid du Colombier
4023e12c5d1SDavid du Colombier return s;
4033e12c5d1SDavid du Colombier }
4043e12c5d1SDavid du Colombier
4053e12c5d1SDavid du Colombier void
syminit(Sym * s)4063e12c5d1SDavid du Colombier syminit(Sym *s)
4073e12c5d1SDavid du Colombier {
4083e12c5d1SDavid du Colombier s->lexical = LNAME;
4093e12c5d1SDavid du Colombier s->block = 0;
4103e12c5d1SDavid du Colombier s->offset = 0;
4113e12c5d1SDavid du Colombier s->type = T;
4123e12c5d1SDavid du Colombier s->suetag = T;
4133e12c5d1SDavid du Colombier s->class = CXXX;
4143e12c5d1SDavid du Colombier s->aused = 0;
415375daca8SDavid du Colombier s->sig = SIGNONE;
4163e12c5d1SDavid du Colombier }
4173e12c5d1SDavid du Colombier
4183e12c5d1SDavid du Colombier #define EOF (-1)
4193e12c5d1SDavid du Colombier #define IGN (-2)
420905f70e7SDavid du Colombier #define ESC (Runemask+1) /* Rune flag: a literal byte */
4213e12c5d1SDavid du Colombier #define GETC() ((--fi.c < 0)? filbuf(): (*fi.p++ & 0xff))
4223e12c5d1SDavid du Colombier
4233e12c5d1SDavid du Colombier enum
4243e12c5d1SDavid du Colombier {
4253e12c5d1SDavid du Colombier Numdec = 1<<0,
4263e12c5d1SDavid du Colombier Numlong = 1<<1,
4273e12c5d1SDavid du Colombier Numuns = 1<<2,
4283e12c5d1SDavid du Colombier Numvlong = 1<<3,
4293e12c5d1SDavid du Colombier Numflt = 1<<4,
4303e12c5d1SDavid du Colombier };
4313e12c5d1SDavid du Colombier
4323e12c5d1SDavid du Colombier long
yylex(void)4333e12c5d1SDavid du Colombier yylex(void)
4343e12c5d1SDavid du Colombier {
435219b2ee8SDavid du Colombier vlong vv;
43622a127bbSDavid du Colombier long c, c1, t;
4373e12c5d1SDavid du Colombier char *cp;
4383e12c5d1SDavid du Colombier Rune rune;
4393e12c5d1SDavid du Colombier Sym *s;
4403e12c5d1SDavid du Colombier
4413e12c5d1SDavid du Colombier if(peekc != IGN) {
4423e12c5d1SDavid du Colombier c = peekc;
4433e12c5d1SDavid du Colombier peekc = IGN;
4443e12c5d1SDavid du Colombier goto l1;
4453e12c5d1SDavid du Colombier }
4463e12c5d1SDavid du Colombier l0:
4473e12c5d1SDavid du Colombier c = GETC();
4483e12c5d1SDavid du Colombier
4493e12c5d1SDavid du Colombier l1:
4503e12c5d1SDavid du Colombier if(c >= Runeself) {
4513e12c5d1SDavid du Colombier /*
4523e12c5d1SDavid du Colombier * extension --
4533e12c5d1SDavid du Colombier * all multibyte runes are alpha
4543e12c5d1SDavid du Colombier */
4553e12c5d1SDavid du Colombier cp = symb;
4563e12c5d1SDavid du Colombier goto talph;
4573e12c5d1SDavid du Colombier }
4583e12c5d1SDavid du Colombier if(isspace(c)) {
4593e12c5d1SDavid du Colombier if(c == '\n')
4603e12c5d1SDavid du Colombier lineno++;
4613e12c5d1SDavid du Colombier goto l0;
4623e12c5d1SDavid du Colombier }
4633e12c5d1SDavid du Colombier if(isalpha(c)) {
4643e12c5d1SDavid du Colombier cp = symb;
4653e12c5d1SDavid du Colombier if(c != 'L')
4663e12c5d1SDavid du Colombier goto talph;
4673e12c5d1SDavid du Colombier *cp++ = c;
4683e12c5d1SDavid du Colombier c = GETC();
4693e12c5d1SDavid du Colombier if(c == '\'') {
4703e12c5d1SDavid du Colombier /* L'x' */
4713e12c5d1SDavid du Colombier c = escchar('\'', 1, 0);
4723e12c5d1SDavid du Colombier if(c == EOF)
4733e12c5d1SDavid du Colombier c = '\'';
4743e12c5d1SDavid du Colombier c1 = escchar('\'', 1, 0);
4753e12c5d1SDavid du Colombier if(c1 != EOF) {
4763e12c5d1SDavid du Colombier yyerror("missing '");
4773e12c5d1SDavid du Colombier peekc = c1;
4783e12c5d1SDavid du Colombier }
47982726826SDavid du Colombier yylval.vval = convvtox(c, TRUNE);
4803e12c5d1SDavid du Colombier return LUCONST;
4813e12c5d1SDavid du Colombier }
4823e12c5d1SDavid du Colombier if(c == '"') {
4833e12c5d1SDavid du Colombier goto caselq;
4843e12c5d1SDavid du Colombier }
4853e12c5d1SDavid du Colombier goto talph;
4863e12c5d1SDavid du Colombier }
4873e12c5d1SDavid du Colombier if(isdigit(c))
4883e12c5d1SDavid du Colombier goto tnum;
4893e12c5d1SDavid du Colombier switch(c)
4903e12c5d1SDavid du Colombier {
4913e12c5d1SDavid du Colombier
4923e12c5d1SDavid du Colombier case EOF:
4933e12c5d1SDavid du Colombier peekc = EOF;
4943e12c5d1SDavid du Colombier return -1;
4953e12c5d1SDavid du Colombier
4963e12c5d1SDavid du Colombier case '_':
4973e12c5d1SDavid du Colombier cp = symb;
4983e12c5d1SDavid du Colombier goto talph;
4993e12c5d1SDavid du Colombier
5003e12c5d1SDavid du Colombier case '#':
5013e12c5d1SDavid du Colombier domacro();
5023e12c5d1SDavid du Colombier goto l0;
5033e12c5d1SDavid du Colombier
5043e12c5d1SDavid du Colombier case '.':
5053e12c5d1SDavid du Colombier c1 = GETC();
5063e12c5d1SDavid du Colombier if(isdigit(c1)) {
5073e12c5d1SDavid du Colombier cp = symb;
5083e12c5d1SDavid du Colombier *cp++ = c;
5093e12c5d1SDavid du Colombier c = c1;
5103e12c5d1SDavid du Colombier c1 = 0;
5113e12c5d1SDavid du Colombier goto casedot;
5123e12c5d1SDavid du Colombier }
5133e12c5d1SDavid du Colombier break;
5143e12c5d1SDavid du Colombier
5153e12c5d1SDavid du Colombier case '"':
5167dd7cddfSDavid du Colombier strcpy(symb, "\"<string>\"");
5177dd7cddfSDavid du Colombier cp = alloc(0);
5183e12c5d1SDavid du Colombier c1 = 0;
5193e12c5d1SDavid du Colombier
5203e12c5d1SDavid du Colombier /* "..." */
5213e12c5d1SDavid du Colombier for(;;) {
5223e12c5d1SDavid du Colombier c = escchar('"', 0, 1);
5233e12c5d1SDavid du Colombier if(c == EOF)
5243e12c5d1SDavid du Colombier break;
5253e12c5d1SDavid du Colombier if(c & ESC) {
5267dd7cddfSDavid du Colombier cp = allocn(cp, c1, 1);
5277dd7cddfSDavid du Colombier cp[c1++] = c;
5283e12c5d1SDavid du Colombier } else {
5293e12c5d1SDavid du Colombier rune = c;
5303e12c5d1SDavid du Colombier c = runelen(rune);
5317dd7cddfSDavid du Colombier cp = allocn(cp, c1, c);
5323e12c5d1SDavid du Colombier runetochar(cp+c1, &rune);
5333e12c5d1SDavid du Colombier c1 += c;
5343e12c5d1SDavid du Colombier }
5353e12c5d1SDavid du Colombier }
5367dd7cddfSDavid du Colombier yylval.sval.l = c1;
5373e12c5d1SDavid du Colombier do {
5387dd7cddfSDavid du Colombier cp = allocn(cp, c1, 1);
5393e12c5d1SDavid du Colombier cp[c1++] = 0;
5407dd7cddfSDavid du Colombier } while(c1 & MAXALIGN);
5417dd7cddfSDavid du Colombier yylval.sval.s = cp;
5423e12c5d1SDavid du Colombier return LSTRING;
5433e12c5d1SDavid du Colombier
5443e12c5d1SDavid du Colombier caselq:
5453e12c5d1SDavid du Colombier /* L"..." */
5467dd7cddfSDavid du Colombier strcpy(symb, "\"L<string>\"");
5477dd7cddfSDavid du Colombier cp = alloc(0);
5487dd7cddfSDavid du Colombier c1 = 0;
5493e12c5d1SDavid du Colombier for(;;) {
5503e12c5d1SDavid du Colombier c = escchar('"', 1, 0);
5513e12c5d1SDavid du Colombier if(c == EOF)
5523e12c5d1SDavid du Colombier break;
55382726826SDavid du Colombier cp = allocn(cp, c1, sizeof(TRune));
55482726826SDavid du Colombier *(TRune*)(cp + c1) = c;
55582726826SDavid du Colombier c1 += sizeof(TRune);
5563e12c5d1SDavid du Colombier }
5577dd7cddfSDavid du Colombier yylval.sval.l = c1;
5583e12c5d1SDavid du Colombier do {
55982726826SDavid du Colombier cp = allocn(cp, c1, sizeof(TRune));
56082726826SDavid du Colombier *(TRune*)(cp + c1) = 0;
56182726826SDavid du Colombier c1 += sizeof(TRune);
5627dd7cddfSDavid du Colombier } while(c1 & MAXALIGN);
5637dd7cddfSDavid du Colombier yylval.sval.s = cp;
5643e12c5d1SDavid du Colombier return LLSTRING;
5653e12c5d1SDavid du Colombier
5663e12c5d1SDavid du Colombier case '\'':
5673e12c5d1SDavid du Colombier /* '.' */
5683e12c5d1SDavid du Colombier c = escchar('\'', 0, 0);
5693e12c5d1SDavid du Colombier if(c == EOF)
5703e12c5d1SDavid du Colombier c = '\'';
5713e12c5d1SDavid du Colombier c1 = escchar('\'', 0, 0);
5723e12c5d1SDavid du Colombier if(c1 != EOF) {
5733e12c5d1SDavid du Colombier yyerror("missing '");
5743e12c5d1SDavid du Colombier peekc = c1;
5753e12c5d1SDavid du Colombier }
576219b2ee8SDavid du Colombier vv = c;
577219b2ee8SDavid du Colombier yylval.vval = convvtox(vv, TUCHAR);
578219b2ee8SDavid du Colombier if(yylval.vval != vv)
5797dd7cddfSDavid du Colombier yyerror("overflow in character constant: 0x%lx", c);
5807dd7cddfSDavid du Colombier else
58122a127bbSDavid du Colombier if(c & 0x80){
58222a127bbSDavid du Colombier nearln = lineno;
5837dd7cddfSDavid du Colombier warn(Z, "sign-extended character constant");
58422a127bbSDavid du Colombier }
585219b2ee8SDavid du Colombier yylval.vval = convvtox(vv, TCHAR);
5863e12c5d1SDavid du Colombier return LCONST;
5873e12c5d1SDavid du Colombier
5883e12c5d1SDavid du Colombier case '/':
5893e12c5d1SDavid du Colombier c1 = GETC();
5903e12c5d1SDavid du Colombier if(c1 == '*') {
5913e12c5d1SDavid du Colombier for(;;) {
5923e12c5d1SDavid du Colombier c = getr();
5933e12c5d1SDavid du Colombier while(c == '*') {
5943e12c5d1SDavid du Colombier c = getr();
5953e12c5d1SDavid du Colombier if(c == '/')
5963e12c5d1SDavid du Colombier goto l0;
5973e12c5d1SDavid du Colombier }
5983e12c5d1SDavid du Colombier if(c == EOF) {
5993e12c5d1SDavid du Colombier yyerror("eof in comment");
6003e12c5d1SDavid du Colombier errorexit();
6013e12c5d1SDavid du Colombier }
6023e12c5d1SDavid du Colombier }
6033e12c5d1SDavid du Colombier }
604219b2ee8SDavid du Colombier if(c1 == '/') {
605219b2ee8SDavid du Colombier for(;;) {
606219b2ee8SDavid du Colombier c = getr();
607219b2ee8SDavid du Colombier if(c == '\n')
608219b2ee8SDavid du Colombier goto l0;
609219b2ee8SDavid du Colombier if(c == EOF) {
610219b2ee8SDavid du Colombier yyerror("eof in comment");
611219b2ee8SDavid du Colombier errorexit();
612219b2ee8SDavid du Colombier }
613219b2ee8SDavid du Colombier }
614219b2ee8SDavid du Colombier }
6153e12c5d1SDavid du Colombier if(c1 == '=')
6163e12c5d1SDavid du Colombier return LDVE;
6173e12c5d1SDavid du Colombier break;
6183e12c5d1SDavid du Colombier
6193e12c5d1SDavid du Colombier case '*':
6203e12c5d1SDavid du Colombier c1 = GETC();
6213e12c5d1SDavid du Colombier if(c1 == '=')
6223e12c5d1SDavid du Colombier return LMLE;
6233e12c5d1SDavid du Colombier break;
6243e12c5d1SDavid du Colombier
6253e12c5d1SDavid du Colombier case '%':
6263e12c5d1SDavid du Colombier c1 = GETC();
6273e12c5d1SDavid du Colombier if(c1 == '=')
6283e12c5d1SDavid du Colombier return LMDE;
6293e12c5d1SDavid du Colombier break;
6303e12c5d1SDavid du Colombier
6313e12c5d1SDavid du Colombier case '+':
6323e12c5d1SDavid du Colombier c1 = GETC();
6333e12c5d1SDavid du Colombier if(c1 == '+')
6343e12c5d1SDavid du Colombier return LPP;
6353e12c5d1SDavid du Colombier if(c1 == '=')
6363e12c5d1SDavid du Colombier return LPE;
6373e12c5d1SDavid du Colombier break;
6383e12c5d1SDavid du Colombier
6393e12c5d1SDavid du Colombier case '-':
6403e12c5d1SDavid du Colombier c1 = GETC();
6413e12c5d1SDavid du Colombier if(c1 == '-')
6423e12c5d1SDavid du Colombier return LMM;
6433e12c5d1SDavid du Colombier if(c1 == '=')
6443e12c5d1SDavid du Colombier return LME;
6453e12c5d1SDavid du Colombier if(c1 == '>')
6463e12c5d1SDavid du Colombier return LMG;
6473e12c5d1SDavid du Colombier break;
6483e12c5d1SDavid du Colombier
6493e12c5d1SDavid du Colombier case '>':
6503e12c5d1SDavid du Colombier c1 = GETC();
6513e12c5d1SDavid du Colombier if(c1 == '>') {
6523e12c5d1SDavid du Colombier c = LRSH;
6533e12c5d1SDavid du Colombier c1 = GETC();
6543e12c5d1SDavid du Colombier if(c1 == '=')
6553e12c5d1SDavid du Colombier return LRSHE;
6563e12c5d1SDavid du Colombier break;
6573e12c5d1SDavid du Colombier }
6583e12c5d1SDavid du Colombier if(c1 == '=')
6593e12c5d1SDavid du Colombier return LGE;
6603e12c5d1SDavid du Colombier break;
6613e12c5d1SDavid du Colombier
6623e12c5d1SDavid du Colombier case '<':
6633e12c5d1SDavid du Colombier c1 = GETC();
6643e12c5d1SDavid du Colombier if(c1 == '<') {
6653e12c5d1SDavid du Colombier c = LLSH;
6663e12c5d1SDavid du Colombier c1 = GETC();
6673e12c5d1SDavid du Colombier if(c1 == '=')
6683e12c5d1SDavid du Colombier return LLSHE;
6693e12c5d1SDavid du Colombier break;
6703e12c5d1SDavid du Colombier }
6713e12c5d1SDavid du Colombier if(c1 == '=')
6723e12c5d1SDavid du Colombier return LLE;
6733e12c5d1SDavid du Colombier break;
6743e12c5d1SDavid du Colombier
6753e12c5d1SDavid du Colombier case '=':
6763e12c5d1SDavid du Colombier c1 = GETC();
6773e12c5d1SDavid du Colombier if(c1 == '=')
6783e12c5d1SDavid du Colombier return LEQ;
6793e12c5d1SDavid du Colombier break;
6803e12c5d1SDavid du Colombier
6813e12c5d1SDavid du Colombier case '!':
6823e12c5d1SDavid du Colombier c1 = GETC();
6833e12c5d1SDavid du Colombier if(c1 == '=')
6843e12c5d1SDavid du Colombier return LNE;
6853e12c5d1SDavid du Colombier break;
6863e12c5d1SDavid du Colombier
6873e12c5d1SDavid du Colombier case '&':
6883e12c5d1SDavid du Colombier c1 = GETC();
6893e12c5d1SDavid du Colombier if(c1 == '&')
6903e12c5d1SDavid du Colombier return LANDAND;
6913e12c5d1SDavid du Colombier if(c1 == '=')
6923e12c5d1SDavid du Colombier return LANDE;
6933e12c5d1SDavid du Colombier break;
6943e12c5d1SDavid du Colombier
6953e12c5d1SDavid du Colombier case '|':
6963e12c5d1SDavid du Colombier c1 = GETC();
6973e12c5d1SDavid du Colombier if(c1 == '|')
6983e12c5d1SDavid du Colombier return LOROR;
6993e12c5d1SDavid du Colombier if(c1 == '=')
7003e12c5d1SDavid du Colombier return LORE;
7013e12c5d1SDavid du Colombier break;
7023e12c5d1SDavid du Colombier
7033e12c5d1SDavid du Colombier case '^':
7043e12c5d1SDavid du Colombier c1 = GETC();
7053e12c5d1SDavid du Colombier if(c1 == '=')
7063e12c5d1SDavid du Colombier return LXORE;
7073e12c5d1SDavid du Colombier break;
7083e12c5d1SDavid du Colombier
7093e12c5d1SDavid du Colombier default:
7103e12c5d1SDavid du Colombier return c;
7113e12c5d1SDavid du Colombier }
7123e12c5d1SDavid du Colombier peekc = c1;
7133e12c5d1SDavid du Colombier return c;
7143e12c5d1SDavid du Colombier
7153e12c5d1SDavid du Colombier talph:
7163e12c5d1SDavid du Colombier /*
7173e12c5d1SDavid du Colombier * cp is set to symb and some
7183e12c5d1SDavid du Colombier * prefix has been stored
7193e12c5d1SDavid du Colombier */
7203e12c5d1SDavid du Colombier for(;;) {
7213e12c5d1SDavid du Colombier if(c >= Runeself) {
7223e12c5d1SDavid du Colombier for(c1=0;;) {
7233e12c5d1SDavid du Colombier cp[c1++] = c;
7243e12c5d1SDavid du Colombier if(fullrune(cp, c1))
7253e12c5d1SDavid du Colombier break;
7263e12c5d1SDavid du Colombier c = GETC();
7273e12c5d1SDavid du Colombier }
7283e12c5d1SDavid du Colombier cp += c1;
7293e12c5d1SDavid du Colombier c = GETC();
7303e12c5d1SDavid du Colombier continue;
7313e12c5d1SDavid du Colombier }
7323e12c5d1SDavid du Colombier if(!isalnum(c) && c != '_')
7333e12c5d1SDavid du Colombier break;
7343e12c5d1SDavid du Colombier *cp++ = c;
7353e12c5d1SDavid du Colombier c = GETC();
7363e12c5d1SDavid du Colombier }
7373e12c5d1SDavid du Colombier *cp = 0;
7383e12c5d1SDavid du Colombier if(debug['L'])
739219b2ee8SDavid du Colombier print("%L: %s\n", lineno, symb);
7403e12c5d1SDavid du Colombier peekc = c;
7413e12c5d1SDavid du Colombier s = lookup();
7423e12c5d1SDavid du Colombier if(s->macro) {
7433e12c5d1SDavid du Colombier newio();
7443e12c5d1SDavid du Colombier cp = ionext->b;
7453e12c5d1SDavid du Colombier macexpand(s, cp);
7463e12c5d1SDavid du Colombier pushio();
7473e12c5d1SDavid du Colombier ionext->link = iostack;
7483e12c5d1SDavid du Colombier iostack = ionext;
7493e12c5d1SDavid du Colombier fi.p = cp;
7503e12c5d1SDavid du Colombier fi.c = strlen(cp);
7513e12c5d1SDavid du Colombier if(peekc != IGN) {
7523e12c5d1SDavid du Colombier cp[fi.c++] = peekc;
7533e12c5d1SDavid du Colombier cp[fi.c] = 0;
7543e12c5d1SDavid du Colombier peekc = IGN;
7553e12c5d1SDavid du Colombier }
7563e12c5d1SDavid du Colombier goto l0;
7573e12c5d1SDavid du Colombier }
7583e12c5d1SDavid du Colombier yylval.sym = s;
75980ee5cbfSDavid du Colombier if(s->class == CTYPEDEF || s->class == CTYPESTR)
76080ee5cbfSDavid du Colombier return LTYPE;
7613e12c5d1SDavid du Colombier return s->lexical;
7623e12c5d1SDavid du Colombier
7633e12c5d1SDavid du Colombier tnum:
7643e12c5d1SDavid du Colombier c1 = 0;
7653e12c5d1SDavid du Colombier cp = symb;
7663e12c5d1SDavid du Colombier if(c != '0') {
7673e12c5d1SDavid du Colombier c1 |= Numdec;
7683e12c5d1SDavid du Colombier for(;;) {
7693e12c5d1SDavid du Colombier *cp++ = c;
7703e12c5d1SDavid du Colombier c = GETC();
7713e12c5d1SDavid du Colombier if(isdigit(c))
7723e12c5d1SDavid du Colombier continue;
7733e12c5d1SDavid du Colombier goto dc;
7743e12c5d1SDavid du Colombier }
7753e12c5d1SDavid du Colombier }
7763e12c5d1SDavid du Colombier *cp++ = c;
7773e12c5d1SDavid du Colombier c = GETC();
7783e12c5d1SDavid du Colombier if(c == 'x' || c == 'X')
7793e12c5d1SDavid du Colombier for(;;) {
7803e12c5d1SDavid du Colombier *cp++ = c;
7813e12c5d1SDavid du Colombier c = GETC();
7823e12c5d1SDavid du Colombier if(isdigit(c))
7833e12c5d1SDavid du Colombier continue;
7843e12c5d1SDavid du Colombier if(c >= 'a' && c <= 'f')
7853e12c5d1SDavid du Colombier continue;
7863e12c5d1SDavid du Colombier if(c >= 'A' && c <= 'F')
7873e12c5d1SDavid du Colombier continue;
7883e12c5d1SDavid du Colombier if(cp == symb+2)
7893e12c5d1SDavid du Colombier yyerror("malformed hex constant");
7903e12c5d1SDavid du Colombier goto ncu;
7913e12c5d1SDavid du Colombier }
7923e12c5d1SDavid du Colombier if(c < '0' || c > '7')
7933e12c5d1SDavid du Colombier goto dc;
7943e12c5d1SDavid du Colombier for(;;) {
7953e12c5d1SDavid du Colombier if(c >= '0' && c <= '7') {
7963e12c5d1SDavid du Colombier *cp++ = c;
7973e12c5d1SDavid du Colombier c = GETC();
7983e12c5d1SDavid du Colombier continue;
7993e12c5d1SDavid du Colombier }
8003e12c5d1SDavid du Colombier goto ncu;
8013e12c5d1SDavid du Colombier }
8023e12c5d1SDavid du Colombier
8033e12c5d1SDavid du Colombier dc:
8043e12c5d1SDavid du Colombier if(c == '.')
8053e12c5d1SDavid du Colombier goto casedot;
8063e12c5d1SDavid du Colombier if(c == 'e' || c == 'E')
8073e12c5d1SDavid du Colombier goto casee;
8083e12c5d1SDavid du Colombier
8093e12c5d1SDavid du Colombier ncu:
8107dd7cddfSDavid du Colombier if((c == 'U' || c == 'u') && !(c1 & Numuns)) {
8113e12c5d1SDavid du Colombier c = GETC();
8123e12c5d1SDavid du Colombier c1 |= Numuns;
8137dd7cddfSDavid du Colombier goto ncu;
8143e12c5d1SDavid du Colombier }
8157dd7cddfSDavid du Colombier if((c == 'L' || c == 'l') && !(c1 & Numvlong)) {
8163e12c5d1SDavid du Colombier c = GETC();
8177dd7cddfSDavid du Colombier if(c1 & Numlong)
8183e12c5d1SDavid du Colombier c1 |= Numvlong;
8197dd7cddfSDavid du Colombier c1 |= Numlong;
8207dd7cddfSDavid du Colombier goto ncu;
8213e12c5d1SDavid du Colombier }
8227dd7cddfSDavid du Colombier *cp = 0;
8233e12c5d1SDavid du Colombier peekc = c;
824219b2ee8SDavid du Colombier if(mpatov(symb, &yylval.vval))
825219b2ee8SDavid du Colombier yyerror("overflow in constant");
826219b2ee8SDavid du Colombier
82722a127bbSDavid du Colombier vv = yylval.vval;
8283e12c5d1SDavid du Colombier if(c1 & Numvlong) {
82922a127bbSDavid du Colombier if((c1 & Numuns) || convvtox(vv, TVLONG) < 0) {
830219b2ee8SDavid du Colombier c = LUVLCONST;
83122a127bbSDavid du Colombier t = TUVLONG;
8323e12c5d1SDavid du Colombier goto nret;
8333e12c5d1SDavid du Colombier }
834219b2ee8SDavid du Colombier c = LVLCONST;
83522a127bbSDavid du Colombier t = TVLONG;
836219b2ee8SDavid du Colombier goto nret;
837219b2ee8SDavid du Colombier }
8383e12c5d1SDavid du Colombier if(c1 & Numlong) {
83922a127bbSDavid du Colombier if((c1 & Numuns) || convvtox(vv, TLONG) < 0) {
840219b2ee8SDavid du Colombier c = LULCONST;
84122a127bbSDavid du Colombier t = TULONG;
842219b2ee8SDavid du Colombier goto nret;
8433e12c5d1SDavid du Colombier }
844219b2ee8SDavid du Colombier c = LLCONST;
84522a127bbSDavid du Colombier t = TLONG;
8463e12c5d1SDavid du Colombier goto nret;
847219b2ee8SDavid du Colombier }
84822a127bbSDavid du Colombier if((c1 & Numuns) || convvtox(vv, TINT) < 0) {
849219b2ee8SDavid du Colombier c = LUCONST;
85022a127bbSDavid du Colombier t = TUINT;
8513e12c5d1SDavid du Colombier goto nret;
852219b2ee8SDavid du Colombier }
853219b2ee8SDavid du Colombier c = LCONST;
85422a127bbSDavid du Colombier t = TINT;
855219b2ee8SDavid du Colombier goto nret;
856219b2ee8SDavid du Colombier
857219b2ee8SDavid du Colombier nret:
85822a127bbSDavid du Colombier yylval.vval = convvtox(vv, t);
85922a127bbSDavid du Colombier if(yylval.vval != vv){
86022a127bbSDavid du Colombier nearln = lineno;
86122a127bbSDavid du Colombier warn(Z, "truncated constant: %T %s", types[t], symb);
86222a127bbSDavid du Colombier }
863219b2ee8SDavid du Colombier return c;
8643e12c5d1SDavid du Colombier
8653e12c5d1SDavid du Colombier casedot:
8663e12c5d1SDavid du Colombier for(;;) {
8673e12c5d1SDavid du Colombier *cp++ = c;
8683e12c5d1SDavid du Colombier c = GETC();
8693e12c5d1SDavid du Colombier if(!isdigit(c))
8703e12c5d1SDavid du Colombier break;
8713e12c5d1SDavid du Colombier }
8723e12c5d1SDavid du Colombier if(c != 'e' && c != 'E')
8733e12c5d1SDavid du Colombier goto caseout;
8743e12c5d1SDavid du Colombier
8753e12c5d1SDavid du Colombier casee:
8763e12c5d1SDavid du Colombier *cp++ = 'e';
8773e12c5d1SDavid du Colombier c = GETC();
8783e12c5d1SDavid du Colombier if(c == '+' || c == '-') {
8793e12c5d1SDavid du Colombier *cp++ = c;
8803e12c5d1SDavid du Colombier c = GETC();
8813e12c5d1SDavid du Colombier }
8823e12c5d1SDavid du Colombier if(!isdigit(c))
8833e12c5d1SDavid du Colombier yyerror("malformed fp constant exponent");
8843e12c5d1SDavid du Colombier while(isdigit(c)) {
8853e12c5d1SDavid du Colombier *cp++ = c;
8863e12c5d1SDavid du Colombier c = GETC();
8873e12c5d1SDavid du Colombier }
8883e12c5d1SDavid du Colombier
8893e12c5d1SDavid du Colombier caseout:
8903e12c5d1SDavid du Colombier if(c == 'L' || c == 'l') {
8913e12c5d1SDavid du Colombier c = GETC();
8923e12c5d1SDavid du Colombier c1 |= Numlong;
8933e12c5d1SDavid du Colombier } else
8943e12c5d1SDavid du Colombier if(c == 'F' || c == 'f') {
8953e12c5d1SDavid du Colombier c = GETC();
8963e12c5d1SDavid du Colombier c1 |= Numflt;
8973e12c5d1SDavid du Colombier }
8983e12c5d1SDavid du Colombier *cp = 0;
8993e12c5d1SDavid du Colombier peekc = c;
90059cc4ca5SDavid du Colombier yylval.dval = strtod(symb, nil);
90159cc4ca5SDavid du Colombier if(isInf(yylval.dval, 1) || isInf(yylval.dval, -1)) {
9023e12c5d1SDavid du Colombier yyerror("overflow in float constant");
9033e12c5d1SDavid du Colombier yylval.dval = 0;
9043e12c5d1SDavid du Colombier }
9053e12c5d1SDavid du Colombier if(c1 & Numflt)
9063e12c5d1SDavid du Colombier return LFCONST;
9073e12c5d1SDavid du Colombier return LDCONST;
9083e12c5d1SDavid du Colombier }
9093e12c5d1SDavid du Colombier
91059cc4ca5SDavid du Colombier /*
91159cc4ca5SDavid du Colombier * convert a string, s, to vlong in *v
91259cc4ca5SDavid du Colombier * return conversion overflow.
91359cc4ca5SDavid du Colombier * required syntax is [0[x]]d*
91459cc4ca5SDavid du Colombier */
91559cc4ca5SDavid du Colombier int
mpatov(char * s,vlong * v)91659cc4ca5SDavid du Colombier mpatov(char *s, vlong *v)
91759cc4ca5SDavid du Colombier {
91859cc4ca5SDavid du Colombier vlong n, nn;
91959cc4ca5SDavid du Colombier int c;
92059cc4ca5SDavid du Colombier
92159cc4ca5SDavid du Colombier n = 0;
92259cc4ca5SDavid du Colombier c = *s;
92359cc4ca5SDavid du Colombier if(c == '0')
92459cc4ca5SDavid du Colombier goto oct;
92559cc4ca5SDavid du Colombier while(c = *s++) {
92659cc4ca5SDavid du Colombier if(c >= '0' && c <= '9')
92759cc4ca5SDavid du Colombier nn = n*10 + c-'0';
92859cc4ca5SDavid du Colombier else
92959cc4ca5SDavid du Colombier goto bad;
93059cc4ca5SDavid du Colombier if(n < 0 && nn >= 0)
93159cc4ca5SDavid du Colombier goto bad;
93259cc4ca5SDavid du Colombier n = nn;
93359cc4ca5SDavid du Colombier }
93459cc4ca5SDavid du Colombier goto out;
93559cc4ca5SDavid du Colombier
93659cc4ca5SDavid du Colombier oct:
93759cc4ca5SDavid du Colombier s++;
93859cc4ca5SDavid du Colombier c = *s;
93959cc4ca5SDavid du Colombier if(c == 'x' || c == 'X')
94059cc4ca5SDavid du Colombier goto hex;
94159cc4ca5SDavid du Colombier while(c = *s++) {
94259cc4ca5SDavid du Colombier if(c >= '0' || c <= '7')
94359cc4ca5SDavid du Colombier nn = n*8 + c-'0';
94459cc4ca5SDavid du Colombier else
94559cc4ca5SDavid du Colombier goto bad;
94659cc4ca5SDavid du Colombier if(n < 0 && nn >= 0)
94759cc4ca5SDavid du Colombier goto bad;
94859cc4ca5SDavid du Colombier n = nn;
94959cc4ca5SDavid du Colombier }
95059cc4ca5SDavid du Colombier goto out;
95159cc4ca5SDavid du Colombier
95259cc4ca5SDavid du Colombier hex:
95359cc4ca5SDavid du Colombier s++;
95459cc4ca5SDavid du Colombier while(c = *s++) {
95559cc4ca5SDavid du Colombier if(c >= '0' && c <= '9')
95659cc4ca5SDavid du Colombier c += 0-'0';
95759cc4ca5SDavid du Colombier else
95859cc4ca5SDavid du Colombier if(c >= 'a' && c <= 'f')
95959cc4ca5SDavid du Colombier c += 10-'a';
96059cc4ca5SDavid du Colombier else
96159cc4ca5SDavid du Colombier if(c >= 'A' && c <= 'F')
96259cc4ca5SDavid du Colombier c += 10-'A';
96359cc4ca5SDavid du Colombier else
96459cc4ca5SDavid du Colombier goto bad;
96559cc4ca5SDavid du Colombier nn = n*16 + c;
96659cc4ca5SDavid du Colombier if(n < 0 && nn >= 0)
96759cc4ca5SDavid du Colombier goto bad;
96859cc4ca5SDavid du Colombier n = nn;
96959cc4ca5SDavid du Colombier }
97059cc4ca5SDavid du Colombier out:
97159cc4ca5SDavid du Colombier *v = n;
97259cc4ca5SDavid du Colombier return 0;
97359cc4ca5SDavid du Colombier
97459cc4ca5SDavid du Colombier bad:
97559cc4ca5SDavid du Colombier *v = ~0;
97659cc4ca5SDavid du Colombier return 1;
97759cc4ca5SDavid du Colombier }
97859cc4ca5SDavid du Colombier
9793e12c5d1SDavid du Colombier int
getc(void)9803e12c5d1SDavid du Colombier getc(void)
9813e12c5d1SDavid du Colombier {
9823e12c5d1SDavid du Colombier int c;
9833e12c5d1SDavid du Colombier
9843e12c5d1SDavid du Colombier if(peekc != IGN) {
9853e12c5d1SDavid du Colombier c = peekc;
9863e12c5d1SDavid du Colombier peekc = IGN;
9873e12c5d1SDavid du Colombier } else
9883e12c5d1SDavid du Colombier c = GETC();
9893e12c5d1SDavid du Colombier if(c == '\n')
9903e12c5d1SDavid du Colombier lineno++;
9913e12c5d1SDavid du Colombier if(c == EOF) {
9923e12c5d1SDavid du Colombier yyerror("End of file");
9933e12c5d1SDavid du Colombier errorexit();
9943e12c5d1SDavid du Colombier }
9953e12c5d1SDavid du Colombier return c;
9963e12c5d1SDavid du Colombier }
9973e12c5d1SDavid du Colombier
9983e12c5d1SDavid du Colombier long
getr(void)9993e12c5d1SDavid du Colombier getr(void)
10003e12c5d1SDavid du Colombier {
10013e12c5d1SDavid du Colombier int c, i;
10023e12c5d1SDavid du Colombier char str[UTFmax+1];
10033e12c5d1SDavid du Colombier Rune rune;
10043e12c5d1SDavid du Colombier
10053e12c5d1SDavid du Colombier
10063e12c5d1SDavid du Colombier c = getc();
10073e12c5d1SDavid du Colombier if(c < Runeself)
10083e12c5d1SDavid du Colombier return c;
10093e12c5d1SDavid du Colombier i = 0;
10103e12c5d1SDavid du Colombier str[i++] = c;
10113e12c5d1SDavid du Colombier
10123e12c5d1SDavid du Colombier loop:
10133e12c5d1SDavid du Colombier c = getc();
10143e12c5d1SDavid du Colombier str[i++] = c;
10153e12c5d1SDavid du Colombier if(!fullrune(str, i))
10163e12c5d1SDavid du Colombier goto loop;
10173e12c5d1SDavid du Colombier c = chartorune(&rune, str);
10183e12c5d1SDavid du Colombier if(rune == Runeerror && c == 1) {
10193e12c5d1SDavid du Colombier nearln = lineno;
10203e12c5d1SDavid du Colombier diag(Z, "illegal rune in string");
10213e12c5d1SDavid du Colombier for(c=0; c<i; c++)
10223e12c5d1SDavid du Colombier print(" %.2x", *(uchar*)(str+c));
10233e12c5d1SDavid du Colombier print("\n");
10243e12c5d1SDavid du Colombier }
10253e12c5d1SDavid du Colombier return rune;
10263e12c5d1SDavid du Colombier }
10273e12c5d1SDavid du Colombier
10283e12c5d1SDavid du Colombier int
getnsc(void)10293e12c5d1SDavid du Colombier getnsc(void)
10303e12c5d1SDavid du Colombier {
10313e12c5d1SDavid du Colombier int c;
10323e12c5d1SDavid du Colombier
10333e12c5d1SDavid du Colombier if(peekc != IGN) {
10343e12c5d1SDavid du Colombier c = peekc;
10353e12c5d1SDavid du Colombier peekc = IGN;
10363e12c5d1SDavid du Colombier } else
10373e12c5d1SDavid du Colombier c = GETC();
10383e12c5d1SDavid du Colombier for(;;) {
103982726826SDavid du Colombier if(c >= Runeself || !isspace(c))
10403e12c5d1SDavid du Colombier return c;
10413e12c5d1SDavid du Colombier if(c == '\n') {
10423e12c5d1SDavid du Colombier lineno++;
10433e12c5d1SDavid du Colombier return c;
10443e12c5d1SDavid du Colombier }
10453e12c5d1SDavid du Colombier c = GETC();
10463e12c5d1SDavid du Colombier }
10473e12c5d1SDavid du Colombier }
10483e12c5d1SDavid du Colombier
10493e12c5d1SDavid du Colombier void
unget(int c)10503e12c5d1SDavid du Colombier unget(int c)
10513e12c5d1SDavid du Colombier {
10523e12c5d1SDavid du Colombier
10533e12c5d1SDavid du Colombier peekc = c;
10543e12c5d1SDavid du Colombier if(c == '\n')
10553e12c5d1SDavid du Colombier lineno--;
10563e12c5d1SDavid du Colombier }
10573e12c5d1SDavid du Colombier
10583e12c5d1SDavid du Colombier long
escchar(long e,int longflg,int escflg)10593e12c5d1SDavid du Colombier escchar(long e, int longflg, int escflg)
10603e12c5d1SDavid du Colombier {
10613e12c5d1SDavid du Colombier long c, l;
10623e12c5d1SDavid du Colombier int i;
10633e12c5d1SDavid du Colombier
10643e12c5d1SDavid du Colombier loop:
10653e12c5d1SDavid du Colombier c = getr();
10663e12c5d1SDavid du Colombier if(c == '\n') {
10673e12c5d1SDavid du Colombier yyerror("newline in string");
10683e12c5d1SDavid du Colombier return EOF;
10693e12c5d1SDavid du Colombier }
10703e12c5d1SDavid du Colombier if(c != '\\') {
10713e12c5d1SDavid du Colombier if(c == e)
10723e12c5d1SDavid du Colombier c = EOF;
10733e12c5d1SDavid du Colombier return c;
10743e12c5d1SDavid du Colombier }
10753e12c5d1SDavid du Colombier c = getr();
10763e12c5d1SDavid du Colombier if(c == 'x') {
10773e12c5d1SDavid du Colombier /*
10783e12c5d1SDavid du Colombier * note this is not ansi,
10793e12c5d1SDavid du Colombier * supposed to only accept 2 hex
10803e12c5d1SDavid du Colombier */
10813e12c5d1SDavid du Colombier i = 2;
10823e12c5d1SDavid du Colombier if(longflg)
1083e94a8e9bSDavid du Colombier i = 6;
10843e12c5d1SDavid du Colombier l = 0;
10853e12c5d1SDavid du Colombier for(; i>0; i--) {
10863e12c5d1SDavid du Colombier c = getc();
1087219b2ee8SDavid du Colombier if(c >= '0' && c <= '9') {
10883e12c5d1SDavid du Colombier l = l*16 + c-'0';
10893e12c5d1SDavid du Colombier continue;
10903e12c5d1SDavid du Colombier }
10913e12c5d1SDavid du Colombier if(c >= 'a' && c <= 'f') {
10923e12c5d1SDavid du Colombier l = l*16 + c-'a' + 10;
10933e12c5d1SDavid du Colombier continue;
10943e12c5d1SDavid du Colombier }
10953e12c5d1SDavid du Colombier if(c >= 'A' && c <= 'F') {
10963e12c5d1SDavid du Colombier l = l*16 + c-'A' + 10;
10973e12c5d1SDavid du Colombier continue;
10983e12c5d1SDavid du Colombier }
10993e12c5d1SDavid du Colombier unget(c);
11003e12c5d1SDavid du Colombier break;
11013e12c5d1SDavid du Colombier }
11023e12c5d1SDavid du Colombier if(escflg)
11033e12c5d1SDavid du Colombier l |= ESC;
11043e12c5d1SDavid du Colombier return l;
11053e12c5d1SDavid du Colombier }
11063e12c5d1SDavid du Colombier if(c >= '0' && c <= '7') {
11073e12c5d1SDavid du Colombier /*
11083e12c5d1SDavid du Colombier * note this is not ansi,
11093e12c5d1SDavid du Colombier * supposed to only accept 3 oct
11103e12c5d1SDavid du Colombier */
11113e12c5d1SDavid du Colombier i = 2;
11123e12c5d1SDavid du Colombier if(longflg)
1113e94a8e9bSDavid du Colombier i = 8;
11143e12c5d1SDavid du Colombier l = c - '0';
11153e12c5d1SDavid du Colombier for(; i>0; i--) {
11163e12c5d1SDavid du Colombier c = getc();
11173e12c5d1SDavid du Colombier if(c >= '0' && c <= '7') {
11183e12c5d1SDavid du Colombier l = l*8 + c-'0';
11193e12c5d1SDavid du Colombier continue;
11203e12c5d1SDavid du Colombier }
11213e12c5d1SDavid du Colombier unget(c);
11223e12c5d1SDavid du Colombier }
11233e12c5d1SDavid du Colombier if(escflg)
11243e12c5d1SDavid du Colombier l |= ESC;
11253e12c5d1SDavid du Colombier return l;
11263e12c5d1SDavid du Colombier }
11273e12c5d1SDavid du Colombier switch(c)
11283e12c5d1SDavid du Colombier {
11293e12c5d1SDavid du Colombier case '\n': goto loop;
11303e12c5d1SDavid du Colombier case 'n': return '\n';
11313e12c5d1SDavid du Colombier case 't': return '\t';
11323e12c5d1SDavid du Colombier case 'b': return '\b';
11333e12c5d1SDavid du Colombier case 'r': return '\r';
11343e12c5d1SDavid du Colombier case 'f': return '\f';
11353e12c5d1SDavid du Colombier case 'a': return '\a';
11363e12c5d1SDavid du Colombier case 'v': return '\v';
11373e12c5d1SDavid du Colombier }
11383e12c5d1SDavid du Colombier return c;
11393e12c5d1SDavid du Colombier }
11403e12c5d1SDavid du Colombier
11413e12c5d1SDavid du Colombier struct
11423e12c5d1SDavid du Colombier {
11433e12c5d1SDavid du Colombier char *name;
11443e12c5d1SDavid du Colombier ushort lexical;
11457dd7cddfSDavid du Colombier ushort type;
11463e12c5d1SDavid du Colombier } itab[] =
11473e12c5d1SDavid du Colombier {
11487dd7cddfSDavid du Colombier "auto", LAUTO, 0,
11497dd7cddfSDavid du Colombier "break", LBREAK, 0,
11507dd7cddfSDavid du Colombier "case", LCASE, 0,
11517dd7cddfSDavid du Colombier "char", LCHAR, TCHAR,
11527dd7cddfSDavid du Colombier "const", LCONSTNT, 0,
11537dd7cddfSDavid du Colombier "continue", LCONTINUE, 0,
11547dd7cddfSDavid du Colombier "default", LDEFAULT, 0,
11557dd7cddfSDavid du Colombier "do", LDO, 0,
11567dd7cddfSDavid du Colombier "double", LDOUBLE, TDOUBLE,
11577dd7cddfSDavid du Colombier "else", LELSE, 0,
11587dd7cddfSDavid du Colombier "enum", LENUM, 0,
11597dd7cddfSDavid du Colombier "extern", LEXTERN, 0,
11607dd7cddfSDavid du Colombier "float", LFLOAT, TFLOAT,
11617dd7cddfSDavid du Colombier "for", LFOR, 0,
11627dd7cddfSDavid du Colombier "goto", LGOTO, 0,
11637dd7cddfSDavid du Colombier "if", LIF, 0,
11644bada075SDavid du Colombier "inline", LINLINE, 0,
11657dd7cddfSDavid du Colombier "int", LINT, TINT,
11667dd7cddfSDavid du Colombier "long", LLONG, TLONG,
11677dd7cddfSDavid du Colombier "register", LREGISTER, 0,
11684bada075SDavid du Colombier "restrict", LRESTRICT, 0,
11697dd7cddfSDavid du Colombier "return", LRETURN, 0,
11707dd7cddfSDavid du Colombier "SET", LSET, 0,
11717dd7cddfSDavid du Colombier "short", LSHORT, TSHORT,
11727dd7cddfSDavid du Colombier "signed", LSIGNED, 0,
11737dd7cddfSDavid du Colombier "signof", LSIGNOF, 0,
11747dd7cddfSDavid du Colombier "sizeof", LSIZEOF, 0,
11757dd7cddfSDavid du Colombier "static", LSTATIC, 0,
11767dd7cddfSDavid du Colombier "struct", LSTRUCT, 0,
11777dd7cddfSDavid du Colombier "switch", LSWITCH, 0,
11787dd7cddfSDavid du Colombier "typedef", LTYPEDEF, 0,
117980ee5cbfSDavid du Colombier "typestr", LTYPESTR, 0,
11807dd7cddfSDavid du Colombier "union", LUNION, 0,
11817dd7cddfSDavid du Colombier "unsigned", LUNSIGNED, 0,
11827dd7cddfSDavid du Colombier "USED", LUSED, 0,
11837dd7cddfSDavid du Colombier "void", LVOID, TVOID,
11847dd7cddfSDavid du Colombier "volatile", LVOLATILE, 0,
11857dd7cddfSDavid du Colombier "while", LWHILE, 0,
11863e12c5d1SDavid du Colombier 0
11873e12c5d1SDavid du Colombier };
11883e12c5d1SDavid du Colombier
11893e12c5d1SDavid du Colombier void
cinit(void)11903e12c5d1SDavid du Colombier cinit(void)
11913e12c5d1SDavid du Colombier {
11923e12c5d1SDavid du Colombier Sym *s;
11933e12c5d1SDavid du Colombier int i;
11943e12c5d1SDavid du Colombier Type *t;
11953e12c5d1SDavid du Colombier
11963e12c5d1SDavid du Colombier nerrors = 0;
11973e12c5d1SDavid du Colombier lineno = 1;
11983e12c5d1SDavid du Colombier iostack = I;
11993e12c5d1SDavid du Colombier iofree = I;
12003e12c5d1SDavid du Colombier peekc = IGN;
12013e12c5d1SDavid du Colombier nhunk = 0;
12023e12c5d1SDavid du Colombier
12033e12c5d1SDavid du Colombier types[TXXX] = T;
12043e12c5d1SDavid du Colombier types[TCHAR] = typ(TCHAR, T);
12053e12c5d1SDavid du Colombier types[TUCHAR] = typ(TUCHAR, T);
12063e12c5d1SDavid du Colombier types[TSHORT] = typ(TSHORT, T);
12073e12c5d1SDavid du Colombier types[TUSHORT] = typ(TUSHORT, T);
12087dd7cddfSDavid du Colombier types[TINT] = typ(TINT, T);
12097dd7cddfSDavid du Colombier types[TUINT] = typ(TUINT, T);
12103e12c5d1SDavid du Colombier types[TLONG] = typ(TLONG, T);
12113e12c5d1SDavid du Colombier types[TULONG] = typ(TULONG, T);
12123e12c5d1SDavid du Colombier types[TVLONG] = typ(TVLONG, T);
1213219b2ee8SDavid du Colombier types[TUVLONG] = typ(TUVLONG, T);
12143e12c5d1SDavid du Colombier types[TFLOAT] = typ(TFLOAT, T);
12153e12c5d1SDavid du Colombier types[TDOUBLE] = typ(TDOUBLE, T);
12163e12c5d1SDavid du Colombier types[TVOID] = typ(TVOID, T);
12173e12c5d1SDavid du Colombier types[TENUM] = typ(TENUM, T);
12187dd7cddfSDavid du Colombier types[TFUNC] = typ(TFUNC, types[TINT]);
12193e12c5d1SDavid du Colombier types[TIND] = typ(TIND, types[TVOID]);
12203e12c5d1SDavid du Colombier
12217dd7cddfSDavid du Colombier for(i=0; i<NHASH; i++)
12227dd7cddfSDavid du Colombier hash[i] = S;
12237dd7cddfSDavid du Colombier for(i=0; itab[i].name; i++) {
12247dd7cddfSDavid du Colombier s = slookup(itab[i].name);
12257dd7cddfSDavid du Colombier s->lexical = itab[i].lexical;
12267dd7cddfSDavid du Colombier if(itab[i].type != 0)
12277dd7cddfSDavid du Colombier s->type = types[itab[i].type];
12287dd7cddfSDavid du Colombier }
12297dd7cddfSDavid du Colombier blockno = 0;
12307dd7cddfSDavid du Colombier autobn = 0;
12317dd7cddfSDavid du Colombier autoffset = 0;
12323e12c5d1SDavid du Colombier
12333e12c5d1SDavid du Colombier t = typ(TARRAY, types[TCHAR]);
12343e12c5d1SDavid du Colombier t->width = 0;
12353e12c5d1SDavid du Colombier symstring = slookup(".string");
12363e12c5d1SDavid du Colombier symstring->class = CSTATIC;
12373e12c5d1SDavid du Colombier symstring->type = t;
12383e12c5d1SDavid du Colombier
12393e12c5d1SDavid du Colombier t = typ(TARRAY, types[TCHAR]);
12403e12c5d1SDavid du Colombier t->width = 0;
12413e12c5d1SDavid du Colombier
12423e12c5d1SDavid du Colombier nodproto = new(OPROTO, Z, Z);
12433e12c5d1SDavid du Colombier dclstack = D;
12443e12c5d1SDavid du Colombier
12457dd7cddfSDavid du Colombier pathname = allocn(pathname, 0, 100);
12467dd7cddfSDavid du Colombier if(mygetwd(pathname, 99) == 0) {
12477dd7cddfSDavid du Colombier pathname = allocn(pathname, 100, 900);
12487dd7cddfSDavid du Colombier if(mygetwd(pathname, 999) == 0)
1249219b2ee8SDavid du Colombier strcpy(pathname, "/???");
1250219b2ee8SDavid du Colombier }
1251219b2ee8SDavid du Colombier
12523e12c5d1SDavid du Colombier fmtinstall('O', Oconv);
12533e12c5d1SDavid du Colombier fmtinstall('T', Tconv);
1254bd389b36SDavid du Colombier fmtinstall('F', FNconv);
12553e12c5d1SDavid du Colombier fmtinstall('L', Lconv);
12563e12c5d1SDavid du Colombier fmtinstall('Q', Qconv);
12573e12c5d1SDavid du Colombier fmtinstall('|', VBconv);
12583e12c5d1SDavid du Colombier }
12593e12c5d1SDavid du Colombier
12603e12c5d1SDavid du Colombier int
filbuf(void)12613e12c5d1SDavid du Colombier filbuf(void)
12623e12c5d1SDavid du Colombier {
12633e12c5d1SDavid du Colombier Io *i;
12643e12c5d1SDavid du Colombier
12653e12c5d1SDavid du Colombier loop:
12663e12c5d1SDavid du Colombier i = iostack;
12673e12c5d1SDavid du Colombier if(i == I)
12683e12c5d1SDavid du Colombier return EOF;
12693e12c5d1SDavid du Colombier if(i->f < 0)
12703e12c5d1SDavid du Colombier goto pop;
12713e12c5d1SDavid du Colombier fi.c = read(i->f, i->b, BUFSIZ) - 1;
12723e12c5d1SDavid du Colombier if(fi.c < 0) {
12733e12c5d1SDavid du Colombier close(i->f);
12743e12c5d1SDavid du Colombier linehist(0, 0);
12753e12c5d1SDavid du Colombier goto pop;
12763e12c5d1SDavid du Colombier }
12773e12c5d1SDavid du Colombier fi.p = i->b + 1;
12783e12c5d1SDavid du Colombier return i->b[0] & 0xff;
12793e12c5d1SDavid du Colombier
12803e12c5d1SDavid du Colombier pop:
12813e12c5d1SDavid du Colombier iostack = i->link;
12823e12c5d1SDavid du Colombier i->link = iofree;
12833e12c5d1SDavid du Colombier iofree = i;
12843e12c5d1SDavid du Colombier i = iostack;
12853e12c5d1SDavid du Colombier if(i == I)
12863e12c5d1SDavid du Colombier return EOF;
12873e12c5d1SDavid du Colombier fi.p = i->p;
12883e12c5d1SDavid du Colombier fi.c = i->c;
12893e12c5d1SDavid du Colombier if(--fi.c < 0)
12903e12c5d1SDavid du Colombier goto loop;
12913e12c5d1SDavid du Colombier return *fi.p++ & 0xff;
12923e12c5d1SDavid du Colombier }
12933e12c5d1SDavid du Colombier
12943e12c5d1SDavid du Colombier int
Oconv(Fmt * fp)12959a747e4fSDavid du Colombier Oconv(Fmt *fp)
12963e12c5d1SDavid du Colombier {
12973e12c5d1SDavid du Colombier int a;
12983e12c5d1SDavid du Colombier
12999a747e4fSDavid du Colombier a = va_arg(fp->args, int);
13009a747e4fSDavid du Colombier if(a < OXXX || a > OEND)
13019a747e4fSDavid du Colombier return fmtprint(fp, "***badO %d***", a);
13029a747e4fSDavid du Colombier
13039a747e4fSDavid du Colombier return fmtstrcpy(fp, onames[a]);
13043e12c5d1SDavid du Colombier }
13053e12c5d1SDavid du Colombier
13063e12c5d1SDavid du Colombier int
Lconv(Fmt * fp)13079a747e4fSDavid du Colombier Lconv(Fmt *fp)
13083e12c5d1SDavid du Colombier {
13093e12c5d1SDavid du Colombier char str[STRINGSZ], s[STRINGSZ];
13103e12c5d1SDavid du Colombier Hist *h;
13113e12c5d1SDavid du Colombier struct
13123e12c5d1SDavid du Colombier {
13133e12c5d1SDavid du Colombier Hist* incl; /* start of this include file */
13143e12c5d1SDavid du Colombier long idel; /* delta line number to apply to include */
13153e12c5d1SDavid du Colombier Hist* line; /* start of this #line directive */
13163e12c5d1SDavid du Colombier long ldel; /* delta line number to apply to #line */
13173e12c5d1SDavid du Colombier } a[HISTSZ];
13183e12c5d1SDavid du Colombier long l, d;
13193e12c5d1SDavid du Colombier int i, n;
13203e12c5d1SDavid du Colombier
13219a747e4fSDavid du Colombier l = va_arg(fp->args, long);
13223e12c5d1SDavid du Colombier n = 0;
13233e12c5d1SDavid du Colombier for(h = hist; h != H; h = h->link) {
13243e12c5d1SDavid du Colombier if(l < h->line)
13253e12c5d1SDavid du Colombier break;
13263e12c5d1SDavid du Colombier if(h->name) {
13273e12c5d1SDavid du Colombier if(h->offset != 0) { /* #line directive, not #pragma */
13283e12c5d1SDavid du Colombier if(n > 0 && n < HISTSZ && h->offset >= 0) {
13293e12c5d1SDavid du Colombier a[n-1].line = h;
13303e12c5d1SDavid du Colombier a[n-1].ldel = h->line - h->offset + 1;
13313e12c5d1SDavid du Colombier }
13323e12c5d1SDavid du Colombier } else {
13333e12c5d1SDavid du Colombier if(n < HISTSZ) { /* beginning of file */
13343e12c5d1SDavid du Colombier a[n].incl = h;
13353e12c5d1SDavid du Colombier a[n].idel = h->line;
13363e12c5d1SDavid du Colombier a[n].line = 0;
13373e12c5d1SDavid du Colombier }
13383e12c5d1SDavid du Colombier n++;
13393e12c5d1SDavid du Colombier }
13403e12c5d1SDavid du Colombier continue;
13413e12c5d1SDavid du Colombier }
13423e12c5d1SDavid du Colombier n--;
13433e12c5d1SDavid du Colombier if(n > 0 && n < HISTSZ) {
13443e12c5d1SDavid du Colombier d = h->line - a[n].incl->line;
13453e12c5d1SDavid du Colombier a[n-1].ldel += d;
13463e12c5d1SDavid du Colombier a[n-1].idel += d;
13473e12c5d1SDavid du Colombier }
13483e12c5d1SDavid du Colombier }
13493e12c5d1SDavid du Colombier if(n > HISTSZ)
13503e12c5d1SDavid du Colombier n = HISTSZ;
13513e12c5d1SDavid du Colombier str[0] = 0;
13523e12c5d1SDavid du Colombier for(i=n-1; i>=0; i--) {
13533e12c5d1SDavid du Colombier if(i != n-1) {
13549a747e4fSDavid du Colombier if(fp->flags & ~(FmtWidth|FmtPrec)) /* BUG ROB - was f3 */
13553e12c5d1SDavid du Colombier break;
13563e12c5d1SDavid du Colombier strcat(str, " ");
13573e12c5d1SDavid du Colombier }
13583e12c5d1SDavid du Colombier if(a[i].line)
1359219b2ee8SDavid du Colombier snprint(s, STRINGSZ, "%s:%ld[%s:%ld]",
13603e12c5d1SDavid du Colombier a[i].line->name, l-a[i].ldel+1,
13613e12c5d1SDavid du Colombier a[i].incl->name, l-a[i].idel+1);
13623e12c5d1SDavid du Colombier else
1363219b2ee8SDavid du Colombier snprint(s, STRINGSZ, "%s:%ld",
13643e12c5d1SDavid du Colombier a[i].incl->name, l-a[i].idel+1);
13653e12c5d1SDavid du Colombier if(strlen(s)+strlen(str) >= STRINGSZ-10)
13663e12c5d1SDavid du Colombier break;
13673e12c5d1SDavid du Colombier strcat(str, s);
13683e12c5d1SDavid du Colombier l = a[i].incl->line - 1; /* now print out start of this file */
13693e12c5d1SDavid du Colombier }
13703e12c5d1SDavid du Colombier if(n == 0)
13713e12c5d1SDavid du Colombier strcat(str, "<eof>");
13729a747e4fSDavid du Colombier return fmtstrcpy(fp, str);
13733e12c5d1SDavid du Colombier }
13743e12c5d1SDavid du Colombier
13753e12c5d1SDavid du Colombier int
Tconv(Fmt * fp)13769a747e4fSDavid du Colombier Tconv(Fmt *fp)
13773e12c5d1SDavid du Colombier {
1378219b2ee8SDavid du Colombier char str[STRINGSZ+20], s[STRINGSZ+20];
13793e12c5d1SDavid du Colombier Type *t, *t1;
13803e12c5d1SDavid du Colombier int et;
13817dd7cddfSDavid du Colombier long n;
13823e12c5d1SDavid du Colombier
13833e12c5d1SDavid du Colombier str[0] = 0;
13849a747e4fSDavid du Colombier for(t = va_arg(fp->args, Type*); t != T; t = t->link) {
13853e12c5d1SDavid du Colombier et = t->etype;
13863e12c5d1SDavid du Colombier if(str[0])
13873e12c5d1SDavid du Colombier strcat(str, " ");
1388375daca8SDavid du Colombier if(t->garb&~GINCOMPLETE) {
1389375daca8SDavid du Colombier sprint(s, "%s ", gnames[t->garb&~GINCOMPLETE]);
13907dd7cddfSDavid du Colombier if(strlen(str) + strlen(s) < STRINGSZ)
13917dd7cddfSDavid du Colombier strcat(str, s);
13927dd7cddfSDavid du Colombier }
13933e12c5d1SDavid du Colombier sprint(s, "%s", tnames[et]);
13943e12c5d1SDavid du Colombier if(strlen(str) + strlen(s) < STRINGSZ)
13953e12c5d1SDavid du Colombier strcat(str, s);
13963e12c5d1SDavid du Colombier if(et == TFUNC && (t1 = t->down)) {
13973e12c5d1SDavid du Colombier sprint(s, "(%T", t1);
1398219b2ee8SDavid du Colombier if(strlen(str) + strlen(s) < STRINGSZ)
13993e12c5d1SDavid du Colombier strcat(str, s);
14003e12c5d1SDavid du Colombier while(t1 = t1->down) {
14013e12c5d1SDavid du Colombier sprint(s, ", %T", t1);
1402219b2ee8SDavid du Colombier if(strlen(str) + strlen(s) < STRINGSZ)
14033e12c5d1SDavid du Colombier strcat(str, s);
14043e12c5d1SDavid du Colombier }
1405219b2ee8SDavid du Colombier if(strlen(str) + strlen(s) < STRINGSZ)
14063e12c5d1SDavid du Colombier strcat(str, ")");
14073e12c5d1SDavid du Colombier }
14083e12c5d1SDavid du Colombier if(et == TARRAY) {
14097dd7cddfSDavid du Colombier n = t->width;
14107dd7cddfSDavid du Colombier if(t->link && t->link->width)
14117dd7cddfSDavid du Colombier n /= t->link->width;
14127dd7cddfSDavid du Colombier sprint(s, "[%ld]", n);
1413219b2ee8SDavid du Colombier if(strlen(str) + strlen(s) < STRINGSZ)
14143e12c5d1SDavid du Colombier strcat(str, s);
14153e12c5d1SDavid du Colombier }
14163e12c5d1SDavid du Colombier if(t->nbits) {
14173e12c5d1SDavid du Colombier sprint(s, " %d:%d", t->shift, t->nbits);
14183e12c5d1SDavid du Colombier if(strlen(str) + strlen(s) < STRINGSZ)
14193e12c5d1SDavid du Colombier strcat(str, s);
14203e12c5d1SDavid du Colombier }
14213e12c5d1SDavid du Colombier if(typesu[et]) {
14223e12c5d1SDavid du Colombier if(t->tag) {
14233e12c5d1SDavid du Colombier strcat(str, " ");
1424219b2ee8SDavid du Colombier if(strlen(str) + strlen(t->tag->name) < STRINGSZ)
14253e12c5d1SDavid du Colombier strcat(str, t->tag->name);
14263e12c5d1SDavid du Colombier } else
14273e12c5d1SDavid du Colombier strcat(str, " {}");
14283e12c5d1SDavid du Colombier break;
14293e12c5d1SDavid du Colombier }
14303e12c5d1SDavid du Colombier }
14319a747e4fSDavid du Colombier return fmtstrcpy(fp, str);
14323e12c5d1SDavid du Colombier }
14333e12c5d1SDavid du Colombier
14343e12c5d1SDavid du Colombier int
FNconv(Fmt * fp)14359a747e4fSDavid du Colombier FNconv(Fmt *fp)
14363e12c5d1SDavid du Colombier {
1437219b2ee8SDavid du Colombier char *str;
14383e12c5d1SDavid du Colombier Node *n;
14393e12c5d1SDavid du Colombier
14409a747e4fSDavid du Colombier n = va_arg(fp->args, Node*);
1441219b2ee8SDavid du Colombier str = "<indirect>";
1442219b2ee8SDavid du Colombier if(n != Z && (n->op == ONAME || n->op == ODOT || n->op == OELEM))
1443219b2ee8SDavid du Colombier str = n->sym->name;
14449a747e4fSDavid du Colombier return fmtstrcpy(fp, str);
14453e12c5d1SDavid du Colombier }
14463e12c5d1SDavid du Colombier
14473e12c5d1SDavid du Colombier int
Qconv(Fmt * fp)14489a747e4fSDavid du Colombier Qconv(Fmt *fp)
14493e12c5d1SDavid du Colombier {
1450219b2ee8SDavid du Colombier char str[STRINGSZ+20], *s;
14513e12c5d1SDavid du Colombier long b;
14523e12c5d1SDavid du Colombier int i;
14533e12c5d1SDavid du Colombier
14543e12c5d1SDavid du Colombier str[0] = 0;
14559a747e4fSDavid du Colombier for(b = va_arg(fp->args, long); b;) {
14563e12c5d1SDavid du Colombier i = bitno(b);
14573e12c5d1SDavid du Colombier if(str[0])
14583e12c5d1SDavid du Colombier strcat(str, " ");
14593e12c5d1SDavid du Colombier s = qnames[i];
1460219b2ee8SDavid du Colombier if(strlen(str) + strlen(s) >= STRINGSZ)
14613e12c5d1SDavid du Colombier break;
14623e12c5d1SDavid du Colombier strcat(str, s);
14633e12c5d1SDavid du Colombier b &= ~(1L << i);
14643e12c5d1SDavid du Colombier }
14659a747e4fSDavid du Colombier return fmtstrcpy(fp, str);
14663e12c5d1SDavid du Colombier }
14673e12c5d1SDavid du Colombier
14683e12c5d1SDavid du Colombier int
VBconv(Fmt * fp)14699a747e4fSDavid du Colombier VBconv(Fmt *fp)
14703e12c5d1SDavid du Colombier {
14713e12c5d1SDavid du Colombier char str[STRINGSZ];
14723e12c5d1SDavid du Colombier int i, n, t, pc;
14733e12c5d1SDavid du Colombier
14749a747e4fSDavid du Colombier n = va_arg(fp->args, int);
14759a747e4fSDavid du Colombier pc = 0; /* BUG: was printcol */
14763e12c5d1SDavid du Colombier i = 0;
14773e12c5d1SDavid du Colombier while(pc < n) {
14789a747e4fSDavid du Colombier t = (pc+4) & ~3;
14793e12c5d1SDavid du Colombier if(t <= n) {
14803e12c5d1SDavid du Colombier str[i++] = '\t';
14813e12c5d1SDavid du Colombier pc = t;
14823e12c5d1SDavid du Colombier continue;
14833e12c5d1SDavid du Colombier }
14843e12c5d1SDavid du Colombier str[i++] = ' ';
14853e12c5d1SDavid du Colombier pc++;
14863e12c5d1SDavid du Colombier }
14873e12c5d1SDavid du Colombier str[i] = 0;
14889a747e4fSDavid du Colombier
14899a747e4fSDavid du Colombier return fmtstrcpy(fp, str);
14903e12c5d1SDavid du Colombier }
14913e12c5d1SDavid du Colombier
14923e12c5d1SDavid du Colombier /*
14937dd7cddfSDavid du Colombier * real allocs
14943e12c5d1SDavid du Colombier */
14953e12c5d1SDavid du Colombier void*
alloc(long n)14967dd7cddfSDavid du Colombier alloc(long n)
14973e12c5d1SDavid du Colombier {
14983e12c5d1SDavid du Colombier void *p;
14993e12c5d1SDavid du Colombier
15004de34a7eSDavid du Colombier while((uintptr)hunk & MAXALIGN) {
15017dd7cddfSDavid du Colombier hunk++;
15027dd7cddfSDavid du Colombier nhunk--;
15037dd7cddfSDavid du Colombier }
15043e12c5d1SDavid du Colombier while(nhunk < n)
15053e12c5d1SDavid du Colombier gethunk();
15063e12c5d1SDavid du Colombier p = hunk;
15073e12c5d1SDavid du Colombier nhunk -= n;
15083e12c5d1SDavid du Colombier hunk += n;
15093e12c5d1SDavid du Colombier return p;
15103e12c5d1SDavid du Colombier }
15113e12c5d1SDavid du Colombier
15123e12c5d1SDavid du Colombier void*
allocn(void * p,long on,long n)15137dd7cddfSDavid du Colombier allocn(void *p, long on, long n)
15143e12c5d1SDavid du Colombier {
15157dd7cddfSDavid du Colombier void *q;
15163e12c5d1SDavid du Colombier
15177dd7cddfSDavid du Colombier q = (uchar*)p + on;
15187dd7cddfSDavid du Colombier if(q != hunk || nhunk < n) {
15197dd7cddfSDavid du Colombier while(nhunk < on+n)
15207dd7cddfSDavid du Colombier gethunk();
15217dd7cddfSDavid du Colombier memmove(hunk, p, on);
15227dd7cddfSDavid du Colombier p = hunk;
15237dd7cddfSDavid du Colombier hunk += on;
15247dd7cddfSDavid du Colombier nhunk -= on;
15257dd7cddfSDavid du Colombier }
15267dd7cddfSDavid du Colombier hunk += n;
15277dd7cddfSDavid du Colombier nhunk -= n;
15283e12c5d1SDavid du Colombier return p;
15293e12c5d1SDavid du Colombier }
15303e12c5d1SDavid du Colombier
15317dd7cddfSDavid du Colombier void
setinclude(char * p)15327dd7cddfSDavid du Colombier setinclude(char *p)
15333e12c5d1SDavid du Colombier {
15347dd7cddfSDavid du Colombier int i;
1535*6bbfed0dSDavid du Colombier char *e, **np;
15363e12c5d1SDavid du Colombier
15377dd7cddfSDavid du Colombier while(*p != 0) {
15387dd7cddfSDavid du Colombier e = strchr(p, ' ');
15397dd7cddfSDavid du Colombier if(e != 0)
15407dd7cddfSDavid du Colombier *e = '\0';
15417dd7cddfSDavid du Colombier
1542*6bbfed0dSDavid du Colombier for(i=0; i < ninclude; i++)
15437dd7cddfSDavid du Colombier if(strcmp(p, include[i]) == 0)
15447dd7cddfSDavid du Colombier break;
15457dd7cddfSDavid du Colombier
1546*6bbfed0dSDavid du Colombier if(i >= ninclude){
1547*6bbfed0dSDavid du Colombier if(i >= maxinclude){
1548*6bbfed0dSDavid du Colombier maxinclude += 20;
1549*6bbfed0dSDavid du Colombier np = alloc(maxinclude * sizeof *np);
1550*6bbfed0dSDavid du Colombier if(include != nil)
1551*6bbfed0dSDavid du Colombier memmove(np, include, (maxinclude - 20) * sizeof *np);
1552*6bbfed0dSDavid du Colombier include = np;
1553*6bbfed0dSDavid du Colombier }
15547dd7cddfSDavid du Colombier include[ninclude++] = p;
15557dd7cddfSDavid du Colombier }
15567dd7cddfSDavid du Colombier
15577dd7cddfSDavid du Colombier if(e == 0)
15587dd7cddfSDavid du Colombier break;
15597dd7cddfSDavid du Colombier p = e+1;
15607dd7cddfSDavid du Colombier }
15613e12c5d1SDavid du Colombier }
1562