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