📄 proc.c
字号:
skipbl(int mode) { Token *tokp; for (;;) { tokp = get_token(mode); if (!is_blank(tokp->token[0])) break; } return tokp;}Token *skipnl(Token *tokp) { if (tokp->val == TK_NL) { st_move(TK_NL); return tokp; } for(;;) { tokp = get_token(MOD_NOGRAM); if (tokp->val == TK_NL) break; } st_move(TK_NL); return tokp;}intsubstitute(SymPtr symp, unsigned mode) { unsigned lmode; char *s,*s1; int nform, nact, n; int plvl; char *mname; StrList *actuals,*p; char text[BUFSIZE]; char dynval[BUFSIZE]; char *d0,*d; int loc_errfl; int linesav; Token *tokp; lmode = (mode & ~MOD_SPACE) | MOD_NOGRAM; tokp = get_cur_tok(); linesav = tokp->lineno; s = symvals(symp); if (symp == filesymp || symp == FILEsymp) { if (*s == FPPDYNMACRO) { sprintf(dynval, "%c\"%s\"%c", 0, curfile->fname, -1); s = dynval + 1 + strlen(dynval+1); } } else if (symp == linesymp || symp == LINEsymp) { if (*s == FPPDYNMACRO) { sprintf(dynval, "%c%d%c", 0, linesav, -1); s = dynval + 1 + strlen(dynval+1); } } if (symrecurse(symp)) return 1; /* don't substitute `#define a(x) 1+a(x)` */ mname = symname(symp); outfl++; nform = *--s & 0xff; if (nform == 255) nform = -1; nact = -1; if (nform >= 0) { /* There must be arguments or () at least */ tokp = skipbl(lmode); if (tokp->token[0] != '(') { set_pos(linesav); if (!(lmode & MOD_COM)) fppmess(ERR_NOPAR); unget_tok(tokp); goto lab1; } nact = 0; actuals = NULL; d0 = text; *d0++ = '\0'; d = d0; plvl = 0; loc_errfl = 0; tokp = skipbl(lmode); for (;;) { switch(tokp->token[0]) { case '(': plvl++; break; case ')': if (!plvl && !nform && !nact && d == d0) { plvl--; break; } /* no break; */ case ',': if (!plvl) { while (is_blank(d[-1])) d--; /* trailing spaces */ *d++ = 0; p = my_alloc(sizeof(StrList),1); p->str = d0; p->next = actuals; actuals = p; d0 = d; nact++; if (tokp->token[0] == ',') { tokp = skipbl(lmode); /* heading spaces*/ continue; } } if (tokp->token[0] == ')') plvl--; break; default: if ((tokp->val == TK_NL) || (tokp->val == TK_BOS) || (tokp->val == TK_EOC)) { if (!(lmode & MOD_COM)) { set_pos(linesav); fppmess(ERR_LONG2, mname); } unget_tok(tokp); outfl--; return 0; } else if (sbfl && is_alpha0(tokp->token[0])) sb_mactual_ref(tokp->token); break; } if (plvl == -1) break; if (!loc_errfl) { /* text overfull */ if (tokp->length > sizeof(text) - (d - text)-1) { if (!(lmode & MOD_COM)) fppmess(ERR_LONG1); loc_errfl = 1; } else { strcpy(d, tokp->token); d += tokp->length; } } tokp = get_token(lmode); } if (sbfl) sb_mref(mname, 1, 1); if (loc_errfl) { /* skiptok(tokp); */ outfl--; return 0; } } else if (sbfl) sb_mref(mname, 0, 1); if (nact != nform && !(lmode & MOD_COM)) { set_pos(linesav); fppmess(ERR_NOMATCH); }lab1: n = line - linesav; /* skiptok(tokp); */ ungetsym(SYM_EOMS); while (n--) { ungetsym('\n'); ungetsym('\\'); } for (;;) { s1 = s--; while (*s && ((*s & 0xff) != SYM_CTRL)) s--; ungetstr(s+1, (s1 - s) - 1); if (!*s) break; n = *--s & 0xff; if (n == SYM_CTRL) { ungetsym(SYM_CTRL); continue; } ungetsym(SYM_EF); if (n <= nact) { p = actuals; n = nact - n; while (n--) p = p->next; ungetstr(p->str, strlen(p->str)); } ungetsym(SYM_BF); } sympush(symp); outfl--; return 0;}/************************************************************** Directives */static voidfpp_define(unsigned lmode) { char *mname,*mval; int npar; SymPtr sym; StrList *formals,*p; int i, n; char body[BUFSIZE]; char *d,*d1; Token *tokp; tokp = skipbl(lmode); if(!is_alpha0(tokp->token[0])) { fppmess(ERR_BADNAM); return; } mname = my_strdup(tokp->token); sym = symget(tokp->token, CL_NM|CL_KEY|CL_FOP); if (sym && (symtype(sym) & (CL_KEY|CL_FOP))) { fppmess(WARN_DUBL1,mname); sym = NULL; } outfl++; tokp = get_token(lmode); npar = -1; formals = NULL; if (tokp->token[0] == '(') { /* macro with arguments */ if (sbfl) sb_mdef(mname, 1); npar = 0; for (;;) { tokp = skipbl(lmode); if (is_alpha0(tokp->token[0])) { if (sbfl) sb_mformal_def(tokp->token); p = my_alloc(sizeof(StrList),1); p->str = my_strdup(tokp->token); p->next = formals; formals = p; npar++; tokp = skipbl(lmode); if (tokp->token[0] == ',') continue; } if (tokp->token[0] == ')') { tokp = skipbl(lmode); break; } else { fppmess(ERR_BADS,"define"); goto exit; } } } else { if (sbfl) sb_mdef(mname, 0); if (is_blank(tokp->token[0])) tokp = skipbl(lmode); } d = body; *d++ = 'b'; for (;;tokp = get_token(lmode)) { if (tokp->val == TK_NL) break; if (is_alpha0(tokp->token[0])) { n = 0; if (npar > 0) { p = formals; for (n=npar,p=formals;n;n--,p=p->next) { if (!strcmp(p->str,tokp->token)) break; } } if (n) { CHECK(p); if (sbfl) sb_mformal_ref(tokp->token); if (d-body > sizeof(body)-4) { fppmess(ERR_LONG); goto exit; } *d++ = n; *d++ = SYM_CTRL; continue; } else if (sbfl) sb_mnonformal_ref(tokp->token); } if (d-body > sizeof(body) - tokp->length -2) { fppmess(ERR_LONG); goto exit; } d1 = tokp->token; for (i=0; i < tokp->length; i++) { if ((*d1 & 0xff) == SYM_CTRL) { /* Double SYM_CTRL */ *d++ = SYM_CTRL; } *d++ = *d1++; } } while (is_blank(d[-1])) d--; /* remove trailng spaces */ *d++ = npar & 0xff; *d = 0; mval = my_strdup(body); *mval = 0; mval += d - body; if (sym) { d = symvals(sym) - 1; d1 = mval - 1; do { if (*d != *d1) { fppmess(WARN_DUBL,mname); break; } } while (*d-- && *d1--); symsetvals(sym,mval); } else symsetnm(mname,mval); if (sbfl) sb_mdef_end(); CHECK(tokp->val == TK_NL);exit: outfl--; return;}static voidfpp_include(unsigned lmode) { char c; InFile *incf; char fname[BUFSIZE]; char fullname[BUFSIZE]; StrList *paths; Token *tokp; paths = &include_path; fname[0] = 0; dosubstfl++; /* enable to use macro */ tokp = skipbl(lmode); dosubstfl--; outfl++; c = tokp->token[0]; if (c == '\"' || c == '\'') { strncpy(fname, tokp->token+1, tokp->length-2); fname[tokp->length-2] = 0; if (sbfl) sb_include(0,fname); } else if (c == '<') { for (;;) { tokp = get_token(0); if (tokp->token[0] == '>') break; strcat(fname,tokp->token); } paths = paths->next; if (sbfl) sb_include(1,fname); } else { fppmess(ERR_BADS,"#include"); tokp = skipnl(tokp); outfl--; return; } tokp = skipnl(tokp); /* skiptok(tokp); */ outfl--; if (fname[0] == '/' ) { /* absolute name */ if (access(fname,F_OK) != 0) { fppmess(ERR_NOINC,fname); return; } strcpy(fullname,fname); } else { for (;paths;paths=paths->next) { strcpy(fullname,paths->str); strcat(fullname,"/"); strcat(fullname,fname); if (access(fullname,F_OK)==0) break; } if (paths == NULL) { fppmess(ERR_NOINC,fname); return; } } incf = my_fopen(fullname,"r"); incf->ifnode = curif; curbuf->psaved = curp; curfile->inbuf = curbuf; curfile->line = line; line = 1; incf->popfile = curfile; curfile = incf; curbuf = curfile->inbuf; curp = INBUF_BEG(curbuf); outpos(1, PUSHINCL); if (mdepfl) md_fwrite(fullname); return;}static voidfpp_if(unsigned lmode) { IfNode *tmp; if (curif) curif->flvlsaved = falselvl; tmp = my_alloc(sizeof(IfNode),1); tmp->popif = curif; tmp->ifline = line; curif = tmp; if (falselvl == 0) { if (sbfl) sb_if(); dosubstfl++; if (!yyparse()) { falselvl++; inactive = 1; } dosubstfl--; if (sbfl) sb_if_end(!falselvl); } else falselvl++;}static voidfpp_ifdef(unsigned lmode) { IfNode *tmp; Token *tokp; if (curif) curif->flvlsaved = falselvl; tmp = my_alloc(sizeof(IfNode),1); tmp->popif = curif; tmp->ifline = line; curif = tmp; if (falselvl == 0) { tokp = skipbl(lmode); if (symget(tokp->token,CL_NM) == NULL) { falselvl++; inactive = 1; } if (sbfl) sb_ifdef(!falselvl, tokp->token); } else falselvl++;}static voidfpp_ifndef(unsigned lmode) { IfNode *tmp; Token *tokp; if (curif) curif->flvlsaved = falselvl; tmp = my_alloc(sizeof(IfNode),1); tmp->popif = curif; tmp->ifline = line; curif = tmp; if (falselvl == 0) { tokp = skipbl(lmode); if (symget(tokp->token,CL_NM)) { falselvl++; inactive = 1; } if (sbfl) sb_ifndef(!falselvl, tokp->token); } else falselvl++;}static voidfpp_else() { if (curif == NULL) { fppmess(ERR_NOIF1); return; } if (curif->elsefl) { fppmess(ERR_ELSE); return; } else curif->elsefl = 1; if (falselvl == 0) { falselvl++; inactive = 1; } else if (falselvl == 1) { falselvl--; inactive = 0; if (sbfl) sb_set_inactive(inactive); }}static voidfpp_elif(unsigned lmode) { if (curif == NULL) { fppmess(ERR_NOIF2); return; } if (curif->elsefl) { fppmess(ERR_ELSE1); return; } if (falselvl == 0) { falselvl += 2; inactive = 1; if (sbfl) sb_set_inactive(1); } else if (falselvl == 1) { if (sbfl) { sb_if(); sb_set_inactive(0); } dosubstfl++; if (yyparse()) { falselvl--; inactive = 0; } dosubstfl--; if (sbfl) sb_if_end(!falselvl); }}static voidfpp_endif() { IfNode *tmp; if (curif == NULL) { fppmess(ERR_NOIF); return; } tmp = curif->popif; free(curif); curif = tmp; if (curif == NULL) { falselvl = 0; inactive = 0; } else { falselvl = curif->flvlsaved; inactive = (falselvl == 1); } if (sbfl && !inactive) sb_set_inactive(0);}static voidfpp_line(unsigned lmode) { Token *tokp; if (ignorelinefl) { tokp = get_token(lmode); tokp = skipnl(tokp); return; } dosubstfl++; /* allow to expand macros */ tokp = skipbl(lmode); if (tokp->val != TK_NUM) { fppmess(ERR_BADS,"#line"); goto exit; } strtoi(tokp->token,(int *)&line,10); tokp = skipbl(lmode); if (tokp->token[0] == '"') { if (tokp->token[tokp->length - 1] == '"') tokp->token[--tokp->length] = 0; if ( tokp->length != 0 && strcmp(curfile->fname,tokp->token+1) ) { free(curfile->fname); curfile->fname = my_strdup(tokp->token+1); ofileid = (unsigned)-1; } tokp = skipbl(lmode); if ((tokp->val == TK_NUM) && ( !strcmp(tokp->token, PUSHINCL) || !strcmp(tokp->token, POPINCL) ) ) { outpos(line, tokp->token); } } line--; /* to compensate the following newline */exit: dosubstfl--; tokp = skipnl(tokp); return;}static voiddirective() { unsigned lmode; int n; SymPtr sym; char locbuf[BUFSIZE]; Token *tokp; line_width = LINE_WIDTH_MAX; lmode = (mmode & ~(MOD_SPACE | MOD_CONT)) | MOD_FPP | MOD_NOGRAM; if (!fixedformfl) /* why not to use & for continuation? */ lmode |= MOD_CONT; outfl++; tokp = skipbl(lmode); if (tokp->val == TK_NL) { /* Just ignore empty # directve */ goto exit; } else if (tokp->val == TK_NUM) { /* This is #<line> [<file>] directive * If we haven't been told to ignore them * then process it. */ unget_tok(tokp); fpp_line(lmode); outfl--; return; } locbuf[0] = '#'; strcpy(locbuf+1,tokp->token); sym = symget(locbuf,CL_FPP); if (sym == NULL) { fppmess(ERR_FPP); goto exit; } n = symvali(sym); switch (n) { case FPPDEF: if (falselvl == 0) fpp_define(lmode); break; case FPPUNDEF: if (falselvl == 0) { tokp = skipbl(lmode); symdel(tokp->token); if (sbfl) sb_undef(tokp->token); } break; case FPPINCL: if (falselvl == 0) { fpp_include(lmode); outfl--; return; } break; case FPPIF: fpp_if(lmode); break; case FPPELIF: fpp_elif(lmode); break; case FPPELSE: fpp_else(); break; case FPPENDIF: fpp_endif(); break; case FPPIFDEF: fpp_ifdef(lmode); break; case FPPIFNDEF: fpp_ifndef(lmode);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -