190 # define MAXIDIRS 20 /* max # of -I directories */
191 # define MAXFRE 14 /* max buffers of macro pushback */
192 # define MAXFRM 31 /* max number of formals/actuals to a macro */
193
194 static char warnc = (char)WARN;
195
196 static int mactop;
197 static int fretop;
198 static char *instack[MAXFRE];
199 static char *bufstack[MAXFRE];
200 static char *endbuf[MAXFRE];
201
202 static int plvl; /* parenthesis level during scan for macro actuals */
203 static int maclin; /* line number of macro call requiring actuals */
204 static char *macfil; /* file name of macro call requiring actuals */
205 static char *macnam; /* name of macro requiring actuals */
206 static int maclvl; /* # calls since last decrease in nesting level */
207 static char *macforw; /* ptr which must be exceeded to decrease nesting lvl */
208 static int macdam; /* offset to macforw due to buffer shifting */
209
210 #if tgp
211 int tgpscan; /* flag for dump(); */
212 #endif
213
214 static int inctop[MAXINC];
215 static char *fnames[MAXINC];
216 static char *dirnams[MAXINC]; /* actual directory of #include files */
217 static int fins[MAXINC];
218 static int lineno[MAXINC];
219
220 /*
221 * We need:
222 * "" include dir as dirs[0] +
223 * MAXIDIRS +
224 * system default include dir +
225 * a NULL pointer at the end
226 */
227 static char *dirs[MAXIDIRS+3]; /* -I and <> directories */
228 static int fin = STDIN_FILENO;
229 static FILE *fout; /* Init in main(), Mac OS is nonPOSIX */
230 static int nd = 1;
231 static int pflag; /* don't put out lines "# 12 foo.c" */
232 static int passcom; /* don't delete comments */
233 static int rflag; /* allow macro recursion */
349 * is kept in 'endbuf' since there may be nulls in the saved buffer.
350 *
351 * similar action is taken when an 'include' statement is processed,
352 * except that the main buffer must be completely emptied. the array
353 * element 'inctop[ifno]' records the last side buffer saved when
354 * file 'ifno' was included. these buffers remain dormant while
355 * the file is being read, and are reactivated at end-of-file.
356 *
357 * instack[0 : mactop] holds the addresses of all pending side buffers.
358 * instack[inctop[ifno]+1 : mactop-1] holds the addresses of the side
359 * buffers which are "live"; the side buffers instack[0 : inctop[ifno]]
360 * are dormant, waiting for end-of-file on the current file.
361 *
362 * space for side buffers is obtained from 'savch' and is never returned.
363 * bufstack[0:fretop-1] holds addresses of side buffers which
364 * are available for use.
365 */
366
367 static void
368 dump() {
369 /*
370 * write part of buffer which lies between outp and inp .
371 * this should be a direct call to 'write', but the system slows to a crawl
372 * if it has to do an unaligned copy. thus we buffer. this silly loop
373 * is 15% of the total time, thus even the 'putc' macro is too slow.
374 */
375 register char *p1;
376 #if tgp
377 register char *p2;
378 #endif
379 register FILE *f;
380 if ((p1=outp)==inp || flslvl!=0) return;
381 #if tgp
382 #define MAXOUT 80
383 if (!tgpscan) {
384 /* scan again to insure <= MAXOUT chars between linefeeds */
385 register char c,*pblank; char savc,stopc,brk;
386 tgpscan=1; brk=stopc=pblank=0; p2=inp; savc= *p2; *p2='\0';
387 while (c= *p1++) {
388 if (c=='\\') c= *p1++;
389 if (stopc==c) stopc=0;
390 else if (c=='"' || c=='\'') stopc=c;
391 if (p1-outp>MAXOUT && pblank!=0) {
392 *pblank++='\n';
393 inp=pblank;
394 dump();
395 brk=1;
396 pblank=0;
397 }
398 if (c==' ' && stopc==0) pblank=p1-1;
399 }
400 if (brk) sayline(NOINCLUDE);
401 *p2=savc; inp=p2; p1=outp; tgpscan=0;
402 }
403 #endif
404 f=fout;
405 while (p1<inp)
406 putc(*p1++,f);
407 outp=p1;
408 }
409
410 static char *
411 refill(p) register char *p; {
412 /*
413 * dump buffer. save chars from inp to p. read into buffer at pbuf,
414 * contiguous with p. update pointers, return new p.
415 */
416 register char *np,*op; register int ninbuf;
417 dump(); np=pbuf-(p-inp); op=inp;
418 if (bob(np+1)) {pperror("token too long"); np=pbeg; p=inp+BUFFERSIZ;}
419 macdam += np-inp; outp=inp=np;
420 while (op<p) *np++= *op++;
421 p=np;
422 for (;;) {
423 if (mactop>inctop[ifno]) {
424 /* retrieve hunk of pushed-back macro text */
425 op=instack[--mactop]; np=pbuf;
426 do {
994
995 } else if (np==elsloc) {/* else */
996 if (flslvl) {
997 if (elflvl > trulvl)
998 ;
999 else if (--flslvl!=0) ++flslvl;
1000 else {++trulvl; sayline(NOINCLUDE);}
1001 }
1002 else if (trulvl) {++flslvl; --trulvl;}
1003 else pperror("If-less else",0);
1004
1005 if (elslvl==trulvl+flslvl)
1006 pperror("Too many #else's");
1007 elslvl=trulvl+flslvl;
1008
1009 } else if (np==udfloc) {/* undefine */
1010 if (flslvl==0) {
1011 ++flslvl; p=skipbl(p); slookup(inp,p,DROP); --flslvl;
1012 }
1013 } else if (np==ifloc) {/* if */
1014 #if tgp
1015 pperror(" IF not implemented, true assumed", 0);
1016 if (flslvl==0) ++trulvl; else ++flslvl;
1017 #else
1018 newp=p;
1019 if (flslvl==0 && yyparse()) ++trulvl; else ++flslvl;
1020 p=newp;
1021 #endif
1022 } else if (np == idtloc) { /* ident */
1023 if (pflag == 0)
1024 while (*inp != '\n') /* pass text */
1025 p = cotoken(p);
1026 } else if (np == pragmaloc) { /* pragma */
1027 while (*inp != '\n') /* pass text */
1028 p = cotoken(p);
1029 #ifdef EXIT_ON_ERROR
1030 } else if (np == errorloc) { /* error */
1031 if (trulvl > 0) {
1032 char ebuf[BUFFERSIZ];
1033
1034 p = ebuf;
1035 while (*inp != '\n') {
1036 if (*inp == '\0')
1037 if (eob(--inp)) {
1038 inp = refill(inp);
1039 continue;
1040 }
1041 *p++ = *inp++;
|
190 # define MAXIDIRS 20 /* max # of -I directories */
191 # define MAXFRE 14 /* max buffers of macro pushback */
192 # define MAXFRM 31 /* max number of formals/actuals to a macro */
193
194 static char warnc = (char)WARN;
195
196 static int mactop;
197 static int fretop;
198 static char *instack[MAXFRE];
199 static char *bufstack[MAXFRE];
200 static char *endbuf[MAXFRE];
201
202 static int plvl; /* parenthesis level during scan for macro actuals */
203 static int maclin; /* line number of macro call requiring actuals */
204 static char *macfil; /* file name of macro call requiring actuals */
205 static char *macnam; /* name of macro requiring actuals */
206 static int maclvl; /* # calls since last decrease in nesting level */
207 static char *macforw; /* ptr which must be exceeded to decrease nesting lvl */
208 static int macdam; /* offset to macforw due to buffer shifting */
209
210 static int inctop[MAXINC];
211 static char *fnames[MAXINC];
212 static char *dirnams[MAXINC]; /* actual directory of #include files */
213 static int fins[MAXINC];
214 static int lineno[MAXINC];
215
216 /*
217 * We need:
218 * "" include dir as dirs[0] +
219 * MAXIDIRS +
220 * system default include dir +
221 * a NULL pointer at the end
222 */
223 static char *dirs[MAXIDIRS+3]; /* -I and <> directories */
224 static int fin = STDIN_FILENO;
225 static FILE *fout; /* Init in main(), Mac OS is nonPOSIX */
226 static int nd = 1;
227 static int pflag; /* don't put out lines "# 12 foo.c" */
228 static int passcom; /* don't delete comments */
229 static int rflag; /* allow macro recursion */
345 * is kept in 'endbuf' since there may be nulls in the saved buffer.
346 *
347 * similar action is taken when an 'include' statement is processed,
348 * except that the main buffer must be completely emptied. the array
349 * element 'inctop[ifno]' records the last side buffer saved when
350 * file 'ifno' was included. these buffers remain dormant while
351 * the file is being read, and are reactivated at end-of-file.
352 *
353 * instack[0 : mactop] holds the addresses of all pending side buffers.
354 * instack[inctop[ifno]+1 : mactop-1] holds the addresses of the side
355 * buffers which are "live"; the side buffers instack[0 : inctop[ifno]]
356 * are dormant, waiting for end-of-file on the current file.
357 *
358 * space for side buffers is obtained from 'savch' and is never returned.
359 * bufstack[0:fretop-1] holds addresses of side buffers which
360 * are available for use.
361 */
362
363 static void
364 dump() {
365 register char *p1;
366 if ((p1=outp)==inp || flslvl!=0) return;
367 fwrite(p1, inp - p1, 1, fout);
368 outp=p1;
369 }
370
371 static char *
372 refill(p) register char *p; {
373 /*
374 * dump buffer. save chars from inp to p. read into buffer at pbuf,
375 * contiguous with p. update pointers, return new p.
376 */
377 register char *np,*op; register int ninbuf;
378 dump(); np=pbuf-(p-inp); op=inp;
379 if (bob(np+1)) {pperror("token too long"); np=pbeg; p=inp+BUFFERSIZ;}
380 macdam += np-inp; outp=inp=np;
381 while (op<p) *np++= *op++;
382 p=np;
383 for (;;) {
384 if (mactop>inctop[ifno]) {
385 /* retrieve hunk of pushed-back macro text */
386 op=instack[--mactop]; np=pbuf;
387 do {
955
956 } else if (np==elsloc) {/* else */
957 if (flslvl) {
958 if (elflvl > trulvl)
959 ;
960 else if (--flslvl!=0) ++flslvl;
961 else {++trulvl; sayline(NOINCLUDE);}
962 }
963 else if (trulvl) {++flslvl; --trulvl;}
964 else pperror("If-less else",0);
965
966 if (elslvl==trulvl+flslvl)
967 pperror("Too many #else's");
968 elslvl=trulvl+flslvl;
969
970 } else if (np==udfloc) {/* undefine */
971 if (flslvl==0) {
972 ++flslvl; p=skipbl(p); slookup(inp,p,DROP); --flslvl;
973 }
974 } else if (np==ifloc) {/* if */
975 newp=p;
976 if (flslvl==0 && yyparse()) ++trulvl; else ++flslvl;
977 p=newp;
978 } else if (np == idtloc) { /* ident */
979 if (pflag == 0)
980 while (*inp != '\n') /* pass text */
981 p = cotoken(p);
982 } else if (np == pragmaloc) { /* pragma */
983 while (*inp != '\n') /* pass text */
984 p = cotoken(p);
985 #ifdef EXIT_ON_ERROR
986 } else if (np == errorloc) { /* error */
987 if (trulvl > 0) {
988 char ebuf[BUFFERSIZ];
989
990 p = ebuf;
991 while (*inp != '\n') {
992 if (*inp == '\0')
993 if (eob(--inp)) {
994 inp = refill(inp);
995 continue;
996 }
997 *p++ = *inp++;
|