/* * Scan quickly the input file searching for: * - '#' directives * - keywords (if not flslvl) * - comments * * Handle strings, numbers and trigraphs with care. * Only data from pp files are scanned here, never any rescans. * TODO: Only print out strings before calling other functions. */ static void fastscan(void) { struct symtab *nl; int ch, i; usch *cp; goto run; for (;;) { ch = inch(); xloop: if (ch == -1) return; #ifdef PCC_DEBUG if (dflag>1) printf("fastscan ch %d (%c)\n", ch, ch > 31 ? ch : '@'); #endif if ((spechr[ch] & C_SPEC) == 0) { PUTCH(ch); continue; } switch (ch) { case EBLOCK: case WARN: case CONC: error("bad char passed"); break; case '/': /* Comments */ if ((ch = inch()) == '/') { cppcmt: if (Cflag) { PUTCH(ch); } else { PUTCH(' '); } do { if (Cflag) PUTCH(ch); ch = inch(); } while (ch != -1 && ch != '\n'); goto xloop; } else if (ch == '*') { eatcmnt(); } else { PUTCH('/'); goto xloop; } break; case '\n': /* newlines, for pp directives */ i = ifiles->escln + 1; ifiles->lineno += i; ifiles->escln = 0; while (i-- > 0) putch('\n'); run: for(;;) { ch = inch(); if (ch == '/') { ch = inch(); if (ch == '/') goto cppcmt; if (ch == '*') { eatcmnt(); continue; } unch(ch); ch = '/'; } if (ch != ' ' && ch != '\t') break; PUTCH(ch); } if (ch == '#') { ppdir(); continue; } else if (ch == '%') { ch = inch(); if (ch == ':') { ppdir(); continue; } unch(ch); ch = '%'; } goto xloop; case '\"': /* strings */ str: PUTCH(ch); while ((ch = inch()) != '\"') { if (ch == '\\') { PUTCH('\\'); ch = inch(); } if (ch == '\n') { warning("unterminated string literal"); goto xloop; } if (ch == -1) return; PUTCH(ch); } PUTCH(ch); break; case '.': /* for pp-number */ PUTCH(ch); ch = inch(); if (ch < '0' || ch > '9') goto xloop; /* FALLTHROUGH */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': do { nxp: PUTCH(ch); ch = inch(); if (ch == -1) return; if (spechr[ch] & C_EP) { PUTCH(ch); ch = inch(); if (ch == '-' || ch == '+') goto nxp; if (ch == -1) return; } } while ((spechr[ch] & C_ID) || (ch == '.')); goto xloop; case '\'': /* character constant */ con: PUTCH(ch); if (tflag) break; /* character constants ignored */ while ((ch = inch()) != '\'') { if (ch == '\\') { PUTCH('\\'); ch = inch(); } if (ch == '\n') { warning("unterminated character constant"); goto xloop; } if (ch == -1) return; PUTCH(ch); } PUTCH(ch); break; case 'L': ch = inch(); if (ch == '\"') { PUTCH('L'); goto str; } if (ch == '\'') { PUTCH('L'); goto con; } unch(ch); ch = 'L'; /* FALLTHROUGH */ default: #ifdef PCC_DEBUG if ((spechr[ch] & C_ID) == 0) error("fastscan"); #endif i = 0; do { yytext[i++] = (usch)ch; ch = inch(); } while (ch != -1 && (spechr[ch] & C_ID)); if (flslvl) goto xloop; yytext[i] = 0; unch(ch); cp = stringbuf; if ((nl = lookup(yytext, FIND)) && kfind(nl)) { putstr(stringbuf); } else putstr(yytext); stringbuf = cp; break; } } }
/* * Scan quickly the input file searching for: * - '#' directives * - keywords (if not flslvl) * - comments * * Handle strings, numbers and trigraphs with care. * Only data from pp files are scanned here, never any rescans. * TODO: Only print out strings before calling other functions. */ static void fastscan(void) { struct symtab *nl; int ch, i; goto run; for (;;) { ch = NXTCH(); xloop: if (ch == -1) return; if ((spechr[ch] & C_SPEC) == 0) { PUTCH(ch); continue; } switch (ch) { case '/': /* Comments */ if ((ch = inch()) == '/') { if (Cflag) { PUTCH(ch); } else { PUTCH(' '); } do { if (Cflag) PUTCH(ch); ch = inch(); } while (ch != -1 && ch != '\n'); goto xloop; } else if (ch == '*') { if (Cflag) { PUTCH('/'); PUTCH('*'); } for (;;) { ch = inch(); if (ch == '\n') { ifiles->lineno++; PUTCH('\n'); } if (ch == -1) return; if (ch == '*') { ch = inch(); if (ch == '/') { if (Cflag) { PUTCH('*'); PUTCH('/'); } else PUTCH(' '); break; } unch(ch); ch = '*'; } if (Cflag) PUTCH(ch); } } else { PUTCH('/'); goto xloop; } break; case '?': /* trigraphs */ if ((ch = chktg())) goto xloop; PUTCH('?'); break; case '\\': if ((ch = NXTCH()) == '\n') { ifiles->lineno++; continue; } else { PUTCH('\\'); } goto xloop; case '\n': /* newlines, for pp directives */ ifiles->lineno++; do { PUTCH(ch); run: ch = NXTCH(); } while (ch == ' ' || ch == '\t'); if (ch == '#') { ppdir(); continue; } else if (ch == '%') { ch = NXTCH(); if (ch == ':') { ppdir(); continue; } else { unch(ch); ch = '%'; } } goto xloop; case '\"': /* strings */ str: PUTCH(ch); while ((ch = inch()) != '\"') { PUTCH(ch); if (ch == '\\') { ch = inch(); PUTCH(ch); } if (ch < 0) return; } PUTCH(ch); break; case '.': /* for pp-number */ PUTCH(ch); ch = NXTCH(); if (ch < '0' || ch > '9') goto xloop; /* FALLTHROUGH */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': do { PUTCH(ch); ch = NXTCH(); if (spechr[ch] & C_EP) { PUTCH(ch); ch = NXTCH(); if (ch == '-' || ch == '+') continue; } } while ((spechr[ch] & C_ID) || (ch == '.')); goto xloop; case '\'': /* character literal */ con: PUTCH(ch); if (tflag) continue; /* character constants ignored */ while ((ch = NXTCH()) != '\'') { PUTCH(ch); if (ch == '\\') { ch = NXTCH(); PUTCH(ch); } else if (ch < 0) return; else if (ch == '\n') goto xloop; } PUTCH(ch); break; case 'L': ch = NXTCH(); if (ch == '\"') { PUTCH('L'); goto str; } if (ch == '\'') { PUTCH('L'); goto con; } unch(ch); ch = 'L'; /* FALLTHROUGH */ default: if ((spechr[ch] & C_ID) == 0) error("fastscan"); if (flslvl) { while (spechr[ch] & C_ID) ch = NXTCH(); goto xloop; } i = 0; do { yytext[i++] = (usch)ch; ch = NXTCH(); if (ch == '\\') { ch = NXTCH(); if (ch != '\n') { unch('\n'); ch = '\\'; } else { ifiles->lineno++; ch = NXTCH(); } } if (ch < 0) return; } while (spechr[ch] & C_ID); yytext[i] = 0; unch(ch); if ((nl = lookup((usch *)yytext, FIND)) != 0) { usch *op = stringbuf; putstr(gotident(nl)); stringbuf = op; } else putstr((usch *)yytext); break; } } }
/* * Scan quickly the input file searching for: * - '#' directives * - keywords (if not flslvl) * - comments * * Handle strings, numbers and trigraphs with care. * Only data from pp files are scanned here, never any rescans. * This loop is always at trulvl. */ void fastscan(void) { struct iobuf *ob, rbs, *rb = &rbs; extern struct iobuf pb; struct iobuf *ib = ifiles->ib; struct symtab *nl; int ch, c2; usch *dp; #define IDSIZE 128 rb->buf = xmalloc(IDSIZE+1); rb->cptr = 0; rb->bsz = IDSIZE; goto run; for (;;) { /* tight loop to find special chars */ /* should use getchar/putchar here */ for (;;) { if (ib->cptr < ib->bsz) ch = ib->buf[ib->cptr++]; else ch = qcchar(); xloop: if (ch < 0) ch = 0; /* XXX */ if ((spechr[ch] & C_SPEC) != 0) break; putch(ch); } switch (ch) { case 0: free(rb->buf); return; case WARN: case CONC: error("bad char passed"); break; case '/': /* Comments */ incmnt++; ch = qcchar(); incmnt--; if (ch == '/' || ch == '*') { if (Cflag == 0) { int n = ifiles->lineno; fastcmnt2(ch); if (n == ifiles->lineno) putch(' '); /* 5.1.1.2 p3 */ } else Ccmnt2(&pb, ch); } else { putch('/'); goto xloop; } break; case '\n': /* newlines, for pp directives */ /* take care of leftover \n */ while (ifiles->escln > 0) { putch('\n'); ifiles->escln--; ifiles->lineno++; } putch('\n'); ifiles->lineno++; /* search for a # */ run: while ((ch = qcchar()) == '\t' || ch == ' ') putch(ch); if (ch == '%') { if ((c2 = qcchar()) != ':') unch(c2); else ch = '#'; } if (ch == '#') ppdir(); else goto xloop; break; case '?': if (ib->cptr+1 >= ib->bsz) inpbuf(2); if (ib->buf[ib->cptr] == '?') { ib->cptr++; if ((ch = chktg2(ib->buf[ib->cptr++]))) goto xloop; ib->cptr -= 2; } putch('?'); break; case '\'': /* character constant */ if (tflag) { putch(ch); break; /* character constants ignored */ } /* FALLTHROUGH */ case '\"': /* strings */ if (skpows) cntline(); faststr(ch, &pb); break; case '.': /* for pp-number */ if ((spechr[c2 = qcchar()] & C_DIGIT) == 0) { putch('.'); goto xloop; } unch(c2); case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (skpows) cntline(); ch = fastnum(ch, &pb); goto xloop; case 'L': case 'U': case 'u': if (ib->cptr+2 >= ib->bsz) inpbuf(2); if ((c2 = ib->buf[ib->cptr]) == '\"' || c2 == '\'') { putch(ch); break; } else if (c2 == '8' && ch == 'u' && ib->buf[ib->cptr+1] == '\"') { ib->cptr++; putstr((usch *)"u8"); break; } /* FALLTHROUGH */ default: #ifdef PCC_DEBUG if ((spechr[ch] & C_ID) == 0) error("fastscan"); #endif if (flslvl) error("fastscan flslvl"); rb->cptr = 0; dp = bufid(ch, rb); if ((nl = lookup(dp, FIND)) != NULL) { if ((ob = kfind(nl)) != NULL) { if (*ob->buf == '-' || *ob->buf == '+') putch(' '); if (skpows) cntline(); buftobuf(ob, &pb); if (ob->cptr > 0 && (ob->buf[ob->cptr-1] == '-' || ob->buf[ob->cptr-1] == '+')) putch(' '); bufree(ob); } } else { putstr(dp); } break; case '\\': ib->buf[--ib->cptr] = '\\'; if ((ch = qcchar()) != '\\') goto xloop; putch('\\'); break; } } }
/* * Scan quickly the input file searching for: * - '#' directives * - keywords (if not flslvl) * - comments * * Handle strings, numbers and trigraphs with care. * Only data from pp files are scanned here, never any rescans. * TODO: Only print out strings before calling other functions. */ static void fastscan(void) { struct symtab *nl; int ch, i = 0; int nnl = 0; usch *cp; goto run; for (;;) { ch = NXTCH(); xloop: if (ch == -1) return; #ifdef PCC_DEBUG if (dflag>1) printf("fastscan ch %d (%c)\n", ch, ch > 31 ? ch : '@'); #endif if ((spechr[ch] & C_SPEC) == 0) { PUTCH(ch); continue; } switch (ch) { case EBLOCK: case WARN: case CONC: error("bad char passed"); break; case '/': /* Comments */ if ((ch = inch()) == '/') { cppcmt: if (Cflag) { PUTCH(ch); } else { PUTCH(' '); } do { if (Cflag) PUTCH(ch); ch = inch(); } while (ch != -1 && ch != '\n'); goto xloop; } else if (ch == '*') { if (eatcmnt()) return; } else { PUTCH('/'); goto xloop; } break; case '?': /* trigraphs */ if ((ch = chktg())) goto xloop; PUTCH('?'); break; case '\\': if ((ch = NXTCH()) == '\n') { ifiles->lineno++; continue; } else { PUTCH('\\'); } goto xloop; case '\n': /* newlines, for pp directives */ while (nnl > 0) { PUTCH('\n'); nnl--; } run2: ifiles->lineno++; do { PUTCH(ch); run: ch = NXTCH(); if (ch == '/') { ch = NXTCH(); if (ch == '/') goto cppcmt; if (ch == '*') { if (eatcmnt()) return; goto run; } unch(ch); ch = '/'; } } while (ch == ' ' || ch == '\t'); if (ch == '\\') { ch = NXTCH(); if (ch == '\n') goto run2; unch(ch); ch = '\\'; } if (ch == '#') { ppdir(); continue; } else if (ch == '%') { ch = NXTCH(); if (ch == ':') { ppdir(); continue; } else { unch(ch); ch = '%'; } } else if (ch == '?') { if ((ch = chktg()) == '#') { ppdir(); continue; } else if (ch == 0) ch = '?'; } goto xloop; case '\"': /* strings */ str: PUTCH(ch); while ((ch = NXTCH()) != '\"') { if (ch == '\n') goto xloop; if (ch == '\\') { if ((ch = NXTCH()) != '\n') { PUTCH('\\'); PUTCH(ch); } else nnl++; continue; } if (ch < 0) return; PUTCH(ch); } PUTCH(ch); break; case '.': /* for pp-number */ PUTCH(ch); ch = NXTCH(); if (ch < '0' || ch > '9') goto xloop; /* FALLTHROUGH */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': do { PUTCH(ch); nxt: ch = NXTCH(); if (ch == '\\') { ch = NXTCH(); if (ch == '\n') { goto nxt; } else { unch(ch); ch = '\\'; } } if (spechr[ch] & C_EP) { PUTCH(ch); ch = NXTCH(); if (ch == '-' || ch == '+') continue; } } while ((spechr[ch] & C_ID) || (ch == '.')); goto xloop; case '\'': /* character literal */ con: PUTCH(ch); if (tflag) continue; /* character constants ignored */ while ((ch = NXTCH()) != '\'') { if (ch == '\n') goto xloop; if (ch == '\\') { if ((ch = NXTCH()) != '\n') { PUTCH('\\'); PUTCH(ch); } else nnl++; continue; } if (ch < 0) return; PUTCH(ch); } PUTCH(ch); break; case 'L': ch = NXTCH(); if (ch == '\"') { PUTCH('L'); goto str; } if (ch == '\'') { PUTCH('L'); goto con; } unch(ch); ch = 'L'; /* FALLTHROUGH */ default: if ((spechr[ch] & C_ID) == 0) error("fastscan"); if (flslvl) { while (spechr[ch] & C_ID) ch = NXTCH(); goto xloop; } i = 0; do { yytext[i++] = (usch)ch; ch = NXTCH(); if (ch == '\\') { ch = NXTCH(); if (ch != '\n') { unch(ch); ch = '\\'; } else { putch('\n'); ifiles->lineno++; ch = NXTCH(); } } if (ch < 0) return; } while (spechr[ch] & C_ID); yytext[i] = 0; unch(ch); cp = stringbuf; if ((nl = lookup((usch *)yytext, FIND)) && kfind(nl)) { putstr(stringbuf); } else putstr((usch *)yytext); stringbuf = cp; break; } } }