/* * macro - the work horse.. */ static void macro(void) { char token[MAXTOK+1]; int t, l; ndptr p; int nlpar; cycle { t = gpbc(); if (t == '_' || isalpha(t)) { p = inspect(t, token); if (p != nil) putback(l = gpbc()); if (p == nil || (l != LPAREN && (p->type & NEEDARGS) != 0)) outputstr(token); else { /* * real thing.. First build a call frame: */ pushf(fp); /* previous call frm */ pushf(p->type); /* type of the call */ pushf(0); /* parenthesis level */ fp = sp; /* new frame pointer */ /* * now push the string arguments: */ pushs1(p->defn); /* defn string */ pushs1(p->name); /* macro name */ pushs(ep); /* start next..*/ if (l != LPAREN && PARLEV == 0) { /* no bracks */ chrsave(EOS); if ((uintptr_t)sp == STACKMAX) errx(1, "internal stack overflow"); eval((const char **) mstack+fp+1, 2, CALTYP); ep = PREVEP; /* flush strspace */ sp = PREVSP; /* previous sp.. */ fp = PREVFP; /* rewind stack...*/ } } } else if (t == EOF) { if (sp > -1) { warnx( "unexpected end of input, unclosed parenthesis:"); dump_stack(paren, PARLEV); exit(1); } if (ilevel <= 0) break; /* all done thanks.. */ release_input(infile+ilevel--); free(inname[ilevel+1]); bufbase = bbase[ilevel]; emitline(); continue; } /* * non-alpha token possibly seen.. * [the order of else if .. stmts is important.] */ else if (LOOK_AHEAD(t,lquote)) { /* strip quotes */ nlpar = 0; record(quotes, nlpar++); /* * Opening quote: scan forward until matching * closing quote has been found. */ do { l = gpbc(); if (LOOK_AHEAD(l,rquote)) { if (--nlpar > 0) outputstr(rquote); } else if (LOOK_AHEAD(l,lquote)) { record(quotes, nlpar++); outputstr(lquote); } else if (l == EOF) { if (nlpar == 1) warnx("unclosed quote:"); else warnx("%d unclosed quotes:", nlpar); dump_stack(quotes, nlpar); exit(1); } else { if (nlpar > 0) { if (sp < 0) putc(l, active); else CHRSAVE(l); } } } while (nlpar != 0); } else if (sp < 0 && LOOK_AHEAD(t, scommt)) { fputs(scommt, active); for(;;) { t = gpbc(); if (LOOK_AHEAD(t, ecommt)) { fputs(ecommt, active); break; } if (t == EOF) break; putc(t, active); } } else if (sp < 0) { /* not in a macro at all */ putc(t, active); /* output directly.. */ } else switch(t) { case LPAREN: if (PARLEV > 0) chrsave(t); while (isspace(l = gpbc())) ; /* skip blank, tab, nl.. */ putback(l); record(paren, PARLEV++); break; case RPAREN: if (--PARLEV > 0) chrsave(t); else { /* end of argument list */ chrsave(EOS); if ((uintptr_t)sp == STACKMAX) errx(1, "internal stack overflow"); eval((const char **) mstack+fp+1, sp-fp, CALTYP); ep = PREVEP; /* flush strspace */ sp = PREVSP; /* previous sp.. */ fp = PREVFP; /* rewind stack...*/ } break; case COMMA: if (PARLEV == 1) { chrsave(EOS); /* new argument */ while (isspace(l = gpbc())) ; putback(l); pushs(ep); } else chrsave(t); break; default: if (LOOK_AHEAD(t, scommt)) { char *pc; for (pc = scommt; *pc; pc++) chrsave(*pc); for(;;) { t = gpbc(); if (LOOK_AHEAD(t, ecommt)) { for (pc = ecommt; *pc; pc++) chrsave(*pc); break; } if (t == EOF) break; CHRSAVE(t); } } else CHRSAVE(t); /* stack the char */ break; } } }
/* * macro - the work horse.. */ static void macro(void) { char token[MAXTOK+1]; int t, l; ndptr p; int nlpar; cycle { t = gpbc(); if (LOOK_AHEAD(t,lquote)) { /* strip quotes */ nlpar = 0; record(quotes, nlpar++); /* * Opening quote: scan forward until matching * closing quote has been found. */ do { l = gpbc(); if (LOOK_AHEAD(l,rquote)) { if (--nlpar > 0) outputstr(rquote); } else if (LOOK_AHEAD(l,lquote)) { record(quotes, nlpar++); outputstr(lquote); } else if (l == EOF) { if (nlpar == 1) warnx("unclosed quote:"); else warnx("%d unclosed quotes:", nlpar); dump_stack(quotes, nlpar); exit(1); } else { if (nlpar > 0) { if (sp < 0) reallyputchar(l); else CHRSAVE(l); } } } while (nlpar != 0); } else if (sp < 0 && LOOK_AHEAD(t, scommt)) { reallyoutputstr(scommt); for(;;) { t = gpbc(); if (LOOK_AHEAD(t, ecommt)) { reallyoutputstr(ecommt); break; } if (t == EOF) break; reallyputchar(t); } } else if (t == '_' || isalpha(t)) { p = inspect(t, token); if (p != NULL) pushback(l = gpbc()); if (p == NULL || (l != LPAREN && (macro_getdef(p)->type & NEEDARGS) != 0)) outputstr(token); else { /* * real thing.. First build a call frame: */ pushf(fp); /* previous call frm */ pushf(macro_getdef(p)->type); /* type of the call */ pushf(is_traced(p)); pushf(0); /* parenthesis level */ fp = sp; /* new frame pointer */ /* * now push the string arguments: */ pushs1(macro_getdef(p)->defn); /* defn string */ pushs1((char *)macro_name(p)); /* macro name */ pushs(ep); /* start next..*/ if (l != LPAREN && PARLEV == 0) { /* no bracks */ chrsave(EOS); if (sp == (int)STACKMAX) errx(1, "internal stack overflow"); eval((const char **) mstack+fp+1, 2, CALTYP, TRACESTATUS); ep = PREVEP; /* flush strspace */ sp = PREVSP; /* previous sp.. */ fp = PREVFP; /* rewind stack...*/ } } } else if (t == EOF) { if (!mimic_gnu /* you can puke right there */ && sp > -1 && ilevel <= 0) { warnx( "unexpected end of input, unclosed parenthesis:"); dump_stack(paren, PARLEV); exit(1); } if (ilevel <= 0) break; /* all done thanks.. */ release_input(infile+ilevel--); emit_synchline(); bufbase = bbase[ilevel]; continue; } else if (sp < 0) { /* not in a macro at all */ reallyputchar(t); /* output directly.. */ } else switch(t) { case LPAREN: if (PARLEV > 0) chrsave(t); while (isspace(l = gpbc())) /* skip blank, tab, nl.. */ if (PARLEV > 0) chrsave(l); pushback(l); record(paren, PARLEV++); break; case RPAREN: if (--PARLEV > 0) chrsave(t); else { /* end of argument list */ chrsave(EOS); if (sp == (int)STACKMAX) errx(1, "internal stack overflow"); eval((const char **) mstack+fp+1, sp-fp, CALTYP, TRACESTATUS); ep = PREVEP; /* flush strspace */ sp = PREVSP; /* previous sp.. */ fp = PREVFP; /* rewind stack...*/ } break; case COMMA: if (PARLEV == 1) { chrsave(EOS); /* new argument */ while (isspace(l = gpbc())) ; pushback(l); pushs(ep); } else chrsave(t); break; default: if (LOOK_AHEAD(t, scommt)) { char *cp; for (cp = scommt; *cp; cp++) chrsave(*cp); for(;;) { t = gpbc(); if (LOOK_AHEAD(t, ecommt)) { for (cp = ecommt; *cp; cp++) chrsave(*cp); break; } if (t == EOF) break; CHRSAVE(t); } } else CHRSAVE(t); /* stack the char */ break; } } }