1*f8bc6aafSDavid du Colombier #include "cc.h"
2*f8bc6aafSDavid du Colombier #include "y.tab.h"
3*f8bc6aafSDavid du Colombier
4*f8bc6aafSDavid du Colombier #ifndef CPP
5*f8bc6aafSDavid du Colombier #define CPP "/bin/cpp"
6*f8bc6aafSDavid du Colombier #endif
7*f8bc6aafSDavid du Colombier
8*f8bc6aafSDavid du Colombier /*
9*f8bc6aafSDavid du Colombier * known debug flags
10*f8bc6aafSDavid du Colombier * -a acid declaration output
11*f8bc6aafSDavid du Colombier * -A !B
12*f8bc6aafSDavid du Colombier * -B non ANSI
13*f8bc6aafSDavid du Colombier * -d print declarations
14*f8bc6aafSDavid du Colombier * -D name define
15*f8bc6aafSDavid du Colombier * -F format specification check
16*f8bc6aafSDavid du Colombier * -i print initialization
17*f8bc6aafSDavid du Colombier * -I path include
18*f8bc6aafSDavid du Colombier * -l generate little-endian code
19*f8bc6aafSDavid du Colombier * -L print every NAME symbol
20*f8bc6aafSDavid du Colombier * -M constant multiplication
21*f8bc6aafSDavid du Colombier * -m print add/sub/mul trees
22*f8bc6aafSDavid du Colombier * -n print acid to file (%.c=%.acid) (with -a or -aa)
23*f8bc6aafSDavid du Colombier * -o file output file
24*f8bc6aafSDavid du Colombier * -p use standard cpp ANSI preprocessor (not on windows)
25*f8bc6aafSDavid du Colombier * -r print registerization
26*f8bc6aafSDavid du Colombier * -s print structure offsets (with -a or -aa)
27*f8bc6aafSDavid du Colombier * -S print assembly
28*f8bc6aafSDavid du Colombier * -t print type trees
29*f8bc6aafSDavid du Colombier * -V enable void* conversion warnings
30*f8bc6aafSDavid du Colombier * -v verbose printing
31*f8bc6aafSDavid du Colombier * -w print warnings
32*f8bc6aafSDavid du Colombier * -X abort on error
33*f8bc6aafSDavid du Colombier * -. Inhibit search for includes in source directory
34*f8bc6aafSDavid du Colombier */
35*f8bc6aafSDavid du Colombier
36*f8bc6aafSDavid du Colombier void
main(int argc,char * argv[])37*f8bc6aafSDavid du Colombier main(int argc, char *argv[])
38*f8bc6aafSDavid du Colombier {
39*f8bc6aafSDavid du Colombier char **defs, **np, *p;
40*f8bc6aafSDavid du Colombier int nproc, nout, status, i, c, ndef, maxdef;
41*f8bc6aafSDavid du Colombier
42*f8bc6aafSDavid du Colombier memset(debug, 0, sizeof(debug));
43*f8bc6aafSDavid du Colombier tinit();
44*f8bc6aafSDavid du Colombier cinit();
45*f8bc6aafSDavid du Colombier ginit();
46*f8bc6aafSDavid du Colombier arginit();
47*f8bc6aafSDavid du Colombier
48*f8bc6aafSDavid du Colombier profileflg = 1; /* #pragma can turn it off */
49*f8bc6aafSDavid du Colombier tufield = simplet((1L<<tfield->etype) | BUNSIGNED);
50*f8bc6aafSDavid du Colombier maxdef = 0;
51*f8bc6aafSDavid du Colombier ndef = 0;
52*f8bc6aafSDavid du Colombier outfile = 0;
53*f8bc6aafSDavid du Colombier defs = nil;
54*f8bc6aafSDavid du Colombier setinclude(".");
55*f8bc6aafSDavid du Colombier ARGBEGIN {
56*f8bc6aafSDavid du Colombier default:
57*f8bc6aafSDavid du Colombier c = ARGC();
58*f8bc6aafSDavid du Colombier if(c >= 0 && c < sizeof(debug))
59*f8bc6aafSDavid du Colombier debug[c]++;
60*f8bc6aafSDavid du Colombier break;
61*f8bc6aafSDavid du Colombier
62*f8bc6aafSDavid du Colombier case 'l': /* for little-endian mips */
63*f8bc6aafSDavid du Colombier switch(thechar) {
64*f8bc6aafSDavid du Colombier default:
65*f8bc6aafSDavid du Colombier print("can only use -l with vc or 4c\n");
66*f8bc6aafSDavid du Colombier errorexit();
67*f8bc6aafSDavid du Colombier
68*f8bc6aafSDavid du Colombier case 'v':
69*f8bc6aafSDavid du Colombier thechar = '0';
70*f8bc6aafSDavid du Colombier thestring = "spim";
71*f8bc6aafSDavid du Colombier break;
72*f8bc6aafSDavid du Colombier
73*f8bc6aafSDavid du Colombier case '4':
74*f8bc6aafSDavid du Colombier thechar = 'x';
75*f8bc6aafSDavid du Colombier thestring = "spim64";
76*f8bc6aafSDavid du Colombier break;
77*f8bc6aafSDavid du Colombier }
78*f8bc6aafSDavid du Colombier break;
79*f8bc6aafSDavid du Colombier
80*f8bc6aafSDavid du Colombier case 'o':
81*f8bc6aafSDavid du Colombier outfile = ARGF();
82*f8bc6aafSDavid du Colombier break;
83*f8bc6aafSDavid du Colombier
84*f8bc6aafSDavid du Colombier case 'D':
85*f8bc6aafSDavid du Colombier p = ARGF();
86*f8bc6aafSDavid du Colombier if(p) {
87*f8bc6aafSDavid du Colombier if(ndef >= maxdef){
88*f8bc6aafSDavid du Colombier maxdef += 50;
89*f8bc6aafSDavid du Colombier np = alloc(maxdef * sizeof *np);
90*f8bc6aafSDavid du Colombier if(defs != nil)
91*f8bc6aafSDavid du Colombier memmove(np, defs, (maxdef - 50) * sizeof *np);
92*f8bc6aafSDavid du Colombier defs = np;
93*f8bc6aafSDavid du Colombier }
94*f8bc6aafSDavid du Colombier defs[ndef++] = p;
95*f8bc6aafSDavid du Colombier dodefine(p);
96*f8bc6aafSDavid du Colombier }
97*f8bc6aafSDavid du Colombier break;
98*f8bc6aafSDavid du Colombier
99*f8bc6aafSDavid du Colombier case 'I':
100*f8bc6aafSDavid du Colombier p = ARGF();
101*f8bc6aafSDavid du Colombier if(p)
102*f8bc6aafSDavid du Colombier setinclude(p);
103*f8bc6aafSDavid du Colombier break;
104*f8bc6aafSDavid du Colombier } ARGEND
105*f8bc6aafSDavid du Colombier if(argc < 1 && outfile == 0) {
106*f8bc6aafSDavid du Colombier print("usage: %cc [-options] files\n", thechar);
107*f8bc6aafSDavid du Colombier errorexit();
108*f8bc6aafSDavid du Colombier }
109*f8bc6aafSDavid du Colombier if(argc > 1 && systemtype(Windows)){
110*f8bc6aafSDavid du Colombier print("can't compile multiple files on windows\n");
111*f8bc6aafSDavid du Colombier errorexit();
112*f8bc6aafSDavid du Colombier }
113*f8bc6aafSDavid du Colombier if(argc > 1 && !systemtype(Windows)) {
114*f8bc6aafSDavid du Colombier nproc = 1;
115*f8bc6aafSDavid du Colombier /*
116*f8bc6aafSDavid du Colombier * if we're writing acid to standard output, don't compile
117*f8bc6aafSDavid du Colombier * concurrently, to avoid interleaving output.
118*f8bc6aafSDavid du Colombier */
119*f8bc6aafSDavid du Colombier if(((!debug['a'] && !debug['Z']) || debug['n']) &&
120*f8bc6aafSDavid du Colombier (p = getenv("NPROC")) != nil)
121*f8bc6aafSDavid du Colombier nproc = atol(p); /* */
122*f8bc6aafSDavid du Colombier c = 0;
123*f8bc6aafSDavid du Colombier nout = 0;
124*f8bc6aafSDavid du Colombier for(;;) {
125*f8bc6aafSDavid du Colombier while(nout < nproc && argc > 0) {
126*f8bc6aafSDavid du Colombier i = myfork();
127*f8bc6aafSDavid du Colombier if(i < 0) {
128*f8bc6aafSDavid du Colombier i = mywait(&status);
129*f8bc6aafSDavid du Colombier if(i < 0) {
130*f8bc6aafSDavid du Colombier print("cannot create a process\n");
131*f8bc6aafSDavid du Colombier errorexit();
132*f8bc6aafSDavid du Colombier }
133*f8bc6aafSDavid du Colombier if(status)
134*f8bc6aafSDavid du Colombier c++;
135*f8bc6aafSDavid du Colombier nout--;
136*f8bc6aafSDavid du Colombier continue;
137*f8bc6aafSDavid du Colombier }
138*f8bc6aafSDavid du Colombier if(i == 0) {
139*f8bc6aafSDavid du Colombier fprint(2, "%s:\n", *argv);
140*f8bc6aafSDavid du Colombier if (compile(*argv, defs, ndef))
141*f8bc6aafSDavid du Colombier errorexit();
142*f8bc6aafSDavid du Colombier exits(0);
143*f8bc6aafSDavid du Colombier }
144*f8bc6aafSDavid du Colombier nout++;
145*f8bc6aafSDavid du Colombier argc--;
146*f8bc6aafSDavid du Colombier argv++;
147*f8bc6aafSDavid du Colombier }
148*f8bc6aafSDavid du Colombier i = mywait(&status);
149*f8bc6aafSDavid du Colombier if(i < 0) {
150*f8bc6aafSDavid du Colombier if(c)
151*f8bc6aafSDavid du Colombier errorexit();
152*f8bc6aafSDavid du Colombier exits(0);
153*f8bc6aafSDavid du Colombier }
154*f8bc6aafSDavid du Colombier if(status)
155*f8bc6aafSDavid du Colombier c++;
156*f8bc6aafSDavid du Colombier nout--;
157*f8bc6aafSDavid du Colombier }
158*f8bc6aafSDavid du Colombier }
159*f8bc6aafSDavid du Colombier
160*f8bc6aafSDavid du Colombier if(argc == 0)
161*f8bc6aafSDavid du Colombier c = compile("stdin", defs, ndef);
162*f8bc6aafSDavid du Colombier else
163*f8bc6aafSDavid du Colombier c = compile(argv[0], defs, ndef);
164*f8bc6aafSDavid du Colombier
165*f8bc6aafSDavid du Colombier if(c)
166*f8bc6aafSDavid du Colombier errorexit();
167*f8bc6aafSDavid du Colombier exits(0);
168*f8bc6aafSDavid du Colombier }
169*f8bc6aafSDavid du Colombier
170*f8bc6aafSDavid du Colombier int
compile(char * file,char ** defs,int ndef)171*f8bc6aafSDavid du Colombier compile(char *file, char **defs, int ndef)
172*f8bc6aafSDavid du Colombier {
173*f8bc6aafSDavid du Colombier char ofile[400], incfile[20];
174*f8bc6aafSDavid du Colombier char *p, **av, opt[256];
175*f8bc6aafSDavid du Colombier int i, c, fd[2];
176*f8bc6aafSDavid du Colombier static int first = 1;
177*f8bc6aafSDavid du Colombier
178*f8bc6aafSDavid du Colombier strcpy(ofile, file);
179*f8bc6aafSDavid du Colombier p = utfrrune(ofile, pathchar());
180*f8bc6aafSDavid du Colombier if(p) {
181*f8bc6aafSDavid du Colombier *p++ = 0;
182*f8bc6aafSDavid du Colombier if(!debug['.'])
183*f8bc6aafSDavid du Colombier include[0] = strdup(ofile);
184*f8bc6aafSDavid du Colombier } else
185*f8bc6aafSDavid du Colombier p = ofile;
186*f8bc6aafSDavid du Colombier
187*f8bc6aafSDavid du Colombier if(outfile == 0) {
188*f8bc6aafSDavid du Colombier outfile = p;
189*f8bc6aafSDavid du Colombier if(outfile) {
190*f8bc6aafSDavid du Colombier if(p = utfrrune(outfile, '.'))
191*f8bc6aafSDavid du Colombier if(p[1] == 'c' && p[2] == 0)
192*f8bc6aafSDavid du Colombier p[0] = 0;
193*f8bc6aafSDavid du Colombier p = utfrune(outfile, 0);
194*f8bc6aafSDavid du Colombier if(debug['a'] && debug['n'])
195*f8bc6aafSDavid du Colombier strcat(p, ".acid");
196*f8bc6aafSDavid du Colombier else if(debug['Z'] && debug['n'])
197*f8bc6aafSDavid du Colombier strcat(p, "_pickle.c");
198*f8bc6aafSDavid du Colombier else {
199*f8bc6aafSDavid du Colombier p[0] = '.';
200*f8bc6aafSDavid du Colombier p[1] = thechar;
201*f8bc6aafSDavid du Colombier p[2] = 0;
202*f8bc6aafSDavid du Colombier }
203*f8bc6aafSDavid du Colombier } else
204*f8bc6aafSDavid du Colombier outfile = "/dev/null";
205*f8bc6aafSDavid du Colombier }
206*f8bc6aafSDavid du Colombier
207*f8bc6aafSDavid du Colombier if(p = getenv("INCLUDE")) {
208*f8bc6aafSDavid du Colombier setinclude(p);
209*f8bc6aafSDavid du Colombier } else {
210*f8bc6aafSDavid du Colombier if(systemtype(Plan9)) {
211*f8bc6aafSDavid du Colombier sprint(incfile, "/%s/include", thestring);
212*f8bc6aafSDavid du Colombier setinclude(strdup(incfile));
213*f8bc6aafSDavid du Colombier setinclude("/sys/include");
214*f8bc6aafSDavid du Colombier }
215*f8bc6aafSDavid du Colombier }
216*f8bc6aafSDavid du Colombier if (first)
217*f8bc6aafSDavid du Colombier Binit(&diagbuf, 1, OWRITE);
218*f8bc6aafSDavid du Colombier /*
219*f8bc6aafSDavid du Colombier * if we're writing acid to standard output, don't keep scratching
220*f8bc6aafSDavid du Colombier * outbuf.
221*f8bc6aafSDavid du Colombier */
222*f8bc6aafSDavid du Colombier if((debug['a'] || debug['Z']) && !debug['n']) {
223*f8bc6aafSDavid du Colombier if (first) {
224*f8bc6aafSDavid du Colombier outfile = 0;
225*f8bc6aafSDavid du Colombier Binit(&outbuf, dup(1, -1), OWRITE);
226*f8bc6aafSDavid du Colombier dup(2, 1);
227*f8bc6aafSDavid du Colombier }
228*f8bc6aafSDavid du Colombier } else {
229*f8bc6aafSDavid du Colombier c = mycreat(outfile, 0664);
230*f8bc6aafSDavid du Colombier if(c < 0) {
231*f8bc6aafSDavid du Colombier diag(Z, "cannot open %s - %r", outfile);
232*f8bc6aafSDavid du Colombier outfile = 0;
233*f8bc6aafSDavid du Colombier errorexit();
234*f8bc6aafSDavid du Colombier }
235*f8bc6aafSDavid du Colombier Binit(&outbuf, c, OWRITE);
236*f8bc6aafSDavid du Colombier }
237*f8bc6aafSDavid du Colombier newio();
238*f8bc6aafSDavid du Colombier first = 0;
239*f8bc6aafSDavid du Colombier
240*f8bc6aafSDavid du Colombier /* Use an ANSI preprocessor */
241*f8bc6aafSDavid du Colombier if(debug['p']) {
242*f8bc6aafSDavid du Colombier if(systemtype(Windows)) {
243*f8bc6aafSDavid du Colombier diag(Z, "-p option not supported on windows");
244*f8bc6aafSDavid du Colombier errorexit();
245*f8bc6aafSDavid du Colombier }
246*f8bc6aafSDavid du Colombier if(myaccess(file) < 0) {
247*f8bc6aafSDavid du Colombier diag(Z, "%s does not exist", file);
248*f8bc6aafSDavid du Colombier errorexit();
249*f8bc6aafSDavid du Colombier }
250*f8bc6aafSDavid du Colombier if(mypipe(fd) < 0) {
251*f8bc6aafSDavid du Colombier diag(Z, "pipe failed");
252*f8bc6aafSDavid du Colombier errorexit();
253*f8bc6aafSDavid du Colombier }
254*f8bc6aafSDavid du Colombier switch(myfork()) {
255*f8bc6aafSDavid du Colombier case -1:
256*f8bc6aafSDavid du Colombier diag(Z, "fork failed");
257*f8bc6aafSDavid du Colombier errorexit();
258*f8bc6aafSDavid du Colombier case 0:
259*f8bc6aafSDavid du Colombier close(fd[0]);
260*f8bc6aafSDavid du Colombier mydup(fd[1], 1);
261*f8bc6aafSDavid du Colombier close(fd[1]);
262*f8bc6aafSDavid du Colombier av = alloc((3 + ndef + ninclude + 2) * sizeof *av);
263*f8bc6aafSDavid du Colombier av[0] = CPP;
264*f8bc6aafSDavid du Colombier i = 1;
265*f8bc6aafSDavid du Colombier if(debug['.'])
266*f8bc6aafSDavid du Colombier av[i++] = strdup("-.");
267*f8bc6aafSDavid du Colombier /* 1999 ANSI C requires recognising // comments */
268*f8bc6aafSDavid du Colombier av[i++] = strdup("-+");
269*f8bc6aafSDavid du Colombier for(c = 0; c < ndef; c++) {
270*f8bc6aafSDavid du Colombier sprint(opt, "-D%s", defs[c]);
271*f8bc6aafSDavid du Colombier av[i++] = strdup(opt);
272*f8bc6aafSDavid du Colombier }
273*f8bc6aafSDavid du Colombier for(c = 0; c < ninclude; c++) {
274*f8bc6aafSDavid du Colombier sprint(opt, "-I%s", include[c]);
275*f8bc6aafSDavid du Colombier av[i++] = strdup(opt);
276*f8bc6aafSDavid du Colombier }
277*f8bc6aafSDavid du Colombier if(strcmp(file, "stdin") != 0)
278*f8bc6aafSDavid du Colombier av[i++] = file;
279*f8bc6aafSDavid du Colombier av[i] = 0;
280*f8bc6aafSDavid du Colombier if(debug['p'] > 1) {
281*f8bc6aafSDavid du Colombier for(c = 0; c < i; c++)
282*f8bc6aafSDavid du Colombier fprint(2, "%s ", av[c]);
283*f8bc6aafSDavid du Colombier fprint(2, "\n");
284*f8bc6aafSDavid du Colombier }
285*f8bc6aafSDavid du Colombier myexec(av[0], av);
286*f8bc6aafSDavid du Colombier fprint(2, "can't exec C preprocessor %s: %r\n", CPP);
287*f8bc6aafSDavid du Colombier errorexit();
288*f8bc6aafSDavid du Colombier default:
289*f8bc6aafSDavid du Colombier close(fd[1]);
290*f8bc6aafSDavid du Colombier newfile(file, fd[0]);
291*f8bc6aafSDavid du Colombier break;
292*f8bc6aafSDavid du Colombier }
293*f8bc6aafSDavid du Colombier } else {
294*f8bc6aafSDavid du Colombier if(strcmp(file, "stdin") == 0)
295*f8bc6aafSDavid du Colombier newfile(file, 0);
296*f8bc6aafSDavid du Colombier else
297*f8bc6aafSDavid du Colombier newfile(file, -1);
298*f8bc6aafSDavid du Colombier }
299*f8bc6aafSDavid du Colombier yyparse();
300*f8bc6aafSDavid du Colombier if(!debug['a'] && !debug['Z'])
301*f8bc6aafSDavid du Colombier gclean();
302*f8bc6aafSDavid du Colombier return nerrors;
303*f8bc6aafSDavid du Colombier }
304*f8bc6aafSDavid du Colombier
305*f8bc6aafSDavid du Colombier void
errorexit(void)306*f8bc6aafSDavid du Colombier errorexit(void)
307*f8bc6aafSDavid du Colombier {
308*f8bc6aafSDavid du Colombier if(outfile)
309*f8bc6aafSDavid du Colombier remove(outfile);
310*f8bc6aafSDavid du Colombier exits("error");
311*f8bc6aafSDavid du Colombier }
312*f8bc6aafSDavid du Colombier
313*f8bc6aafSDavid du Colombier void
pushio(void)314*f8bc6aafSDavid du Colombier pushio(void)
315*f8bc6aafSDavid du Colombier {
316*f8bc6aafSDavid du Colombier Io *i;
317*f8bc6aafSDavid du Colombier
318*f8bc6aafSDavid du Colombier i = iostack;
319*f8bc6aafSDavid du Colombier if(i == I) {
320*f8bc6aafSDavid du Colombier yyerror("botch in pushio");
321*f8bc6aafSDavid du Colombier errorexit();
322*f8bc6aafSDavid du Colombier }
323*f8bc6aafSDavid du Colombier i->p = fi.p;
324*f8bc6aafSDavid du Colombier i->c = fi.c;
325*f8bc6aafSDavid du Colombier }
326*f8bc6aafSDavid du Colombier
327*f8bc6aafSDavid du Colombier void
newio(void)328*f8bc6aafSDavid du Colombier newio(void)
329*f8bc6aafSDavid du Colombier {
330*f8bc6aafSDavid du Colombier Io *i;
331*f8bc6aafSDavid du Colombier static int pushdepth = 0;
332*f8bc6aafSDavid du Colombier
333*f8bc6aafSDavid du Colombier i = iofree;
334*f8bc6aafSDavid du Colombier if(i == I) {
335*f8bc6aafSDavid du Colombier pushdepth++;
336*f8bc6aafSDavid du Colombier if(pushdepth > 1000) {
337*f8bc6aafSDavid du Colombier yyerror("macro/io expansion too deep");
338*f8bc6aafSDavid du Colombier errorexit();
339*f8bc6aafSDavid du Colombier }
340*f8bc6aafSDavid du Colombier i = alloc(sizeof(*i));
341*f8bc6aafSDavid du Colombier } else
342*f8bc6aafSDavid du Colombier iofree = i->link;
343*f8bc6aafSDavid du Colombier i->c = 0;
344*f8bc6aafSDavid du Colombier i->f = -1;
345*f8bc6aafSDavid du Colombier ionext = i;
346*f8bc6aafSDavid du Colombier }
347*f8bc6aafSDavid du Colombier
348*f8bc6aafSDavid du Colombier void
newfile(char * s,int f)349*f8bc6aafSDavid du Colombier newfile(char *s, int f)
350*f8bc6aafSDavid du Colombier {
351*f8bc6aafSDavid du Colombier Io *i;
352*f8bc6aafSDavid du Colombier
353*f8bc6aafSDavid du Colombier if(debug['e'])
354*f8bc6aafSDavid du Colombier print("%L: %s\n", lineno, s);
355*f8bc6aafSDavid du Colombier
356*f8bc6aafSDavid du Colombier i = ionext;
357*f8bc6aafSDavid du Colombier i->link = iostack;
358*f8bc6aafSDavid du Colombier iostack = i;
359*f8bc6aafSDavid du Colombier i->f = f;
360*f8bc6aafSDavid du Colombier if(f < 0)
361*f8bc6aafSDavid du Colombier i->f = open(s, 0);
362*f8bc6aafSDavid du Colombier if(i->f < 0) {
363*f8bc6aafSDavid du Colombier yyerror("%cc: %r: %s", thechar, s);
364*f8bc6aafSDavid du Colombier errorexit();
365*f8bc6aafSDavid du Colombier }
366*f8bc6aafSDavid du Colombier fi.c = 0;
367*f8bc6aafSDavid du Colombier linehist(s, 0);
368*f8bc6aafSDavid du Colombier }
369*f8bc6aafSDavid du Colombier
370*f8bc6aafSDavid du Colombier Sym*
slookup(char * s)371*f8bc6aafSDavid du Colombier slookup(char *s)
372*f8bc6aafSDavid du Colombier {
373*f8bc6aafSDavid du Colombier
374*f8bc6aafSDavid du Colombier strcpy(symb, s);
375*f8bc6aafSDavid du Colombier return lookup();
376*f8bc6aafSDavid du Colombier }
377*f8bc6aafSDavid du Colombier
378*f8bc6aafSDavid du Colombier Sym*
lookup(void)379*f8bc6aafSDavid du Colombier lookup(void)
380*f8bc6aafSDavid du Colombier {
381*f8bc6aafSDavid du Colombier Sym *s;
382*f8bc6aafSDavid du Colombier ulong h;
383*f8bc6aafSDavid du Colombier char *p;
384*f8bc6aafSDavid du Colombier int c, n;
385*f8bc6aafSDavid du Colombier
386*f8bc6aafSDavid du Colombier h = 0;
387*f8bc6aafSDavid du Colombier for(p=symb; *p;) {
388*f8bc6aafSDavid du Colombier h = h * 3;
389*f8bc6aafSDavid du Colombier h += *p++;
390*f8bc6aafSDavid du Colombier }
391*f8bc6aafSDavid du Colombier n = (p - symb) + 1;
392*f8bc6aafSDavid du Colombier if((long)h < 0)
393*f8bc6aafSDavid du Colombier h = ~h;
394*f8bc6aafSDavid du Colombier h %= NHASH;
395*f8bc6aafSDavid du Colombier c = symb[0];
396*f8bc6aafSDavid du Colombier for(s = hash[h]; s != S; s = s->link) {
397*f8bc6aafSDavid du Colombier if(s->name[0] != c)
398*f8bc6aafSDavid du Colombier continue;
399*f8bc6aafSDavid du Colombier if(strcmp(s->name, symb) == 0)
400*f8bc6aafSDavid du Colombier return s;
401*f8bc6aafSDavid du Colombier }
402*f8bc6aafSDavid du Colombier s = alloc(sizeof(*s));
403*f8bc6aafSDavid du Colombier s->name = alloc(n);
404*f8bc6aafSDavid du Colombier memmove(s->name, symb, n);
405*f8bc6aafSDavid du Colombier
406*f8bc6aafSDavid du Colombier strcpy(s->name, symb);
407*f8bc6aafSDavid du Colombier s->link = hash[h];
408*f8bc6aafSDavid du Colombier hash[h] = s;
409*f8bc6aafSDavid du Colombier syminit(s);
410*f8bc6aafSDavid du Colombier
411*f8bc6aafSDavid du Colombier return s;
412*f8bc6aafSDavid du Colombier }
413*f8bc6aafSDavid du Colombier
414*f8bc6aafSDavid du Colombier void
syminit(Sym * s)415*f8bc6aafSDavid du Colombier syminit(Sym *s)
416*f8bc6aafSDavid du Colombier {
417*f8bc6aafSDavid du Colombier s->lexical = LNAME;
418*f8bc6aafSDavid du Colombier s->block = 0;
419*f8bc6aafSDavid du Colombier s->offset = 0;
420*f8bc6aafSDavid du Colombier s->type = T;
421*f8bc6aafSDavid du Colombier s->suetag = T;
422*f8bc6aafSDavid du Colombier s->class = CXXX;
423*f8bc6aafSDavid du Colombier s->aused = 0;
424*f8bc6aafSDavid du Colombier s->sig = SIGNONE;
425*f8bc6aafSDavid du Colombier }
426*f8bc6aafSDavid du Colombier
427*f8bc6aafSDavid du Colombier #define EOF (-1)
428*f8bc6aafSDavid du Colombier #define IGN (-2)
429*f8bc6aafSDavid du Colombier #define ESC (Runemask+1) /* Rune flag: a literal byte */
430*f8bc6aafSDavid du Colombier #define GETC() ((--fi.c < 0)? filbuf(): (*fi.p++ & 0xff))
431*f8bc6aafSDavid du Colombier
432*f8bc6aafSDavid du Colombier enum
433*f8bc6aafSDavid du Colombier {
434*f8bc6aafSDavid du Colombier Numdec = 1<<0,
435*f8bc6aafSDavid du Colombier Numlong = 1<<1,
436*f8bc6aafSDavid du Colombier Numuns = 1<<2,
437*f8bc6aafSDavid du Colombier Numvlong = 1<<3,
438*f8bc6aafSDavid du Colombier Numflt = 1<<4,
439*f8bc6aafSDavid du Colombier };
440*f8bc6aafSDavid du Colombier
441*f8bc6aafSDavid du Colombier long
yylex(void)442*f8bc6aafSDavid du Colombier yylex(void)
443*f8bc6aafSDavid du Colombier {
444*f8bc6aafSDavid du Colombier vlong vv;
445*f8bc6aafSDavid du Colombier long c, c1, t;
446*f8bc6aafSDavid du Colombier char *cp;
447*f8bc6aafSDavid du Colombier Rune rune;
448*f8bc6aafSDavid du Colombier Sym *s;
449*f8bc6aafSDavid du Colombier
450*f8bc6aafSDavid du Colombier if(peekc != IGN) {
451*f8bc6aafSDavid du Colombier c = peekc;
452*f8bc6aafSDavid du Colombier peekc = IGN;
453*f8bc6aafSDavid du Colombier goto l1;
454*f8bc6aafSDavid du Colombier }
455*f8bc6aafSDavid du Colombier l0:
456*f8bc6aafSDavid du Colombier c = GETC();
457*f8bc6aafSDavid du Colombier
458*f8bc6aafSDavid du Colombier l1:
459*f8bc6aafSDavid du Colombier if(c >= Runeself) {
460*f8bc6aafSDavid du Colombier /*
461*f8bc6aafSDavid du Colombier * extension --
462*f8bc6aafSDavid du Colombier * all multibyte runes are alpha
463*f8bc6aafSDavid du Colombier */
464*f8bc6aafSDavid du Colombier cp = symb;
465*f8bc6aafSDavid du Colombier goto talph;
466*f8bc6aafSDavid du Colombier }
467*f8bc6aafSDavid du Colombier if(isspace(c)) {
468*f8bc6aafSDavid du Colombier if(c == '\n')
469*f8bc6aafSDavid du Colombier lineno++;
470*f8bc6aafSDavid du Colombier goto l0;
471*f8bc6aafSDavid du Colombier }
472*f8bc6aafSDavid du Colombier if(isalpha(c)) {
473*f8bc6aafSDavid du Colombier cp = symb;
474*f8bc6aafSDavid du Colombier if(c != 'L')
475*f8bc6aafSDavid du Colombier goto talph;
476*f8bc6aafSDavid du Colombier *cp++ = c;
477*f8bc6aafSDavid du Colombier c = GETC();
478*f8bc6aafSDavid du Colombier if(c == '\'') {
479*f8bc6aafSDavid du Colombier /* L'x' */
480*f8bc6aafSDavid du Colombier c = escchar('\'', 1, 0);
481*f8bc6aafSDavid du Colombier if(c == EOF)
482*f8bc6aafSDavid du Colombier c = '\'';
483*f8bc6aafSDavid du Colombier c1 = escchar('\'', 1, 0);
484*f8bc6aafSDavid du Colombier if(c1 != EOF) {
485*f8bc6aafSDavid du Colombier yyerror("missing '");
486*f8bc6aafSDavid du Colombier peekc = c1;
487*f8bc6aafSDavid du Colombier }
488*f8bc6aafSDavid du Colombier yylval.vval = convvtox(c, TRUNE);
489*f8bc6aafSDavid du Colombier return LUCONST;
490*f8bc6aafSDavid du Colombier }
491*f8bc6aafSDavid du Colombier if(c == '"') {
492*f8bc6aafSDavid du Colombier goto caselq;
493*f8bc6aafSDavid du Colombier }
494*f8bc6aafSDavid du Colombier goto talph;
495*f8bc6aafSDavid du Colombier }
496*f8bc6aafSDavid du Colombier if(isdigit(c))
497*f8bc6aafSDavid du Colombier goto tnum;
498*f8bc6aafSDavid du Colombier switch(c)
499*f8bc6aafSDavid du Colombier {
500*f8bc6aafSDavid du Colombier
501*f8bc6aafSDavid du Colombier case EOF:
502*f8bc6aafSDavid du Colombier peekc = EOF;
503*f8bc6aafSDavid du Colombier return -1;
504*f8bc6aafSDavid du Colombier
505*f8bc6aafSDavid du Colombier case '_':
506*f8bc6aafSDavid du Colombier cp = symb;
507*f8bc6aafSDavid du Colombier goto talph;
508*f8bc6aafSDavid du Colombier
509*f8bc6aafSDavid du Colombier case '#':
510*f8bc6aafSDavid du Colombier domacro();
511*f8bc6aafSDavid du Colombier goto l0;
512*f8bc6aafSDavid du Colombier
513*f8bc6aafSDavid du Colombier case '.':
514*f8bc6aafSDavid du Colombier c1 = GETC();
515*f8bc6aafSDavid du Colombier if(isdigit(c1)) {
516*f8bc6aafSDavid du Colombier cp = symb;
517*f8bc6aafSDavid du Colombier *cp++ = c;
518*f8bc6aafSDavid du Colombier c = c1;
519*f8bc6aafSDavid du Colombier c1 = 0;
520*f8bc6aafSDavid du Colombier goto casedot;
521*f8bc6aafSDavid du Colombier }
522*f8bc6aafSDavid du Colombier break;
523*f8bc6aafSDavid du Colombier
524*f8bc6aafSDavid du Colombier case '"':
525*f8bc6aafSDavid du Colombier strcpy(symb, "\"<string>\"");
526*f8bc6aafSDavid du Colombier cp = alloc(0);
527*f8bc6aafSDavid du Colombier c1 = 0;
528*f8bc6aafSDavid du Colombier
529*f8bc6aafSDavid du Colombier /* "..." */
530*f8bc6aafSDavid du Colombier for(;;) {
531*f8bc6aafSDavid du Colombier c = escchar('"', 0, 1);
532*f8bc6aafSDavid du Colombier if(c == EOF)
533*f8bc6aafSDavid du Colombier break;
534*f8bc6aafSDavid du Colombier if(c & ESC) {
535*f8bc6aafSDavid du Colombier cp = allocn(cp, c1, 1);
536*f8bc6aafSDavid du Colombier cp[c1++] = c;
537*f8bc6aafSDavid du Colombier } else {
538*f8bc6aafSDavid du Colombier rune = c;
539*f8bc6aafSDavid du Colombier c = runelen(rune);
540*f8bc6aafSDavid du Colombier cp = allocn(cp, c1, c);
541*f8bc6aafSDavid du Colombier runetochar(cp+c1, &rune);
542*f8bc6aafSDavid du Colombier c1 += c;
543*f8bc6aafSDavid du Colombier }
544*f8bc6aafSDavid du Colombier }
545*f8bc6aafSDavid du Colombier yylval.sval.l = c1;
546*f8bc6aafSDavid du Colombier do {
547*f8bc6aafSDavid du Colombier cp = allocn(cp, c1, 1);
548*f8bc6aafSDavid du Colombier cp[c1++] = 0;
549*f8bc6aafSDavid du Colombier } while(c1 & MAXALIGN);
550*f8bc6aafSDavid du Colombier yylval.sval.s = cp;
551*f8bc6aafSDavid du Colombier return LSTRING;
552*f8bc6aafSDavid du Colombier
553*f8bc6aafSDavid du Colombier caselq:
554*f8bc6aafSDavid du Colombier /* L"..." */
555*f8bc6aafSDavid du Colombier strcpy(symb, "\"L<string>\"");
556*f8bc6aafSDavid du Colombier cp = alloc(0);
557*f8bc6aafSDavid du Colombier c1 = 0;
558*f8bc6aafSDavid du Colombier for(;;) {
559*f8bc6aafSDavid du Colombier c = escchar('"', 1, 0);
560*f8bc6aafSDavid du Colombier if(c == EOF)
561*f8bc6aafSDavid du Colombier break;
562*f8bc6aafSDavid du Colombier cp = allocn(cp, c1, sizeof(TRune));
563*f8bc6aafSDavid du Colombier *(TRune*)(cp + c1) = c;
564*f8bc6aafSDavid du Colombier c1 += sizeof(TRune);
565*f8bc6aafSDavid du Colombier }
566*f8bc6aafSDavid du Colombier yylval.sval.l = c1;
567*f8bc6aafSDavid du Colombier do {
568*f8bc6aafSDavid du Colombier cp = allocn(cp, c1, sizeof(TRune));
569*f8bc6aafSDavid du Colombier *(TRune*)(cp + c1) = 0;
570*f8bc6aafSDavid du Colombier c1 += sizeof(TRune);
571*f8bc6aafSDavid du Colombier } while(c1 & MAXALIGN);
572*f8bc6aafSDavid du Colombier yylval.sval.s = cp;
573*f8bc6aafSDavid du Colombier return LLSTRING;
574*f8bc6aafSDavid du Colombier
575*f8bc6aafSDavid du Colombier case '\'':
576*f8bc6aafSDavid du Colombier /* '.' */
577*f8bc6aafSDavid du Colombier c = escchar('\'', 0, 0);
578*f8bc6aafSDavid du Colombier if(c == EOF)
579*f8bc6aafSDavid du Colombier c = '\'';
580*f8bc6aafSDavid du Colombier c1 = escchar('\'', 0, 0);
581*f8bc6aafSDavid du Colombier if(c1 != EOF) {
582*f8bc6aafSDavid du Colombier yyerror("missing '");
583*f8bc6aafSDavid du Colombier peekc = c1;
584*f8bc6aafSDavid du Colombier }
585*f8bc6aafSDavid du Colombier vv = c;
586*f8bc6aafSDavid du Colombier yylval.vval = convvtox(vv, TUCHAR);
587*f8bc6aafSDavid du Colombier if(yylval.vval != vv)
588*f8bc6aafSDavid du Colombier yyerror("overflow in character constant: 0x%lx", c);
589*f8bc6aafSDavid du Colombier else
590*f8bc6aafSDavid du Colombier if(c & 0x80){
591*f8bc6aafSDavid du Colombier nearln = lineno;
592*f8bc6aafSDavid du Colombier warn(Z, "sign-extended character constant");
593*f8bc6aafSDavid du Colombier }
594*f8bc6aafSDavid du Colombier yylval.vval = convvtox(vv, TCHAR);
595*f8bc6aafSDavid du Colombier return LCONST;
596*f8bc6aafSDavid du Colombier
597*f8bc6aafSDavid du Colombier case '/':
598*f8bc6aafSDavid du Colombier c1 = GETC();
599*f8bc6aafSDavid du Colombier if(c1 == '*') {
600*f8bc6aafSDavid du Colombier for(;;) {
601*f8bc6aafSDavid du Colombier c = getr();
602*f8bc6aafSDavid du Colombier while(c == '*') {
603*f8bc6aafSDavid du Colombier c = getr();
604*f8bc6aafSDavid du Colombier if(c == '/')
605*f8bc6aafSDavid du Colombier goto l0;
606*f8bc6aafSDavid du Colombier }
607*f8bc6aafSDavid du Colombier if(c == EOF) {
608*f8bc6aafSDavid du Colombier yyerror("eof in comment");
609*f8bc6aafSDavid du Colombier errorexit();
610*f8bc6aafSDavid du Colombier }
611*f8bc6aafSDavid du Colombier }
612*f8bc6aafSDavid du Colombier }
613*f8bc6aafSDavid du Colombier if(c1 == '/') {
614*f8bc6aafSDavid du Colombier for(;;) {
615*f8bc6aafSDavid du Colombier c = getr();
616*f8bc6aafSDavid du Colombier if(c == '\n')
617*f8bc6aafSDavid du Colombier goto l0;
618*f8bc6aafSDavid du Colombier if(c == EOF) {
619*f8bc6aafSDavid du Colombier yyerror("eof in comment");
620*f8bc6aafSDavid du Colombier errorexit();
621*f8bc6aafSDavid du Colombier }
622*f8bc6aafSDavid du Colombier }
623*f8bc6aafSDavid du Colombier }
624*f8bc6aafSDavid du Colombier if(c1 == '=')
625*f8bc6aafSDavid du Colombier return LDVE;
626*f8bc6aafSDavid du Colombier break;
627*f8bc6aafSDavid du Colombier
628*f8bc6aafSDavid du Colombier case '*':
629*f8bc6aafSDavid du Colombier c1 = GETC();
630*f8bc6aafSDavid du Colombier if(c1 == '=')
631*f8bc6aafSDavid du Colombier return LMLE;
632*f8bc6aafSDavid du Colombier break;
633*f8bc6aafSDavid du Colombier
634*f8bc6aafSDavid du Colombier case '%':
635*f8bc6aafSDavid du Colombier c1 = GETC();
636*f8bc6aafSDavid du Colombier if(c1 == '=')
637*f8bc6aafSDavid du Colombier return LMDE;
638*f8bc6aafSDavid du Colombier break;
639*f8bc6aafSDavid du Colombier
640*f8bc6aafSDavid du Colombier case '+':
641*f8bc6aafSDavid du Colombier c1 = GETC();
642*f8bc6aafSDavid du Colombier if(c1 == '+')
643*f8bc6aafSDavid du Colombier return LPP;
644*f8bc6aafSDavid du Colombier if(c1 == '=')
645*f8bc6aafSDavid du Colombier return LPE;
646*f8bc6aafSDavid du Colombier break;
647*f8bc6aafSDavid du Colombier
648*f8bc6aafSDavid du Colombier case '-':
649*f8bc6aafSDavid du Colombier c1 = GETC();
650*f8bc6aafSDavid du Colombier if(c1 == '-')
651*f8bc6aafSDavid du Colombier return LMM;
652*f8bc6aafSDavid du Colombier if(c1 == '=')
653*f8bc6aafSDavid du Colombier return LME;
654*f8bc6aafSDavid du Colombier if(c1 == '>')
655*f8bc6aafSDavid du Colombier return LMG;
656*f8bc6aafSDavid du Colombier break;
657*f8bc6aafSDavid du Colombier
658*f8bc6aafSDavid du Colombier case '>':
659*f8bc6aafSDavid du Colombier c1 = GETC();
660*f8bc6aafSDavid du Colombier if(c1 == '>') {
661*f8bc6aafSDavid du Colombier c = LRSH;
662*f8bc6aafSDavid du Colombier c1 = GETC();
663*f8bc6aafSDavid du Colombier if(c1 == '=')
664*f8bc6aafSDavid du Colombier return LRSHE;
665*f8bc6aafSDavid du Colombier break;
666*f8bc6aafSDavid du Colombier }
667*f8bc6aafSDavid du Colombier if(c1 == '=')
668*f8bc6aafSDavid du Colombier return LGE;
669*f8bc6aafSDavid du Colombier break;
670*f8bc6aafSDavid du Colombier
671*f8bc6aafSDavid du Colombier case '<':
672*f8bc6aafSDavid du Colombier c1 = GETC();
673*f8bc6aafSDavid du Colombier if(c1 == '<') {
674*f8bc6aafSDavid du Colombier c = LLSH;
675*f8bc6aafSDavid du Colombier c1 = GETC();
676*f8bc6aafSDavid du Colombier if(c1 == '=')
677*f8bc6aafSDavid du Colombier return LLSHE;
678*f8bc6aafSDavid du Colombier break;
679*f8bc6aafSDavid du Colombier }
680*f8bc6aafSDavid du Colombier if(c1 == '=')
681*f8bc6aafSDavid du Colombier return LLE;
682*f8bc6aafSDavid du Colombier break;
683*f8bc6aafSDavid du Colombier
684*f8bc6aafSDavid du Colombier case '=':
685*f8bc6aafSDavid du Colombier c1 = GETC();
686*f8bc6aafSDavid du Colombier if(c1 == '=')
687*f8bc6aafSDavid du Colombier return LEQ;
688*f8bc6aafSDavid du Colombier break;
689*f8bc6aafSDavid du Colombier
690*f8bc6aafSDavid du Colombier case '!':
691*f8bc6aafSDavid du Colombier c1 = GETC();
692*f8bc6aafSDavid du Colombier if(c1 == '=')
693*f8bc6aafSDavid du Colombier return LNE;
694*f8bc6aafSDavid du Colombier break;
695*f8bc6aafSDavid du Colombier
696*f8bc6aafSDavid du Colombier case '&':
697*f8bc6aafSDavid du Colombier c1 = GETC();
698*f8bc6aafSDavid du Colombier if(c1 == '&')
699*f8bc6aafSDavid du Colombier return LANDAND;
700*f8bc6aafSDavid du Colombier if(c1 == '=')
701*f8bc6aafSDavid du Colombier return LANDE;
702*f8bc6aafSDavid du Colombier break;
703*f8bc6aafSDavid du Colombier
704*f8bc6aafSDavid du Colombier case '|':
705*f8bc6aafSDavid du Colombier c1 = GETC();
706*f8bc6aafSDavid du Colombier if(c1 == '|')
707*f8bc6aafSDavid du Colombier return LOROR;
708*f8bc6aafSDavid du Colombier if(c1 == '=')
709*f8bc6aafSDavid du Colombier return LORE;
710*f8bc6aafSDavid du Colombier break;
711*f8bc6aafSDavid du Colombier
712*f8bc6aafSDavid du Colombier case '^':
713*f8bc6aafSDavid du Colombier c1 = GETC();
714*f8bc6aafSDavid du Colombier if(c1 == '=')
715*f8bc6aafSDavid du Colombier return LXORE;
716*f8bc6aafSDavid du Colombier break;
717*f8bc6aafSDavid du Colombier
718*f8bc6aafSDavid du Colombier default:
719*f8bc6aafSDavid du Colombier return c;
720*f8bc6aafSDavid du Colombier }
721*f8bc6aafSDavid du Colombier peekc = c1;
722*f8bc6aafSDavid du Colombier return c;
723*f8bc6aafSDavid du Colombier
724*f8bc6aafSDavid du Colombier talph:
725*f8bc6aafSDavid du Colombier /*
726*f8bc6aafSDavid du Colombier * cp is set to symb and some
727*f8bc6aafSDavid du Colombier * prefix has been stored
728*f8bc6aafSDavid du Colombier */
729*f8bc6aafSDavid du Colombier for(;;) {
730*f8bc6aafSDavid du Colombier if(c >= Runeself) {
731*f8bc6aafSDavid du Colombier for(c1=0;;) {
732*f8bc6aafSDavid du Colombier cp[c1++] = c;
733*f8bc6aafSDavid du Colombier if(fullrune(cp, c1))
734*f8bc6aafSDavid du Colombier break;
735*f8bc6aafSDavid du Colombier c = GETC();
736*f8bc6aafSDavid du Colombier }
737*f8bc6aafSDavid du Colombier cp += c1;
738*f8bc6aafSDavid du Colombier c = GETC();
739*f8bc6aafSDavid du Colombier continue;
740*f8bc6aafSDavid du Colombier }
741*f8bc6aafSDavid du Colombier if(!isalnum(c) && c != '_')
742*f8bc6aafSDavid du Colombier break;
743*f8bc6aafSDavid du Colombier *cp++ = c;
744*f8bc6aafSDavid du Colombier c = GETC();
745*f8bc6aafSDavid du Colombier }
746*f8bc6aafSDavid du Colombier *cp = 0;
747*f8bc6aafSDavid du Colombier if(debug['L'])
748*f8bc6aafSDavid du Colombier print("%L: %s\n", lineno, symb);
749*f8bc6aafSDavid du Colombier peekc = c;
750*f8bc6aafSDavid du Colombier s = lookup();
751*f8bc6aafSDavid du Colombier if(s->macro) {
752*f8bc6aafSDavid du Colombier newio();
753*f8bc6aafSDavid du Colombier cp = ionext->b;
754*f8bc6aafSDavid du Colombier macexpand(s, cp);
755*f8bc6aafSDavid du Colombier pushio();
756*f8bc6aafSDavid du Colombier ionext->link = iostack;
757*f8bc6aafSDavid du Colombier iostack = ionext;
758*f8bc6aafSDavid du Colombier fi.p = cp;
759*f8bc6aafSDavid du Colombier fi.c = strlen(cp);
760*f8bc6aafSDavid du Colombier if(peekc != IGN) {
761*f8bc6aafSDavid du Colombier cp[fi.c++] = peekc;
762*f8bc6aafSDavid du Colombier cp[fi.c] = 0;
763*f8bc6aafSDavid du Colombier peekc = IGN;
764*f8bc6aafSDavid du Colombier }
765*f8bc6aafSDavid du Colombier goto l0;
766*f8bc6aafSDavid du Colombier }
767*f8bc6aafSDavid du Colombier yylval.sym = s;
768*f8bc6aafSDavid du Colombier if(s->class == CTYPEDEF || s->class == CTYPESTR)
769*f8bc6aafSDavid du Colombier return LTYPE;
770*f8bc6aafSDavid du Colombier return s->lexical;
771*f8bc6aafSDavid du Colombier
772*f8bc6aafSDavid du Colombier tnum:
773*f8bc6aafSDavid du Colombier c1 = 0;
774*f8bc6aafSDavid du Colombier cp = symb;
775*f8bc6aafSDavid du Colombier if(c != '0') {
776*f8bc6aafSDavid du Colombier c1 |= Numdec;
777*f8bc6aafSDavid du Colombier for(;;) {
778*f8bc6aafSDavid du Colombier *cp++ = c;
779*f8bc6aafSDavid du Colombier c = GETC();
780*f8bc6aafSDavid du Colombier if(isdigit(c))
781*f8bc6aafSDavid du Colombier continue;
782*f8bc6aafSDavid du Colombier goto dc;
783*f8bc6aafSDavid du Colombier }
784*f8bc6aafSDavid du Colombier }
785*f8bc6aafSDavid du Colombier *cp++ = c;
786*f8bc6aafSDavid du Colombier c = GETC();
787*f8bc6aafSDavid du Colombier if(c == 'x' || c == 'X')
788*f8bc6aafSDavid du Colombier for(;;) {
789*f8bc6aafSDavid du Colombier *cp++ = c;
790*f8bc6aafSDavid du Colombier c = GETC();
791*f8bc6aafSDavid du Colombier if(isdigit(c))
792*f8bc6aafSDavid du Colombier continue;
793*f8bc6aafSDavid du Colombier if(c >= 'a' && c <= 'f')
794*f8bc6aafSDavid du Colombier continue;
795*f8bc6aafSDavid du Colombier if(c >= 'A' && c <= 'F')
796*f8bc6aafSDavid du Colombier continue;
797*f8bc6aafSDavid du Colombier if(cp == symb+2)
798*f8bc6aafSDavid du Colombier yyerror("malformed hex constant");
799*f8bc6aafSDavid du Colombier goto ncu;
800*f8bc6aafSDavid du Colombier }
801*f8bc6aafSDavid du Colombier if(c < '0' || c > '7')
802*f8bc6aafSDavid du Colombier goto dc;
803*f8bc6aafSDavid du Colombier for(;;) {
804*f8bc6aafSDavid du Colombier if(c >= '0' && c <= '7') {
805*f8bc6aafSDavid du Colombier *cp++ = c;
806*f8bc6aafSDavid du Colombier c = GETC();
807*f8bc6aafSDavid du Colombier continue;
808*f8bc6aafSDavid du Colombier }
809*f8bc6aafSDavid du Colombier goto ncu;
810*f8bc6aafSDavid du Colombier }
811*f8bc6aafSDavid du Colombier
812*f8bc6aafSDavid du Colombier dc:
813*f8bc6aafSDavid du Colombier if(c == '.')
814*f8bc6aafSDavid du Colombier goto casedot;
815*f8bc6aafSDavid du Colombier if(c == 'e' || c == 'E')
816*f8bc6aafSDavid du Colombier goto casee;
817*f8bc6aafSDavid du Colombier
818*f8bc6aafSDavid du Colombier ncu:
819*f8bc6aafSDavid du Colombier if((c == 'U' || c == 'u') && !(c1 & Numuns)) {
820*f8bc6aafSDavid du Colombier c = GETC();
821*f8bc6aafSDavid du Colombier c1 |= Numuns;
822*f8bc6aafSDavid du Colombier goto ncu;
823*f8bc6aafSDavid du Colombier }
824*f8bc6aafSDavid du Colombier if((c == 'L' || c == 'l') && !(c1 & Numvlong)) {
825*f8bc6aafSDavid du Colombier c = GETC();
826*f8bc6aafSDavid du Colombier if(c1 & Numlong)
827*f8bc6aafSDavid du Colombier c1 |= Numvlong;
828*f8bc6aafSDavid du Colombier c1 |= Numlong;
829*f8bc6aafSDavid du Colombier goto ncu;
830*f8bc6aafSDavid du Colombier }
831*f8bc6aafSDavid du Colombier *cp = 0;
832*f8bc6aafSDavid du Colombier peekc = c;
833*f8bc6aafSDavid du Colombier if(mpatov(symb, &yylval.vval))
834*f8bc6aafSDavid du Colombier yyerror("overflow in constant");
835*f8bc6aafSDavid du Colombier
836*f8bc6aafSDavid du Colombier vv = yylval.vval;
837*f8bc6aafSDavid du Colombier if(c1 & Numvlong) {
838*f8bc6aafSDavid du Colombier if((c1 & Numuns) || convvtox(vv, TVLONG) < 0) {
839*f8bc6aafSDavid du Colombier c = LUVLCONST;
840*f8bc6aafSDavid du Colombier t = TUVLONG;
841*f8bc6aafSDavid du Colombier goto nret;
842*f8bc6aafSDavid du Colombier }
843*f8bc6aafSDavid du Colombier c = LVLCONST;
844*f8bc6aafSDavid du Colombier t = TVLONG;
845*f8bc6aafSDavid du Colombier goto nret;
846*f8bc6aafSDavid du Colombier }
847*f8bc6aafSDavid du Colombier if(c1 & Numlong) {
848*f8bc6aafSDavid du Colombier if((c1 & Numuns) || convvtox(vv, TLONG) < 0) {
849*f8bc6aafSDavid du Colombier c = LULCONST;
850*f8bc6aafSDavid du Colombier t = TULONG;
851*f8bc6aafSDavid du Colombier goto nret;
852*f8bc6aafSDavid du Colombier }
853*f8bc6aafSDavid du Colombier c = LLCONST;
854*f8bc6aafSDavid du Colombier t = TLONG;
855*f8bc6aafSDavid du Colombier goto nret;
856*f8bc6aafSDavid du Colombier }
857*f8bc6aafSDavid du Colombier if((c1 & Numuns) || convvtox(vv, TINT) < 0) {
858*f8bc6aafSDavid du Colombier c = LUCONST;
859*f8bc6aafSDavid du Colombier t = TUINT;
860*f8bc6aafSDavid du Colombier goto nret;
861*f8bc6aafSDavid du Colombier }
862*f8bc6aafSDavid du Colombier c = LCONST;
863*f8bc6aafSDavid du Colombier t = TINT;
864*f8bc6aafSDavid du Colombier goto nret;
865*f8bc6aafSDavid du Colombier
866*f8bc6aafSDavid du Colombier nret:
867*f8bc6aafSDavid du Colombier yylval.vval = convvtox(vv, t);
868*f8bc6aafSDavid du Colombier if(yylval.vval != vv){
869*f8bc6aafSDavid du Colombier nearln = lineno;
870*f8bc6aafSDavid du Colombier warn(Z, "truncated constant: %T %s", types[t], symb);
871*f8bc6aafSDavid du Colombier }
872*f8bc6aafSDavid du Colombier return c;
873*f8bc6aafSDavid du Colombier
874*f8bc6aafSDavid du Colombier casedot:
875*f8bc6aafSDavid du Colombier for(;;) {
876*f8bc6aafSDavid du Colombier *cp++ = c;
877*f8bc6aafSDavid du Colombier c = GETC();
878*f8bc6aafSDavid du Colombier if(!isdigit(c))
879*f8bc6aafSDavid du Colombier break;
880*f8bc6aafSDavid du Colombier }
881*f8bc6aafSDavid du Colombier if(c != 'e' && c != 'E')
882*f8bc6aafSDavid du Colombier goto caseout;
883*f8bc6aafSDavid du Colombier
884*f8bc6aafSDavid du Colombier casee:
885*f8bc6aafSDavid du Colombier *cp++ = 'e';
886*f8bc6aafSDavid du Colombier c = GETC();
887*f8bc6aafSDavid du Colombier if(c == '+' || c == '-') {
888*f8bc6aafSDavid du Colombier *cp++ = c;
889*f8bc6aafSDavid du Colombier c = GETC();
890*f8bc6aafSDavid du Colombier }
891*f8bc6aafSDavid du Colombier if(!isdigit(c))
892*f8bc6aafSDavid du Colombier yyerror("malformed fp constant exponent");
893*f8bc6aafSDavid du Colombier while(isdigit(c)) {
894*f8bc6aafSDavid du Colombier *cp++ = c;
895*f8bc6aafSDavid du Colombier c = GETC();
896*f8bc6aafSDavid du Colombier }
897*f8bc6aafSDavid du Colombier
898*f8bc6aafSDavid du Colombier caseout:
899*f8bc6aafSDavid du Colombier if(c == 'L' || c == 'l') {
900*f8bc6aafSDavid du Colombier c = GETC();
901*f8bc6aafSDavid du Colombier c1 |= Numlong;
902*f8bc6aafSDavid du Colombier } else
903*f8bc6aafSDavid du Colombier if(c == 'F' || c == 'f') {
904*f8bc6aafSDavid du Colombier c = GETC();
905*f8bc6aafSDavid du Colombier c1 |= Numflt;
906*f8bc6aafSDavid du Colombier }
907*f8bc6aafSDavid du Colombier *cp = 0;
908*f8bc6aafSDavid du Colombier peekc = c;
909*f8bc6aafSDavid du Colombier yylval.dval = strtod(symb, nil);
910*f8bc6aafSDavid du Colombier if(isInf(yylval.dval, 1) || isInf(yylval.dval, -1)) {
911*f8bc6aafSDavid du Colombier yyerror("overflow in float constant");
912*f8bc6aafSDavid du Colombier yylval.dval = 0;
913*f8bc6aafSDavid du Colombier }
914*f8bc6aafSDavid du Colombier if(c1 & Numflt)
915*f8bc6aafSDavid du Colombier return LFCONST;
916*f8bc6aafSDavid du Colombier return LDCONST;
917*f8bc6aafSDavid du Colombier }
918*f8bc6aafSDavid du Colombier
919*f8bc6aafSDavid du Colombier /*
920*f8bc6aafSDavid du Colombier * convert a string, s, to vlong in *v
921*f8bc6aafSDavid du Colombier * return conversion overflow.
922*f8bc6aafSDavid du Colombier * required syntax is [0[x]]d*
923*f8bc6aafSDavid du Colombier */
924*f8bc6aafSDavid du Colombier int
mpatov(char * s,vlong * v)925*f8bc6aafSDavid du Colombier mpatov(char *s, vlong *v)
926*f8bc6aafSDavid du Colombier {
927*f8bc6aafSDavid du Colombier vlong n, nn;
928*f8bc6aafSDavid du Colombier int c;
929*f8bc6aafSDavid du Colombier
930*f8bc6aafSDavid du Colombier n = 0;
931*f8bc6aafSDavid du Colombier c = *s;
932*f8bc6aafSDavid du Colombier if(c == '0')
933*f8bc6aafSDavid du Colombier goto oct;
934*f8bc6aafSDavid du Colombier while(c = *s++) {
935*f8bc6aafSDavid du Colombier if(c >= '0' && c <= '9')
936*f8bc6aafSDavid du Colombier nn = n*10 + c-'0';
937*f8bc6aafSDavid du Colombier else
938*f8bc6aafSDavid du Colombier goto bad;
939*f8bc6aafSDavid du Colombier if(n < 0 && nn >= 0)
940*f8bc6aafSDavid du Colombier goto bad;
941*f8bc6aafSDavid du Colombier n = nn;
942*f8bc6aafSDavid du Colombier }
943*f8bc6aafSDavid du Colombier goto out;
944*f8bc6aafSDavid du Colombier
945*f8bc6aafSDavid du Colombier oct:
946*f8bc6aafSDavid du Colombier s++;
947*f8bc6aafSDavid du Colombier c = *s;
948*f8bc6aafSDavid du Colombier if(c == 'x' || c == 'X')
949*f8bc6aafSDavid du Colombier goto hex;
950*f8bc6aafSDavid du Colombier while(c = *s++) {
951*f8bc6aafSDavid du Colombier if(c >= '0' || c <= '7')
952*f8bc6aafSDavid du Colombier nn = n*8 + c-'0';
953*f8bc6aafSDavid du Colombier else
954*f8bc6aafSDavid du Colombier goto bad;
955*f8bc6aafSDavid du Colombier if(n < 0 && nn >= 0)
956*f8bc6aafSDavid du Colombier goto bad;
957*f8bc6aafSDavid du Colombier n = nn;
958*f8bc6aafSDavid du Colombier }
959*f8bc6aafSDavid du Colombier goto out;
960*f8bc6aafSDavid du Colombier
961*f8bc6aafSDavid du Colombier hex:
962*f8bc6aafSDavid du Colombier s++;
963*f8bc6aafSDavid du Colombier while(c = *s++) {
964*f8bc6aafSDavid du Colombier if(c >= '0' && c <= '9')
965*f8bc6aafSDavid du Colombier c += 0-'0';
966*f8bc6aafSDavid du Colombier else
967*f8bc6aafSDavid du Colombier if(c >= 'a' && c <= 'f')
968*f8bc6aafSDavid du Colombier c += 10-'a';
969*f8bc6aafSDavid du Colombier else
970*f8bc6aafSDavid du Colombier if(c >= 'A' && c <= 'F')
971*f8bc6aafSDavid du Colombier c += 10-'A';
972*f8bc6aafSDavid du Colombier else
973*f8bc6aafSDavid du Colombier goto bad;
974*f8bc6aafSDavid du Colombier nn = n*16 + c;
975*f8bc6aafSDavid du Colombier if(n < 0 && nn >= 0)
976*f8bc6aafSDavid du Colombier goto bad;
977*f8bc6aafSDavid du Colombier n = nn;
978*f8bc6aafSDavid du Colombier }
979*f8bc6aafSDavid du Colombier out:
980*f8bc6aafSDavid du Colombier *v = n;
981*f8bc6aafSDavid du Colombier return 0;
982*f8bc6aafSDavid du Colombier
983*f8bc6aafSDavid du Colombier bad:
984*f8bc6aafSDavid du Colombier *v = ~0;
985*f8bc6aafSDavid du Colombier return 1;
986*f8bc6aafSDavid du Colombier }
987*f8bc6aafSDavid du Colombier
988*f8bc6aafSDavid du Colombier int
getc(void)989*f8bc6aafSDavid du Colombier getc(void)
990*f8bc6aafSDavid du Colombier {
991*f8bc6aafSDavid du Colombier int c;
992*f8bc6aafSDavid du Colombier
993*f8bc6aafSDavid du Colombier if(peekc != IGN) {
994*f8bc6aafSDavid du Colombier c = peekc;
995*f8bc6aafSDavid du Colombier peekc = IGN;
996*f8bc6aafSDavid du Colombier } else
997*f8bc6aafSDavid du Colombier c = GETC();
998*f8bc6aafSDavid du Colombier if(c == '\n')
999*f8bc6aafSDavid du Colombier lineno++;
1000*f8bc6aafSDavid du Colombier if(c == EOF) {
1001*f8bc6aafSDavid du Colombier yyerror("End of file");
1002*f8bc6aafSDavid du Colombier errorexit();
1003*f8bc6aafSDavid du Colombier }
1004*f8bc6aafSDavid du Colombier return c;
1005*f8bc6aafSDavid du Colombier }
1006*f8bc6aafSDavid du Colombier
1007*f8bc6aafSDavid du Colombier long
getr(void)1008*f8bc6aafSDavid du Colombier getr(void)
1009*f8bc6aafSDavid du Colombier {
1010*f8bc6aafSDavid du Colombier int c, i;
1011*f8bc6aafSDavid du Colombier char str[UTFmax+1];
1012*f8bc6aafSDavid du Colombier Rune rune;
1013*f8bc6aafSDavid du Colombier
1014*f8bc6aafSDavid du Colombier
1015*f8bc6aafSDavid du Colombier c = getc();
1016*f8bc6aafSDavid du Colombier if(c < Runeself)
1017*f8bc6aafSDavid du Colombier return c;
1018*f8bc6aafSDavid du Colombier i = 0;
1019*f8bc6aafSDavid du Colombier str[i++] = c;
1020*f8bc6aafSDavid du Colombier
1021*f8bc6aafSDavid du Colombier loop:
1022*f8bc6aafSDavid du Colombier c = getc();
1023*f8bc6aafSDavid du Colombier str[i++] = c;
1024*f8bc6aafSDavid du Colombier if(!fullrune(str, i))
1025*f8bc6aafSDavid du Colombier goto loop;
1026*f8bc6aafSDavid du Colombier c = chartorune(&rune, str);
1027*f8bc6aafSDavid du Colombier if(rune == Runeerror && c == 1) {
1028*f8bc6aafSDavid du Colombier nearln = lineno;
1029*f8bc6aafSDavid du Colombier diag(Z, "illegal rune in string");
1030*f8bc6aafSDavid du Colombier for(c=0; c<i; c++)
1031*f8bc6aafSDavid du Colombier print(" %.2x", *(uchar*)(str+c));
1032*f8bc6aafSDavid du Colombier print("\n");
1033*f8bc6aafSDavid du Colombier }
1034*f8bc6aafSDavid du Colombier return rune;
1035*f8bc6aafSDavid du Colombier }
1036*f8bc6aafSDavid du Colombier
1037*f8bc6aafSDavid du Colombier int
getnsc(void)1038*f8bc6aafSDavid du Colombier getnsc(void)
1039*f8bc6aafSDavid du Colombier {
1040*f8bc6aafSDavid du Colombier int c;
1041*f8bc6aafSDavid du Colombier
1042*f8bc6aafSDavid du Colombier if(peekc != IGN) {
1043*f8bc6aafSDavid du Colombier c = peekc;
1044*f8bc6aafSDavid du Colombier peekc = IGN;
1045*f8bc6aafSDavid du Colombier } else
1046*f8bc6aafSDavid du Colombier c = GETC();
1047*f8bc6aafSDavid du Colombier for(;;) {
1048*f8bc6aafSDavid du Colombier if(c >= Runeself || !isspace(c))
1049*f8bc6aafSDavid du Colombier return c;
1050*f8bc6aafSDavid du Colombier if(c == '\n') {
1051*f8bc6aafSDavid du Colombier lineno++;
1052*f8bc6aafSDavid du Colombier return c;
1053*f8bc6aafSDavid du Colombier }
1054*f8bc6aafSDavid du Colombier c = GETC();
1055*f8bc6aafSDavid du Colombier }
1056*f8bc6aafSDavid du Colombier }
1057*f8bc6aafSDavid du Colombier
1058*f8bc6aafSDavid du Colombier void
unget(int c)1059*f8bc6aafSDavid du Colombier unget(int c)
1060*f8bc6aafSDavid du Colombier {
1061*f8bc6aafSDavid du Colombier
1062*f8bc6aafSDavid du Colombier peekc = c;
1063*f8bc6aafSDavid du Colombier if(c == '\n')
1064*f8bc6aafSDavid du Colombier lineno--;
1065*f8bc6aafSDavid du Colombier }
1066*f8bc6aafSDavid du Colombier
1067*f8bc6aafSDavid du Colombier long
escchar(long e,int longflg,int escflg)1068*f8bc6aafSDavid du Colombier escchar(long e, int longflg, int escflg)
1069*f8bc6aafSDavid du Colombier {
1070*f8bc6aafSDavid du Colombier long c, l;
1071*f8bc6aafSDavid du Colombier int i;
1072*f8bc6aafSDavid du Colombier
1073*f8bc6aafSDavid du Colombier loop:
1074*f8bc6aafSDavid du Colombier c = getr();
1075*f8bc6aafSDavid du Colombier if(c == '\n') {
1076*f8bc6aafSDavid du Colombier yyerror("newline in string");
1077*f8bc6aafSDavid du Colombier return EOF;
1078*f8bc6aafSDavid du Colombier }
1079*f8bc6aafSDavid du Colombier if(c != '\\') {
1080*f8bc6aafSDavid du Colombier if(c == e)
1081*f8bc6aafSDavid du Colombier c = EOF;
1082*f8bc6aafSDavid du Colombier return c;
1083*f8bc6aafSDavid du Colombier }
1084*f8bc6aafSDavid du Colombier c = getr();
1085*f8bc6aafSDavid du Colombier if(c == 'x') {
1086*f8bc6aafSDavid du Colombier /*
1087*f8bc6aafSDavid du Colombier * note this is not ansi,
1088*f8bc6aafSDavid du Colombier * supposed to only accept 2 hex
1089*f8bc6aafSDavid du Colombier */
1090*f8bc6aafSDavid du Colombier i = 2;
1091*f8bc6aafSDavid du Colombier if(longflg)
1092*f8bc6aafSDavid du Colombier i = 6;
1093*f8bc6aafSDavid du Colombier l = 0;
1094*f8bc6aafSDavid du Colombier for(; i>0; i--) {
1095*f8bc6aafSDavid du Colombier c = getc();
1096*f8bc6aafSDavid du Colombier if(c >= '0' && c <= '9') {
1097*f8bc6aafSDavid du Colombier l = l*16 + c-'0';
1098*f8bc6aafSDavid du Colombier continue;
1099*f8bc6aafSDavid du Colombier }
1100*f8bc6aafSDavid du Colombier if(c >= 'a' && c <= 'f') {
1101*f8bc6aafSDavid du Colombier l = l*16 + c-'a' + 10;
1102*f8bc6aafSDavid du Colombier continue;
1103*f8bc6aafSDavid du Colombier }
1104*f8bc6aafSDavid du Colombier if(c >= 'A' && c <= 'F') {
1105*f8bc6aafSDavid du Colombier l = l*16 + c-'A' + 10;
1106*f8bc6aafSDavid du Colombier continue;
1107*f8bc6aafSDavid du Colombier }
1108*f8bc6aafSDavid du Colombier unget(c);
1109*f8bc6aafSDavid du Colombier break;
1110*f8bc6aafSDavid du Colombier }
1111*f8bc6aafSDavid du Colombier if(escflg)
1112*f8bc6aafSDavid du Colombier l |= ESC;
1113*f8bc6aafSDavid du Colombier return l;
1114*f8bc6aafSDavid du Colombier }
1115*f8bc6aafSDavid du Colombier if(c >= '0' && c <= '7') {
1116*f8bc6aafSDavid du Colombier /*
1117*f8bc6aafSDavid du Colombier * note this is not ansi,
1118*f8bc6aafSDavid du Colombier * supposed to only accept 3 oct
1119*f8bc6aafSDavid du Colombier */
1120*f8bc6aafSDavid du Colombier i = 2;
1121*f8bc6aafSDavid du Colombier if(longflg)
1122*f8bc6aafSDavid du Colombier i = 8;
1123*f8bc6aafSDavid du Colombier l = c - '0';
1124*f8bc6aafSDavid du Colombier for(; i>0; i--) {
1125*f8bc6aafSDavid du Colombier c = getc();
1126*f8bc6aafSDavid du Colombier if(c >= '0' && c <= '7') {
1127*f8bc6aafSDavid du Colombier l = l*8 + c-'0';
1128*f8bc6aafSDavid du Colombier continue;
1129*f8bc6aafSDavid du Colombier }
1130*f8bc6aafSDavid du Colombier unget(c);
1131*f8bc6aafSDavid du Colombier }
1132*f8bc6aafSDavid du Colombier if(escflg)
1133*f8bc6aafSDavid du Colombier l |= ESC;
1134*f8bc6aafSDavid du Colombier return l;
1135*f8bc6aafSDavid du Colombier }
1136*f8bc6aafSDavid du Colombier switch(c)
1137*f8bc6aafSDavid du Colombier {
1138*f8bc6aafSDavid du Colombier case '\n': goto loop;
1139*f8bc6aafSDavid du Colombier case 'n': return '\n';
1140*f8bc6aafSDavid du Colombier case 't': return '\t';
1141*f8bc6aafSDavid du Colombier case 'b': return '\b';
1142*f8bc6aafSDavid du Colombier case 'r': return '\r';
1143*f8bc6aafSDavid du Colombier case 'f': return '\f';
1144*f8bc6aafSDavid du Colombier case 'a': return '\a';
1145*f8bc6aafSDavid du Colombier case 'v': return '\v';
1146*f8bc6aafSDavid du Colombier }
1147*f8bc6aafSDavid du Colombier return c;
1148*f8bc6aafSDavid du Colombier }
1149*f8bc6aafSDavid du Colombier
1150*f8bc6aafSDavid du Colombier struct
1151*f8bc6aafSDavid du Colombier {
1152*f8bc6aafSDavid du Colombier char *name;
1153*f8bc6aafSDavid du Colombier ushort lexical;
1154*f8bc6aafSDavid du Colombier ushort type;
1155*f8bc6aafSDavid du Colombier } itab[] =
1156*f8bc6aafSDavid du Colombier {
1157*f8bc6aafSDavid du Colombier "auto", LAUTO, 0,
1158*f8bc6aafSDavid du Colombier "break", LBREAK, 0,
1159*f8bc6aafSDavid du Colombier "case", LCASE, 0,
1160*f8bc6aafSDavid du Colombier "char", LCHAR, TCHAR,
1161*f8bc6aafSDavid du Colombier "const", LCONSTNT, 0,
1162*f8bc6aafSDavid du Colombier "continue", LCONTINUE, 0,
1163*f8bc6aafSDavid du Colombier "default", LDEFAULT, 0,
1164*f8bc6aafSDavid du Colombier "do", LDO, 0,
1165*f8bc6aafSDavid du Colombier "double", LDOUBLE, TDOUBLE,
1166*f8bc6aafSDavid du Colombier "else", LELSE, 0,
1167*f8bc6aafSDavid du Colombier "enum", LENUM, 0,
1168*f8bc6aafSDavid du Colombier "extern", LEXTERN, 0,
1169*f8bc6aafSDavid du Colombier "float", LFLOAT, TFLOAT,
1170*f8bc6aafSDavid du Colombier "for", LFOR, 0,
1171*f8bc6aafSDavid du Colombier "goto", LGOTO, 0,
1172*f8bc6aafSDavid du Colombier "if", LIF, 0,
1173*f8bc6aafSDavid du Colombier "inline", LINLINE, 0,
1174*f8bc6aafSDavid du Colombier "int", LINT, TINT,
1175*f8bc6aafSDavid du Colombier "long", LLONG, TLONG,
1176*f8bc6aafSDavid du Colombier "register", LREGISTER, 0,
1177*f8bc6aafSDavid du Colombier "restrict", LRESTRICT, 0,
1178*f8bc6aafSDavid du Colombier "return", LRETURN, 0,
1179*f8bc6aafSDavid du Colombier "SET", LSET, 0,
1180*f8bc6aafSDavid du Colombier "short", LSHORT, TSHORT,
1181*f8bc6aafSDavid du Colombier "signed", LSIGNED, 0,
1182*f8bc6aafSDavid du Colombier "signof", LSIGNOF, 0,
1183*f8bc6aafSDavid du Colombier "sizeof", LSIZEOF, 0,
1184*f8bc6aafSDavid du Colombier "static", LSTATIC, 0,
1185*f8bc6aafSDavid du Colombier "struct", LSTRUCT, 0,
1186*f8bc6aafSDavid du Colombier "switch", LSWITCH, 0,
1187*f8bc6aafSDavid du Colombier "typedef", LTYPEDEF, 0,
1188*f8bc6aafSDavid du Colombier "typestr", LTYPESTR, 0,
1189*f8bc6aafSDavid du Colombier "union", LUNION, 0,
1190*f8bc6aafSDavid du Colombier "unsigned", LUNSIGNED, 0,
1191*f8bc6aafSDavid du Colombier "USED", LUSED, 0,
1192*f8bc6aafSDavid du Colombier "void", LVOID, TVOID,
1193*f8bc6aafSDavid du Colombier "volatile", LVOLATILE, 0,
1194*f8bc6aafSDavid du Colombier "while", LWHILE, 0,
1195*f8bc6aafSDavid du Colombier 0
1196*f8bc6aafSDavid du Colombier };
1197*f8bc6aafSDavid du Colombier
1198*f8bc6aafSDavid du Colombier void
cinit(void)1199*f8bc6aafSDavid du Colombier cinit(void)
1200*f8bc6aafSDavid du Colombier {
1201*f8bc6aafSDavid du Colombier Sym *s;
1202*f8bc6aafSDavid du Colombier int i;
1203*f8bc6aafSDavid du Colombier Type *t;
1204*f8bc6aafSDavid du Colombier
1205*f8bc6aafSDavid du Colombier nerrors = 0;
1206*f8bc6aafSDavid du Colombier lineno = 1;
1207*f8bc6aafSDavid du Colombier iostack = I;
1208*f8bc6aafSDavid du Colombier iofree = I;
1209*f8bc6aafSDavid du Colombier peekc = IGN;
1210*f8bc6aafSDavid du Colombier nhunk = 0;
1211*f8bc6aafSDavid du Colombier
1212*f8bc6aafSDavid du Colombier types[TXXX] = T;
1213*f8bc6aafSDavid du Colombier types[TCHAR] = typ(TCHAR, T);
1214*f8bc6aafSDavid du Colombier types[TUCHAR] = typ(TUCHAR, T);
1215*f8bc6aafSDavid du Colombier types[TSHORT] = typ(TSHORT, T);
1216*f8bc6aafSDavid du Colombier types[TUSHORT] = typ(TUSHORT, T);
1217*f8bc6aafSDavid du Colombier types[TINT] = typ(TINT, T);
1218*f8bc6aafSDavid du Colombier types[TUINT] = typ(TUINT, T);
1219*f8bc6aafSDavid du Colombier types[TLONG] = typ(TLONG, T);
1220*f8bc6aafSDavid du Colombier types[TULONG] = typ(TULONG, T);
1221*f8bc6aafSDavid du Colombier types[TVLONG] = typ(TVLONG, T);
1222*f8bc6aafSDavid du Colombier types[TUVLONG] = typ(TUVLONG, T);
1223*f8bc6aafSDavid du Colombier types[TFLOAT] = typ(TFLOAT, T);
1224*f8bc6aafSDavid du Colombier types[TDOUBLE] = typ(TDOUBLE, T);
1225*f8bc6aafSDavid du Colombier types[TVOID] = typ(TVOID, T);
1226*f8bc6aafSDavid du Colombier types[TENUM] = typ(TENUM, T);
1227*f8bc6aafSDavid du Colombier types[TFUNC] = typ(TFUNC, types[TINT]);
1228*f8bc6aafSDavid du Colombier types[TIND] = typ(TIND, types[TVOID]);
1229*f8bc6aafSDavid du Colombier
1230*f8bc6aafSDavid du Colombier for(i=0; i<NHASH; i++)
1231*f8bc6aafSDavid du Colombier hash[i] = S;
1232*f8bc6aafSDavid du Colombier for(i=0; itab[i].name; i++) {
1233*f8bc6aafSDavid du Colombier s = slookup(itab[i].name);
1234*f8bc6aafSDavid du Colombier s->lexical = itab[i].lexical;
1235*f8bc6aafSDavid du Colombier if(itab[i].type != 0)
1236*f8bc6aafSDavid du Colombier s->type = types[itab[i].type];
1237*f8bc6aafSDavid du Colombier }
1238*f8bc6aafSDavid du Colombier blockno = 0;
1239*f8bc6aafSDavid du Colombier autobn = 0;
1240*f8bc6aafSDavid du Colombier autoffset = 0;
1241*f8bc6aafSDavid du Colombier
1242*f8bc6aafSDavid du Colombier t = typ(TARRAY, types[TCHAR]);
1243*f8bc6aafSDavid du Colombier t->width = 0;
1244*f8bc6aafSDavid du Colombier symstring = slookup(".string");
1245*f8bc6aafSDavid du Colombier symstring->class = CSTATIC;
1246*f8bc6aafSDavid du Colombier symstring->type = t;
1247*f8bc6aafSDavid du Colombier
1248*f8bc6aafSDavid du Colombier t = typ(TARRAY, types[TCHAR]);
1249*f8bc6aafSDavid du Colombier t->width = 0;
1250*f8bc6aafSDavid du Colombier
1251*f8bc6aafSDavid du Colombier nodproto = new(OPROTO, Z, Z);
1252*f8bc6aafSDavid du Colombier dclstack = D;
1253*f8bc6aafSDavid du Colombier
1254*f8bc6aafSDavid du Colombier pathname = allocn(pathname, 0, 100);
1255*f8bc6aafSDavid du Colombier if(mygetwd(pathname, 99) == 0) {
1256*f8bc6aafSDavid du Colombier pathname = allocn(pathname, 100, 900);
1257*f8bc6aafSDavid du Colombier if(mygetwd(pathname, 999) == 0)
1258*f8bc6aafSDavid du Colombier strcpy(pathname, "/???");
1259*f8bc6aafSDavid du Colombier }
1260*f8bc6aafSDavid du Colombier
1261*f8bc6aafSDavid du Colombier fmtinstall('O', Oconv);
1262*f8bc6aafSDavid du Colombier fmtinstall('T', Tconv);
1263*f8bc6aafSDavid du Colombier fmtinstall('F', FNconv);
1264*f8bc6aafSDavid du Colombier fmtinstall('L', Lconv);
1265*f8bc6aafSDavid du Colombier fmtinstall('Q', Qconv);
1266*f8bc6aafSDavid du Colombier fmtinstall('|', VBconv);
1267*f8bc6aafSDavid du Colombier }
1268*f8bc6aafSDavid du Colombier
1269*f8bc6aafSDavid du Colombier int
filbuf(void)1270*f8bc6aafSDavid du Colombier filbuf(void)
1271*f8bc6aafSDavid du Colombier {
1272*f8bc6aafSDavid du Colombier Io *i;
1273*f8bc6aafSDavid du Colombier
1274*f8bc6aafSDavid du Colombier loop:
1275*f8bc6aafSDavid du Colombier i = iostack;
1276*f8bc6aafSDavid du Colombier if(i == I)
1277*f8bc6aafSDavid du Colombier return EOF;
1278*f8bc6aafSDavid du Colombier if(i->f < 0)
1279*f8bc6aafSDavid du Colombier goto pop;
1280*f8bc6aafSDavid du Colombier fi.c = read(i->f, i->b, BUFSIZ) - 1;
1281*f8bc6aafSDavid du Colombier if(fi.c < 0) {
1282*f8bc6aafSDavid du Colombier close(i->f);
1283*f8bc6aafSDavid du Colombier linehist(0, 0);
1284*f8bc6aafSDavid du Colombier goto pop;
1285*f8bc6aafSDavid du Colombier }
1286*f8bc6aafSDavid du Colombier fi.p = i->b + 1;
1287*f8bc6aafSDavid du Colombier return i->b[0] & 0xff;
1288*f8bc6aafSDavid du Colombier
1289*f8bc6aafSDavid du Colombier pop:
1290*f8bc6aafSDavid du Colombier iostack = i->link;
1291*f8bc6aafSDavid du Colombier i->link = iofree;
1292*f8bc6aafSDavid du Colombier iofree = i;
1293*f8bc6aafSDavid du Colombier i = iostack;
1294*f8bc6aafSDavid du Colombier if(i == I)
1295*f8bc6aafSDavid du Colombier return EOF;
1296*f8bc6aafSDavid du Colombier fi.p = i->p;
1297*f8bc6aafSDavid du Colombier fi.c = i->c;
1298*f8bc6aafSDavid du Colombier if(--fi.c < 0)
1299*f8bc6aafSDavid du Colombier goto loop;
1300*f8bc6aafSDavid du Colombier return *fi.p++ & 0xff;
1301*f8bc6aafSDavid du Colombier }
1302*f8bc6aafSDavid du Colombier
1303*f8bc6aafSDavid du Colombier int
Oconv(Fmt * fp)1304*f8bc6aafSDavid du Colombier Oconv(Fmt *fp)
1305*f8bc6aafSDavid du Colombier {
1306*f8bc6aafSDavid du Colombier int a;
1307*f8bc6aafSDavid du Colombier
1308*f8bc6aafSDavid du Colombier a = va_arg(fp->args, int);
1309*f8bc6aafSDavid du Colombier if(a < OXXX || a > OEND)
1310*f8bc6aafSDavid du Colombier return fmtprint(fp, "***badO %d***", a);
1311*f8bc6aafSDavid du Colombier
1312*f8bc6aafSDavid du Colombier return fmtstrcpy(fp, onames[a]);
1313*f8bc6aafSDavid du Colombier }
1314*f8bc6aafSDavid du Colombier
1315*f8bc6aafSDavid du Colombier int
Lconv(Fmt * fp)1316*f8bc6aafSDavid du Colombier Lconv(Fmt *fp)
1317*f8bc6aafSDavid du Colombier {
1318*f8bc6aafSDavid du Colombier char str[STRINGSZ], s[STRINGSZ];
1319*f8bc6aafSDavid du Colombier Hist *h;
1320*f8bc6aafSDavid du Colombier struct
1321*f8bc6aafSDavid du Colombier {
1322*f8bc6aafSDavid du Colombier Hist* incl; /* start of this include file */
1323*f8bc6aafSDavid du Colombier long idel; /* delta line number to apply to include */
1324*f8bc6aafSDavid du Colombier Hist* line; /* start of this #line directive */
1325*f8bc6aafSDavid du Colombier long ldel; /* delta line number to apply to #line */
1326*f8bc6aafSDavid du Colombier } a[HISTSZ];
1327*f8bc6aafSDavid du Colombier long l, d;
1328*f8bc6aafSDavid du Colombier int i, n;
1329*f8bc6aafSDavid du Colombier
1330*f8bc6aafSDavid du Colombier l = va_arg(fp->args, long);
1331*f8bc6aafSDavid du Colombier n = 0;
1332*f8bc6aafSDavid du Colombier for(h = hist; h != H; h = h->link) {
1333*f8bc6aafSDavid du Colombier if(l < h->line)
1334*f8bc6aafSDavid du Colombier break;
1335*f8bc6aafSDavid du Colombier if(h->name) {
1336*f8bc6aafSDavid du Colombier if(h->offset != 0) { /* #line directive, not #pragma */
1337*f8bc6aafSDavid du Colombier if(n > 0 && n < HISTSZ && h->offset >= 0) {
1338*f8bc6aafSDavid du Colombier a[n-1].line = h;
1339*f8bc6aafSDavid du Colombier a[n-1].ldel = h->line - h->offset + 1;
1340*f8bc6aafSDavid du Colombier }
1341*f8bc6aafSDavid du Colombier } else {
1342*f8bc6aafSDavid du Colombier if(n < HISTSZ) { /* beginning of file */
1343*f8bc6aafSDavid du Colombier a[n].incl = h;
1344*f8bc6aafSDavid du Colombier a[n].idel = h->line;
1345*f8bc6aafSDavid du Colombier a[n].line = 0;
1346*f8bc6aafSDavid du Colombier }
1347*f8bc6aafSDavid du Colombier n++;
1348*f8bc6aafSDavid du Colombier }
1349*f8bc6aafSDavid du Colombier continue;
1350*f8bc6aafSDavid du Colombier }
1351*f8bc6aafSDavid du Colombier n--;
1352*f8bc6aafSDavid du Colombier if(n > 0 && n < HISTSZ) {
1353*f8bc6aafSDavid du Colombier d = h->line - a[n].incl->line;
1354*f8bc6aafSDavid du Colombier a[n-1].ldel += d;
1355*f8bc6aafSDavid du Colombier a[n-1].idel += d;
1356*f8bc6aafSDavid du Colombier }
1357*f8bc6aafSDavid du Colombier }
1358*f8bc6aafSDavid du Colombier if(n > HISTSZ)
1359*f8bc6aafSDavid du Colombier n = HISTSZ;
1360*f8bc6aafSDavid du Colombier str[0] = 0;
1361*f8bc6aafSDavid du Colombier for(i=n-1; i>=0; i--) {
1362*f8bc6aafSDavid du Colombier if(i != n-1) {
1363*f8bc6aafSDavid du Colombier if(fp->flags & ~(FmtWidth|FmtPrec)) /* BUG ROB - was f3 */
1364*f8bc6aafSDavid du Colombier break;
1365*f8bc6aafSDavid du Colombier strcat(str, " ");
1366*f8bc6aafSDavid du Colombier }
1367*f8bc6aafSDavid du Colombier if(a[i].line)
1368*f8bc6aafSDavid du Colombier snprint(s, STRINGSZ, "%s:%ld[%s:%ld]",
1369*f8bc6aafSDavid du Colombier a[i].line->name, l-a[i].ldel+1,
1370*f8bc6aafSDavid du Colombier a[i].incl->name, l-a[i].idel+1);
1371*f8bc6aafSDavid du Colombier else
1372*f8bc6aafSDavid du Colombier snprint(s, STRINGSZ, "%s:%ld",
1373*f8bc6aafSDavid du Colombier a[i].incl->name, l-a[i].idel+1);
1374*f8bc6aafSDavid du Colombier if(strlen(s)+strlen(str) >= STRINGSZ-10)
1375*f8bc6aafSDavid du Colombier break;
1376*f8bc6aafSDavid du Colombier strcat(str, s);
1377*f8bc6aafSDavid du Colombier l = a[i].incl->line - 1; /* now print out start of this file */
1378*f8bc6aafSDavid du Colombier }
1379*f8bc6aafSDavid du Colombier if(n == 0)
1380*f8bc6aafSDavid du Colombier strcat(str, "<eof>");
1381*f8bc6aafSDavid du Colombier return fmtstrcpy(fp, str);
1382*f8bc6aafSDavid du Colombier }
1383*f8bc6aafSDavid du Colombier
1384*f8bc6aafSDavid du Colombier int
Tconv(Fmt * fp)1385*f8bc6aafSDavid du Colombier Tconv(Fmt *fp)
1386*f8bc6aafSDavid du Colombier {
1387*f8bc6aafSDavid du Colombier char str[STRINGSZ+20], s[STRINGSZ+20];
1388*f8bc6aafSDavid du Colombier Type *t, *t1;
1389*f8bc6aafSDavid du Colombier int et;
1390*f8bc6aafSDavid du Colombier long n;
1391*f8bc6aafSDavid du Colombier
1392*f8bc6aafSDavid du Colombier str[0] = 0;
1393*f8bc6aafSDavid du Colombier for(t = va_arg(fp->args, Type*); t != T; t = t->link) {
1394*f8bc6aafSDavid du Colombier et = t->etype;
1395*f8bc6aafSDavid du Colombier if(str[0])
1396*f8bc6aafSDavid du Colombier strcat(str, " ");
1397*f8bc6aafSDavid du Colombier if(t->garb&~GINCOMPLETE) {
1398*f8bc6aafSDavid du Colombier sprint(s, "%s ", gnames[t->garb&~GINCOMPLETE]);
1399*f8bc6aafSDavid du Colombier if(strlen(str) + strlen(s) < STRINGSZ)
1400*f8bc6aafSDavid du Colombier strcat(str, s);
1401*f8bc6aafSDavid du Colombier }
1402*f8bc6aafSDavid du Colombier sprint(s, "%s", tnames[et]);
1403*f8bc6aafSDavid du Colombier if(strlen(str) + strlen(s) < STRINGSZ)
1404*f8bc6aafSDavid du Colombier strcat(str, s);
1405*f8bc6aafSDavid du Colombier if(et == TFUNC && (t1 = t->down)) {
1406*f8bc6aafSDavid du Colombier sprint(s, "(%T", t1);
1407*f8bc6aafSDavid du Colombier if(strlen(str) + strlen(s) < STRINGSZ)
1408*f8bc6aafSDavid du Colombier strcat(str, s);
1409*f8bc6aafSDavid du Colombier while(t1 = t1->down) {
1410*f8bc6aafSDavid du Colombier sprint(s, ", %T", t1);
1411*f8bc6aafSDavid du Colombier if(strlen(str) + strlen(s) < STRINGSZ)
1412*f8bc6aafSDavid du Colombier strcat(str, s);
1413*f8bc6aafSDavid du Colombier }
1414*f8bc6aafSDavid du Colombier if(strlen(str) + strlen(s) < STRINGSZ)
1415*f8bc6aafSDavid du Colombier strcat(str, ")");
1416*f8bc6aafSDavid du Colombier }
1417*f8bc6aafSDavid du Colombier if(et == TARRAY) {
1418*f8bc6aafSDavid du Colombier n = t->width;
1419*f8bc6aafSDavid du Colombier if(t->link && t->link->width)
1420*f8bc6aafSDavid du Colombier n /= t->link->width;
1421*f8bc6aafSDavid du Colombier sprint(s, "[%ld]", n);
1422*f8bc6aafSDavid du Colombier if(strlen(str) + strlen(s) < STRINGSZ)
1423*f8bc6aafSDavid du Colombier strcat(str, s);
1424*f8bc6aafSDavid du Colombier }
1425*f8bc6aafSDavid du Colombier if(t->nbits) {
1426*f8bc6aafSDavid du Colombier sprint(s, " %d:%d", t->shift, t->nbits);
1427*f8bc6aafSDavid du Colombier if(strlen(str) + strlen(s) < STRINGSZ)
1428*f8bc6aafSDavid du Colombier strcat(str, s);
1429*f8bc6aafSDavid du Colombier }
1430*f8bc6aafSDavid du Colombier if(typesu[et]) {
1431*f8bc6aafSDavid du Colombier if(t->tag) {
1432*f8bc6aafSDavid du Colombier strcat(str, " ");
1433*f8bc6aafSDavid du Colombier if(strlen(str) + strlen(t->tag->name) < STRINGSZ)
1434*f8bc6aafSDavid du Colombier strcat(str, t->tag->name);
1435*f8bc6aafSDavid du Colombier } else
1436*f8bc6aafSDavid du Colombier strcat(str, " {}");
1437*f8bc6aafSDavid du Colombier break;
1438*f8bc6aafSDavid du Colombier }
1439*f8bc6aafSDavid du Colombier }
1440*f8bc6aafSDavid du Colombier return fmtstrcpy(fp, str);
1441*f8bc6aafSDavid du Colombier }
1442*f8bc6aafSDavid du Colombier
1443*f8bc6aafSDavid du Colombier int
FNconv(Fmt * fp)1444*f8bc6aafSDavid du Colombier FNconv(Fmt *fp)
1445*f8bc6aafSDavid du Colombier {
1446*f8bc6aafSDavid du Colombier char *str;
1447*f8bc6aafSDavid du Colombier Node *n;
1448*f8bc6aafSDavid du Colombier
1449*f8bc6aafSDavid du Colombier n = va_arg(fp->args, Node*);
1450*f8bc6aafSDavid du Colombier str = "<indirect>";
1451*f8bc6aafSDavid du Colombier if(n != Z && (n->op == ONAME || n->op == ODOT || n->op == OELEM))
1452*f8bc6aafSDavid du Colombier str = n->sym->name;
1453*f8bc6aafSDavid du Colombier return fmtstrcpy(fp, str);
1454*f8bc6aafSDavid du Colombier }
1455*f8bc6aafSDavid du Colombier
1456*f8bc6aafSDavid du Colombier int
Qconv(Fmt * fp)1457*f8bc6aafSDavid du Colombier Qconv(Fmt *fp)
1458*f8bc6aafSDavid du Colombier {
1459*f8bc6aafSDavid du Colombier char str[STRINGSZ+20], *s;
1460*f8bc6aafSDavid du Colombier long b;
1461*f8bc6aafSDavid du Colombier int i;
1462*f8bc6aafSDavid du Colombier
1463*f8bc6aafSDavid du Colombier str[0] = 0;
1464*f8bc6aafSDavid du Colombier for(b = va_arg(fp->args, long); b;) {
1465*f8bc6aafSDavid du Colombier i = bitno(b);
1466*f8bc6aafSDavid du Colombier if(str[0])
1467*f8bc6aafSDavid du Colombier strcat(str, " ");
1468*f8bc6aafSDavid du Colombier s = qnames[i];
1469*f8bc6aafSDavid du Colombier if(strlen(str) + strlen(s) >= STRINGSZ)
1470*f8bc6aafSDavid du Colombier break;
1471*f8bc6aafSDavid du Colombier strcat(str, s);
1472*f8bc6aafSDavid du Colombier b &= ~(1L << i);
1473*f8bc6aafSDavid du Colombier }
1474*f8bc6aafSDavid du Colombier return fmtstrcpy(fp, str);
1475*f8bc6aafSDavid du Colombier }
1476*f8bc6aafSDavid du Colombier
1477*f8bc6aafSDavid du Colombier int
VBconv(Fmt * fp)1478*f8bc6aafSDavid du Colombier VBconv(Fmt *fp)
1479*f8bc6aafSDavid du Colombier {
1480*f8bc6aafSDavid du Colombier char str[STRINGSZ];
1481*f8bc6aafSDavid du Colombier int i, n, t, pc;
1482*f8bc6aafSDavid du Colombier
1483*f8bc6aafSDavid du Colombier n = va_arg(fp->args, int);
1484*f8bc6aafSDavid du Colombier pc = 0; /* BUG: was printcol */
1485*f8bc6aafSDavid du Colombier i = 0;
1486*f8bc6aafSDavid du Colombier while(pc < n) {
1487*f8bc6aafSDavid du Colombier t = (pc+4) & ~3;
1488*f8bc6aafSDavid du Colombier if(t <= n) {
1489*f8bc6aafSDavid du Colombier str[i++] = '\t';
1490*f8bc6aafSDavid du Colombier pc = t;
1491*f8bc6aafSDavid du Colombier continue;
1492*f8bc6aafSDavid du Colombier }
1493*f8bc6aafSDavid du Colombier str[i++] = ' ';
1494*f8bc6aafSDavid du Colombier pc++;
1495*f8bc6aafSDavid du Colombier }
1496*f8bc6aafSDavid du Colombier str[i] = 0;
1497*f8bc6aafSDavid du Colombier
1498*f8bc6aafSDavid du Colombier return fmtstrcpy(fp, str);
1499*f8bc6aafSDavid du Colombier }
1500*f8bc6aafSDavid du Colombier
1501*f8bc6aafSDavid du Colombier /*
1502*f8bc6aafSDavid du Colombier * real allocs
1503*f8bc6aafSDavid du Colombier */
1504*f8bc6aafSDavid du Colombier void*
alloc(long n)1505*f8bc6aafSDavid du Colombier alloc(long n)
1506*f8bc6aafSDavid du Colombier {
1507*f8bc6aafSDavid du Colombier void *p;
1508*f8bc6aafSDavid du Colombier
1509*f8bc6aafSDavid du Colombier while((uintptr)hunk & MAXALIGN) {
1510*f8bc6aafSDavid du Colombier hunk++;
1511*f8bc6aafSDavid du Colombier nhunk--;
1512*f8bc6aafSDavid du Colombier }
1513*f8bc6aafSDavid du Colombier while(nhunk < n)
1514*f8bc6aafSDavid du Colombier gethunk();
1515*f8bc6aafSDavid du Colombier p = hunk;
1516*f8bc6aafSDavid du Colombier nhunk -= n;
1517*f8bc6aafSDavid du Colombier hunk += n;
1518*f8bc6aafSDavid du Colombier return p;
1519*f8bc6aafSDavid du Colombier }
1520*f8bc6aafSDavid du Colombier
1521*f8bc6aafSDavid du Colombier void*
allocn(void * p,long on,long n)1522*f8bc6aafSDavid du Colombier allocn(void *p, long on, long n)
1523*f8bc6aafSDavid du Colombier {
1524*f8bc6aafSDavid du Colombier void *q;
1525*f8bc6aafSDavid du Colombier
1526*f8bc6aafSDavid du Colombier q = (uchar*)p + on;
1527*f8bc6aafSDavid du Colombier if(q != hunk || nhunk < n) {
1528*f8bc6aafSDavid du Colombier while(nhunk < on+n)
1529*f8bc6aafSDavid du Colombier gethunk();
1530*f8bc6aafSDavid du Colombier memmove(hunk, p, on);
1531*f8bc6aafSDavid du Colombier p = hunk;
1532*f8bc6aafSDavid du Colombier hunk += on;
1533*f8bc6aafSDavid du Colombier nhunk -= on;
1534*f8bc6aafSDavid du Colombier }
1535*f8bc6aafSDavid du Colombier hunk += n;
1536*f8bc6aafSDavid du Colombier nhunk -= n;
1537*f8bc6aafSDavid du Colombier return p;
1538*f8bc6aafSDavid du Colombier }
1539*f8bc6aafSDavid du Colombier
1540*f8bc6aafSDavid du Colombier void
setinclude(char * p)1541*f8bc6aafSDavid du Colombier setinclude(char *p)
1542*f8bc6aafSDavid du Colombier {
1543*f8bc6aafSDavid du Colombier int i;
1544*f8bc6aafSDavid du Colombier char *e, **np;
1545*f8bc6aafSDavid du Colombier
1546*f8bc6aafSDavid du Colombier while(*p != 0) {
1547*f8bc6aafSDavid du Colombier e = strchr(p, ' ');
1548*f8bc6aafSDavid du Colombier if(e != 0)
1549*f8bc6aafSDavid du Colombier *e = '\0';
1550*f8bc6aafSDavid du Colombier
1551*f8bc6aafSDavid du Colombier for(i=0; i < ninclude; i++)
1552*f8bc6aafSDavid du Colombier if(strcmp(p, include[i]) == 0)
1553*f8bc6aafSDavid du Colombier break;
1554*f8bc6aafSDavid du Colombier
1555*f8bc6aafSDavid du Colombier if(i >= ninclude){
1556*f8bc6aafSDavid du Colombier if(i >= maxinclude){
1557*f8bc6aafSDavid du Colombier maxinclude += 20;
1558*f8bc6aafSDavid du Colombier np = alloc(maxinclude * sizeof *np);
1559*f8bc6aafSDavid du Colombier if(include != nil)
1560*f8bc6aafSDavid du Colombier memmove(np, include, (maxinclude - 20) * sizeof *np);
1561*f8bc6aafSDavid du Colombier include = np;
1562*f8bc6aafSDavid du Colombier }
1563*f8bc6aafSDavid du Colombier include[ninclude++] = p;
1564*f8bc6aafSDavid du Colombier }
1565*f8bc6aafSDavid du Colombier
1566*f8bc6aafSDavid du Colombier if(e == 0)
1567*f8bc6aafSDavid du Colombier break;
1568*f8bc6aafSDavid du Colombier p = e+1;
1569*f8bc6aafSDavid du Colombier }
1570*f8bc6aafSDavid du Colombier }
1571