📄 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 _STANDALONE
static 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);
}
#endif
static 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 + -