📄 preproc.c
字号:
/* `
* 68K/386 32-bit C compiler.
*
* copyright (c) 1997, David Lindauer
*
* This compiler is intended for educational use. It may not be used
* for profit without the express written consent of the author.
*
* It may be freely redistributed, as long as this notice remains intact
* and either the original sources or derived sources
* are distributed along with any executables derived from the originals.
*
* The author is not responsible for any damages that may arise from use
* of this software, either idirect or consequential.
*
* v1.35 March 1997
* David Lindauer, gclind01@starbase.spd.louisville.edu
*
* Credits to Mathew Brandt for original K&R C compiler
*
*/
#include <stdio.h>
#include <ctype.h>
#include "utype.h"
#include "cmdline.h"
#include "expr.h"
#include "c.h"
#include "errors.h"
#include "time.h"
extern short inputline[];
extern FILE *inputFile;
extern TABLE gsyms,defsyms;
extern long ival;
extern char laststr[];
extern HASHREC **defhash;
extern char *infile;
extern int incconst;
extern char *prm_searchpath;
extern int prm_cplusplus, prm_ansi;
extern short *lptr;
extern int cantnewline;
extern char *infile;
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;
typedef struct _list {
struct _list *link;
char *data;
} LIST;
typedef struct _startups_ {
struct _startups_ *link;
char *name;
int prio;
} STARTUPS;
char *errfile;
int errlineno = 0;
IFSTRUCT *ifshold[10];
char *inclfname[10];
FILE *inclfile[10];
int incldepth = 0;
int inclline[10];
short *lptr;
LIST *incfiles = 0,*lastinc;
IFSTRUCT *ifs = 0;
int ifskip = 0;
int elsetaken = 0;
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 };
/* List of standard macros */
#define INGROWNMACROS 4
struct inmac {
char *s;
void (*func)();
} ingrownmacros[INGROWNMACROS] = {
{ "__FILE__",filemac }, { "__DATE__",datemac, },
{ "__TIME__", timemac }, { "__LINE__",linemac } };
void pushif(void);
/* Moudle init */
void preprocini()
{
floatregs = basefr;
dataregs = basedr;
addrregs = basear;
incldepth = 0;
incfiles = 0;
ifs = 0;
ifskip = elsetaken = 0;
unmangid = lastid;
if (prm_cmangle)
unmangid++;
startuplist = rundownlist = 0;
}
/* Preprocessor dispatch */
int preprocess(void)
{
++lptr;
lastch = ' ';
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)
i+=installphichar(*lptr++,temp,i);
temp[i-1] = 0;
global_flag--;
basicerror(ERR_ERROR,temp);
return incldepth == 0;
}
int dopragma(void)
{
char buf[40],*p=buf;
STARTUPS *a;
int val = 0,sflag;
if (ifskip)
return incldepth == 0;
lineToCpp();
getsym();
if (lastst != id)
return incldepth == 0;
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 return incldepth == 0;
if (prm_cmangle)
*p++ = '_';
while (isalnum(*lptr) || *lptr == '_')
*p++=*lptr++;
*p=0;
while (*lptr && (*lptr == ' ' || *lptr == '\t' || *lptr == ','))
lptr++;
if (*lptr && *lptr != '\n' && !isdigit(*lptr)) {
generror(ERR_ILLCHAR,*lptr,0);
while (*lptr)
lptr++;
}
if (isdigit(*lptr))
while (isdigit(*lptr)) {
val *= 10;
val += (*lptr++)-'0';
}
else
val = 64;
++global_flag;
a = xalloc(sizeof(STARTUPS));
a->name = litlate(buf);
a->prio = val;
if (sflag) {
a->link = startuplist;
startuplist = a;
}
else {
a->link = rundownlist;
rundownlist = a;
}
--global_flag;
while (*lptr && (*lptr == ' ' || *lptr == '\t'))
lptr++;
if (*lptr && *lptr != '\n')
generror(ERR_ILLCHAR,*lptr,0);
return incldepth == 0;
}
void dumpstartups(void)
/*
* Dump references to startup/rundown code
*/
{
SYM *s;
if (startuplist) {
startupseg();
while (startuplist) {
s = search(startuplist->name,&gsyms);
if (!s || s->tp->type != bt_ifunc)
gensymerror(ERR_UPDOWN,startuplist->name);
else {
gensrref(s,startuplist->prio);
s->tp->uflags |= UF_USED;
}
startuplist = startuplist->link;
}
}
if (rundownlist) {
rundownseg();
while (rundownlist) {
s = search(rundownlist->name,&gsyms);
if (!s || s->tp->type != bt_ifunc)
gensymerror(ERR_UPDOWN,rundownlist->name);
else {
gensrref(s,rundownlist->prio);
s->tp->uflags |= UF_USED;
}
rundownlist = rundownlist->link;
}
}
}
int doline(void)
/*
* Handle #line directive
*/
{
int n;
getsym();
if (lastst != iconst)
gensymerror(ERR_PREPROCID,"#line");
else {
n = ival;
getsym();
if (lastst != sconst)
gensymerror(ERR_PREPROCID,"#line");
else
if (!ifskip) {
errfile = litlate(laststr);
errlineno = n-1;
}
}
return incldepth == 0;
}
int doinclude(void)
/*
* HAndle include files
*/
{ int rv;
FILE *oldfile = inputFile;
incconst = TRUE;
getsym(); /* get file to include */
incconst = FALSE;
if (ifskip)
return incldepth == 0;
if( lastst != sconst ) {
gensymerror(ERR_INCLFILE,"include");
return incldepth == 0;
}
if (incldepth > 9) {
generror(ERR_PREPROCID, 0,0);
return incldepth == 0;
}
inputFile = SearchPath(laststr,prm_searchpath,"r");
if( inputFile == 0 ) {
gensymerror(ERR_CANTOPEN,laststr);
inputFile = oldfile;
rv = incldepth == 0;
}
else {
LIST *list;
pushif();
ifshold[incldepth] = ifs;
elsetaken = 0;
ifskip = 0;
ifs = 0;
inclline[incldepth] = lineno;
inclfile[incldepth] = oldfile; /* push current input file */
inclfname[incldepth++] = infile;
global_flag++;
infile = litlate(laststr);
list = xalloc(sizeof(LIST));
list->data = infile;
list->link = 0;
if (incfiles)
lastinc = lastinc->link = list;
else
incfiles = lastinc = list;
errfile = infile;
errlineno = 0;
global_flag--;
rv = incldepth == 1;
lineno = 0;
}
return rv;
}
short *plitlate(short *string)
{
short *temp = xalloc(pstrlen(string)*sizeof(short)+sizeof(short));
pstrcpy(temp,string);
return temp;
}
void glbdefine(char *name, char*value)
{
{ SYM *sp;
short *p;
DEFSTRUCT *def;
if (( sp = search(name,&defsyms) )!= 0)
return;
++global_flag; /* always do #define as globals */
sp = xalloc(sizeof(SYM));
sp->name = litlate(name);
def = xalloc(sizeof(DEFSTRUCT));
def->args = 0;
def->argcount = 0;
def->string = p = xalloc(strlen(value)*sizeof(short));
while (*value)
*p++=*value++;
*p++=0;
sp->value.s = (char *) def;
insert(sp,&defsyms);
--global_flag;
return;
}
}
/* Handle #defines
* Doesn't check for redefine with different value
* Does handle ANSI macros
*/
int dodefine(void)
{ SYM *sp;
DEFSTRUCT *def;
short *args[40],count=0;
short *olptr;
int p;
getsym(); /* get past #define */
if (ifskip)
return incldepth == 0;
olptr = lptr;
if( lastst != id ) {
generror(ERR_IDEXPECT,0,0);
return incldepth == 0;
}
if (( sp = search(unmangid,&defsyms) )!= 0)
undef2();
++global_flag; /* always do #define as globals */
sp = xalloc(sizeof(SYM));
sp->name = litlate(unmangid);
def = xalloc(sizeof(DEFSTRUCT));
def->args = 0;
def->argcount = 0;
if (lastch == '(') {
getdefsym();
getdefsym();
while (lastst == id) {
args[count++] = plitlate(unmangid);
getdefsym();
if (lastst != comma)
break;
getdefsym();
}
if (lastst != closepa)
generror(ERR_PUNCT,closepa,0);
olptr = lptr;
def->args = xalloc(count*sizeof(short *));
memcpy(def->args,args,count*sizeof(short *));
def->argcount = count+1;
}
while (iswhitespacechar(*olptr))
olptr++;
p = pstrlen(olptr);
if (olptr[p-1] == 0x0a)
olptr[p-1] = 0;
def->string = plitlate(olptr);
sp->value.s = (char *) def;
insert(sp,&defsyms);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -