📄 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 10
static 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 + -