📄 preproc.c
字号:
text[r++] = '\"';
text[r] = 0;
for (i = r; i >= 0; i--)
text[i + 1] = text[i];
*text = '\"';
}
}
p = pstrlen(text);
val = p - replen;
r = pstrlen(begin);
if (val + (int)strlen(begin) + 1 >= len)
{
generror(ERR_MACROSUBS, 0, 0);
return ( - 8000);
}
if (val > 0)
for (q = begin + r + 1; q >= end; q--)
*(q + val) = *q;
else
if (val < 0)
{
r = pstrlen(end) + 1;
for (q = end; q < end + r; q++)
*(q + val) = *q;
}
for (i = 0; i < p; i++)
begin[i] = text[i];
return (p);
}
/* replace macro args */
int defreplace(short *macro, int count, short **oldargs, short **newargs)
{
int i, rv;
int instring = 0;
short narg[1024];
short name[100];
short *p = macro, *q;
while (*p)
{
if (*p == instring)
instring = 0;
else if (*p == '\'' || *p == '"')
instring = *p;
else if (!instring && isstartchar(*p))
{
q = p;
defid(name, &p, 0);
for (i = 0; i < count; i++)
if (!pstrcmp(name, oldargs[i]))
{
pstrcpy(narg, newargs[i]);
if ((rv = definsert(p, q, narg, 1024-(q - macro), p - q)) == -
8000)
return (FALSE);
else
{
p = q + rv;
break;
}
}
}
p++;
}
return (TRUE);
}
/* Handlers for default macros */
void cnvt(short *out, char *in)
{
while (*in)
*out++ = *in++;
*out = 0;
}
//-------------------------------------------------------------------------
void filemac(short *string)
{
char str1[40];
sprintf(str1, "\"%s\"", infile);
cnvt(string, str1);
}
//-------------------------------------------------------------------------
void datemac(short *string)
{
char str1[40];
struct tm *t1;
time_t t2;
time(&t2);
t1 = localtime(&t2);
strftime(str1, 40, "\"%b %d %Y\"", t1);
cnvt(string, str1);
}
//-------------------------------------------------------------------------
void timemac(short *string)
{
char str1[40];
struct tm *t1;
time_t t2;
time(&t2);
t1 = localtime(&t2);
str1[0] = '"';
strftime(str1, 40, "\"%X\"", t1);
cnvt(string, str1);
}
//-------------------------------------------------------------------------
void linemac(short *string)
{
char str1[40];
sprintf(str1, "%d", lineno);
cnvt(string, str1);
}
/* Scan for default macros and replace them */
void defmacroreplace(short *macro, short *name)
{
int i;
macro[0] = 0;
for (i = 0; i < INGROWNMACROS; i++)
if (!strcmp(name, ingrownmacros[i].s))
{
(ingrownmacros[i].func)(macro);
break;
}
}
/* The next few functions support recursion blocking for macros.
* Basicall a list of all active macros is kept and if a lookup would
* result in one of those macros, no replacement is done.
*/
void nodefines(void)
{
definelistcount = 0;
}
//-------------------------------------------------------------------------
int indefine(SYM *sp)
{
int i;
for (i = 0; i < definelistcount; i++)
if (sp == definelist[i])
return TRUE;
return FALSE;
}
//-------------------------------------------------------------------------
void enterdefine(SYM *sp)
{
definelist[definelistcount++] = sp;
}
//-------------------------------------------------------------------------
void exitdefine(void)
{
definelistcount--;
}
//-------------------------------------------------------------------------
int replacesegment(short *start, short *end, int *inbuffer, int totallen, int
*changed)
{
short macro[1024];
short name[1024];
short *args[40];
char ascii[60];
int waiting = FALSE, rv;
short *p, *q;
SYM *sp;
p = start;
while (p < end)
{
q = p;
if (*p == '"')
{
waiting = !waiting;
p++;
}
else if (waiting)
p++;
else if (isstartchar(*p))
{
defid(name, &p, ascii);
if ((sp = search(ascii, &defsyms)) != 0 && !indefine(sp))
{
DEFSTRUCT *def = sp->value.s;
enterdefine(sp);
pstrcpy(macro, def->string);
if (def->argcount)
{
int count = 0;
short *q = p;
while (iswhitespacechar(*q))
q++;
if (*q++ != '(')
{
exitdefine();
goto join;
}
p = q;
if (def->argcount > 1)
{
do
{
short *nm = name;
int nestedparen = 0;
int nestedstring = 0;
while (((*p != ',' && *p != ')') || nestedparen ||
nestedstring) && *p != '\n')
{
if (*p == '(')nestedparen++;
if (*p == ')' && nestedparen)
nestedparen--;
if (nestedstring)
{
if (*p == nestedstring)
nestedstring = 0;
}
else if (*p == '\'' || *p == '"')
nestedstring = *p;
*nm++ = *p++;
}
while (iswhitespacechar(*(nm - 1)))
nm--;
*nm = 0;
nm = name;
while (iswhitespacechar(*nm))
nm++;
args[count++] = plitlate(nm);
}
while (*p++ == ',')
;
}
else
while (iswhitespacechar(*p++))
;
if (*(p - 1) != ')' || count != def->argcount - 1)
{
if (*(p - 1) == '\n')
return - 10;
gensymerror(ERR_WRONGMACROARGS, ascii);
return - 1;
}
/* Can't replace if tokenizing next */
if (*p == '#' && *(p + 1) == '#')
continue;
if (count == 0)
goto insert;
if (!defreplace(macro, count, def->args, args))
return - 1;
}
insert: if ((rv = definsert(p, q, macro, totallen - *inbuffer,
p - q)) == - 8000)
return - 1;
*changed = TRUE;
rv = replacesegment(q, q + rv, inbuffer, totallen, changed);
if (rv < 0)
return rv;
end += rv - (p - q);
*inbuffer += rv - (p - q);
p = q + rv;
exitdefine();
*changed = TRUE;
}
else
{
join: defmacroreplace(macro, ascii);
if (macro[0])
{
if ((rv = definsert(p, q, macro, totallen - *inbuffer, p -
q)) == - 8000)
return - 1;
*changed = TRUE;
end += rv - (p - q);
*inbuffer += rv - (p - q);
p = q + rv;
}
}
}
else
p++;
}
return (int)(end - start);
}
/* Scan line for macros and do replacements */
int defcheck(short *line)
{
int x;
short *p = line, *q;
int inbuffer = pstrlen(line);
int changed = FALSE;
nodefines();
if ((x = replacesegment(line, line + inbuffer, &inbuffer, 4096, &changed))
< 0)
return x;
/* Token pasting */
if (changed)
{
p = q = line;
while (*p)
{
if (*p == '#' && *(p + 1) == '#')
p += 2;
else
*q++ = *p++;
}
*q = 0;
}
return 0;
}
//-------------------------------------------------------------------------
static void repdefines(short *lptr)
/*
* replace 'defined' keyword in #IF and #ELIF statements
*/
{
short *q = lptr;
short name[40];
char ascii[60];
while (*lptr)
{
if (!pstrncmp(lptr, defkw, 7))
{
int needend = FALSE;
lptr += 7;
if (*lptr == '(')
{
lptr++;
needend = TRUE;
}
while (iswhitespacechar(*lptr))
lptr++;
defid(name, &lptr, ascii);
while (iswhitespacechar(*lptr))
lptr++;
if (needend)
if (*lptr == ')')
lptr++;
else
expecttoken(closepa, 0);
if (search(ascii, &defsyms) != 0)
*q++ = '1';
else
*q++ = '0';
*q++ = ' ';
}
else
{
*q++ = *lptr++;
}
}
*q = 0;
}
//-------------------------------------------------------------------------
void pushif(void)
/* Push an if context */
{
IFSTRUCT *p;
p = AllocateMemory(sizeof(IFSTRUCT));
p->link = ifs;
p->iflevel = ifskip;
p->elsetaken = elsetaken;
elsetaken = FALSE;
ifs = p;
}
//-------------------------------------------------------------------------
void popif(void)
/* Pop an if context */
{
if (ifs)
{
ifskip = ifs->iflevel;
elsetaken = ifs->elsetaken;
ifs = ifs->link;
}
else
{
ifskip = 0;
elsetaken = 0;
}
}
//-------------------------------------------------------------------------
void ansieol(void)
{
if (prm_ansi)
{
while (iswhitespacechar(*lptr))
lptr++;
if (*lptr)
{
lastch = *lptr;
lastst = ident;
generror(ERR_UNEXPECT, 0, 0);
}
}
}
//-------------------------------------------------------------------------
int doifdef(int flag)
/* Handle IFDEF */
{
SYM *sp;
if (ifskip)
{
skiplevel++;
return (incldepth == 0);
}
getch();
while (isspace(lastch))
getch();
if (!isstartchar(lastch))
{
generror(ERR_IDEXPECT, 0, 0);
return incldepth == 0;
}
else
getid();
sp = search(unmangid, &defsyms);
pushif();
if (sp && !flag || !sp && flag)
ifskip = TRUE;
ansieol();
return (incldepth == 0);
}
//-------------------------------------------------------------------------
int doif(int flag)
/* Handle #if */
{
if (ifskip)
{
skiplevel++;
return (incldepth == 0);
}
getsym();
pushif();
// cantnewline = TRUE;
if (!intexpr())
ifskip = TRUE;
else
elsetaken = TRUE;
// cantnewline = FALSE;
ansieol();
return (incldepth == 0);
}
//-------------------------------------------------------------------------
int doelif(void)
/* Handle #elif */
{
int is;
if (skiplevel)
{
return (incldepth == 0);
}
getsym();
// cantnewline = TRUE;
is = !intexpr();
// cantnewline = FALSE;
if (!elsetaken)
{
if (ifs)
{
if (!ifs->iflevel)
ifskip = !ifskip || is || elsetaken;
if (!ifskip)
elsetaken = TRUE;
}
else
generror(ERR_PREPROCMATCH, 0, 0);
}
else
ifskip = TRUE;
ansieol();
return (incldepth == 0);
}
/* handle else */
int doelse(void)
{
if (skiplevel)
{
return (incldepth == 0);
}
if (ifs)
{
if (!ifs->iflevel)
ifskip = !ifskip || elsetaken;
}
else
generror(ERR_PREPROCMATCH, 0, 0);
ansieol();
return (incldepth == 0);
}
/* HAndle endif */
int doendif(void)
{
if (skiplevel)
{
skiplevel--;
return (incldepth == 0);
}
if (!ifs)
generror(ERR_PREPROCMATCH, 0, 0);
popif();
ansieol();
return (incldepth == 0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -