Print this page
cpp: don't exit with an error count, or we'll overflow to 0 and 'succeed'
Split |
Close |
Expand all |
Collapse all |
--- old/cpp/cpp.c
+++ new/cpp/cpp.c
1 1 /*
2 2 * C command
3 3 * written by John F. Reiser
4 4 * July/August 1978
5 5 */
6 6 /* Copyright (c) 2012 Joyent, Inc. All rights reserved. */
7 7 /*
8 8 * This implementation is based on the UNIX 32V release from 1978
9 9 * with permission from Caldera Inc.
10 10 *
11 11 * Copyright (c) 2010 J. Schilling
12 12 * All rights reserved.
13 13 *
14 14 * Redistribution and use in source and binary forms, with or without
15 15 * modification, are permitted provided that the following conditions
16 16 * are met:
17 17 * 1. Redistributions of source code must retain the above copyright
18 18 * notice, this list of conditions and the following disclaimer.
19 19 * 2. Redistributions in binary form must reproduce the above copyright
20 20 * notice, this list of conditions and the following disclaimer in the
21 21 * documentation and/or other materials provided with the distribution.
22 22 * 3. Neither the name of the copyright holder nor the names of contributors
23 23 * may be used to endorse or promote products derived from this software
24 24 * without specific prior written permission.
25 25 *
26 26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
27 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
30 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 36 * SUCH DAMAGE.
37 37 */
38 38 /*
39 39 * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
40 40 *
41 41 * Redistribution and use in source and binary forms, with or without
42 42 * modification, are permitted provided that the following conditions are
43 43 * met:
44 44 * 1. Redistributions of source code and documentation must retain the above
45 45 * copyright notice, this list of conditions and the following
46 46 * disclaimer.
47 47 *
48 48 * 2. Redistributions in binary form must reproduce the above copyright
49 49 * notice, this list of conditions and the following disclaimer in the
50 50 * documentation and/or other materials provided with the distribution.
51 51 *
52 52 * 3. All advertising materials mentioning features or use of this software
53 53 * must display the following acknowledgement: This product includes
54 54 * software developed or owned by Caldera International, Inc.
55 55 *
56 56 * 4. Neither the name of Caldera International, Inc. nor the names of other
57 57 * contributors may be used to endorse or promote products derived from
58 58 * this software without specific prior written permission.
59 59 *
60 60 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
61 61 * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
62 62 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63 63 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64 64 * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE FOR
65 65 * ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
66 66 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
67 67 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
68 68 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
69 69 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
70 70 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
71 71 * POSSIBILITY OF SUCH DAMAGE.
72 72 */
73 73 #include <stdio.h>
74 74 #include <unistd.h>
75 75 #include <stdlib.h>
76 76 #include <fcntl.h>
77 77 #include <string.h>
78 78 #include <stdarg.h>
79 79
80 80 #include "cpp.h"
81 81
82 82 #define SYMLEN 128
83 83 static int symlen = SYMLEN;
84 84
85 85
86 86 #define SALT '#'
87 87 #ifndef BUFSIZ
88 88 #define BUFSIZ 512
89 89 #endif
90 90
91 91 static char *pbeg;
92 92 static char *pbuf;
93 93 static char *pend;
94 94 char *outp,*inp;
95 95 char *newp;
96 96 static char cinit;
97 97
98 98 /* some code depends on whether characters are sign or zero extended */
99 99 /* #if '\377' < 0 not used here, old cpp doesn't understand */
100 100 #if pdp11 | vax | '\377' < 0
101 101 #define COFF 128
102 102 #else
103 103 #define COFF 0
104 104 #endif
105 105
106 106 #define ALFSIZ 256 /* alphabet size */
107 107 static char macbit[ALFSIZ+11];
108 108 static char toktyp[ALFSIZ];
109 109 #define BLANK 1 /* white space (" \t\v\f\r") */
110 110 #define IDENT 2 /* valid char for identifier names */
111 111 #define NUMBR 3 /* chars is of "0123456789." */
112 112
113 113 /*
114 114 * a superimposed code is used to reduce the number of calls to the
115 115 * symbol table lookup routine. (if the kth character of an identifier
116 116 * is 'a' and there are no macro names whose kth character is 'a'
117 117 * then the identifier cannot be a macro name, hence there is no need
118 118 * to look in the symbol table.) 'scw1' enables the test based on
119 119 * single characters and their position in the identifier. 'scw2'
120 120 * enables the test based on adjacent pairs of characters and their
121 121 * position in the identifier. scw1 typically costs 1 indexed fetch,
122 122 * an AND, and a jump per character of identifier, until the identifier
123 123 * is known as a non-macro name or until the end of the identifier.
124 124 * scw1 is inexpensive. scw2 typically costs 4 indexed fetches,
125 125 * an add, an AND, and a jump per character of identifier, but it is also
126 126 * slightly more effective at reducing symbol table searches.
127 127 * scw2 usually costs too much because the symbol table search is
128 128 * usually short; but if symbol table search should become expensive,
129 129 * the code is here.
130 130 * using both scw1 and scw2 is of dubious value.
131 131 */
132 132 #define scw1 1
133 133 #define scw2 0
134 134
135 135 #if scw2
136 136 char t21[ALFSIZ],t22[ALFSIZ],t23[ALFSIZ+SYMLEN];
137 137 #endif
138 138
139 139 #if scw1
140 140 #define b0 1
141 141 #define b1 2
142 142 #define b2 4
143 143 #define b3 8
144 144 #define b4 16
145 145 #define b5 32
146 146 #define b6 64
147 147 #define b7 128
148 148 #endif
149 149
150 150 #define IB 1
151 151 #define SB 2
152 152 #define NB 4
153 153 #define CB 8
154 154 #define QB 16
155 155 #define WB 32
156 156 char fastab[ALFSIZ];
157 157 static char slotab[ALFSIZ];
158 158 static char *ptrtab;
159 159
160 160 /*
161 161 * Cast the array index to int in order to avoid GCCs warnings:
162 162 * warning: subscript has type `char'
163 163 */
164 164 #define isslo (ptrtab==(slotab+COFF))
165 165 #define isid(a) ((fastab+COFF)[(int)a]&IB)
166 166 #define isspc(a) (ptrtab[(int)a]&SB)
167 167 #define isnum(a) ((fastab+COFF)[(int)a]&NB)
168 168 #define iscom(a) ((fastab+COFF)[(int)a]&CB)
169 169 #define isquo(a) ((fastab+COFF)[(int)a]&QB)
170 170 #define iswarn(a) ((fastab+COFF)[(int)a]&WB)
171 171
172 172 #define eob(a) ((a)>=pend)
173 173 #define bob(a) (pbeg>=(a))
174 174
175 175 #define BUFFERSIZ 8192
176 176 static char buffer[SYMLEN+BUFFERSIZ+BUFFERSIZ+SYMLEN];
177 177
178 178 /*
179 179 * SBSIZE was 12000 in 1978, we need to have a way to
180 180 * malloc more space.
181 181 */
182 182 #define SBSIZE 512000
183 183 static char sbf[SBSIZE];
184 184 static char *savch = sbf;
185 185
186 186 # define DROP 0xFE /* special character not legal ASCII or EBCDIC */
187 187 # define WARN DROP
188 188 # define SAME 0
189 189 # define MAXINC 16 /* max include nesting depth */
190 190 # define MAXIDIRS 20 /* max # of -I directories */
191 191 # define MAXFRE 14 /* max buffers of macro pushback */
192 192 # define MAXFRM 31 /* max number of formals/actuals to a macro */
193 193
194 194 static char warnc = (char)WARN;
195 195
196 196 static int mactop;
197 197 static int fretop;
198 198 static char *instack[MAXFRE];
199 199 static char *bufstack[MAXFRE];
200 200 static char *endbuf[MAXFRE];
201 201
202 202 static int plvl; /* parenthesis level during scan for macro actuals */
203 203 static int maclin; /* line number of macro call requiring actuals */
204 204 static char *macfil; /* file name of macro call requiring actuals */
205 205 static char *macnam; /* name of macro requiring actuals */
206 206 static int maclvl; /* # calls since last decrease in nesting level */
207 207 static char *macforw; /* ptr which must be exceeded to decrease nesting lvl */
208 208 static int macdam; /* offset to macforw due to buffer shifting */
209 209
210 210 static int inctop[MAXINC];
211 211 static char *fnames[MAXINC];
212 212 static char *dirnams[MAXINC]; /* actual directory of #include files */
213 213 static int fins[MAXINC];
214 214 static int lineno[MAXINC];
215 215
216 216 /*
217 217 * We need:
218 218 * "" include dir as dirs[0] +
219 219 * MAXIDIRS +
220 220 * system default include dir +
221 221 * a NULL pointer at the end
222 222 */
223 223 static char *dirs[MAXIDIRS+3]; /* -I and <> directories */
224 224 static int fin = STDIN_FILENO;
225 225 static FILE *fout; /* Init in main(), Mac OS is nonPOSIX */
226 226 static int nd = 1;
227 227 static int pflag; /* don't put out lines "# 12 foo.c" */
228 228 static int passcom; /* don't delete comments */
229 229 static int rflag; /* allow macro recursion */
230 230 static int hflag; /* Print included filenames */
231 231 static int nopredef; /* -undef all */
232 232 static int ifno;
233 233 # define NPREDEF 64
234 234 static char *prespc[NPREDEF];
235 235 static char **predef = prespc;
236 236 static char *punspc[NPREDEF];
237 237 static char **prund = punspc;
238 238 static int exfail;
239 239 static struct symtab *lastsym;
240 240
241 241
242 242 static void sayline(char *);
243 243 static void dump(void);
244 244 static char *refill(char *);
245 245 static char *cotoken(char *);
246 246 char *skipbl(char *);
247 247 static char *unfill(char *);
248 248 static char *doincl(char *);
249 249 static int equfrm(char *, char *, char *);
250 250 static char *dodef(char *);
251 251 static char *control(char *);
252 252 static struct symtab *stsym(char *);
253 253 static struct symtab *ppsym(char *);
254 254 void pperror(char *fmt, ...);
255 255 void yyerror(char *fmt, ...);
256 256 static void ppwarn(char *fmt, ...);
257 257 struct symtab *lookup(char *, int);
258 258 static struct symtab *slookup(char *, char *, int);
259 259 static char *subst(char *, struct symtab *);
260 260 static char *trmdir(char *);
261 261 static char *copy(char *);
262 262 static char *strdex(char *, int);
263 263 int yywrap(void);
264 264 int main(int argc, char **argav);
265 265
266 266
267 267 #define symsiz 4000
268 268 static struct symtab stab[symsiz];
269 269
270 270 static struct symtab *defloc;
271 271 static struct symtab *udfloc;
272 272 static struct symtab *incloc;
273 273 static struct symtab *ifloc;
274 274 static struct symtab *elsloc;
275 275 static struct symtab *eifloc;
276 276 static struct symtab *elifloc;
277 277 static struct symtab *ifdloc;
278 278 static struct symtab *ifnloc;
279 279 static struct symtab *ysysloc;
280 280 static struct symtab *varloc;
281 281 static struct symtab *lneloc;
282 282 static struct symtab *ulnloc;
283 283 static struct symtab *uflloc;
284 284 static struct symtab *idtloc;
285 285 static struct symtab *pragmaloc;
286 286 static struct symtab *errorloc;
287 287 static int trulvl;
288 288 int flslvl;
289 289 static int elflvl;
290 290 static int elslvl;
291 291
292 292 /*
293 293 * The sun cpp prints a classification token past the
294 294 * "# linenumber filename" lines:
295 295 */
296 296 #define NOINCLUDE "" /* Not related to enter/leave incl. file */
297 297 #define ENTERINCLUDE "1" /* We are just entering an include file */
298 298 #define LEAVEINCLUDE "2" /* We are just leaving an include file */
299 299
300 300 /* ARGSUSED */
301 301 static void
302 302 sayline(what)
303 303 char *what;
304 304 {
305 305 if (pflag==0)
306 306 fprintf(fout,"# %d \"%s\" %s\n", lineno[ifno], fnames[ifno], what);
307 307 }
308 308
309 309 /*
310 310 * data structure guide
311 311 *
312 312 * most of the scanning takes place in the buffer:
313 313 *
314 314 * (low address) (high address)
315 315 * pbeg pbuf pend
316 316 * | <-- BUFFERSIZ chars --> | <-- BUFFERSIZ chars --> |
317 317 * _______________________________________________________________________
318 318 * |_______________________________________________________________________|
319 319 * | | |
320 320 * |<-- waiting -->| |<-- waiting -->
321 321 * | to be |<-- current -->| to be
322 322 * | written | token | scanned
323 323 * | | |
324 324 * outp inp p
325 325 *
326 326 * *outp first char not yet written to output file
327 327 * *inp first char of current token
328 328 * *p first char not yet scanned
329 329 *
330 330 * macro expansion: write from *outp to *inp (chars waiting to be written),
331 331 * ignore from *inp to *p (chars of the macro call), place generated
332 332 * characters in front of *p (in reverse order), update pointers,
333 333 * resume scanning.
334 334 *
335 335 * symbol table pointers point to just beyond the end of macro definitions;
336 336 * the first preceding character is the number of formal parameters.
337 337 * the appearance of a formal in the body of a definition is marked by
338 338 * 2 chars: the char WARN, and a char containing the parameter number.
339 339 * the first char of a definition is preceded by a zero character.
340 340 *
341 341 * when macro expansion attempts to back up over the beginning of the
342 342 * buffer, some characters preceding *pend are saved in a side buffer,
343 343 * the address of the side buffer is put on 'instack', and the rest
344 344 * of the main buffer is moved to the right. the end of the saved buffer
345 345 * is kept in 'endbuf' since there may be nulls in the saved buffer.
346 346 *
347 347 * similar action is taken when an 'include' statement is processed,
348 348 * except that the main buffer must be completely emptied. the array
349 349 * element 'inctop[ifno]' records the last side buffer saved when
350 350 * file 'ifno' was included. these buffers remain dormant while
351 351 * the file is being read, and are reactivated at end-of-file.
352 352 *
353 353 * instack[0 : mactop] holds the addresses of all pending side buffers.
354 354 * instack[inctop[ifno]+1 : mactop-1] holds the addresses of the side
355 355 * buffers which are "live"; the side buffers instack[0 : inctop[ifno]]
356 356 * are dormant, waiting for end-of-file on the current file.
357 357 *
358 358 * space for side buffers is obtained from 'savch' and is never returned.
359 359 * bufstack[0:fretop-1] holds addresses of side buffers which
360 360 * are available for use.
361 361 */
362 362
363 363 static void
364 364 dump() {
365 365 register char *p1;
366 366 if ((p1=outp)==inp || flslvl!=0) return;
367 367 fwrite(p1, inp - p1, 1, fout);
368 368 outp=p1;
369 369 }
370 370
371 371 static char *
372 372 refill(p) register char *p; {
373 373 /*
374 374 * dump buffer. save chars from inp to p. read into buffer at pbuf,
375 375 * contiguous with p. update pointers, return new p.
376 376 */
377 377 register char *np,*op; register int ninbuf;
378 378 dump(); np=pbuf-(p-inp); op=inp;
379 379 if (bob(np+1)) {pperror("token too long"); np=pbeg; p=inp+BUFFERSIZ;}
380 380 macdam += np-inp; outp=inp=np;
381 381 while (op<p) *np++= *op++;
382 382 p=np;
383 383 for (;;) {
384 384 if (mactop>inctop[ifno]) {
385 385 /* retrieve hunk of pushed-back macro text */
386 386 op=instack[--mactop]; np=pbuf;
387 387 do {
388 388 while ((*np++= *op++) != '\0');
389 389 } while (op<endbuf[mactop]); pend=np-1;
390 390 /* make buffer space avail for 'include' processing */
391 391 if (fretop<MAXFRE) bufstack[fretop++]=instack[mactop];
392 392 return(p);
393 393 } else {/* get more text from file(s) */
394 394 maclvl=0;
395 395 if (0<(ninbuf=read(fin,pbuf,BUFFERSIZ))) {
396 396 pend=pbuf+ninbuf; *pend='\0';
397 397 return(p);
398 398 }
399 399 /* end of #include file */
400 400 if (ifno==0) {/* end of input */
401 401 if (plvl!=0) {
402 402 int n=plvl,tlin=lineno[ifno];
403 403 char *tfil=fnames[ifno];
404 404 lineno[ifno]=maclin;
405 405 fnames[ifno]=macfil;
406 406 pperror("%s: unterminated macro call",
407 407 macnam);
408 408 lineno[ifno]=tlin; fnames[ifno]=tfil;
409 409 np=p;
410 410 /*
411 411 * shut off unterminated quoted string
412 412 */
413 413 *np++='\n';
414 414 /* supply missing parens */
415 415 while (--n>=0) *np++=')';
416 416 pend=np; *np='\0';
417 417 if (plvl<0) plvl=0;
418 418 return(p);
419 419 }
420 420 inp=p; dump(); exit(exfail);
421 421 }
422 422 close(fin);
423 423 fin=fins[--ifno];
424 424 dirs[0]=dirnams[ifno];
425 425 sayline(LEAVEINCLUDE);
426 426 }
427 427 }
428 428 }
429 429
430 430 #define BEG 0
431 431 #define LF 1
432 432
433 433 static char *
434 434 cotoken(p) register char *p; {
435 435 register int c,i; char quoc;
436 436 static int state = BEG;
437 437
438 438 if (state!=BEG) goto prevlf;
439 439 for (;;) {
440 440 again:
441 441 while (!isspc(*p++));
442 442 switch (*(inp=p-1)) {
443 443 case 0: {
444 444 if (eob(--p)) {p=refill(p); goto again;}
445 445 else ++p; /* ignore null byte */
446 446 } break;
447 447 case '|': case '&': for (;;) {/* sloscan only */
448 448 if (*p++== *inp) break;
449 449 if (eob(--p)) p=refill(p);
450 450 else break;
451 451 } break;
452 452 case '=': case '!': for (;;) {/* sloscan only */
453 453 if (*p++=='=') break;
454 454 if (eob(--p)) p=refill(p);
455 455 else break;
456 456 } break;
457 457 case '<': case '>': for (;;) {/* sloscan only */
458 458 if (*p++=='=' || p[-2]==p[-1]) break;
459 459 if (eob(--p)) p=refill(p);
460 460 else break;
461 461 } break;
462 462 case '\\': for (;;) {
463 463 if (*p++=='\n') {++lineno[ifno]; break;}
464 464 if (eob(--p)) p=refill(p);
465 465 else {++p; break;}
466 466 } break;
467 467 case '/': for (;;) {
468 468 if (*p++=='*') {/* comment */
469 469 if (!passcom) {inp=p-2; dump(); ++flslvl;}
470 470 for (;;) {
471 471 while (!iscom(*p++));
472 472 if (p[-1]=='*') for (;;) {
473 473 if (*p++=='/') goto endcom;
474 474 if (eob(--p)) {
475 475 if (!passcom) {
476 476 inp=p;
477 477 p=refill(p);
478 478 } else if ((p-inp)>=BUFFERSIZ) {
479 479 /* split long comment */
480 480 inp=p;
481 481 /*
482 482 * last char written
483 483 * is '*'
484 484 */
485 485 p=refill(p);
486 486 /*
487 487 * terminate first part
488 488 */
489 489 putc('/',fout);
490 490 /*
491 491 * and fake start of 2nd
492 492 */
493 493 outp=inp=p-=3;
494 494 *p++='/';
495 495 *p++='*';
496 496 *p++='*';
497 497 } else {
498 498 p=refill(p);
499 499 }
500 500 } else {
501 501 break;
502 502 }
503 503 } else if (p[-1]=='\n') {
504 504 ++lineno[ifno];
505 505 if (!passcom)
506 506 putc('\n',fout);
507 507 } else if (eob(--p)) {
508 508 if (!passcom) {
509 509 inp=p; p=refill(p);
510 510 } else if ((p-inp)>=BUFFERSIZ) {
511 511 /* split long comment */
512 512 inp=p; p=refill(p);
513 513 putc('*',fout); putc('/',fout);
514 514 outp=inp=p-=2;
515 515 *p++='/';
516 516 *p++='*';
517 517 } else {
518 518 p=refill(p);
519 519 }
520 520 } else {
521 521 ++p; /* ignore null byte */
522 522 }
523 523 }
524 524 endcom:
525 525 if (!passcom) {outp=inp=p; --flslvl; goto again;}
526 526 break;
527 527 }
528 528 if (eob(--p)) p=refill(p);
529 529 else break;
530 530 } break;
531 531 case '"': case '\'': {
532 532 quoc=p[-1];
533 533 for (;;) {
534 534 while (!isquo(*p++));
535 535 if (p[-1]==quoc)
536 536 break;
537 537 if (p[-1]=='\n') {
538 538 --p;
539 539 break;
540 540 } /* bare \n terminates quotation */
541 541 if (p[-1]=='\\') {
542 542 for (;;) {
543 543 if (*p++=='\n') {
544 544 ++lineno[ifno];
545 545 break;
546 546 } /* escaped \n ignored */
547 547 if (eob(--p)) {
548 548 p=refill(p);
549 549 } else {
550 550 ++p;
551 551 break;
552 552 }
553 553 }
554 554 } else if (eob(--p)) {
555 555 p=refill(p);
556 556 } else {
557 557 ++p; /* it was a different quote character */
558 558 }
559 559 }
560 560 } break;
561 561 case '\n': {
562 562 ++lineno[ifno]; if (isslo) {state=LF; return(p);}
563 563 prevlf:
564 564 state=BEG;
565 565 for (;;) {
566 566 if (*p++=='#') return(p);
567 567 if (eob(inp= --p)) p=refill(p);
568 568 else goto again;
569 569 }
570 570 }
571 571 /* NOTREACHED */
572 572 case '0': case '1': case '2': case '3': case '4':
573 573 case '5': case '6': case '7': case '8': case '9':
574 574 for (;;) {
575 575 while (isnum(*p++));
576 576 if (eob(--p)) p=refill(p);
577 577 else break;
578 578 } break;
579 579 case 'A': case 'B': case 'C': case 'D': case 'E':
580 580 case 'F': case 'G': case 'H': case 'I': case 'J':
581 581 case 'K': case 'L': case 'M': case 'N': case 'O':
582 582 case 'P': case 'Q': case 'R': case 'S': case 'T':
583 583 case 'U': case 'V': case 'W': case 'X': case 'Y':
584 584 case 'Z': case '_':
585 585 case 'a': case 'b': case 'c': case 'd': case 'e':
586 586 case 'f': case 'g': case 'h': case 'i': case 'j':
587 587 case 'k': case 'l': case 'm': case 'n': case 'o':
588 588 case 'p': case 'q': case 'r': case 's': case 't':
589 589 case 'u': case 'v': case 'w': case 'x': case 'y':
590 590 case 'z':
591 591 #if scw1
592 592 #define tmac1(c,bit) if (!xmac1(c,bit,&)) goto nomac
593 593 #define xmac1(c,bit,op) ((macbit+COFF)[c] op (bit))
594 594 #else
595 595 #define tmac1(c,bit)
596 596 #define xmac1(c,bit,op)
597 597 #endif
598 598
599 599 #if scw2
600 600 #define tmac2(c0,c1,cpos) if (!xmac2(c0,c1,cpos,&)) goto nomac
601 601 #define xmac2(c0,c1,cpos,op)\
602 602 ((macbit+COFF)[(t21+COFF)[c0]+(t22+COFF)[c1]] op (t23+COFF+cpos)[c0])
603 603 #else
604 604 #define tmac2(c0,c1,cpos)
605 605 #define xmac2(c0,c1,cpos,op)
606 606 #endif
607 607
608 608 if (flslvl) goto nomac;
609 609 for (;;) {
610 610 c= p[-1]; tmac1(c,b0);
611 611 i= *p++; if (!isid(i)) goto endid; tmac1(i,b1); tmac2(c,i,0);
612 612 c= *p++; if (!isid(c)) goto endid; tmac1(c,b2); tmac2(i,c,1);
613 613 i= *p++; if (!isid(i)) goto endid; tmac1(i,b3); tmac2(c,i,2);
614 614 c= *p++; if (!isid(c)) goto endid; tmac1(c,b4); tmac2(i,c,3);
615 615 i= *p++; if (!isid(i)) goto endid; tmac1(i,b5); tmac2(c,i,4);
616 616 c= *p++; if (!isid(c)) goto endid; tmac1(c,b6); tmac2(i,c,5);
617 617 i= *p++; if (!isid(i)) goto endid; tmac1(i,b7); tmac2(c,i,6);
618 618 tmac2(i,0,7);
619 619 while (isid(*p++));
620 620 if (eob(--p)) {refill(p); p=inp+1; continue;}
621 621 goto lokid;
622 622 endid:
623 623 if (eob(--p)) {refill(p); p=inp+1; continue;}
624 624 tmac2(p[-1],0,-1+(p-inp));
625 625 lokid:
626 626 slookup(inp,p,0); if (newp) {p=newp; goto again;}
627 627 else break;
628 628 nomac:
629 629 while (isid(*p++));
630 630 if (eob(--p)) {p=refill(p); goto nomac;}
631 631 else break;
632 632 } break;
633 633 } /* end of switch */
634 634
635 635 if (isslo) return(p);
636 636 } /* end of infinite loop */
637 637 }
638 638
639 639 char *
640 640 skipbl(p) register char *p; {/* get next non-blank token */
641 641 do {
642 642 outp=inp=p;
643 643 p=cotoken(p);
644 644 } while ((toktyp+COFF)[(int)*inp]==BLANK);
645 645 return(p);
646 646 }
647 647
648 648 static char *
649 649 unfill(p) register char *p; {
650 650 /*
651 651 * take <= BUFFERSIZ chars from right end of buffer and put them on instack .
652 652 * slide rest of buffer to the right, update pointers, return new p.
653 653 */
654 654 register char *np,*op; register int d;
655 655 if (mactop>=MAXFRE) {
656 656 pperror("%s: too much pushback",macnam);
657 657 p=inp=pend; dump(); /* begin flushing pushback */
658 658 while (mactop>inctop[ifno]) {p=refill(p); p=inp=pend; dump();}
659 659 }
660 660 if (fretop>0)
661 661 np=bufstack[--fretop];
662 662 else {
663 663 np=savch; savch+=BUFFERSIZ;
664 664 if (savch>=sbf+SBSIZE) {pperror("no space"); exit(exfail);}
665 665 *savch++='\0';
666 666 }
667 667 instack[mactop]=np; op=pend-BUFFERSIZ; if (op<p) op=p;
668 668 for (;;) {
669 669 while ((*np++= *op++) != '\0');
670 670 if (eob(op))
671 671 break;
672 672 } /* out with old */
673 673 endbuf[mactop++]=np; /* mark end of saved text */
674 674 np=pbuf+BUFFERSIZ;
675 675 op=pend-BUFFERSIZ;
676 676 pend=np;
677 677 if (op<p)
678 678 op=p;
679 679 while (outp<op) *--np= *--op; /* slide over new */
680 680 if (bob(np))
681 681 pperror("token too long");
682 682 d=np-outp; outp+=d; inp+=d; macdam+=d;
683 683 return(p+d);
684 684 }
685 685
686 686 static char *
687 687 doincl(p) register char *p; {
688 688 int filok,inctype;
689 689 register char *cp; char **dirp,*nfil; char filname[BUFFERSIZ];
690 690
691 691 filname[0] = '\0'; /* Make lint quiet */
692 692 p=skipbl(p); cp=filname;
693 693 if (*inp++=='<') {/* special <> syntax */
694 694 inctype=1;
695 695 for (;;) {
696 696 outp=inp=p; p=cotoken(p);
697 697 if (*inp=='\n') {--p; *cp='\0'; break;}
698 698 if (*inp=='>') { *cp='\0'; break;}
699 699 # ifdef gimpel
700 700 if (*inp=='.' && !intss()) *inp='#';
701 701 # endif
702 702 while (inp<p) *cp++= *inp++;
703 703 }
704 704 } else if (inp[-1]=='"') {/* regular "" syntax */
705 705 inctype=0;
706 706 # ifdef gimpel
707 707 while (inp<p) {if (*inp=='.' && !intss()) *inp='#'; *cp++= *inp++;}
708 708 # else
709 709 while (inp<p) *cp++= *inp++;
710 710 # endif
711 711 if (*--cp=='"') *cp='\0';
712 712 } else {pperror("bad include syntax",0); inctype=2;}
713 713 /* flush current file to \n , then write \n */
714 714 ++flslvl; do {outp=inp=p; p=cotoken(p);} while (*inp!='\n'); --flslvl;
715 715 inp=p; dump(); if (inctype==2) return(p);
716 716 /* look for included file */
717 717 if (ifno+1 >=MAXINC) {
718 718 pperror("Unreasonable include nesting",0); return(p);
719 719 }
720 720 if ((nfil=savch)>sbf+SBSIZE-BUFFERSIZ) {
721 721 pperror("no space");
722 722 exit(exfail);
723 723 }
724 724 filok=0;
725 725 for (dirp=dirs+inctype; *dirp; ++dirp) {
726 726 if (filname[0]=='/' || **dirp=='\0') {
727 727 strcpy(nfil,filname);
728 728 } else {
729 729 strcpy(nfil,*dirp);
730 730 # if unix
731 731 strcat(nfil,"/");
732 732 # endif
733 733 strcat(nfil,filname);
734 734 }
735 735 if (0<(fins[ifno+1]=open(nfil, O_RDONLY))) {
736 736 filok=1; fin=fins[++ifno]; break;
737 737 }
738 738 }
739 739 if (filok==0) {
740 740 pperror("Can't find include file %s",filname);
741 741 } else {
742 742 lineno[ifno]=1; fnames[ifno]=cp=nfil; while (*cp++); savch=cp;
743 743 dirnams[ifno]=dirs[0]=trmdir(copy(nfil));
744 744 sayline(ENTERINCLUDE);
745 745 if (hflag)
746 746 fprintf(stderr, "%s\n", nfil);
747 747 /* save current contents of buffer */
748 748 while (!eob(p)) p=unfill(p);
749 749 inctop[ifno]=mactop;
750 750 }
751 751 return(p);
752 752 }
753 753
754 754 static int
755 755 equfrm(a,p1,p2) register char *a,*p1,*p2; {
756 756 register char c; int flag;
757 757 c= *p2; *p2='\0';
758 758 flag=strcmp(a,p1); *p2=c; return(flag==SAME);
759 759 }
760 760
761 761 static char *
762 762 dodef(p) char *p; {/* process '#define' */
763 763 register char *pin,*psav,*cf;
764 764 char **pf,**qf; int b,c,params; struct symtab *np;
765 765 char *oldval,*oldsavch;
766 766 char *formal[MAXFRM]; /* formal[n] is name of nth formal */
767 767 char formtxt[BUFFERSIZ]; /* space for formal names */
768 768
769 769 formtxt[0] = '\0'; /* Make lint quiet */
770 770
771 771 if (savch>sbf+SBSIZE-BUFFERSIZ) {
772 772 pperror("too much defining");
773 773 return(p);
774 774 }
775 775 oldsavch=savch; /* to reclaim space if redefinition */
776 776 ++flslvl; /* prevent macro expansion during 'define' */
777 777 p=skipbl(p); pin=inp;
778 778 if ((toktyp+COFF)[(int)*pin]!=IDENT) {
779 779 ppwarn("illegal macro name");
780 780 while (*inp!='\n')
781 781 p=skipbl(p);
782 782 return(p);
783 783 }
784 784 np=slookup(pin,p,1);
785 785 if (getenv("CPP_DEBUG_DEFINITIONS") != NULL)
786 786 fprintf(stderr, "*** defining %s at %s:%d\n",
787 787 np->name, fnames[ifno], lineno[ifno]);
788 788 if ((oldval=np->value) != NULL)
789 789 savch=oldsavch; /* was previously defined */
790 790 b=1; cf=pin;
791 791 while (cf<p) {/* update macbit */
792 792 c= *cf++; xmac1(c,b,|=); b=(b+b)&0xFF;
793 793 if (cf!=p) {
794 794 xmac2(c,*cf,-1+(cf-pin),|=);
795 795 } else {
796 796 xmac2(c,0,-1+(cf-pin),|=);
797 797 }
798 798 }
799 799 params=0; outp=inp=p; p=cotoken(p); pin=inp;
800 800 formal[0] = ""; /* Prepare for hack at next line... */
801 801 pf = formal; /* Make gcc/lint quiet, pf only used with params!=0 */
802 802 if (*pin=='(') {/* with parameters; identify the formals */
803 803 cf=formtxt; pf=formal;
804 804 for (;;) {
805 805 p=skipbl(p); pin=inp;
806 806 if (*pin=='\n') {
807 807 --lineno[ifno];
808 808 --p;
809 809 pperror("%s: missing )",np->name);
810 810 break;
811 811 }
812 812 if (*pin==')') break;
813 813 if (*pin==',') continue;
814 814 if ((toktyp+COFF)[(int)*pin]!=IDENT) {
815 815 c= *p;
816 816 *p='\0';
817 817 pperror("bad formal: %s",pin);
818 818 *p=c;
819 819 } else if (pf>= &formal[MAXFRM]) {
820 820 c= *p;
821 821 *p='\0';
822 822 pperror("too many formals: %s",pin);
823 823 *p=c;
824 824 } else {
825 825 *pf++=cf;
826 826 while (pin<p)
827 827 *cf++= *pin++;
828 828 *cf++='\0';
829 829 ++params;
830 830 }
831 831 }
832 832 if (params==0)
833 833 --params; /* #define foo() ... */
834 834 } else if (*pin=='\n') {
835 835 --lineno[ifno];
836 836 --p;
837 837 }
838 838 /*
839 839 * remember beginning of macro body, so that we can
840 840 * warn if a redefinition is different from old value.
841 841 */
842 842 oldsavch=psav=savch;
843 843 for (;;) {/* accumulate definition until linefeed */
844 844 outp=inp=p; p=cotoken(p); pin=inp;
845 845 if (*pin=='\\' && pin[1]=='\n')
846 846 continue; /* ignore escaped lf */
847 847 if (*pin=='\n') break;
848 848 if (params) {
849 849 /* mark the appearance of formals in the definiton */
850 850 if ((toktyp+COFF)[(int)*pin]==IDENT) {
851 851 for (qf=pf; --qf>=formal; ) {
852 852 if (equfrm(*qf,pin,p)) {
853 853 *psav++=qf-formal+1;
854 854 *psav++=WARN;
855 855 pin=p;
856 856 break;
857 857 }
858 858 }
859 859 } else if (*pin=='"' || *pin=='\'') {
860 860 /* inside quotation marks, too */
861 861 char quoc= *pin;
862 862 for (*psav++= *pin++; pin<p && *pin!=quoc; ) {
863 863 while (pin<p && !isid(*pin))
864 864 *psav++= *pin++;
865 865 cf=pin;
866 866 while (cf<p && isid(*cf))
867 867 ++cf;
868 868 for (qf=pf; --qf>=formal; ) {
869 869 if (equfrm(*qf,pin,cf)) {
870 870 *psav++=qf-formal+1;
871 871 *psav++=WARN;
872 872 pin=cf;
873 873 break;
874 874 }
875 875 }
876 876 while (pin<cf)
877 877 *psav++= *pin++;
878 878 }
879 879 }
880 880 }
881 881 while (pin<p) *psav++= *pin++;
882 882 }
883 883 *psav++=params; *psav++='\0';
884 884 if ((cf=oldval)!=NULL) {/* redefinition */
885 885 --cf; /* skip no. of params, which may be zero */
886 886 while (*--cf); /* go back to the beginning */
887 887 if (0!=strcmp(++cf,oldsavch)) {
888 888 /* redefinition different from old */
889 889 --lineno[ifno];
890 890 ppwarn("%s redefined",np->name);
891 891 ++lineno[ifno];
892 892 np->value=psav-1;
893 893 } else {
894 894 psav=oldsavch; /* identical redef.; reclaim space */
895 895 }
896 896 } else {
897 897 np->value=psav-1;
898 898 }
899 899 --flslvl; inp=pin; savch=psav; return(p);
900 900 }
901 901
902 902 #define fasscan() ptrtab=fastab+COFF
903 903 #define sloscan() ptrtab=slotab+COFF
904 904
905 905 static char *
906 906 control(p) register char *p; {/* find and handle preprocessor control lines */
907 907 register struct symtab *np;
908 908 for (;;) {
909 909 fasscan(); p=cotoken(p); if (*inp=='\n') ++inp; dump();
910 910 sloscan(); p=skipbl(p);
911 911 *--inp=SALT; outp=inp; ++flslvl; np=slookup(inp,p,0); --flslvl;
912 912 if (np==defloc) {/* define */
913 913 if (flslvl==0) {p=dodef(p); continue;}
914 914 } else if (np==incloc) {/* include */
915 915 if (flslvl==0) {p=doincl(p); continue;}
916 916 } else if (np==ifnloc) {/* ifndef */
917 917 ++flslvl; p=skipbl(p); np=slookup(inp,p,0); --flslvl;
918 918 if (flslvl==0 && np->value==0) ++trulvl;
919 919 else ++flslvl;
920 920 } else if (np==ifdloc) {/* ifdef */
921 921 ++flslvl; p=skipbl(p); np=slookup(inp,p,0); --flslvl;
922 922 if (flslvl==0 && np->value!=0) ++trulvl;
923 923 else ++flslvl;
924 924 } else if (np==eifloc) {/* endif */
925 925 if (flslvl) {if (--flslvl==0) sayline(NOINCLUDE);}
926 926 else if (trulvl) --trulvl;
927 927 else pperror("If-less endif",0);
928 928
929 929 if (flslvl == 0)
930 930 elflvl = 0;
931 931 elslvl = 0;
932 932 } else if (np==elifloc) {/* elif */
933 933 if (flslvl == 0)
934 934 elflvl = trulvl;
935 935 if (flslvl) {
936 936 if (elflvl > trulvl) {
937 937 ;
938 938 } else if (--flslvl != 0) {
939 939 ++flslvl;
940 940 } else {
941 941 newp = p;
942 942 if (yyparse()) {
943 943 ++trulvl;
944 944 sayline(NOINCLUDE);
945 945 } else {
946 946 ++flslvl;
947 947 }
948 948 p = newp;
949 949 }
950 950 } else if (trulvl) {
951 951 ++flslvl;
952 952 --trulvl;
953 953 } else
954 954 pperror("If-less elif");
955 955
956 956 } else if (np==elsloc) {/* else */
957 957 if (flslvl) {
958 958 if (elflvl > trulvl)
959 959 ;
960 960 else if (--flslvl!=0) ++flslvl;
961 961 else {++trulvl; sayline(NOINCLUDE);}
962 962 }
963 963 else if (trulvl) {++flslvl; --trulvl;}
964 964 else pperror("If-less else",0);
965 965
966 966 if (elslvl==trulvl+flslvl)
967 967 pperror("Too many #else's");
968 968 elslvl=trulvl+flslvl;
969 969
970 970 } else if (np==udfloc) {/* undefine */
971 971 if (flslvl==0) {
972 972 ++flslvl; p=skipbl(p); slookup(inp,p,DROP); --flslvl;
973 973 }
974 974 } else if (np==ifloc) {/* if */
975 975 newp=p;
976 976 if (flslvl==0 && yyparse()) ++trulvl; else ++flslvl;
977 977 p=newp;
978 978 } else if (np == idtloc) { /* ident */
979 979 if (pflag == 0)
980 980 while (*inp != '\n') /* pass text */
981 981 p = cotoken(p);
982 982 } else if (np == pragmaloc) { /* pragma */
983 983 while (*inp != '\n') /* pass text */
984 984 p = cotoken(p);
985 985 #ifdef EXIT_ON_ERROR
986 986 } else if (np == errorloc) { /* error */
987 987 if (trulvl > 0) {
988 988 char ebuf[BUFFERSIZ];
989 989
990 990 p = ebuf;
991 991 while (*inp != '\n') {
992 992 if (*inp == '\0')
993 993 if (eob(--inp)) {
994 994 inp = refill(inp);
995 995 continue;
996 996 }
997 997 *p++ = *inp++;
998 998 if (p >= &ebuf[BUFFERSIZ-1])
999 999 break;
1000 1000 }
1001 1001 *p = '\0';
1002 1002 pperror(ebuf);
1003 1003 exit(exfail);
1004 1004 }
1005 1005 #endif
1006 1006 } else if (np==lneloc) {/* line */
1007 1007 if (flslvl==0 && pflag==0) {
1008 1008 outp=inp=p;
1009 1009 *--outp='#';
1010 1010 while (*inp!='\n')
1011 1011 p=cotoken(p);
1012 1012 continue;
1013 1013 }
1014 1014 } else if (*++inp=='\n') {
1015 1015 outp=inp; /* allows blank line after # */
1016 1016 } else {
1017 1017 pperror("undefined control",0);
1018 1018 }
1019 1019 /* flush to lf */
1020 1020 ++flslvl;
1021 1021 while (*inp!='\n') {
1022 1022 outp=inp=p;
1023 1023 p=cotoken(p);
1024 1024 }
1025 1025 --flslvl;
1026 1026 }
1027 1027 }
1028 1028
1029 1029 static struct symtab *
1030 1030 stsym(s) register char *s; {
1031 1031 char buf[BUFFERSIZ]; register char *p;
1032 1032
1033 1033 /* make definition look exactly like end of #define line */
1034 1034 /* copy to avoid running off end of world when param list is at end */
1035 1035 p=buf; while ((*p++= *s++) != '\0');
1036 1036 p=buf; while (isid(*p++)); /* skip first identifier */
1037 1037 if (*--p=='=') {*p++=' '; while (*p++);}
1038 1038 else {s=" 1"; while ((*p++= *s++) != '\0');}
1039 1039 pend=p; *--p='\n';
1040 1040 sloscan(); dodef(buf); return(lastsym);
1041 1041 }
1042 1042
1043 1043 static struct symtab *
1044 1044 ppsym(s) char *s; {/* kluge */
1045 1045 register struct symtab *sp;
1046 1046 cinit=SALT; *savch++=SALT; sp=stsym(s); --sp->name; cinit=0; return(sp);
1047 1047 }
1048 1048
1049 1049 void
1050 1050 verror(char *fmt, va_list args)
1051 1051 {
1052 1052 if (fnames[ifno][0])
1053 1053 fprintf(stderr, "%s: ", fnames[ifno]);
1054 1054 fprintf(stderr, "%d: ",lineno[ifno]);
1055 1055
1056 1056 (void)vfprintf(stderr, fmt, args);
1057 1057 fputc('\n', stderr);
1058 1058 }
1059 1059
↓ open down ↓ |
1059 lines elided |
↑ open up ↑ |
1060 1060 /* VARARGS1 */
1061 1061 void
1062 1062 pperror(char *fmt, ...)
1063 1063 {
1064 1064 va_list args;
1065 1065
1066 1066 va_start(args, fmt);
1067 1067 verror(fmt, args);
1068 1068 va_end(args);
1069 1069
1070 - ++exfail;
1070 + exfail = 1;
1071 1071 }
1072 1072
1073 1073 /* VARARGS1 */
1074 1074 void
1075 1075 yyerror(char *fmt, ...)
1076 1076 {
1077 1077 va_list args;
1078 1078
1079 1079 va_start(args, fmt);
1080 1080 verror(fmt, args);
1081 1081 va_end(args);
1082 1082 }
1083 1083
1084 1084 /* VARARGS1 */
1085 1085 static void
1086 1086 ppwarn(char *fmt, ...)
1087 1087 {
1088 1088 va_list args;
1089 1089 int fail = exfail;
1090 - exfail = -1;
1091 1090
1092 1091 va_start(args, fmt);
1093 1092 verror(fmt, args);
1094 1093 va_end(args);
1095 1094
1096 1095 exfail = fail;
1097 1096 }
1098 1097
1099 1098 struct symtab *
1100 1099 lookup(namep, enterf)
1101 1100 char *namep;
1102 1101 int enterf;
1103 1102 {
1104 1103 register char *np, *snp;
1105 1104 register int c, i; int around;
1106 1105 register struct symtab *sp;
1107 1106
1108 1107 /* namep had better not be too long (currently, <=symlen chars) */
1109 1108 np=namep; around=0; i=cinit;
1110 1109 while ((c = *np++) != '\0')
1111 1110 i += i+c;
1112 1111 c=i; /* c=i for register usage on pdp11 */
1113 1112 c %= symsiz;
1114 1113 if (c<0)
1115 1114 c += symsiz;
1116 1115 sp = &stab[c];
1117 1116 while ((snp=sp->name) != NULL) {
1118 1117 np = namep;
1119 1118 while (*snp++ == *np)
1120 1119 if (*np++ == '\0') {
1121 1120 if (enterf==DROP) {
1122 1121 sp->name[0]= DROP;
1123 1122 sp->value=0;
1124 1123 }
1125 1124 return(lastsym=sp);
1126 1125 }
1127 1126 if (--sp < &stab[0]) {
1128 1127 if (around) {
1129 1128 pperror("too many defines", 0);
1130 1129 exit(exfail);
1131 1130 } else {
1132 1131 ++around;
1133 1132 sp = &stab[symsiz-1];
1134 1133 }
1135 1134 }
1136 1135 }
1137 1136 if (enterf>0)
1138 1137 sp->name=namep;
1139 1138 return (lastsym=sp);
1140 1139 }
1141 1140
1142 1141 static struct symtab *
1143 1142 slookup(p1,p2,enterf) register char *p1,*p2; int enterf;{
1144 1143 register char *p3; char c2,c3; struct symtab *np;
1145 1144 c2= *p2; *p2='\0'; /* mark end of token */
1146 1145 if ((p2-p1)>symlen)
1147 1146 p3=p1+symlen;
1148 1147 else
1149 1148 p3=p2;
1150 1149 c3= *p3; *p3='\0'; /* truncate to symlen chars or less */
1151 1150 if (enterf==1)
1152 1151 p1=copy(p1);
1153 1152 np=lookup(p1,enterf); *p3=c3; *p2=c2;
1154 1153 if (np->value!=0 && flslvl==0)
1155 1154 newp=subst(p2,np);
1156 1155 else
1157 1156 newp=0;
1158 1157 return(np);
1159 1158 }
1160 1159
1161 1160 /*
1162 1161 * When a macro substitution must happen, arrange the input stack based on the
1163 1162 * macro definition and any parameters such that the expanded macro is what is
1164 1163 * next read by the preprocessor as if it were input
1165 1164 */
1166 1165 static char *
1167 1166 subst(p,sp) register char *p; struct symtab *sp; {
1168 1167 static char match[]="%s: argument mismatch";
1169 1168 register char *ca,*vp; int params;
1170 1169 char *actual[MAXFRM]; /* actual[n] is text of nth actual */
1171 1170 char acttxt[BUFFERSIZ]; /* space for actuals */
1172 1171 /* State while pasting, TRAIL is trailing space, INTRA is in the body */
1173 1172 enum { TRAIL, INTRA } state = TRAIL;
1174 1173 int pasted = 0; /* # of character pasted */
1175 1174
1176 1175 if (0==(vp=sp->value)) return(p);
1177 1176 if ((p-macforw)<=macdam) {
1178 1177 if (++maclvl>symsiz && !rflag) {
1179 1178 pperror("%s: macro recursion",sp->name);
1180 1179 return(p);
1181 1180 }
1182 1181 } else {
1183 1182 maclvl=0; /* level decreased */
1184 1183 }
1185 1184 macforw=p; macdam=0; /* new target for decrease in level */
1186 1185 macnam=sp->name;
1187 1186 /* flush all buffered output prior to the expansion */
1188 1187 dump();
1189 1188 if (sp==ulnloc) {
1190 1189 vp=acttxt; *vp++='\0';
1191 1190 sprintf(vp,"%d",lineno[ifno]); while (*vp++);
1192 1191 } else if (sp==uflloc) {
1193 1192 vp=acttxt; *vp++='\0';
1194 1193 sprintf(vp,"\"%s\"",fnames[ifno]); while (*vp++);
1195 1194 }
1196 1195 if (0!=(params= *--vp&0xFF)) {/* definition calls for params */
1197 1196 register char **pa;
1198 1197 ca=acttxt; pa=actual;
1199 1198 if (params==0xFF)
1200 1199 params=1; /* #define foo() ... */
1201 1200 sloscan();
1202 1201 ++flslvl; /* no expansion during search for actuals */
1203 1202 plvl= -1;
1204 1203 do p=skipbl(p); while (*inp=='\n'); /* skip \n too */
1205 1204 if (*inp=='(') {
1206 1205 maclin=lineno[ifno]; macfil=fnames[ifno];
1207 1206 for (plvl=1; plvl!=0; ) {
1208 1207 *ca++='\0';
1209 1208 for (;;) {
1210 1209 outp=inp=p; p=cotoken(p);
1211 1210 if (*inp=='(') ++plvl;
1212 1211 if (*inp==')' && --plvl==0) {
1213 1212 --params;
1214 1213 break;
1215 1214 }
1216 1215 if (plvl==1 && *inp==',') {
1217 1216 --params;
1218 1217 break;
1219 1218 }
1220 1219 while (inp<p) {
1221 1220 /*
1222 1221 * Sun cpp compatibility.
1223 1222 * Needed for kernel assembler
1224 1223 * preprocessing.
1225 1224 * Replace newlines in actual
1226 1225 * macro parameters by spaces.
1227 1226 * Keep escaped newlines, they
1228 1227 * are assumed to be inside a
1229 1228 * string.
1230 1229 *
1231 1230 * XXX: The above is actually
1232 1231 * false in a couple of ways.
1233 1232 *
1234 1233 * 1) Sun cpp turns newlines
1235 1234 * into spaces, but inserts an
1236 1235 * equal number of newlines
1237 1236 * prior to pasting the body.
1238 1237 *
1239 1238 * 2) Sun does _not_ preserved
1240 1239 * escaped newlines, the \ is
1241 1240 * removed, and the newline
1242 1241 * otherwise treated
1243 1242 * identically to in #1.
1244 1243 */
1245 1244 if (*inp == '\n' &&
1246 1245 inp[-1] != '\\')
1247 1246 *inp = ' ';
1248 1247 *ca++= *inp++;
1249 1248 }
1250 1249 if (ca> &acttxt[BUFFERSIZ])
1251 1250 pperror("%s: actuals too long",
1252 1251 sp->name);
1253 1252 }
1254 1253 if (pa>= &actual[MAXFRM])
1255 1254 ppwarn(match,sp->name);
1256 1255 else
1257 1256 *pa++=ca;
1258 1257 }
1259 1258 }
1260 1259 if (params!=0)
1261 1260 ppwarn(match,sp->name);
1262 1261 while (--params>=0)
1263 1262 *pa++=""+1; /* null string for missing actuals */
1264 1263 --flslvl; fasscan();
1265 1264 }
1266 1265
1267 1266 for (;;) {/* push definition onto front of input stack */
1268 1267 /*
1269 1268 * Loop until we hit the end of the macro, or a parameter
1270 1269 * placement. Note that we expand the macro into the input
1271 1270 * backwards (so it replays forwards.)
1272 1271 */
1273 1272 while (!iswarn(*--vp)) {
1274 1273 if (bob(p)) {outp=inp=p; p=unfill(p);}
1275 1274
1276 1275 /* Unless we are mid-paste, swallow all spaces */
1277 1276 if (state == TRAIL) {
1278 1277 while (isspace(*vp) && !iswarn(*vp))
1279 1278 vp--;
1280 1279 } else {
1281 1280 /*
1282 1281 * If we're mid-paste, compress spaces to a
1283 1282 * single space
1284 1283 */
1285 1284 while (isspace(*vp)) {
1286 1285 if (!isspace(vp[1])) {
1287 1286 *vp = ' ';
1288 1287 break;
1289 1288 } else {
1290 1289 vp--;
1291 1290 }
1292 1291 }
1293 1292 }
1294 1293 state = INTRA; /* Hit a non-space */
1295 1294
1296 1295 if (iswarn(*vp))
1297 1296 break;
1298 1297 *--p= *vp;
1299 1298 pasted++;
1300 1299 }
1301 1300 if (*vp==warnc) {/* insert actual param */
1302 1301 state = INTRA;
1303 1302 ca=actual[*--vp-1];
1304 1303 while (*--ca) {
1305 1304 if (bob(p)) {outp=inp=p; p=unfill(p);}
1306 1305 *--p= *ca;
1307 1306 pasted++;
1308 1307 }
1309 1308 } else {
1310 1309 /*
1311 1310 * Trim leading spaces, but only those from our pasting
1312 1311 */
1313 1312 while (isspace(*p) && pasted > 0) {
1314 1313 p++;
1315 1314 pasted--;
1316 1315 }
1317 1316 break;
1318 1317 }
1319 1318 }
1320 1319 outp=inp=p;
1321 1320 return(p);
1322 1321 }
1323 1322
1324 1323 static char *
1325 1324 trmdir(s) register char *s; {
1326 1325 register char *p = s;
1327 1326 while (*p++); --p; while (p>s && *--p!='/');
1328 1327 # if unix
1329 1328 if (p==s) *p++='.';
1330 1329 # endif
1331 1330 *p='\0';
1332 1331 return(s);
1333 1332 }
1334 1333
1335 1334 static char *
1336 1335 copy(s) register char *s; {
1337 1336 register char *old;
1338 1337
1339 1338 old = savch; while ((*savch++ = *s++) != '\0');
1340 1339 return(old);
1341 1340 }
1342 1341
1343 1342 static char *
1344 1343 strdex(s,c) char *s,c; {
1345 1344 while (*s) if (*s++==c) return(--s);
1346 1345 return(0);
1347 1346 }
1348 1347
1349 1348 int
1350 1349 yywrap() {
1351 1350 return(1);
1352 1351 }
1353 1352
1354 1353 int
1355 1354 main(argc,argv)
1356 1355 char *argv[];
1357 1356 int argc;
1358 1357 {
1359 1358 register int i,c;
1360 1359 register char *p;
1361 1360 char *tf,**cp2;
1362 1361 char *sysdir = NULL;
1363 1362
1364 1363 fout = stdout; /* Mac OS X is not POSIX compliant (stdout nonconst.) */
1365 1364
1366 1365 p="_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
1367 1366 i=0;
1368 1367 while ((c= *p++) != '\0') {
1369 1368 (fastab+COFF)[c] |= IB|NB|SB;
1370 1369 (toktyp+COFF)[c]=IDENT;
1371 1370 #if scw2
1372 1371 /*
1373 1372 * 53 == 63-10; digits rarely appear in identifiers,
1374 1373 * and can never be the first char of an identifier.
1375 1374 * 11 == 53*53/sizeof(macbit) .
1376 1375 */
1377 1376 ++i; (t21+COFF)[c]=(53*i)/11; (t22+COFF)[c]=i%11;
1378 1377 #endif
1379 1378 }
1380 1379 p="0123456789.";
1381 1380 while ((c = *p++) != '\0') {
1382 1381 (fastab+COFF)[c] |= NB|SB;
1383 1382 (toktyp+COFF)[c]=NUMBR;
1384 1383 }
1385 1384 p="\n\"'/\\";
1386 1385 while ((c = *p++) != '\0')
1387 1386 (fastab+COFF)[c] |= SB;
1388 1387 p="\n\"'\\";
1389 1388 while ((c = *p++) != '\0')
1390 1389 (fastab+COFF)[c] |= QB;
1391 1390 p="*\n";
1392 1391 while ((c = *p++)!= '\0')
1393 1392 (fastab+COFF)[c] |= CB;
1394 1393 (fastab+COFF)[(int)warnc] |= WB;
1395 1394 (fastab+COFF)['\0'] |= CB|QB|SB|WB;
1396 1395 for (i=ALFSIZ; --i>=0; )
1397 1396 slotab[i]=fastab[i]|SB;
1398 1397 p=" \t\013\f\r"; /* note no \n; \v not legal for vertical tab? */
1399 1398 while ((c = *p++) != '\0')
1400 1399 (toktyp+COFF)[c]=BLANK;
1401 1400 #if scw2
1402 1401 for ((t23+COFF)[i=ALFSIZ+7-COFF]=1; --i>=-COFF; )
1403 1402 if (((t23+COFF)[i]=(t23+COFF+1)[i]<<1)==0)
1404 1403 (t23+COFF)[i]=1;
1405 1404 #endif
1406 1405
1407 1406 # if unix
1408 1407 fnames[ifno=0] = "";
1409 1408 dirs[0]=dirnams[0]= ".";
1410 1409 # endif
1411 1410 # if ibm
1412 1411 fnames[ifno=0] = "";
1413 1412 # endif
1414 1413 # if gimpel
1415 1414 fnames[ifno=0] = (char *)inquire(stdin, _FILENAME);
1416 1415 dirnams[0] = dirs[0] = trmdir(copy(fnames[0]));
1417 1416 # endif
1418 1417 for (i=1; i<argc; i++) {
1419 1418 switch(argv[i][0]) {
1420 1419 case '-':
1421 1420 switch(argv[i][1]) {
1422 1421 case 'P':
1423 1422 pflag++;
1424 1423 continue;
1425 1424 case 'E':
1426 1425 continue;
1427 1426 case 'R':
1428 1427 ++rflag;
1429 1428 continue;
1430 1429 case 'C':
1431 1430 passcom++;
1432 1431 continue;
1433 1432 case 'D':
1434 1433 if (predef>prespc+NPREDEF) {
1435 1434 pperror("too many -D options, "
1436 1435 "ignoring %s", argv[i]);
1437 1436 continue;
1438 1437 }
1439 1438 /* ignore plain "-D" (no argument) */
1440 1439 if (*(argv[i]+2))
1441 1440 *predef++ = argv[i]+2;
1442 1441 continue;
1443 1442 case 'U':
1444 1443 if (prund>punspc+NPREDEF) {
1445 1444 pperror("too many -U options, "
1446 1445 "ignoring %s", argv[i]);
1447 1446 continue;
1448 1447 }
1449 1448 *prund++ = argv[i]+2;
1450 1449 continue;
1451 1450 case 'u':
1452 1451 if (strcmp(argv[i], "-undef") == 0)
1453 1452 nopredef = 1;
1454 1453 else
1455 1454 goto unknown;
1456 1455 continue;
1457 1456 case 'I':
1458 1457 if (nd>=MAXIDIRS)
1459 1458 pperror("excessive -I file "
1460 1459 "(%s) ignored", argv[i]);
1461 1460 else
1462 1461 dirs[nd++] = argv[i]+2;
1463 1462 continue;
1464 1463 case 'T':
1465 1464 symlen = 8;
1466 1465 /* Compatibility with V7 */
1467 1466 continue;
1468 1467 case 'H':
1469 1468 /* Print included filenames */
1470 1469 hflag++;
1471 1470 continue;
1472 1471 case 'Y':
1473 1472 /* Replace system include dir */
1474 1473 sysdir = argv[i]+2;
1475 1474 continue;
1476 1475 case '\0': continue;
1477 1476 default:
1478 1477 unknown:
1479 1478 pperror("unknown flag %s", argv[i]);
1480 1479 continue;
1481 1480 }
1482 1481 default:
1483 1482 if (fin == STDIN_FILENO) {
1484 1483 if (0>(fin=open(argv[i], O_RDONLY))) {
1485 1484 pperror("No source file %s",
1486 1485 argv[i]);
1487 1486 exit(8);
1488 1487 }
1489 1488 fnames[ifno]=copy(argv[i]);
1490 1489 dirs[0]=dirnams[ifno]=trmdir(argv[i]);
1491 1490 /* too dangerous to have file name in same syntactic position
1492 1491 be input or output file depending on file redirections,
1493 1492 so force output to stdout, willy-nilly
1494 1493 [i don't see what the problem is. jfr]
1495 1494 */
1496 1495 } else if (fout==stdout) {
1497 1496 static char _sobuff[BUFSIZ];
1498 1497 if (NULL==(fout=fopen(argv[i], "w"))) {
1499 1498 pperror("Can't create %s",
1500 1499 argv[i]);
1501 1500 exit(8);
1502 1501 } else {
1503 1502 fclose(stdout);
1504 1503 setbuf(fout,_sobuff);
1505 1504 }
1506 1505 } else {
1507 1506 pperror("extraneous name %s", argv[i]);
1508 1507 }
1509 1508 }
1510 1509 }
1511 1510
1512 1511 fins[ifno]=fin;
1513 1512 exfail = 0;
1514 1513 /* after user -I files here are the standard include libraries */
1515 1514 if (sysdir != NULL) {
1516 1515 dirs[nd++] = sysdir;
1517 1516 } else {
1518 1517 # if unix
1519 1518 dirs[nd++] = "/usr/include";
1520 1519 # endif
1521 1520 /* dirs[nd++] = "/compool"; */
1522 1521 }
1523 1522 dirs[nd++] = 0;
1524 1523 defloc=ppsym("define");
1525 1524 udfloc=ppsym("undef");
1526 1525 incloc=ppsym("include");
1527 1526 elsloc=ppsym("else");
1528 1527 eifloc=ppsym("endif");
1529 1528 elifloc=ppsym("elif");
1530 1529 ifdloc=ppsym("ifdef");
1531 1530 ifnloc=ppsym("ifndef");
1532 1531 ifloc=ppsym("if");
1533 1532 lneloc=ppsym("line");
1534 1533 idtloc=ppsym("ident");
1535 1534 pragmaloc=ppsym("pragma");
1536 1535 errorloc=ppsym("error");
1537 1536 for (i=sizeof(macbit)/sizeof(macbit[0]); --i>=0; )
1538 1537 macbit[i]=0;
1539 1538
1540 1539 if (! nopredef) {
1541 1540 ysysloc=stsym("unix");
1542 1541 ysysloc=stsym("sun");
1543 1542 # if __sparc__
1544 1543 varloc=stsym ("sparc");
1545 1544 # endif
1546 1545 # if __i386__
1547 1546 varloc=stsym ("i386");
1548 1547 # endif
1549 1548 }
1550 1549 ulnloc=stsym ("__LINE__");
1551 1550 uflloc=stsym ("__FILE__");
1552 1551 varloc=stsym ("__BUILTIN_VA_ARG_INCR");
1553 1552
1554 1553 tf=fnames[ifno]; fnames[ifno]="command line"; lineno[ifno]=1;
1555 1554 cp2=prespc;
1556 1555 while (cp2<predef) stsym(*cp2++);
1557 1556 cp2=punspc;
1558 1557 while (cp2<prund) {
1559 1558 if ((p=strdex(*cp2, '=')) != NULL) *p++='\0';
1560 1559 if (strlen(*cp2) > symlen)
1561 1560 (*cp2)[symlen] = '\0';
1562 1561 lookup(*cp2++, DROP);
1563 1562 }
1564 1563 fnames[ifno]=tf;
1565 1564 pbeg=buffer+symlen; pbuf=pbeg+BUFFERSIZ; pend=pbuf+BUFFERSIZ;
1566 1565
1567 1566 trulvl = 0; flslvl = 0;
1568 1567 lineno[0] = 1; sayline(NOINCLUDE);
1569 1568 outp=inp=pend;
1570 1569 control(pend);
1571 1570 return (exfail);
1572 1571 }
↓ open down ↓ |
472 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX