📄 preproc.c
字号:
/*
Copyright 1994-2003 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
This program is derived from the cc68k complier by
Matthew Brandt (mattb@walkingdog.net)
You may contact the author of this derivative at:
mailto::camille@bluegrass.net
or by snail mail at:
David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222
*/
#include <stdio.h>
#include <fcntl.h>
#include <ctype.h>
#include <string.h>
#include <limits.h>
#include "utype.h"
#include "cmdline.h"
#include "lists.h"
#include "expr.h"
#include "c.h"
#include "ccerr.h"
#include <time.h>
#define REPLACED_TOKENIZING 0x80
#define TOKENIZING_PLACEHOLDER 0x81
extern int prm_nasm, prm_c99;
extern short inputline[];
extern int inputFile;
extern TABLE *gsyms, defsyms;
extern LLONG_TYPE ival;
extern char laststr[];
extern HASHREC **defhash;
extern char *infile;
extern int incconst;
extern char *prm_searchpath, *sys_searchpath;
extern int prm_cplusplus, prm_ansi;
extern short *lptr;
extern int cantnewline;
extern int backupchar;
extern int floatregs, dataregs, addrregs, basefr, basedr, basear;
extern int prm_cmangle;
extern enum e_sym lastst;
extern char lastid[];
extern int lastch;
extern int lineno;
extern int global_flag;
extern char inputbuffer[32768];
extern int inputlen;
extern char *ibufPtr;
typedef struct _startups_
{
struct _startups_ *link;
char *name;
int prio;
} STARTUPS;
#define INCL_LEVEL_MAX 16
char *errfile;
int sys_inc;
int errlineno = 0;
IFSTRUCT *ifshold[70];
char *inclfname[INCL_LEVEL_MAX];
int inclfile[INCL_LEVEL_MAX];
int incldepth = 0;
int inclline[64];
int inclcurrent[INCL_LEVEL_MAX];
char *incldata[INCL_LEVEL_MAX];
int inclpos[INCL_LEVEL_MAX];
int inclsysflags[INCL_LEVEL_MAX];
char *inclptr[INCL_LEVEL_MAX];
short *lptr;
int stdpragmas;
FILELIST *incfiles = 0, *lastinc;
LIST *libincludes = 0;
IFSTRUCT *ifs = 0;
int ifskip = 0;
int elsetaken = 0;
int currentfile = 0;
AUXLIST *auxlist;
int packdata[100] =
{
1
};
int packlevel;
void filemac(short *string);
void datemac(short *string);
void timemac(short *string);
void linemac(short *string);
static char *unmangid; /* In this module we have to ignore leading underscores
*/
static STARTUPS *startuplist, *rundownlist;
static short defkw[] =
{
'd', 'e', 'f', 'i', 'n', 'e', 'd', 0
};
static int definelistcount;
static SYM *definelist[100]; /* Way deep but hey! */
static int skiplevel;
/* List of standard macros */
#define INGROWNMACROS 4
struct inmac
{
char *s;
void(*func)();
} ingrownmacros[INGROWNMACROS] =
{
{
"__FILE__", filemac
}
,
{
"__DATE__", datemac,
}
,
{
"__TIME__", timemac
}
,
{
"__LINE__", linemac
}
};
static void repdefines(short *lptr);
void pushif(void);
/* Moudle init */
void preprocini()
{
stdpragmas = STD_PRAGMA_FCONTRACT ;
skiplevel = 0;
libincludes = 0;
floatregs = basefr;
dataregs = basedr;
addrregs = basear;
incldepth = 0;
incfiles = 0;
ifs = 0;
ifskip = elsetaken = 0;
currentfile = 0;
unmangid = lastid;
if (prm_cmangle)
unmangid++;
startuplist = rundownlist = 0;
lastinc = 0;
}
/* Preprocessor dispatch */
int preprocess(void)
{
++lptr;
lastch = ' ';
while (isspace (*lptr))
lptr++ ;
if (*lptr == '\n' || ! *lptr)
return incldepth == 0;
getsym(); /* get first word on line */
if (lastst != id && lastst != kw_else && lastst != kw_if)
{
generror(ERR_IDEXPECT, 0, 0);
return incldepth == 0;
}
if (strcmp(unmangid, "include") == 0)
return doinclude();
else if (strcmp(unmangid, "define") == 0)
return dodefine();
else if (strcmp(unmangid, "endif") == 0)
return doendif();
else if (lastst == kw_else)
return doelse();
else if (strcmp(unmangid, "ifdef") == 0)
return doifdef(TRUE);
else if (strcmp(unmangid, "ifndef") == 0)
return doifdef(FALSE);
else if (lastst == kw_if)
{
repdefines(lptr);
defcheck(lptr);
return doif(0);
}
else if (strcmp(unmangid, "elif") == 0)
{
repdefines(lptr);
defcheck(lptr);
return doelif();
}
else if (strcmp(unmangid, "undef") == 0)
return (doundef());
else if (strcmp(unmangid, "error") == 0)
return (doerror());
else if (strcmp(unmangid, "pragma") == 0)
return (dopragma());
else if (strcmp(unmangid, "line") == 0)
return (doline());
else
{
gensymerror(ERR_PREPROCID, unmangid);
return incldepth == 0;
}
}
//-------------------------------------------------------------------------
int doerror(void)
{
char *temp;
int i = 0;
if (ifskip)
return incldepth == 0;
global_flag++;
temp = xalloc(pstrlen(lptr) *3+2);
pstrcpy(temp, lptr);
while (*lptr)
temp[i++] = *lptr++;
temp[i - 1] = 0;
global_flag--;
basicerror(ERR_ERROR, temp);
return incldepth == 0;
}
//-------------------------------------------------------------------------
char *getauxname(short *ptr, char **bufp)
{
char buf[200], *bp = buf;
while (isspace(*ptr))
ptr++;
if (*ptr != '"' && *ptr != '<')
{
generror(ERR_ILLCHAR, *ptr, 0);
return 0;
}
ptr++;
if (prm_cmangle)
*bp++ = '_';
while (*ptr && *ptr != '>' && *ptr != '"')
*bp++ = *ptr++;
*bp++ = 0;
if (! *ptr || *ptr != '"' && *ptr != '>')
{
generror(ERR_ILLCHAR, *(ptr - 1), 0);
return 0;
}
ptr++;
while (isspace(*ptr))
ptr++;
*bufp = xalloc(strlen(buf) + 1);
strcpy(*bufp, buf);
return ptr;
}
//-------------------------------------------------------------------------
static int pragerror(int errno)
{
char buf[100], *p = buf, i = 99;
short *s = lptr;
while (i-- && *s && *s != '\n')
*p++ = *s++;
*p = 0;
basicerror(errno, buf);
return (incldepth == 0);
}
//-------------------------------------------------------------------------
int dopragma(void)
{
char buf[40], *p = buf;
STARTUPS *a;
int val = 0, sflag;
if (ifskip)
return incldepth == 0;
cantnewline = TRUE;
lineToCpp();
getsym();
cantnewline = FALSE;
if (lastst != id)
return incldepth == 0;
if (!strcmp(unmangid, "error"))
return pragerror(ERR_USERERR);
else if (!strcmp(unmangid, "warning"))
return pragerror(ERR_USERWARN);
else if (!strcmp(unmangid, "startup"))
sflag = 1;
else if (!strcmp(unmangid, "rundown"))
sflag = 0;
else if (!strncmp(unmangid, "regopt", 6))
{
short *s = lptr;
dataregs = floatregs = addrregs = 0;
while (*s != '\n')
{
switch (*s)
{
case 'a':
case 'A':
addrregs = 1;
break;
case 'f':
case 'F':
floatregs = 1;
break;
case 'd':
case 'D':
dataregs = 1;
break;
}
s++;
}
return incldepth == 0;
}
else if (!strncmp(unmangid, "STDC", 4))
{
int val = 0, on = 0;
cantnewline = TRUE;
getsym();
cantnewline = FALSE;
if (!strncmp(unmangid, "FENV_ACCESS", 11))
val = STD_PRAGMA_FENV;
else if (!strncmp(unmangid, "CX_LIMITED_RANGE", 16))
val = STD_PRAGMA_CXLIMITED;
else if (!strncmp(unmangid, "FP_CONTRACT", 11))
val = STD_PRAGMA_FCONTRACT;
else
return incldepth == 0;
cantnewline = TRUE;
getsym();
cantnewline = FALSE;
if (!strncmp(unmangid, "ON", 2))
on = 1;
else if (strncmp(unmangid, "OFF", 3))
return incldepth == 0;
if (on)
stdpragmas |= val;
else
stdpragmas &= ~val;
return incldepth == 0;
}
else
if (!strncmp(unmangid, "library", 7))
{
if (prm_nasm)
{
generror(ERR_PREPIG, *lptr, 0);
}
else
{
short *s = lptr - 1;
char buf[128], *p = buf;
while (isspace(*s))
s++;
if (*s++ != '(')
{
generror(ERR_ILLCHAR, *lptr, 0);
}
else
{
while (isspace(*s))
s++;
while (isalnum(*s) || *s == '.' || *s == ':' || *s == '\\')
*p++ = *s++;
*p = 0;
while (isspace(*s))
s++;
if (*s++ != ')')
{
generror(ERR_ILLCHAR, *lptr, 0);
}
else
{
LIST *l;
char *f;
global_flag++;
f = litlate(buf);
l = xalloc(sizeof(LIST));
l->data = f;
l->link = libincludes;
libincludes = l;
global_flag--;
}
}
}
return incldepth == 0;
}
else
if (!strncmp(unmangid, "pack", 4))
{
lptr--;
while (isspace(*lptr))
lptr++;
if (*lptr != '(')
{
generror(ERR_ILLCHAR, *lptr, 0);
return incldepth = 0;
}
lptr++;
while (isspace(*lptr))
lptr++;
if (*lptr == ')')
{
if (packlevel)
packlevel--;
}
else if (isdigit(*lptr))
{
if (packlevel < sizeof(packdata) - 1)
{
packdata[++packlevel] = 0;
while (isdigit(*lptr))
{
packdata[packlevel] *= 10;
packdata[packlevel] += *lptr++ - '0';
}
if (packdata[packlevel] < 1)
packdata[packlevel] = 1;
}
while (isdigit(*lptr))
lptr++;
while (isspace(*lptr))
lptr++;
if (*lptr != ')')
generror(ERR_ILLCHAR, *lptr, 0);
}
return incldepth == 0;
}
else
if (!strcmp(unmangid, "aux"))
{
AUXLIST *newaux;
SYM *sp;
char *name;
char *alias;
++global_flag;
lptr = getauxname(lptr, &name);
--global_flag;
if (!lptr)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -