/* * Generate a line directive for cursource */ void genline(void) { static Token ta = { UNCLASS, NULL, 0, 0 }; static Tokenrow tr = { &ta, &ta, &ta+1, 1 }; uchar *p; if(nolineinfo) return; ta.t = p = (uchar*)outp; strcpy((char*)p, "#line "); p += sizeof("#line ")-1; p = (uchar*)outnum((char*)p, cursource->line); *p++ = ' '; *p++ = '"'; if (cursource->filename[0]!='/' && wd[0]) { strcpy((char*)p, wd); p += strlen(wd); *p++ = '/'; } strcpy((char*)p, cursource->filename); p += strlen((char*)p); *p++ = '"'; *p++ = '\n'; ta.len = (char*)p-outp; outp = (char*)p; tr.tp = tr.bp; puttokens(&tr); }
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(); } } }
/* * Generate a line directive for cursource */ void genline(void) { static Token ta = { UNCLASS }; static Tokenrow tr = { &ta, &ta, &ta+1, 1 }; uchar *p; ta.t = p = (uchar*)xoutp; strcpy((char*)p, "#line "); p += sizeof("#line ")-1; p = (uchar*)outnum((char*)p, cursource->line); *p++ = ' '; *p++ = '"'; strcpy((char*)p, cursource->filename); p += strlen((char*)p); *p++ = '"'; *p++ = '\n'; ta.len = (char*)p-xoutp; xoutp = (char*)p; tr.tp = tr.bp; puttokens(&tr); }
/** * 为当前输入源产生一个行控制指令信息 * Generate a line directive for cursource * TODO: 一般来说像gcc或者tcc之类的编译器产生的行控制指令是类似如下这样的: * # 3 "cpp_line_control.c" 2 * 而像lcc这样的编译器产生的行控制指令是类似如下这样的: * #line 2 "cpp_line_control.c" * 也就是说lcc产生的行控制信息中多了一个 line (而这其实是可选的单词)而且也少了flag信息,具体请参考testprog/c预处理小知识.txt一文 */ void genline(void) { static Token ta = { UNCLASS }; static Tokenrow tr = { &ta, &ta, &ta + 1, 1 }; uchar *p; ta.t = p = (uchar*) outp; strcpy((char*) p, "#line "); /* 将“#line ”复制到输出缓冲区 */ p += sizeof("#line ") - 1; p = (uchar*) outnum((char*) p, cursource->line); /* 输出当前文件的行号 */ *p++ = ' '; *p++ = '"'; strcpy((char*) p, cursource->filename); /* 输出当前文件的文件名 */ p += strlen((char*) p); *p++ = '"'; *p++ = '\n'; ta.len = (char*) p - outp; outp = (char*) p; /* 更新输出缓冲区的当前指针 */ tr.tp = tr.bp; /* 将当前token设置为token row中的第一个token的首地址,以便接下来调用puttokens函数输出token row */ puttokens(&tr); /* 输出 token row */ }
/** * 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(); } } }