📄 preproc.c
字号:
*++s = '\0'; if (parms.n != 0) parameterise(&parms); newmacro(&parms); kill_Items(&parms);}int EiC_Include_file(char *e, /* name of file to Include for */ int mode) /* if 1, look locally first */{ /* returns 1 on success else it returns 0 */ int i,fd; char fname[512] = {0}; if(mode == 1) /* look in current directory first */ fd = open(e,O_RDONLY); else fd = -1; for(i=0;i<NINCLUDES && fd < 0;i++) { strcpy(fname,Include_prefixes[i]); strcat(fname,"/"); strcat(fname,e); if(EiC_verboseON) printf("looking for %s:%d\n",fname,file_cnt); fd = open(fname, O_RDONLY); } if (fd >= 0) NewInfile(fd,e,fname); else return 0; return fd;}static int control_line(void){ char key[25]; int k; char *s, *e; if (*line == '#') { s = line + 1; skipfws(s); if(!*s) /* test for null directive */ return 1; for(k=0;isalpha(*s);k++) key[k] = *s++; key[k] = '\0'; k = EiC_iskeyword(pwords, key, sizeof(pwords) / sizeof(keyword_t)); skipfws(s); switch (k) { case DEFINE: if (!skip) { if(*s) dodefmacro(s); else EiC_pre_error("empty '#define' directive"); } break; case ELIF: if(skip && skip == iflevel) { if(EiC_cpp_parse(s)) skip = 0; } else if(!skip && iflevel) skip = iflevel + 1; break; case ELSE: if (iflevel == 0) EiC_pre_error("Unmatched #else"); else if (skip == iflevel) skip = 0; else if (skip == 0) skip = iflevel; break; case ENDIF: if (iflevel == 0) EiC_pre_error("Unmatched #endif"); else { if (skip >= iflevel) skip = 0; --iflevel; } break; case IF: ++iflevel; if(!skip) { if(*s) { if(!EiC_cpp_parse(s)) skip = iflevel; } else EiC_pre_error("empty '#if' directive"); } break; case IFDEF: case IFNDEF: ++iflevel; if (!skip) { if (isalpha(*s) || *s == '_') { e = s; skipnws(s); *s = '\0'; if (EiC_ismacroid(e) > -1) { if (k == IFNDEF) skip = iflevel; } else if (k == IFDEF) skip = iflevel; } else EiC_pre_error("Illegal macro identifier"); } break; case INCLUDE: { if(skip) break; if(!*s) { EiC_pre_error("empty '#include' directive"); break; } if (*s == '\"') /* " */ s++, cmode = CMstr; else if (*s == '<') s++, cmode = CMang; else cmode = 0; e = s; skipnws(s); if (cmode) { if (cmode == CMstr && *(s - 1) != '\"') EiC_pre_error("Missing \""); else if (cmode == CMang && *(s - 1) != '>') EiC_pre_error("Missing >"); *--s = '\0'; } else { /* token_sequence */ lp = line; while (e != s) *lp++ = *e++; *lp = '\0'; process(); e = oline; } if(!EiC_Include_file(e,(cmode != CMang))) EiC_pre_error("failed to open include file %s",e); cmode = 0; } case UNDEF: if (!skip) { e = s; skipnws(s); *s = '\0'; k = EiC_ismacroid(e); if (k > -1) remmacroid(k); } break; case ERROR: if(!skip) { char *S = EiC_process2(s,0,0); EiC_pre_error(S); if(S) xfree(S); } break; case PRAGMA: if(!skip) { char *S = EiC_process2(s,0,0); if(S) { doPragma(S); xfree(S); } } break; default: { extern int ScriptMode; if(!ScriptMode) EiC_pre_error("undefined or invalid # directive"); } break; } return 1; } return skip;}#define TopMax 256#define MoD 10static int forbid[TopMax];static char * stringise(char * seq){ int i = 0; char *S=NULL; S = outChar(S,'\"',MoD,i++); /* " */ while(*seq) { if(*seq == '\"' || *seq == '\\') /* " */ S = outChar(S,'\\',MoD,i++); S = outChar(S,*seq++,MoD,i++); } S = outChar(S,'\"',MoD,i++); /* " */ S[i]='\0'; return S;}static char * EiC_expand(char *fld,char **end, int bot, int top){ char word[128]; int i = 0, k; char *p, *p2; macro_t *mac; char *S =NULL; eicstack_t parms = {0, NULL}; for(i=0;*fld && (isalnum(*fld) || *fld == '_');++i) word[i] = *fld++; word[i]=0; if(end) *end = fld; if ((k = EiC_ismacroid(word)) < 0) return NULL; for(i=bot;i<top;i++) if(k == forbid[i]) return NULL; forbid[top++] = k; skipfws(fld); mac = macros.val[k].p.p; if (mac->nparms > 0) { if (*fld != '(') return NULL; /**/ else { /* collect arguments */ ++fld; expr_list(&parms,&fld,1); } if(end) *end = fld; } if (parms.n != mac->nparms) EiC_pre_error("Macro syntax error"); else { char * t, *s; p = mac->tok_seq; /* Now substitute in arguments and * expand as necessary */ i = 0; S = NULL; while (*p) { if (*p < 0) { if(mac->protect && mac->protect[-*p] == 1) p2 = NULL; else if((i && S[i-1] == '#') || (i >= 2 && S[i-2] == '#')) { p2 = stringise(Item(&parms,-*p - 1,p.p)); if(S[i-1] == '#') i--; else i -= 2; } else p2 = EiC_process2(Item(&parms,-*p-1,p.p),top,top); if(p2) { char *p = p2; while (*p2) S = outChar(S,*p2++,MoD,i++); xfree(p); } else { p2 = Item(&parms,-*p - 1,p.p); while (*p2) S = outChar(S,*p2++,MoD,i++); } p++; } else S = outChar(S,*p++,MoD,i++); } if(S) { /* Now rescan macro definition */ char *S2=NULL; int k = 0; if(mac->nparms > 0) do { /* catch possible new macro funcs */ /* bit of hack, but seems to work */ /* should really check also for */ /* brackets in strings and char literals */ while(*fld && isspace(*fld)) fld++; while(*fld == '(') { int parens = 0; do { S = outChar(S,*fld,MoD,i++); if(*fld == '(') parens++; else if(*fld == ')') parens--; if(! *++fld && parens) { /* need more input */ if(EiC_Infile->fd == STDIN) { EiC_pre_error("Illegal line continuation " "during macro expansion"); break; } getline(); fld = line; } } while(*fld && parens); if(parens) EiC_pre_error("Missing `)'"); *end = fld; } } while(isspace(*fld)); s = S; S[i] = 0; while(*s) { if (*s == '"') { if (!cmode) cmode = CMstr; else if (cmode == CMstr) cmode = 0; } else if (*s == '\'') { if (!cmode) cmode = CMchr; else if (cmode == CMchr) cmode = 0; } else if(*s == '\\') S2 = outChar(S2,*s++,MoD,k++); else if((isalpha(*s) || *s == '_') && !cmode) { t = EiC_expand(s,&p,bot,top); if(t) { char * h = t; while(*t) S2 = outChar(S2,*t++,MoD,k++); xfree(h); s = p; } else while(s < p) S2 = outChar(S2,*s++,MoD,k++); continue; } S2 = outChar(S2,*s++,MoD,k++); } S2[k] = 0; xfree(S); S = S2; } } kill_Items(&parms); return S;}char * EiC_process2(char * line,int bot,int top){ int k = 0; char *p, *s, *S = NULL; char * lp = line; while (*lp) if (!cmode && (isalpha(*lp) || *lp == '_')) { s = lp; p = EiC_expand(lp, &lp,bot,top); if(p) { s = p; while(*p) S = outChar(S,*p++,MoD,k++); xfree(s); } else while(s != lp) S = outChar(S,*s++,MoD,k++); } else { if(*lp == '\'') { if (cmode == 0) cmode = CMchr; else if (cmode == CMchr) cmode = 0; } if (*lp == '\"') { /* " */ if (cmode == 0) cmode = CMstr; else if(cmode == CMstr) cmode = 0; } else if (*lp == '\\' && (cmode == CMstr || cmode == CMchr) ) { S = outChar(S,*lp++,MoD,k++); if (!*lp) /* get second char */ break; } S = outChar(S,*lp++,MoD,k++); } if(S) S[k] = '\0'; return S;}static void cp2out(char *S){ if(S) { while(*S) out(*S++); }}static void process(void){ char *S; *(olp = oline) = '\0'; S = EiC_process2(line,0,0); if(S) { cp2out(S); xfree(S); } cmode = 0;} int EiC_setinfile(char * fname){ /* look in current directory */ char name[100] = {0,}; int fd = open(fname,O_RDONLY); if(fd < 0) { sprintf(name,"%s/%s",getenv("HOME"),fname); fd = open(name,O_RDONLY); if(fd < 0) { /* look in search path include directories */ fd = EiC_Include_file(fname,0); return fd; } } if(fd > 0) NewInfile(fd,fname,name); return fd;}extern char *EiC_nextproline(void){ extern int EiC_SHOWLINE; while (1) { getline(); if(line[0] != ':') { if (!control_line()) { process(); break; } else if (EiC_Infile->fd == STDIN) { olp = oline; break; } } else if(!skip) { /* else got an EiC command line */ *(olp = oline) = '\0'; cp2out(line); break; } } if (EiC_Infile->fd == STDIN) out(EOF); if (EiC_SHOWLINE && !showON) { out('\0'); fputs(oline,stdout); fputc('\n',stdout); } return oline;}int EiC_insertpath(char *path){ /* Adds path to include path list */ int i; /* * don't append the same path more than once */ for(i=0;i<NINCLUDES;++i) if(strcmp(path,Include_prefixes[i]) == 0) return 1; Include_prefixes = realloc(Include_prefixes, sizeof(char*)*(NINCLUDES+1)); Include_prefixes[NINCLUDES] = EiC_strsave(path); if(!Include_prefixes[NINCLUDES]) return 0; NINCLUDES++; return 1;}int EiC_removepath(char *path){ int i,k; for(i=0;i<NINCLUDES;++i) if(Include_prefixes[i] && strcmp(path,Include_prefixes[i])==0) { xfree(Include_prefixes[i]); for(k=i;k<NINCLUDES-1;k++) Include_prefixes[k] = Include_prefixes[k+1]; NINCLUDES--; return 1; } return 0;}void EiC_listpath(void){ int i; for(i=0;i<NINCLUDES;++i) printf("%s\n",Include_prefixes[i]);}int EiC_initpp(void){ static int ftime = 1; NewInfile(STDIN,"::EiC::","::EiC::"); if (line) free(line); if (oline) free(oline); line = (char *) calloc(REBUFF_INCREMENT, sizeof(char)); oline = (char *) calloc(REBUFF_INCREMENT, sizeof(char)); linelen = olinelen = REBUFF_INCREMENT; if (!line || !oline) return 0; if(ftime) { dodefine("__FILE__=emp"); dodefine("__LINE__=emp"); dodefine("__DATE__=emp"); dodefine("__TIME__=emp"); dodefine("__STDC__=1"); ftime = 0; } return 1;}#ifdef _STANDALONE/* TODO: eicmod.c global needs header */extern int EiC_showIncludes = 0;static int EiC_iskeyword(keyword_t *keywords,char*id,int n){ int i; for(i=0;i<n;i++) if(strcmp(keywords[i].id,id) == 0) return keywords[i].token; return 0;}static void EiC_eicpush(eicstack_t *s, val_t v){ if(!(s->n%2)) { if(!s->n) s->val = (val_t*)xcalloc(sizeof(val_t),2); else s->val = (val_t*)xrealloc(s->val,(s->n+2)*sizeof(val_t)); } s->val[s->n] = v; s->n++;}static int EiC_eicpop(eicstack_t *s, val_t *pop){ if(s->n == 0) return 0; s->n--; *pop = s->val[s->n]; if(!(s->n%2)) { if(!s->n) xfree(s->val); else s->val = (val_t*)xrealloc(s->val,s->n*sizeof(val_t)); } return 1;}static extern char * EiC_strsave(char *s){ char *p; if((p = (char*)xcalloc(strlen(s)+1,sizeof(char))) != NULL) strcpy(p,s); return(p);}/* TODO: eicmod.c global needs header */int EiC_SHOWLINE = 1;static int do_sw_commands(char *cp){ switch(*cp++) { case 'D': dodefine(cp); return 1; case 'I': EiC_insertpath(cp);return 1; case '\?': case 'r': case 'R': EiC_setinfile(cp); return 1; case 's': case 'S': EiC_verboseON = 0; return 1; default: return 0; }}void main(int argc, char ** argv){ char *buf; EiC_initpp(); if(argc > 1) while(argv[1]) { if(argv[1][0] == '-') { if(!do_sw_commands(&argv[1][1])) { fprintf(stderr,"Unknown switch command [%s]\n",argv[1]); exit(0); } } else { fprintf(stderr,"Unknown switch command [%s]\n",argv[1]); exit(0); } argv++; } if(EiC_Infile->fd == STDIN) { fputs("testpp> ",stdout); fflush(stdout); } do { buf = EiC_nextproline(); while(*buf && *buf != EOF) buf++; }while(*buf != EOF); }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -