void process(Tokenrow *trp) { int anymacros = 0; for (;;) { if (trp->tp >= trp->lp) { trp->tp = trp->lp = trp->bp; outbufp = outbuf; anymacros |= gettokens(trp, 1); trp->tp = trp->bp; } if (trp->tp->type == END) { if (--incdepth >= 0) { if (cursource->ifdepth) error(ERROR, "Unterminated conditional in #include"); unsetsource(); cursource->line += cursource->lineinc; trp->tp = trp->lp; genline(); continue; } if (ifdepth) error(ERROR, "Unterminated #if/#ifdef/#ifndef"); break; } if (trp->tp->type == SHARP) { trp->tp += 1; control(trp); } else if (!skipping && anymacros) expandrow(trp, NULL); if (skipping) setempty(trp); puttokens(trp); anymacros = 0; cursource->line += cursource->lineinc; if (cursource->lineinc > 1) { genline(); } } }
/* * Do macro expansion in a row of tokens. * Flag is NULL if more input can be gathered. */ void expandrow(Tokenrow *trp, char *flag) { Token *tp; Nlist *np; if (flag) setsource(flag, -1, ""); for (tp = trp->tp; tp<trp->lp; ) { if (tp->type!=NAME || quicklook(tp->t[0], tp->len>1?tp->t[1]:0)==0 || (np = lookup(tp, 0))==NULL || (np->flag&(ISDEFINED|ISMAC))==0 || tp->hideset && checkhideset(tp->hideset, np)) { tp++; continue; } trp->tp = tp; if (np->val==KDEFINED) { tp->type = DEFINED; if ((tp+1)<trp->lp && (tp+1)->type==NAME) (tp+1)->type = NAME1; else if ((tp+3)<trp->lp && (tp+1)->type==LP && (tp+2)->type==NAME && (tp+3)->type==RP) (tp+2)->type = NAME1; else error(ERROR, "Incorrect syntax for `defined'"); tp++; continue; } if (np->flag&ISMAC) builtin(trp, np->val); else { expand(trp, np); } tp = trp->tp; } if (flag) unsetsource(); }
/** * process - 处理c源程序的总函数 * @trp: 用来存储c源程序中的一行Token */ void process(Tokenrow *trp) { int anymacros = 0; for (;;) { if (trp->tp >= trp->lp) { /* 如果当前token row中没有有效数据 */ trp->tp = trp->lp = trp->bp; /* 重置token row的当前token指针 */ outp = outbuf; /* 重置输出缓冲区的当前指针 */ anymacros |= gettokens(trp, 1); /* 得到一行Token */ trp->tp = trp->bp; } if (trp->tp->type == END) { /* 如果遇到EOFC结束符 */ if (--incdepth >= 0) { if (cursource->ifdepth) error(ERROR,"Unterminated conditional in #include"); unsetsource(); cursource->line += cursource->lineinc; trp->tp = trp->lp; genline(); continue; } if (ifdepth) error(ERROR, "Unterminated #if/#ifdef/#ifndef"); break; } if (trp->tp->type==SHARP) { /* 如果当前Token是'#'字符 */ trp->tp += 1; /* tp移动到token row中的下一个token */ control(trp); /* 处理预处理指令部分(宏定义,条件编译,头文件包含) */ } else if (!skipping && anymacros) expandrow(trp, NULL); if (skipping) /* 如果当前是忽略状态 */ setempty(trp); /* 置空当前行 */ puttokens(trp); /* 输出当前行 */ anymacros = 0; cursource->line += cursource->lineinc; if (cursource->lineinc>1) { genline(); } } }
/* * Evaluate the ## operators in a tokenrow */ void doconcat(Tokenrow *trp) { Token *ltp, *ntp; STATIC Tokenrow ntr; int len; CHECKIN(); for (trp->tp=trp->bp; trp->tp<trp->lp; trp->tp++) { if (trp->tp->type==DSHARP1) trp->tp->type = DSHARP; else if (trp->tp->type==DSHARP) { STATIC char tt[128]; ltp = trp->tp-1; ntp = trp->tp+1; if (ltp<trp->bp || ntp>=trp->lp) { error(ERROR, "## occurs at border of replacement"); continue; } len = ltp->len + ntp->len; strncpy((char*)tt, (char*)ltp->t, ltp->len); strncpy((char*)tt+ltp->len, (char*)ntp->t, ntp->len); tt[len] = '\0'; setsource("<##>", -1, tt); maketokenrow(3, &ntr); gettokens(&ntr, 1); unsetsource(); if (ntr.lp-ntr.bp!=2 || ntr.bp->type==UNCLASS) error(WARNING, "Bad token %r produced by ##", &ntr); ntr.lp = ntr.bp+1; trp->tp = ltp; makespace(&ntr); insertrow(trp, (ntp-ltp)+1, &ntr); dofree(ntr.bp); trp->tp--; } } CHECKOUT(); }
void setup(int argc, char **argv) { int c, fd, i; char *fp, *dp; Tokenrow tr; extern void setup_kwtab(void); setup_kwtab(); while ((c = getopt(argc, argv, "MNOVv+I:D:U:F:lg")) != -1) switch (c) { case 'N': for (i=0; i<NINCLUDE; i++) if (includelist[i].always==1) includelist[i].deleted = 1; break; case 'I': for (i=NINCLUDE-2; i>=0; i--) { if (includelist[i].file==NULL) { includelist[i].always = 1; includelist[i].file = optarg; break; } } if (i<0) error(FATAL, "Too many -I directives"); break; case 'D': case 'U': setsource("<cmdarg>", -1, optarg); maketokenrow(3, &tr); gettokens(&tr, 1); doadefine(&tr, c); unsetsource(); break; case 'M': Mflag++; break; case 'v': fprintf(stderr, "%s %s\n", argv[0], rcsid); break; case 'V': verbose++; break; case '+': Cplusplus++; break; default: break; } dp = "."; fp = "<stdin>"; fd = 0; if (optind<argc) { if ((fp = strrchr(argv[optind], '/')) != NULL) { int len = fp - argv[optind]; dp = (char*)newstring((uchar*)argv[optind], len+1, 0); dp[len] = '\0'; } fp = (char*)newstring((uchar*)argv[optind], strlen(argv[optind]), 0); if ((fd = open(fp, 0)) <= 0) error(FATAL, "Can't open input file %s", fp); } if (optind+1<argc) { int fdo = creat(argv[optind+1], 0666); if (fdo<0) error(FATAL, "Can't open output file %s", argv[optind+1]); dup2(fdo, 1); } if(Mflag) setobjname(fp); includelist[NINCLUDE-1].always = 0; includelist[NINCLUDE-1].file = dp; setsource(fp, fd, NULL); }
/* * Evaluate the ## operators in a tokenrow */ void doconcat(Tokenrow * trp) { Token *ltp, *ntp; Tokenrow ntr; size_t len; for (trp->tp = trp->bp; trp->tp < trp->lp; trp->tp++) { if (trp->tp->type == DSHARP1) trp->tp->type = DSHARP; else if (trp->tp->type == DSHARP) { int i; char tt[NCONCAT]; ltp = trp->tp - 1; ntp = trp->tp + 1; if (ltp < trp->bp || ntp >= trp->lp) { error(ERROR, "## occurs at border of replacement"); continue; } ntp = ltp; i = 1; len = 0; do { if (len + ntp->len + ntp->wslen > sizeof(tt)) { error(ERROR, "## string concatination buffer overrun"); break; } if (ntp != trp->tp + 1) { strncpy((char *) tt + len, (char *) ntp->t - ntp->wslen, ntp->len + ntp->wslen); len += ntp->len + ntp->wslen; } else // Leerzeichen um ## herum entfernen: { strncpy((char *) tt + len, (char *) ntp->t, ntp->len); len += ntp->len; } ntp = trp->tp + i; i++; } while (ntp < trp->lp); tt[len] = '\0'; setsource("<##>", -1, -1, tt, 0); maketokenrow(3, &ntr); gettokens(&ntr, 1); unsetsource(); if (ntr.bp->type == UNCLASS) error(WARNING, "Bad token %r produced by ##", &ntr); while ((ntr.lp-1)->len == 0 && ntr.lp != ntr.bp) ntr.lp--; doconcat(&ntr); trp->tp = ltp; makespace(&ntr, ltp); insertrow(trp, (int)(ntp - ltp), &ntr); dofree(ntr.bp); trp->tp--; } } }
/* * Do macro expansion in a row of tokens. * Flag is NULL if more input can be gathered. */ void expandrow(Tokenrow * trp, char *flag) { Token * tp; Nlist * np; MacroValidatorList validators; mvl_init(&validators); /* Sets all token-identifiers to 0 because tokens may not be initialised (never use C!) */ tokenrow_zeroTokenIdentifiers(trp); if (flag) setsource(flag, -1, -1, "", 0); for (tp = trp->tp; tp < trp->lp;) { mvl_check(&validators, tp); if (tp->type != NAME || quicklook(tp->t[0], tp->len > 1 ? tp->t[1] : 0) == 0 || (np = lookup(tp, 0)) == NULL || (np->flag & (ISDEFINED | ISMAC)) == 0 || (np->flag & ISACTIVE) != 0) { tp++; continue; } trp->tp = tp; if (np->val == KDEFINED) { tp->type = DEFINED; if ((tp + 1) < trp->lp && (tp + 1)->type == NAME) (tp + 1)->type = NAME1; else if ((tp + 3) < trp->lp && (tp + 1)->type == LP && (tp + 2)->type == NAME && (tp + 3)->type == RP) (tp + 2)->type = NAME1; else error(ERROR, "Incorrect syntax for `defined'"); tp++; continue; } else if (np->val == KMACHINE) { if (((tp - 1) >= trp->bp) && ((tp - 1)->type == SHARP)) { tp->type = ARCHITECTURE; if ((tp + 1) < trp->lp && (tp + 1)->type == NAME) (tp + 1)->type = NAME2; else if ((tp + 3) < trp->lp && (tp + 1)->type == LP && (tp + 2)->type == NAME && (tp + 3)->type == RP) (tp + 2)->type = NAME2; else error(ERROR, "Incorrect syntax for `#machine'"); } tp++; continue; } if (np->flag & ISMAC) builtin(trp, np->val); else expand(trp, np, &validators); tp = trp->tp; } // end for if (flag) unsetsource(); mvl_destruct(&validators); }
void setup(int argc, char **argv) { int c, fd, i, n; char *fp, *dp; Tokenrow tr; setup_kwtab(); #if defined(MACOSX) || defined(AIX) || defined(_WIN32) while ((c = stgetopt(argc, argv, "NOPV:I:D:U:F:A:X:u:l:+")) != -1) #else while ((c = getopt(argc, argv, "NOPV:I:D:U:F:A:X:u:l:+")) != -1) #endif switch (c) { case 'N': for (i = 0; i < NINCLUDE; i++) if (includelist[i].always == 1) includelist[i].deleted = 1; break; case 'I': for (i = NINCLUDE - 2; i >= 0; i--) { if (includelist[i].file == NULL) { includelist[i].always = 1; includelist[i].file = optarg; break; } } if (i < 0) error(FATAL, "Too many -I directives"); break; case 'D': case 'U': case 'A': setsource("<cmdarg>", -1, -1, optarg, 0); maketokenrow(3, &tr); gettokens(&tr, 1); doadefine(&tr, c); dofree(tr.bp); unsetsource(); break; case 'P': /* Lineinfo */ Pflag++; break; case 'V': for (n = 0; (c = optarg[n]) != '\0'; n++) switch (c) { case 'i': Iflag++; break; case 'm': Mflag = 1; break; case 'x': Mflag = 2; break; case 't': Vflag++; break; case 'v': fprintf(stderr, "%s\n", argv[0]); break; default: error(WARNING, "Unknown verbose option %c", c); } break; case 'X': for (n = 0; (c = optarg[n]) != '\0'; n++) switch (c) { case 'a': Aflag++; break; case 'i': Xflag++; break; case 'c': Cflag++; break; case 'd': Dflag++; break; case 'w': dp = &optarg[n + 1]; n += (int)strlen(dp); while (isspace(*dp)) dp++; for (i = NINCLUDE - 1; i >= 0; i--) { if (wraplist[i].file == NULL) { wraplist[i].file = dp; break; } } if (i < 0) error(WARNING, "Too many -Xw directives"); break; default: error(WARNING, "Unknown extension option %c", c); } break; case '+': Cplusplus++; break; case 'u': /* -undef fuer GCC (dummy) */ case 'l': /* -lang-c++ fuer GCC (dummy) */ break; default: break; } dp = "."; fp = "<stdin>"; fd = 0; if (optind < argc) { if ((fp = strrchr(argv[optind], '/')) != NULL) { int len = (int)(fp - argv[optind]); dp = (char *) newstring((uchar *) argv[optind], len + 1, 0); dp[len] = '\0'; } fp = (char *) newstring((uchar *) argv[optind], strlen(argv[optind]), 0); if ((fd = open(fp, O_RDONLY)) <= 0) error(FATAL, "Can't open input file %s", fp); } if (optind + 1 < argc) { int fdo = creat(argv[optind + 1], 0666); if (fdo < 0) error(FATAL, "Can't open output file %s", argv[optind + 1]); dup2(fdo, 1); } includelist[NINCLUDE - 1].always = 0; includelist[NINCLUDE - 1].file = dp; setsource(fp, -1, fd, NULL, 0); }