📄 preproc.c
字号:
if (lp != line) break; if (EiC_Infile->next) { NextInfile(); if(EiC_Infile->next) continue; }else if(!EiC_Interact) { int EiC_exit_EiC(); EiC_exit_EiC(); } break; case '/': if (cmode == 0) { /* check for comment*/ if((c = Rgetc()) == '*' || c == '/') { int i = 0; void (*sC) (char *s); char *comment = NULL; if(c == '/') /* Allow for C++ style comments */ lcom = 1; /* strip comment out */ c = Rgetc(); sC = EiC_saveComment(); if(lp != line) in(' '); /* replace comment with space */ while(c != EOF) { if(sC) comment = outChar(comment,c,5,i++); if(c == '\n') { if(lcom == 1) { Ugetc(c); lcom = 0; break; } else ++EiC_Infile->lineno; } if(c == '*' && !lcom) { if((c = Rgetc()) == '/') break; } else if (c == '\\' && lcom) { /* allow for line splicing */ c = Rgetc(); /* waste next char */ if(c=='\r') c=Rgetc(); c = Rgetc(); } else c = Rgetc(); } if(sC) { comment = outChar(comment,'\0',5,i++); sC(comment); } } else { in('/'); if(c == '\n') ++EiC_Infile->lineno; if(c != EOF) in(c); } } else in('/'); continue; case '\"': /* " */ if (cmode == 0) cmode = CMstr; else if (cmode == CMstr) cmode = 0; in('\"'); /* " */ continue; case '\'': if (cmode == 0) cmode = CMchr; else if (cmode == CMchr) cmode = 0; in('\''); continue; case '\r': /* ignore carriage returns */ continue; case '\n': ++EiC_Infile->lineno; if(lp == line && EiC_Infile->next ) { continue; } if (cmode == CMstr) { if (!skip) EiC_pre_error("unbalanced \""); /* " */ else in('\"'); /* " */ cmode = 0; } else if (cmode == CMchr) { if (!skip) EiC_pre_error("unbalanced \'"); else in('\''); cmode = 0; } } break; } *lp = '\0'; return 1;}static void expr_list(eicstack_t *parms, char **p,int more){ extern char *EiC_strsave(char *); int c = 0, b = 0; char *s = *p; static unsigned sz =BUFSIZE; static char *str = NULL; val_t v; if(!str) str = (char*)malloc(BUFSIZE); while (1) { for (; *s; ++s) { if(isspace(*s) && !cmode) { while(*s && isspace(*s)) s++; if(!*s) break; s--; } if(c == sz) { sz += BUFSIZE; str = realloc(str,sz); } str[c++] = *s; switch (*s) { case '\\': str[c++] = *++s; /*get next char */ continue; case '{': case '(': if (cmode == 0) ++b; continue; case ',': if (cmode || b) continue; --c; break; case '}': case ')': if(b) {b--;continue;} if (cmode) continue; --c; break; case '\'': switch (cmode) { case 0: cmode = CMchr; case CMstr: continue; } cmode = 0; continue; case '\"': /* " */ switch (cmode) { case 0: cmode = CMstr; case CMchr: continue; } cmode = 0; continue; default: continue; } /* end switch */ break; } /* end for loop */ if(!b && *s) { str[c] = '\0'; /*strip leading white space */ c = 0; while(str[c] && isspace(str[c])) c++; v.p.p = EiC_strsave(&str[c]); EiC_eicpush(parms, v); } if(!*s && more) { /*need more input*/ if(EiC_Infile->fd == STDIN) { EiC_pre_error("Illegal line continuation during macro expansion"); break; } getline(); if(c && !isspace(str[c-1]) && !isspace(*line)) str[c++] = ' '; /* need white space */ s = line; continue; } if (*s == ')') break; if (*s != ',') { EiC_pre_error("Illegal macro definition"); break; } c = 0; s++; } /* end while */ *p = ++s; if(sz > BUFSIZE << 2) { sz = BUFSIZE; str = realloc(str,sz); } }static int findparm(eicstack_t *parms,char *name, size_t len){ int i; val_t *v; for (v = parms->val, i = 1; i <= parms->n; i++, v++) if (strncmp(v->p.p, name, len) == 0) return i; return 0;}static void mergeTokens(macro_t *mac){ char * s, *seq; int left, right; if(mac->nparms) { mac->protect = xcalloc(mac->nparms + 1,sizeof(char)); /*printf("%s id %ld\n",mac->id,tot_seen);*/ } s = seq = mac->tok_seq; while(*s) { if(!cmode && *s == '#' && *(s+1) == '#') { int d = (int)(s - seq) - 1; while(d >= 0 && seq[d] > 0 && isspace(seq[d])) d--; if(d < 0) EiC_pre_error("macro definition begins with ##"); left = d; d = (int)(s - seq) + 2; while(seq[d] > 0 && isspace(seq[d])) d++; if(!seq[d]) EiC_pre_error("macro definition ends with ##"); right = d; s = seq + left + 1; if(seq[left] < 0) mac->protect[-seq[left]] = 1; if(seq[right] < 0) mac->protect[-seq[right]] = 1; while(seq[left] != 0) seq[++left] = seq[right++]; } else 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; } s++; }}static void parameterise(eicstack_t *parms){ char *s, *id, *op; int i; cmode = 0; op = s = defmacro.tok_seq; while (*s) { if (!cmode && (isalpha(*s) || *s == '_')) { id = s++; while (isalnum(*s) || *s == '_') ++s; if ((i = findparm(parms, id, (size_t) (s - id))) != 0) *op++ = -i; else while (id < s) *op++ = *id++; } else { 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 (isspace(*s) && !cmode) { do s++; while(*s && isspace(*s)); *--s = ' '; } *op++ = *s++; } } *op = '\0'; if (cmode) { if (cmode == CMstr) EiC_pre_error("Missing end \" in macro token sequence"); else EiC_pre_error("Missing end ' in macro token sequence"); } else mergeTokens(&defmacro);}#ifndef _STANDALONEstatic void markmacro(macro_t * mac, char mark){ xmark(mac, mark); xmark(mac->id, mark); if(mac->protect) xmark(mac->protect,mark); if(mac->tok_seq != empty_string) xmark(mac->tok_seq, mark); EiC_stab_Mark(&FileNames,mark);}void EiC_markmacros(char mark){ macro_t *mac; val_t *v; int i; if (macros.n) { xmark(macros.val, mark); v = macros.val; for (i = 0; i < macros.n; ++i, ++v) { mac = v->p.p; markmacro(mac, mark); } } for(i=0;i<NINCLUDES;++i) xmark(Include_prefixes[i],mark);}#endifstatic void Check4Res(macro_t * mac){ char str[20]; char * itoa(int,char *s, int); int c = 0, q = 1; char * s = NULL; if(mac->id[0] == '_' && mac->id[1] == '_') { switch(mac->id[2]) { case 'F': if(strcmp(mac->id,"__FILE__") == 0) { c = 1; s = EiC_Infile->fname; if(strcmp(s,mac->tok_seq) == 0) return; } break; case 'L': if(strcmp(mac->id,"__LINE__")== 0) { sprintf(str,"%d",EiC_Infile->lineno); s = str; c = 1; q = 0; } break; case 'D': case 'T': if(strcmp(mac->id,"__DATE__") == 0 || strcmp(mac->id,"__TIME__") == 0) { time_t t = time(NULL); char * ct = ctime(&t); c = 1; s = str; if(mac->id[2] == 'D') { strncpy(str, ct+4, 7); strncpy(&str[7], ct+20, 4); str[11] = 0; } else { strncpy(str, ct+11, 8); str[8] = 0; } } break;/* case 'S': if(strcmp(mac->id,"__STDC__")== 0) { str[0] = '1'; str[1] = 0; s = str; c = 1; } break;*/ } if(c && s) { char * p; xfree(mac->tok_seq); p = mac->tok_seq = (char*)xmalloc(strlen(s) + 3); xmark(mac->tok_seq,eicstay); if(q) *p++ = '\"'; while(*s) *p++ = *s++; if(q) *p++ ='\"'; *p='\0'; } }}static void displayMacro(int k, char *id){ macro_t *mac = macros.val[k].p.p; char *s = mac->tok_seq; int c,p; printf("%s -> #define %s",id,id); if(mac->nparms) { putchar('('); for(p = 0;*s != 0;++s) if(*s < p) p = *s; s = mac->tok_seq; p = abs(p); for(k=0; k<p;++k) { c = 'a'+k; putchar(c); if(k+1 < mac->nparms) putchar(','); } putchar(')'); } putchar('\t'); for(k = 0;*s != 0;++s,++k) if(*s < 0) { if(k) if(*(s-1) > EOF && isalnum(*(s-1))) printf(" ## "); c = 'a' - *s - 1; putchar(c); if(*(s+1) && (*(s+1) < 0 || isalnum(*(s+1)))) printf(" ## "); } else putchar(*s); putchar('\n');} int EiC_showMacro(char * id){ int k; if((k = EiC_ismacroid(id)) >= 0) { displayMacro(k,id); return 1; } return 0;}void EiC_showFileMacros(char *fname){ macro_t *mac; val_t *v; int i; v = macros.val; for (i = 0; i < macros.n; ++i, ++v) { mac = v->p.p; if (strcmp(mac->fname, fname) == 0) displayMacro(i,mac->id); }}void EiC_ClearFileMacros(char *fname){ /* clear all the macros from the macro lut * that were entered via file `fname' */ macro_t *mac; val_t *v; int i, *ind = NULL, cnt = 0; v = macros.val; for (i = 0; i < macros.n; ++i, ++v) { mac = v->p.p; if (strcmp(mac->fname, fname) == 0) { if(cnt) ind = xrealloc(ind,sizeof(int) * (cnt + 1)); else ind = xmalloc(sizeof(int)); ind[cnt++] = i; } } for(i = cnt; i>0;i--) remmacroid(ind[i-1]); if(ind) xfree(ind);}int EiC_ismacroid(char *id){ unsigned long hc; macro_t *mac; val_t *v; int i; v = macros.val; hc = get_hcode((unsigned char *)id); for (i = 0; i < macros.n; ++i, ++v) { mac = v->p.p; if (hc == mac->hcode && strcmp(mac->id, id) == 0) { Check4Res(mac); return i; } } return -1;}static void kill_Items(eicstack_t *parms){ if (parms->n) { int i; for (i = 0; i < parms->n; i++) xfree(parms->val[i].p.p); xfree(parms->val); parms->n = 0; } parms->val = NULL;}static void freemacro(macro_t * mac){ if (mac->id) { xfree(mac->id); mac->id = NULL; } if (mac->tok_seq) { if(mac->tok_seq != empty_string) xfree(mac->tok_seq); mac->tok_seq = NULL; } if(mac->protect) xfree(mac->protect);}static void remmacroid(int k){ val_t v; macro_t *mac; mac = macros.val[k].p.p; freemacro(mac); if(macros.n) { if(k < macros.n-1) { memmove(¯os.val[k], ¯os.val[k + 1], ((macros.n-1) - k) * sizeof(val_t)); } /* Throw away last item on stack*/ EiC_eicpop(¯os,&v); } xfree(mac);}static void newmacro(eicstack_t *parms){ macro_t *new; int k; k = EiC_ismacroid(defmacro.id); if (k > -1) { macro_t *old; old = macros.val[k].p.p; if ((old->nparms != parms->n) || !((old->tok_seq == empty_string && !*defmacro.tok_seq) || strcmp(old->tok_seq, defmacro.tok_seq) == 0)) { EiC_pre_error("Re-declaration of macro %s",defmacro.id); } if(defmacro.protect) xfree(defmacro.protect); } else { val_t v; new = (macro_t *) xcalloc(1, sizeof(macro_t)); defmacro.id = EiC_strsave(defmacro.id); defmacro.hcode = get_hcode((unsigned char *)defmacro.id); defmacro.fname = CurrentFileName(); if(*defmacro.tok_seq) defmacro.tok_seq = EiC_strsave(defmacro.tok_seq); else /* allow for empty macro */ defmacro.tok_seq = empty_string; defmacro.nparms = parms->n; *new = defmacro; v.p.p = new; EiC_eicpush(¯os, v); } defmacro.protect = defmacro.id = defmacro.tok_seq = NULL;}extern void dodefine(char *def){ /* * for processing -Dname[=value] switch * def = name[=value] */ if(def) { char * p; int i = strlen(def); char * str = xmalloc(i+3); memcpy(str,def,i+1); for(p = str;*p && *p != '=';++p) ; if(*p) { *p = ' '; str[i] = 0; }else { str[i] = ' '; str[i+1] = '1'; str[i+2] = 0; } dodefmacro(str); xfree(str); }} static void dodefmacro(char *s){ eicstack_t parms = {0, NULL}; skipfws(s); defmacro.id = s; while (*s && !isspace(*s) && *s != '(') ++s; if (*s == '(') { *s++ = '\0'; expr_list(&parms,&s,0); } else if(*s) *s++ = '\0'; skipfws(s); defmacro.tok_seq = s; defmacro.nparms = parms.n; skipall(s); --s; skipbws(s);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -