version using input module and detecting preprocessor loops
This commit is contained in:
parent
91aad0b28e
commit
53d6dfcb6b
13 changed files with 239 additions and 599 deletions
|
@ -21,9 +21,6 @@
|
|||
/* Data about the token yielded */
|
||||
struct token dot, ahead, aside;
|
||||
|
||||
unsigned int LineNumber = 0; /* current LineNumber */
|
||||
char *FileName = 0; /* current filename */
|
||||
|
||||
int ReplaceMacros = 1; /* replacing macros */
|
||||
int EoiForNewline = 0; /* return EOI upon encountering newline */
|
||||
int PreProcKeys = 0; /* return preprocessor key */
|
||||
|
@ -31,6 +28,7 @@ int AccFileSpecifier = 0; /* return filespecifier <...> */
|
|||
int AccDefined = 0; /* accept "defined(...)" */
|
||||
int UnknownIdIsZero = 0; /* interpret unknown id as integer 0 */
|
||||
int SkipEscNewline = 0; /* how to interpret backslash-newline */
|
||||
int Unstacked = 0; /* an unstack is done */
|
||||
|
||||
#define MAX_LL_DEPTH 2
|
||||
|
||||
|
@ -102,21 +100,28 @@ GetToken(ptok)
|
|||
char buf[(IDFSIZE > NUMSIZE ? IDFSIZE : NUMSIZE) + 1];
|
||||
register int ch, nch;
|
||||
|
||||
if (! LineNumber) goto firstline;
|
||||
again: /* rescan the input after an error or replacement */
|
||||
#ifndef NOPP
|
||||
if (Unstacked) EnableMacros();
|
||||
#endif
|
||||
LoadChar(ch);
|
||||
go_on: /* rescan, the following character has been read */
|
||||
if ((ch & 0200) && ch != EOI) /* stop on non-ascii character */
|
||||
fatal("non-ascii '\\%03o' read", ch & 0377);
|
||||
switch (class(ch)) { /* detect character class */
|
||||
case STNL: /* newline, vertical space or formfeed */
|
||||
firstline:
|
||||
LineNumber++; /* also at vs and ff */
|
||||
if (EoiForNewline) /* called in control line */
|
||||
/* a newline in a control line indicates the
|
||||
end-of-information of the line.
|
||||
*/
|
||||
return ptok->tk_symb = EOI;
|
||||
while (LoadChar(ch), ch == '#') /* a control line follows */
|
||||
while (LoadChar(ch), ch == '#') { /* a control line follows */
|
||||
domacro();
|
||||
if (!LineNumber) goto firstline;
|
||||
}
|
||||
/* We have to loop here, because in
|
||||
`domacro' the nl, vt or ff is read. The
|
||||
character following it may again be a `#'.
|
||||
|
@ -253,6 +258,9 @@ go_on: /* rescan, the following character has been read */
|
|||
hash = STARTHASH();
|
||||
do { /* read the identifier */
|
||||
if (++pos < idfsize) {
|
||||
#ifndef NOPP
|
||||
if (Unstacked) EnableMacros();
|
||||
#endif
|
||||
*tg++ = ch;
|
||||
hash = ENHASH(hash, ch, pos);
|
||||
}
|
||||
|
@ -485,8 +493,10 @@ string_token(nm, stop_char, plen)
|
|||
}
|
||||
if (ch == '\\') {
|
||||
LoadChar(ch);
|
||||
if (ch == '\n')
|
||||
if (ch == '\n') {
|
||||
LineNumber++;
|
||||
continue;
|
||||
}
|
||||
ch = quoted(ch);
|
||||
}
|
||||
str[pos++] = ch;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
#include "nofloat.h"
|
||||
#include "file_info.h"
|
||||
|
||||
/* the structure of a token: */
|
||||
struct token {
|
||||
|
@ -42,8 +43,6 @@ struct token {
|
|||
#endif NOFLOAT
|
||||
|
||||
extern struct token dot, ahead, aside;
|
||||
extern unsigned int LineNumber; /* "LLlex.c" */
|
||||
extern char *FileName; /* "LLlex.c" */
|
||||
|
||||
extern int ReplaceMacros; /* "LLlex.c" */
|
||||
extern int EoiForNewline; /* "LLlex.c" */
|
||||
|
@ -52,6 +51,7 @@ extern int AccFileSpecifier; /* "LLlex.c" */
|
|||
extern int AccDefined; /* "LLlex.c" */
|
||||
extern int UnknownIdIsZero; /* "LLlex.c" */
|
||||
extern int SkipEscNewline; /* "LLlex.c" */
|
||||
extern int Unstacked; /* "LLlex.c" */
|
||||
|
||||
extern int NoUnstack; /* buffer.c */
|
||||
|
||||
|
|
|
@ -17,21 +17,23 @@ EMELIB = $(EM)/modules/lib/libeme.a
|
|||
STRLIB = $(EM)/modules/lib/libstr.a
|
||||
PRTLIB = $(EM)/modules/lib/libprint.a
|
||||
EMMESLIB = $(EM)/modules/lib/libem_mes.a
|
||||
INPLIB = $(EM)/modules/lib/libinput.a
|
||||
#CH3LIB = $(EM)/modules/lib/libch3.a
|
||||
CH3LIB =
|
||||
LIBS = $(CH3LIB) $(EMMESLIB) $(EMKLIB) $(PRTLIB) $(STRLIB) $(SYSLIB)
|
||||
ELIBS = $(CH3LIB) $(EMMESLIB) $(EMELIB) $(PRTLIB) $(STRLIB) $(SYSLIB)
|
||||
LIB_INCLUDES = $(EM)/modules/h
|
||||
EM_INCLUDES = $(EM)/h
|
||||
LIBS = $(INPLIB) $(CH3LIB) $(EMMESLIB) $(EMKLIB) $(PRTLIB) $(STRLIB) $(SYSLIB)
|
||||
ELIBS = $(INPLIB) $(CH3LIB) $(EMMESLIB) $(EMELIB) $(PRTLIB) $(STRLIB) $(SYSLIB)
|
||||
LIB_INCLUDES = -I$(EM)/modules/h -I$(EM)/modules/pkg
|
||||
EM_INCLUDES = -I$(EM)/h
|
||||
SYSLLIB = $(EM)/modules/lib/llib-lsys.ln
|
||||
EMKLLIB = $(EM)/modules/lib/llib-lemk.ln
|
||||
EMELLIB = $(EM)/modules/lib/llib-leme.ln
|
||||
STRLLIB = $(EM)/modules/lib/llib-lstr.ln
|
||||
PRTLLIB = $(EM)/modules/lib/llib-lprint.ln
|
||||
EMMESLLIB = $(EM)/modules/lib/llib-lmes.ln
|
||||
INPLLIB = $(EM)/modules/lib/llib-linput.ln
|
||||
CH3LLIB = $(EM)/modules/lib/llib-lch3.ln
|
||||
LINTLIBS =
|
||||
#LINTLIBS = $(CH3LLIB) $(EMMESLLIB) $(EMKLLIB) $(PRTLLIB) $(STRLLIB) $(SYSLLIB)
|
||||
#LINTLIBS = $(CH3LLIB) $(INPLLIB) $(EMMESLLIB) $(EMKLLIB) $(PRTLLIB) $(STRLLIB) $(SYSLLIB)
|
||||
|
||||
# Where to install the compiler and its driver
|
||||
CEMCOM = $(DESTINATION)/cemcom
|
||||
|
@ -48,7 +50,7 @@ GEN = $(EM)/bin/LLgen
|
|||
GENOPTIONS = -vv
|
||||
|
||||
# Special #defines during compilation
|
||||
CDEFS = $(MAP) -I$(EM_INCLUDES) -I$(LIB_INCLUDES)
|
||||
CDEFS = $(MAP) $(EM_INCLUDES) $(LIB_INCLUDES)
|
||||
CFLAGS = $(CDEFS) $(COPTIONS) -O# # we cannot pass the COPTIONS to lint!
|
||||
|
||||
# Grammar files and their objects
|
||||
|
@ -77,7 +79,7 @@ GSRC = char.c symbol2str.c next.c \
|
|||
GHSRC = botch_free.h dataflow.h debug.h density.h errout.h \
|
||||
idepth.h idfsize.h ifdepth.h inputtype.h inumlength.h lapbuf.h \
|
||||
maxincl.h myalloc.h nobitfield.h nofloat.h nopp.h \
|
||||
nparams.h numsize.h parbufsize.h pathlength.h predefine.h \
|
||||
nparams.h numsize.h parbufsize.h pathlength.h \
|
||||
strsize.h target_sizes.h textsize.h use_tmp.h spec_arith.h static.h
|
||||
|
||||
# Other generated files, for 'make clean' only
|
||||
|
@ -206,47 +208,47 @@ sim: cfiles
|
|||
$(SIM) $(SIMFLAGS) `sources $(COBJ)` $(GSRC) $(LSRC)
|
||||
|
||||
#AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO
|
||||
LLlex.o: LLlex.h Lpars.h alloc.h arith.h assert.h class.h debug.h def.h idf.h idfsize.h input.h nofloat.h nopp.h numsize.h sizes.h spec_arith.h strsize.h
|
||||
LLmessage.o: LLlex.h Lpars.h alloc.h arith.h idf.h nofloat.h nopp.h spec_arith.h
|
||||
Lpars.o: Lpars.h
|
||||
alloc.o: alloc.h assert.h debug.h myalloc.h
|
||||
arith.o: Lpars.h alloc.h arith.h botch_free.h expr.h field.h idf.h label.h mes.h nobitfield.h nofloat.h nopp.h spec_arith.h storage.h type.h
|
||||
blocks.o: arith.h atw.h nofloat.h sizes.h spec_arith.h
|
||||
ch7.o: Lpars.h arith.h assert.h debug.h def.h expr.h idf.h label.h nobitfield.h nofloat.h nopp.h spec_arith.h struct.h type.h
|
||||
ch7bin.o: Lpars.h arith.h botch_free.h expr.h idf.h label.h nobitfield.h nofloat.h nopp.h spec_arith.h storage.h struct.h type.h
|
||||
ch7mon.o: Lpars.h arith.h botch_free.h def.h expr.h idf.h label.h nobitfield.h nofloat.h nopp.h spec_arith.h storage.h type.h
|
||||
char.o: class.h
|
||||
code.o: LLlex.h Lpars.h alloc.h arith.h assert.h atw.h botch_free.h code.h dataflow.h debug.h declar.h decspecs.h def.h expr.h idf.h label.h level.h mes.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h specials.h stack.h stmt.h storage.h type.h use_tmp.h
|
||||
conversion.o: Lpars.h arith.h nobitfield.h nofloat.h sizes.h spec_arith.h type.h
|
||||
cstoper.o: Lpars.h arith.h assert.h debug.h expr.h idf.h label.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h target_sizes.h type.h
|
||||
dataflow.o: dataflow.h
|
||||
declar.o: LLlex.h Lpars.h arith.h debug.h declar.h decspecs.h def.h expr.h field.h idf.h label.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h storage.h struct.h type.h
|
||||
main.o: LLlex.h Lpars.h alloc.h arith.h debug.h declar.h file_info.h idf.h input.h inputtype.h level.h maxincl.h myalloc.h nobitfield.h nofloat.h nopp.h spec_arith.h specials.h target_sizes.h tokenname.h type.h use_tmp.h
|
||||
idf.o: LLlex.h Lpars.h align.h alloc.h arith.h assert.h botch_free.h debug.h declar.h decspecs.h def.h file_info.h idf.h idfsize.h label.h level.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h specials.h stack.h storage.h struct.h type.h
|
||||
declarator.o: Lpars.h alloc.h arith.h botch_free.h declar.h expr.h idf.h label.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h storage.h type.h
|
||||
decspecs.o: Lpars.h arith.h decspecs.h def.h level.h nobitfield.h nofloat.h spec_arith.h type.h
|
||||
domacro.o: LLlex.h Lpars.h alloc.h arith.h assert.h botch_free.h class.h debug.h idf.h idfsize.h ifdepth.h input.h interface.h macro.h nofloat.h nopp.h nparams.h parbufsize.h spec_arith.h storage.h textsize.h
|
||||
struct.o: LLlex.h Lpars.h align.h arith.h assert.h botch_free.h debug.h def.h field.h file_info.h idf.h level.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h stack.h storage.h struct.h type.h
|
||||
expr.o: LLlex.h Lpars.h alloc.h arith.h botch_free.h declar.h decspecs.h def.h expr.h file_info.h idf.h label.h level.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h storage.h type.h
|
||||
ch7.o: Lpars.h arith.h assert.h debug.h def.h expr.h idf.h label.h nobitfield.h nofloat.h nopp.h spec_arith.h struct.h type.h
|
||||
ch7bin.o: Lpars.h arith.h botch_free.h expr.h idf.h label.h nobitfield.h nofloat.h nopp.h spec_arith.h storage.h struct.h type.h
|
||||
cstoper.o: Lpars.h arith.h assert.h debug.h expr.h idf.h label.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h target_sizes.h type.h
|
||||
arith.o: Lpars.h alloc.h arith.h botch_free.h expr.h field.h idf.h label.h mes.h nobitfield.h nofloat.h nopp.h spec_arith.h storage.h type.h
|
||||
alloc.o: alloc.h assert.h debug.h myalloc.h
|
||||
code.o: LLlex.h Lpars.h alloc.h arith.h assert.h atw.h botch_free.h code.h dataflow.h debug.h declar.h decspecs.h def.h expr.h file_info.h idf.h label.h level.h mes.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h specials.h stack.h stmt.h storage.h type.h use_tmp.h
|
||||
dumpidf.o: Lpars.h arith.h debug.h def.h expr.h field.h idf.h label.h nobitfield.h nofloat.h nopp.h spec_arith.h stack.h static.h struct.h type.h
|
||||
error.o: LLlex.h arith.h debug.h errout.h expr.h label.h nofloat.h nopp.h spec_arith.h tokenname.h use_tmp.h
|
||||
eval.o: Lpars.h align.h arith.h assert.h atw.h code.h dataflow.h debug.h def.h expr.h idf.h label.h level.h mes.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h stack.h type.h
|
||||
expr.o: LLlex.h Lpars.h alloc.h arith.h botch_free.h declar.h decspecs.h def.h expr.h idf.h label.h level.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h storage.h type.h
|
||||
expression.o: LLlex.h Lpars.h arith.h expr.h idf.h label.h nobitfield.h nofloat.h nopp.h spec_arith.h type.h
|
||||
error.o: LLlex.h arith.h debug.h errout.h expr.h file_info.h label.h nofloat.h nopp.h spec_arith.h tokenname.h use_tmp.h
|
||||
field.o: Lpars.h arith.h assert.h code.h debug.h expr.h field.h idf.h label.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h type.h
|
||||
idf.o: LLlex.h Lpars.h align.h alloc.h arith.h assert.h botch_free.h debug.h declar.h decspecs.h def.h idf.h idfsize.h label.h level.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h specials.h stack.h storage.h struct.h type.h
|
||||
init.o: alloc.h class.h idf.h interface.h macro.h nopp.h predefine.h
|
||||
input.o: LLlex.h alloc.h arith.h assert.h debug.h idepth.h input.h inputtype.h interface.h nofloat.h nopp.h pathlength.h spec_arith.h static.h
|
||||
ival.o: Lpars.h align.h arith.h assert.h class.h debug.h def.h expr.h field.h idf.h label.h level.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h struct.h type.h
|
||||
label.o: Lpars.h arith.h def.h idf.h label.h level.h nobitfield.h nofloat.h nopp.h spec_arith.h type.h
|
||||
main.o: LLlex.h Lpars.h alloc.h arith.h debug.h declar.h idf.h input.h inputtype.h level.h maxincl.h myalloc.h nobitfield.h nofloat.h nopp.h spec_arith.h specials.h target_sizes.h tokenname.h type.h use_tmp.h
|
||||
tokenname.o: LLlex.h Lpars.h arith.h file_info.h idf.h nofloat.h nopp.h spec_arith.h tokenname.h
|
||||
LLlex.o: LLlex.h Lpars.h alloc.h arith.h assert.h class.h debug.h def.h file_info.h idf.h idfsize.h input.h nofloat.h nopp.h numsize.h sizes.h spec_arith.h strsize.h
|
||||
LLmessage.o: LLlex.h Lpars.h alloc.h arith.h file_info.h idf.h nofloat.h nopp.h spec_arith.h
|
||||
input.o: file_info.h input.h inputtype.h nopp.h
|
||||
domacro.o: LLlex.h Lpars.h alloc.h arith.h assert.h botch_free.h class.h debug.h file_info.h idf.h idfsize.h ifdepth.h input.h interface.h macro.h nofloat.h nopp.h nparams.h parbufsize.h spec_arith.h storage.h textsize.h
|
||||
replace.o: LLlex.h alloc.h arith.h assert.h class.h debug.h file_info.h idf.h input.h interface.h macro.h nofloat.h nopp.h pathlength.h spec_arith.h static.h strsize.h
|
||||
init.o: alloc.h class.h idf.h interface.h macro.h nopp.h
|
||||
options.o: align.h arith.h class.h idf.h idfsize.h macro.h maxincl.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h storage.h use_tmp.h
|
||||
program.o: LLlex.h Lpars.h alloc.h arith.h code.h declar.h decspecs.h def.h expr.h idf.h label.h nobitfield.h nofloat.h nopp.h spec_arith.h type.h
|
||||
replace.o: LLlex.h alloc.h arith.h assert.h class.h debug.h idf.h input.h interface.h macro.h nofloat.h nopp.h pathlength.h spec_arith.h static.h strsize.h
|
||||
scan.o: class.h idf.h input.h interface.h lapbuf.h macro.h nopp.h nparams.h
|
||||
skip.o: LLlex.h arith.h class.h input.h interface.h nofloat.h nopp.h spec_arith.h
|
||||
skip.o: LLlex.h arith.h class.h file_info.h input.h interface.h nofloat.h nopp.h spec_arith.h
|
||||
stack.o: Lpars.h alloc.h arith.h botch_free.h debug.h def.h idf.h level.h mes.h nobitfield.h nofloat.h nopp.h spec_arith.h stack.h storage.h struct.h type.h use_tmp.h
|
||||
statement.o: LLlex.h Lpars.h arith.h botch_free.h code.h debug.h def.h expr.h idf.h label.h nobitfield.h nofloat.h nopp.h spec_arith.h stack.h storage.h type.h
|
||||
storage.o: alloc.h assert.h botch_free.h debug.h storage.h
|
||||
struct.o: LLlex.h Lpars.h align.h arith.h assert.h botch_free.h debug.h def.h field.h idf.h level.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h stack.h storage.h struct.h type.h
|
||||
switch.o: Lpars.h arith.h assert.h botch_free.h code.h debug.h density.h expr.h idf.h label.h nobitfield.h nofloat.h nopp.h spec_arith.h storage.h switch.h type.h
|
||||
symbol2str.o: Lpars.h
|
||||
tokenfile.o: Lpars.h
|
||||
tokenname.o: LLlex.h Lpars.h arith.h idf.h nofloat.h nopp.h spec_arith.h tokenname.h
|
||||
type.o: Lpars.h align.h alloc.h arith.h def.h idf.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h storage.h type.h
|
||||
ch7mon.o: Lpars.h arith.h botch_free.h def.h expr.h idf.h label.h nobitfield.h nofloat.h nopp.h spec_arith.h storage.h type.h
|
||||
label.o: Lpars.h arith.h def.h idf.h label.h level.h nobitfield.h nofloat.h nopp.h spec_arith.h type.h
|
||||
eval.o: Lpars.h align.h arith.h assert.h atw.h code.h dataflow.h debug.h def.h expr.h idf.h label.h level.h mes.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h stack.h type.h
|
||||
switch.o: Lpars.h arith.h assert.h botch_free.h code.h debug.h density.h expr.h idf.h label.h nobitfield.h nofloat.h nopp.h spec_arith.h storage.h switch.h type.h
|
||||
storage.o: alloc.h assert.h botch_free.h debug.h storage.h
|
||||
ival.o: Lpars.h align.h arith.h assert.h class.h debug.h def.h expr.h field.h idf.h label.h level.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h struct.h type.h
|
||||
conversion.o: Lpars.h arith.h nobitfield.h nofloat.h sizes.h spec_arith.h type.h
|
||||
blocks.o: arith.h atw.h label.h nofloat.h sizes.h spec_arith.h stack.h
|
||||
dataflow.o: dataflow.h
|
||||
tokenfile.o: Lpars.h
|
||||
declar.o: LLlex.h Lpars.h arith.h debug.h declar.h decspecs.h def.h expr.h field.h file_info.h idf.h label.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h storage.h struct.h type.h
|
||||
statement.o: LLlex.h Lpars.h arith.h botch_free.h code.h debug.h def.h expr.h file_info.h idf.h label.h nobitfield.h nofloat.h nopp.h spec_arith.h stack.h storage.h type.h
|
||||
expression.o: LLlex.h Lpars.h arith.h expr.h file_info.h idf.h label.h nobitfield.h nofloat.h nopp.h spec_arith.h type.h
|
||||
program.o: LLlex.h Lpars.h alloc.h arith.h code.h declar.h decspecs.h def.h expr.h file_info.h idf.h label.h nobitfield.h nofloat.h nopp.h spec_arith.h type.h
|
||||
Lpars.o: Lpars.h
|
||||
char.o: class.h
|
||||
symbol2str.o: Lpars.h
|
||||
|
|
|
@ -42,10 +42,6 @@
|
|||
#define DENSITY 2 /* see switch.[ch] for an explanation */
|
||||
|
||||
|
||||
!File: predefine.h
|
||||
#define PREDEFINE "vax,VAX,BSD4_1,bsd4_1"
|
||||
|
||||
|
||||
!File: lapbuf.h
|
||||
#define LAPBUF 4096 /* size of macro actual parameter buffer */
|
||||
|
||||
|
@ -115,7 +111,7 @@
|
|||
|
||||
|
||||
!File: inputtype.h
|
||||
#undef READ_IN_ONE 1 /* read input file in one */
|
||||
#undef INP_READ_IN_ONE 1 /* read input file in one */
|
||||
|
||||
|
||||
!File: nopp.h
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "storage.h"
|
||||
|
||||
IMPORT char *inctable[]; /* list of include directories */
|
||||
IMPORT char *getwdir();
|
||||
PRIVATE char ifstack[IFDEPTH]; /* if-stack: the content of an entry is */
|
||||
/* 1 if a corresponding ELSE has been */
|
||||
/* encountered. */
|
||||
|
@ -223,6 +224,7 @@ do_include()
|
|||
/* do_include() performs the inclusion of a file.
|
||||
*/
|
||||
char *filenm;
|
||||
char *result;
|
||||
int tok;
|
||||
struct token tk;
|
||||
|
||||
|
@ -235,8 +237,17 @@ do_include()
|
|||
}
|
||||
AccFileSpecifier = 0;
|
||||
SkipRestOfLine();
|
||||
if (filenm && !InsertFile(filenm, &inctable[tok == FILESPECIFIER]))
|
||||
lexerror("cannot find include file \"%s\"", filenm);
|
||||
inctable[0] = WorkingDir;
|
||||
if (filenm) {
|
||||
if (!InsertFile(filenm, &inctable[tok==FILESPECIFIER],&result)){
|
||||
lexerror("cannot find include file \"%s\"", filenm);
|
||||
}
|
||||
else {
|
||||
WorkingDir = getwdir(result);
|
||||
FileName = result;
|
||||
LineNumber = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PRIVATE
|
||||
|
@ -341,35 +352,31 @@ do_if()
|
|||
PRIVATE
|
||||
do_ifdef(how)
|
||||
{
|
||||
struct idf *id;
|
||||
register struct idf *id;
|
||||
|
||||
/* how == 1 : ifdef; how == 0 : ifndef
|
||||
*/
|
||||
push_if();
|
||||
if (id = GetIdentifier()) {
|
||||
if (
|
||||
(how && !(id && id->id_macro))
|
||||
||
|
||||
(!how && id && id->id_macro)
|
||||
) /* this id is not defined */
|
||||
skip_block();
|
||||
else
|
||||
SkipRestOfLine();
|
||||
}
|
||||
else {
|
||||
if (!(id = GetIdentifier()))
|
||||
lexerror("illegal #ifdef construction");
|
||||
|
||||
/* The next test is a shorthand for:
|
||||
(how && !id->id_macro) || (!how && id->id_macro)
|
||||
*/
|
||||
if (how ^ (id && id->id_macro != 0))
|
||||
skip_block();
|
||||
else
|
||||
SkipRestOfLine();
|
||||
}
|
||||
}
|
||||
|
||||
PRIVATE
|
||||
do_undef()
|
||||
{
|
||||
struct idf *id;
|
||||
register struct idf *id;
|
||||
|
||||
/* Forget a macro definition. */
|
||||
if (id = GetIdentifier()) {
|
||||
if (id && id->id_macro) { /* forget the macro */
|
||||
if (id->id_macro) { /* forget the macro */
|
||||
free_macro(id->id_macro);
|
||||
id->id_macro = (struct macro *) 0;
|
||||
} /* else: don't complain */
|
||||
|
@ -406,14 +413,15 @@ getparams(buf, parbuf)
|
|||
Note that the '(' has already been eaten.
|
||||
The names of the formal parameters are stored into parbuf.
|
||||
*/
|
||||
register count = 0;
|
||||
register c;
|
||||
register char **pbuf = &buf[0];
|
||||
register int c;
|
||||
register char *ptr = &parbuf[0];
|
||||
register char **pbuf2;
|
||||
|
||||
LoadChar(c);
|
||||
c = skipspaces(c);
|
||||
if (c == ')') { /* no parameters: #define name() */
|
||||
buf[0] = (char *) 0;
|
||||
*pbuf = (char *) 0;
|
||||
return 0;
|
||||
}
|
||||
for (;;) { /* eat the formal parameter list */
|
||||
|
@ -421,7 +429,7 @@ getparams(buf, parbuf)
|
|||
lexerror("#define: bad formal parameter");
|
||||
return -1;
|
||||
}
|
||||
buf[count++] = ptr; /* name of the formal */
|
||||
*pbuf = ptr; /* name of the formal */
|
||||
*ptr++ = c;
|
||||
if (ptr >= &parbuf[PARBUFSIZE])
|
||||
fatal("formal parameter buffer overflow");
|
||||
|
@ -432,10 +440,22 @@ getparams(buf, parbuf)
|
|||
fatal("formal parameter buffer overflow");
|
||||
} while (in_idf(c));
|
||||
*(ptr - 1) = '\0'; /* mark end of the name */
|
||||
|
||||
/* Check if this formal parameter is already used.
|
||||
Usually, macros do not have many parameters, so ...
|
||||
*/
|
||||
for (pbuf2 = pbuf - 1; pbuf2 >= &buf[0]; pbuf2--) {
|
||||
if (!strcmp(*pbuf2, *pbuf)) {
|
||||
warning("formal parameter \"%s\" already used",
|
||||
*pbuf);
|
||||
}
|
||||
}
|
||||
|
||||
pbuf++;
|
||||
c = skipspaces(c);
|
||||
if (c == ')') { /* end of the formal parameter list */
|
||||
buf[count] = (char *) 0;
|
||||
return count;
|
||||
*pbuf = (char *) 0;
|
||||
return pbuf - buf;
|
||||
}
|
||||
if (c != ',') {
|
||||
lexerror("#define: bad formal parameter list");
|
||||
|
@ -444,11 +464,12 @@ getparams(buf, parbuf)
|
|||
LoadChar(c);
|
||||
c = skipspaces(c);
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
EXPORT
|
||||
macro_def(id, text, nformals, length, flags)
|
||||
struct idf *id;
|
||||
register struct idf *id;
|
||||
char *text;
|
||||
{
|
||||
register struct macro *newdef = id->id_macro;
|
||||
|
@ -456,15 +477,12 @@ macro_def(id, text, nformals, length, flags)
|
|||
/* macro_def() puts the contents and information of a macro
|
||||
definition into a structure and stores it into the symbol
|
||||
table entry belonging to the name of the macro.
|
||||
A warning is given if the definition overwrites another
|
||||
(unless predefined!)
|
||||
A warning is given if the definition overwrites another.
|
||||
*/
|
||||
if (newdef) { /* is there a redefinition? */
|
||||
if ((newdef->mc_flag & PREDEF) == 0) {
|
||||
if (macroeq(newdef->mc_text, text))
|
||||
return;
|
||||
lexwarning("redefine \"%s\"", id->id_text);
|
||||
} /* else: overwrite pre-definition */
|
||||
if (macroeq(newdef->mc_text, text))
|
||||
return;
|
||||
lexwarning("redefine \"%s\"", id->id_text);
|
||||
}
|
||||
else
|
||||
id->id_macro = newdef = new_macro();
|
||||
|
@ -472,6 +490,7 @@ macro_def(id, text, nformals, length, flags)
|
|||
newdef->mc_nps = nformals; /* nr of formals */
|
||||
newdef->mc_length = length; /* length of repl. text */
|
||||
newdef->mc_flag = flags; /* special flags */
|
||||
newdef->mc_count = 0;
|
||||
}
|
||||
|
||||
PRIVATE int
|
||||
|
|
14
lang/cem/cemcom/file_info.h
Normal file
14
lang/cem/cemcom/file_info.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
/* $Header$ */
|
||||
/* F I L E I N F O R M A T I O N S T R U C T U R E */
|
||||
|
||||
struct file_info {
|
||||
unsigned int fil_lino;
|
||||
char *fil_name;
|
||||
char *fil_wdir;
|
||||
};
|
||||
|
||||
#define LineNumber finfo.fil_lino
|
||||
#define FileName finfo.fil_name
|
||||
#define WorkingDir finfo.fil_wdir
|
||||
|
||||
extern struct file_info finfo; /* input.c */
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#ifndef NOPP
|
||||
#include <system.h>
|
||||
#include "predefine.h" /* UF */
|
||||
#include "alloc.h"
|
||||
#include "class.h"
|
||||
#include "macro.h"
|
||||
|
@ -57,10 +56,7 @@ init_pp()
|
|||
}
|
||||
|
||||
/* Initialize __DATE__, __FILE__ and __LINE__ macro
|
||||
definitions. The compile-time specified predefined macros
|
||||
are also predefined: if this file is compiled with
|
||||
-DPREDEFINE="vax,pdp", the macro definitions "vax" and
|
||||
"pdp" are predefined macros.
|
||||
definitions.
|
||||
*/
|
||||
/* __DATE__ */
|
||||
clock = sys_time();
|
||||
|
@ -77,33 +73,5 @@ init_pp()
|
|||
|
||||
/* defined(??) */
|
||||
macro_def(str2idf("defined"), "", 1, 1, FUNC);
|
||||
|
||||
#ifdef PREDEFINE
|
||||
{
|
||||
/* PREDEFINE is a compile-time defined string
|
||||
containing a number of identifiers to be
|
||||
predefined at the host machine (for example
|
||||
-DPREDEFINE="vax,unix,pmds").
|
||||
*/
|
||||
register char *s = PREDEFINE;
|
||||
register char *id;
|
||||
char c;
|
||||
|
||||
for (;;) {
|
||||
while (*s && class(*s++) != STIDF);
|
||||
if (*s) {
|
||||
/* gobble identifier */
|
||||
id = s - 1;
|
||||
while (in_idf(*s++));
|
||||
c = *--s;
|
||||
*s = '\0';
|
||||
macro_def(str2idf(id), "1", -1, 1, PREDEF);
|
||||
*s = c;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif PREDEFINE
|
||||
}
|
||||
#endif NOPP
|
||||
|
|
|
@ -1,427 +1,18 @@
|
|||
/* $Header$ */
|
||||
/* INPUT AND BUFFER HANDLING MODULE */
|
||||
|
||||
/*
|
||||
[input.c input.h]
|
||||
Input buffering module: this module contains the routines that
|
||||
offers an input buffering mechanism to the user.
|
||||
|
||||
This module exports the following objects:
|
||||
InsertFile() : suspend input from current buffer and obtain the
|
||||
next input characters from the specified file
|
||||
InsertText() : suspend input from current buffer and take the
|
||||
specified text as stream of input characters
|
||||
LoadChar() : (defined in input.h) read next character from
|
||||
the input ; LoadChar() invokes loadbuf() on
|
||||
encounting a ASCII NUL character
|
||||
NoUnstack : if set to non-zero:
|
||||
loadbuf() reports "unexpected EOF" on encounting
|
||||
the end-of-file or end-of-stacked-text.
|
||||
|
||||
Imported objects are:
|
||||
IDEPTH, DEBUG, READ_IN_ONE, PATHLENGTH: compile-time parameters
|
||||
Malloc(), Salloc(): memory allocation routines
|
||||
fatal(), lexerror(): exception handling
|
||||
FileName, LineNumber, WorkingDir: input trace for lexical analyser
|
||||
|
||||
READ_IN_ONE DEFINED: every input file is read into memory completely
|
||||
and made an input buffer
|
||||
READ_IN_ONE NOT DEFINED: the input from files is buffered in
|
||||
a fixed length input buffer
|
||||
*/
|
||||
|
||||
#include <system.h>
|
||||
#include "nopp.h"
|
||||
#include "inputtype.h"
|
||||
#include "interface.h"
|
||||
#include "arith.h"
|
||||
#include "LLlex.h"
|
||||
#include "input.h"
|
||||
#include "alloc.h"
|
||||
#include "inputtype.h"
|
||||
#include "file_info.h"
|
||||
#include "input.h"
|
||||
#define INP_TYPE struct file_info
|
||||
#define INP_VAR finfo
|
||||
struct file_info finfo;
|
||||
#include <inp_pkg.body>
|
||||
#include "nopp.h"
|
||||
|
||||
#ifndef NOPP
|
||||
#include "idepth.h"
|
||||
#include "debug.h"
|
||||
#include "pathlength.h"
|
||||
#include "assert.h"
|
||||
#include "static.h"
|
||||
#endif NOPP
|
||||
|
||||
EXPORT char *ipp = 0; /* input pointer */
|
||||
EXPORT int NoUnstack = 0; /* if 1: report EOF */
|
||||
|
||||
#ifndef READ_IN_ONE
|
||||
PRIVATE File *FilDes = 0; /* current input medium */
|
||||
#endif READ_IN_ONE
|
||||
|
||||
#ifndef NOPP
|
||||
struct buffer_header {
|
||||
char *bh_name; /* file name where the text comes from */
|
||||
unsigned int bh_lineno;
|
||||
/* current lineno in file */
|
||||
long bh_size; /* = strlen (text), should be unsigned */
|
||||
char *bh_text; /* pointer to buffer containing text */
|
||||
char *bh_ipp; /* current read pointer (= stacked ipp) */
|
||||
char *bh_wdir; /* directory of current file */
|
||||
File *bh_fp; /* needed for files if !READ_IN_ONE */
|
||||
};
|
||||
|
||||
PRIVATE struct buffer_header instack[IDEPTH]; /* stack of input media */
|
||||
PRIVATE struct buffer_header *head = 0; /* current input buffer */
|
||||
|
||||
IMPORT char **WorkingDir; /* name of current working directory */
|
||||
#else NOPP
|
||||
long isize;
|
||||
char ibuf[BUFSIZ + 1];
|
||||
#endif NOPP
|
||||
|
||||
#ifdef READ_IN_ONE
|
||||
/* readfile() creates a buffer in which the text of the file
|
||||
is situated. A pointer to the start of this text is
|
||||
returned. *size is initialized with the buffer length.
|
||||
Note that the file input buffer is prepared for the
|
||||
preprocessor by inserting a '\n' in the beginning of the
|
||||
text and appending a '\n' at the end of the text. The
|
||||
file text start at position 1 of the input buffer. This is
|
||||
done to allow pushback.
|
||||
*/
|
||||
|
||||
PRIVATE char *
|
||||
readfile(filename, size)
|
||||
char *filename;
|
||||
long *size;
|
||||
{
|
||||
File *fp; /* filedescriptor for `filename' */
|
||||
char *cbuf; /* pointer to buffer to be returned */
|
||||
int tmp;
|
||||
long sys_filesize();
|
||||
|
||||
if (sys_open(filename, OP_READ, &fp) == 0) /* can't open this file */
|
||||
return (char *) 0;
|
||||
if ((*size = sys_filesize(filename)) == -1L)
|
||||
fatal("(readfile) cannot get size of file");
|
||||
/* allocate enough space to store contents of the file */
|
||||
cbuf = Malloc(*size + 2);
|
||||
if (sys_read(fp, cbuf + 1, (int) *size, &tmp) == 0 || tmp != *size)
|
||||
fatal("(readfile) bad read");
|
||||
(*size)++; /* keep book of the size! */
|
||||
sys_close(fp); /* filedes no longer needed */
|
||||
cbuf[0] = '\0'; /* allow pushback of first char */
|
||||
cbuf[*size] = '\0'; /* invoke loadbuf() at end */
|
||||
return cbuf;
|
||||
}
|
||||
#endif READ_IN_ONE
|
||||
|
||||
#ifndef NOPP
|
||||
#ifndef READ_IN_ONE
|
||||
/* Input buffer supplying routines: pushbuf() and popbuf()
|
||||
*/
|
||||
PRIVATE char *bufstack[IDEPTH] = 0;
|
||||
PRIVATE bufstptr = 0;
|
||||
|
||||
PRIVATE char *
|
||||
pushbuf()
|
||||
{
|
||||
if (bufstptr >= IDEPTH)
|
||||
fatal("ran out of input buffers");
|
||||
if (bufstack[bufstptr] == 0) {
|
||||
bufstack[bufstptr] = Malloc(BUFSIZ + 4);
|
||||
}
|
||||
return bufstack[bufstptr++];
|
||||
}
|
||||
|
||||
PRIVATE
|
||||
popbuf()
|
||||
{
|
||||
bufstptr--;
|
||||
ASSERT(bufstptr >= 0);
|
||||
}
|
||||
#endif READ_IN_ONE
|
||||
#endif NOPP
|
||||
|
||||
#ifndef NOPP
|
||||
/* Input buffer administration: push_bh() and pop_bh()
|
||||
*/
|
||||
PRIVATE struct buffer_header *
|
||||
push_bh()
|
||||
{
|
||||
if (head) {
|
||||
if (head >= &instack[IDEPTH - 1])
|
||||
fatal("too many nested input texts");
|
||||
head->bh_ipp = ipp;
|
||||
head->bh_lineno = LineNumber;
|
||||
head++;
|
||||
}
|
||||
else
|
||||
head = &instack[0];
|
||||
|
||||
return head;
|
||||
}
|
||||
#endif NOPP
|
||||
|
||||
#ifndef NOPP
|
||||
/* pop_bh() uncovers the previous inputbuffer on the stack
|
||||
of headers. 0 is returned if there are no more
|
||||
inputbuffers on the stack, 1 is returned in the other case.
|
||||
*/
|
||||
PRIVATE int
|
||||
pop_bh()
|
||||
{
|
||||
File *pfp = head->bh_fp;
|
||||
|
||||
if (NoUnstack) {
|
||||
lexerror("unexpected EOF");
|
||||
}
|
||||
|
||||
if (head <= &instack[0]) { /* no more entries */
|
||||
head = (struct buffer_header *) 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ipp = (--head)->bh_ipp; /* restore the previous input pointer */
|
||||
|
||||
if (pfp != 0) { /* unstack a file */
|
||||
#ifndef READ_IN_ONE
|
||||
closefile(pfp);
|
||||
popbuf(); /* free last buffer */
|
||||
#endif READ_IN_ONE
|
||||
LineNumber = head->bh_lineno;
|
||||
FileName = head->bh_name;
|
||||
*WorkingDir = head->bh_wdir;
|
||||
}
|
||||
|
||||
#ifndef READ_IN_ONE
|
||||
FilDes = head->bh_fp;
|
||||
#endif READ_IN_ONE
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif NOPP
|
||||
|
||||
#ifndef READ_IN_ONE
|
||||
/* low level IO routines: openfile(), readblock() and closefile()
|
||||
*/
|
||||
|
||||
PRIVATE File *
|
||||
openfile(filename)
|
||||
char *filename;
|
||||
{
|
||||
File *fp;
|
||||
|
||||
if (filename == 0)
|
||||
return STDIN;
|
||||
if (sys_open(filename, OP_READ, &fp) == 0)
|
||||
return (File *)0;
|
||||
return fp;
|
||||
}
|
||||
|
||||
PRIVATE
|
||||
closefile(fp)
|
||||
File *fp;
|
||||
{
|
||||
if (fp != STDIN)
|
||||
sys_close(fp);
|
||||
}
|
||||
|
||||
PRIVATE int
|
||||
readblock(fp, buf)
|
||||
File *fp;
|
||||
char buf[];
|
||||
{
|
||||
int n;
|
||||
|
||||
if (sys_read(fp, &buf[1], BUFSIZ, &n) == 0)
|
||||
fatal("(readblock) bad read");
|
||||
buf[0] = buf[n + 1] = '\0';
|
||||
return n;
|
||||
}
|
||||
#endif READ_IN_ONE
|
||||
|
||||
/* Interface routines : InsertFile(), InsertText() and loadbuf()
|
||||
*/
|
||||
|
||||
EXPORT int
|
||||
InsertFile(filnam, table)
|
||||
char *filnam;
|
||||
char *table[];
|
||||
{
|
||||
char *mk_filename(), *newfn;
|
||||
char *strcpy();
|
||||
File *openfile();
|
||||
|
||||
#ifdef READ_IN_ONE
|
||||
char *readfile(), *text;
|
||||
long size;
|
||||
#else READ_IN_ONE
|
||||
File *fp = 0;
|
||||
#endif READ_IN_ONE
|
||||
|
||||
#ifdef READ_IN_ONE
|
||||
if (!filnam)
|
||||
return 0;
|
||||
#endif READ_IN_ONE
|
||||
|
||||
#ifndef NOPP
|
||||
if (table == 0 || filnam[0] == '/') { /* don't look in the table! */
|
||||
#endif NOPP
|
||||
#ifdef READ_IN_ONE
|
||||
text = readfile(filnam, &size);
|
||||
#else READ_IN_ONE
|
||||
fp = openfile(filnam);
|
||||
if (filnam == 0)
|
||||
filnam = "standard input";
|
||||
#endif READ_IN_ONE
|
||||
#ifndef NOPP
|
||||
}
|
||||
else {
|
||||
ASSERT(filnam != 0);
|
||||
while (*table) { /* look in the directory table */
|
||||
newfn = mk_filename(*table++, filnam);
|
||||
#ifdef READ_IN_ONE
|
||||
if (text = readfile(newfn, &size))
|
||||
#else READ_IN_ONE
|
||||
if ((fp = openfile(newfn)) != 0)
|
||||
#endif READ_IN_ONE
|
||||
{
|
||||
/* free filnam ??? */
|
||||
filnam = Salloc(newfn, strlen(newfn) + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif NOPP
|
||||
|
||||
#ifdef READ_IN_ONE
|
||||
if (text)
|
||||
#else READ_IN_ONE
|
||||
if (fp != 0)
|
||||
#endif READ_IN_ONE
|
||||
#ifndef NOPP
|
||||
{
|
||||
struct buffer_header *push_bh();
|
||||
register struct buffer_header *bh = push_bh();
|
||||
|
||||
setwdir(WorkingDir, filnam);
|
||||
bh->bh_lineno = LineNumber = 0;
|
||||
bh->bh_name = FileName = filnam;
|
||||
bh->bh_wdir = *WorkingDir;
|
||||
#ifdef READ_IN_ONE
|
||||
bh->bh_size = size;
|
||||
bh->bh_fp = STDIN; /* this is a file */
|
||||
ipp = bh->bh_text = text;
|
||||
#else READ_IN_ONE
|
||||
bh->bh_size = readblock(fp, ipp = bh->bh_text = pushbuf()) + 1;
|
||||
FilDes = bh->bh_fp = fp;
|
||||
#endif READ_IN_ONE
|
||||
bh->bh_text[0] = '\n'; /* wake up pp if '#' comes first */
|
||||
return 1;
|
||||
}
|
||||
#else NOPP
|
||||
{
|
||||
LineNumber = 0;
|
||||
FileName = filnam;
|
||||
#ifdef READ_IN_ONE
|
||||
isize = size;
|
||||
ipp = text;
|
||||
#else READ_IN_ONE
|
||||
isize = readblock(FilDes = fp, ipp = &ibuf[0]) + 1;
|
||||
#endif READ_IN_ONE
|
||||
ibuf[0] = '\n';
|
||||
return 1;
|
||||
}
|
||||
#endif NOPP
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef NOPP
|
||||
EXPORT
|
||||
InsertText(text, length)
|
||||
char *text;
|
||||
{
|
||||
struct buffer_header *push_bh();
|
||||
register struct buffer_header *bh = push_bh();
|
||||
|
||||
bh->bh_name = FileName;
|
||||
bh->bh_lineno = LineNumber;
|
||||
bh->bh_size = (long) length;
|
||||
bh->bh_text = text;
|
||||
bh->bh_wdir = *WorkingDir;
|
||||
bh->bh_fp = 0; /* this is not a file ! */
|
||||
ipp = text + 1;
|
||||
#ifndef READ_IN_ONE
|
||||
FilDes = 0;
|
||||
#endif READ_IN_ONE
|
||||
}
|
||||
#endif NOPP
|
||||
|
||||
/* loadbuf() is called if LoadChar meets a '\0' character
|
||||
which may be the end-of-buffer mark of the current input
|
||||
buffer. The '\0' could be genuine although not likely.
|
||||
Note: this routine is exported due to its occurence in the definition
|
||||
of LoadChar [input.h], that is defined as a macro.
|
||||
*/
|
||||
EXPORT int
|
||||
loadbuf()
|
||||
{
|
||||
#ifndef NOPP
|
||||
if (!head) /* stack exhausted, EOF on sourcefile */
|
||||
return EOI;
|
||||
#endif NOPP
|
||||
|
||||
#ifndef NOPP
|
||||
if (ipp < &(head->bh_text[head->bh_size]))
|
||||
#else NOPP
|
||||
if (ipp < &ibuf[isize])
|
||||
#endif NOPP
|
||||
return '\0'; /* a genuine '\0' character has been seen */
|
||||
|
||||
#ifndef READ_IN_ONE
|
||||
#ifndef NOPP
|
||||
if ( FilDes != 0
|
||||
&& (head->bh_size = readblock(FilDes, head->bh_text)) > 0
|
||||
)
|
||||
return ipp = &(head->bh_text[1]), *ipp++;
|
||||
#else NOPP
|
||||
if (FilDes != 0 && (isize = readblock(FilDes, &ibuf[0])) > 0)
|
||||
return ipp = &ibuf[1], *ipp++;
|
||||
#endif NOPP
|
||||
#endif READ_IN_ONE
|
||||
|
||||
#ifdef NOPP
|
||||
if (NoUnstack)
|
||||
lexerror("unexpected EOF");
|
||||
#ifndef READ_IN_ONE
|
||||
closefile(FilDes);
|
||||
#endif READ_IN_ONE
|
||||
#endif NOPP
|
||||
|
||||
#ifndef NOPP
|
||||
if (pop_bh())
|
||||
return *ipp ? *ipp++ : loadbuf();
|
||||
#endif NOPP
|
||||
ipp = &"\0\0"[1];
|
||||
return EOI;
|
||||
}
|
||||
|
||||
/* Some miscellaneous routines : setwdir() and mk_filename()
|
||||
*/
|
||||
|
||||
#ifndef NOPP
|
||||
/* setwdir() updates *wdir according to the old working
|
||||
directory (*wdir) and the filename fn, which may contain
|
||||
some path name. The algorithm used here is:
|
||||
setwdir(DIR, FILE):
|
||||
if (FILE == "/***")
|
||||
*DIR = "/"
|
||||
else
|
||||
if (contains(FILE, '/'))
|
||||
*DIR = directory(FILE)
|
||||
else
|
||||
*DIR remains unchanged
|
||||
*/
|
||||
PRIVATE
|
||||
setwdir(wdir, fn)
|
||||
char *fn, **wdir;
|
||||
char *
|
||||
getwdir(fn)
|
||||
char *fn;
|
||||
{
|
||||
register char *p;
|
||||
char *strrindex();
|
||||
|
@ -433,32 +24,31 @@ setwdir(wdir, fn)
|
|||
}
|
||||
|
||||
if (fn[0] == '\0' || (fn[0] == '/' && p == &fn[0])) /* absolute path */
|
||||
*wdir = "/";
|
||||
return "";
|
||||
else
|
||||
if (p) {
|
||||
*p = '\0';
|
||||
*wdir = Salloc(fn, p - &fn[0] + 1);
|
||||
fn = Salloc(fn, p - &fn[0] + 1);
|
||||
*p = '/';
|
||||
return fn;
|
||||
}
|
||||
else return ".";
|
||||
}
|
||||
#endif NOPP
|
||||
|
||||
#ifndef NOPP
|
||||
/* mk_filename() concatenates a dir and filename.
|
||||
*/
|
||||
GSTATIC char path[PATHLENGTH];
|
||||
int NoUnstack;
|
||||
|
||||
PRIVATE char *
|
||||
mk_filename(dir, file)
|
||||
register char *dir, *file;
|
||||
AtEoIT()
|
||||
{
|
||||
register char *dst = &path[0];
|
||||
|
||||
if (!(dir[0] == '.' && dir[1] == '\0')) {
|
||||
while (*dst++ = *dir++);
|
||||
*(dst - 1) = '/';
|
||||
}
|
||||
while (*dst++ = *file++);
|
||||
return &path[0];
|
||||
}
|
||||
#ifndef NOPP
|
||||
if (NoUnstack) lexerror("unexpected EOF");
|
||||
DoUnstack();
|
||||
#endif NOPP
|
||||
return 0;
|
||||
}
|
||||
|
||||
AtEoIF()
|
||||
{
|
||||
if (NoUnstack) lexerror("unexpected EOF");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,3 @@
|
|||
/* $Header$ */
|
||||
/* INPUT PRIMITIVES */
|
||||
|
||||
#define LoadChar(dest) ((dest = *ipp++) || (dest = loadbuf()))
|
||||
#define PushBack() (ipp--)
|
||||
|
||||
/* EOF may be defined as -1 in most programs but the character -1 may
|
||||
be expanded to the int -1 which causes troubles at the indexing in
|
||||
the class or boolean arrays.
|
||||
*/
|
||||
#define EOI (0200)
|
||||
|
||||
extern char *ipp;
|
||||
#include <inp_pkg.spec>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*/
|
||||
#define NOFLAG 0 /* no special flags */
|
||||
#define FUNC 01 /* function attached */
|
||||
#define PREDEF 02 /* predefined macro */
|
||||
#define NOREPLACE 02 /* don't replace */
|
||||
|
||||
#define FORMALP 0200 /* mask for creating macro formal parameter */
|
||||
|
||||
|
@ -21,8 +21,9 @@
|
|||
struct macro {
|
||||
struct macro *next;
|
||||
char * mc_text; /* the replacement text */
|
||||
int mc_nps; /* number of formal parameters */
|
||||
int mc_nps; /* number of formal parameters */
|
||||
int mc_length; /* length of replacement text */
|
||||
int mc_count; /* # of "concurrent" invocations*/
|
||||
char mc_flag; /* marking this macro */
|
||||
};
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ char *inctable[MAXINCL] = { /* list for includes */
|
|||
0
|
||||
};
|
||||
|
||||
char **WorkingDir = &inctable[0];
|
||||
extern char *getwdir();
|
||||
#endif NOPP
|
||||
|
||||
struct sp_id special_ids[] = {
|
||||
|
@ -90,19 +90,17 @@ main(argc, argv)
|
|||
#endif NOPP
|
||||
|
||||
/* Note: source file "-" indicates that the source is supplied
|
||||
as standard input. This is only allowed if READ_IN_ONE is
|
||||
as standard input. This is only allowed if INP_READ_IN_ONE is
|
||||
not defined!
|
||||
*/
|
||||
#ifdef READ_IN_ONE
|
||||
#ifdef INP_READ_IN_ONE
|
||||
while (argc > 1 && *argv[1] == '-')
|
||||
#else READ_IN_ONE
|
||||
#else INP_READ_IN_ONE
|
||||
while (argc > 1 && *argv[1] == '-' && argv[1][1] != '\0')
|
||||
#endif READ_IN_ONE
|
||||
#endif INP_READ_IN_ONE
|
||||
{
|
||||
char *par = &argv[1][1];
|
||||
|
||||
if (*par == '-')
|
||||
par++;
|
||||
do_option(par);
|
||||
argc--, argv++;
|
||||
}
|
||||
|
@ -139,6 +137,7 @@ compile(argc, argv)
|
|||
#ifdef USE_TMP
|
||||
char tmpf[256];
|
||||
#endif
|
||||
char *result;
|
||||
|
||||
#ifndef NOPP
|
||||
int pp_only = options['E'] || options['P'];
|
||||
|
@ -172,11 +171,15 @@ compile(argc, argv)
|
|||
|
||||
if (destination && strcmp(destination, "-") == 0)
|
||||
destination = 0;
|
||||
if (!InsertFile(source, (char **) 0)) /* read the source file */
|
||||
if (!InsertFile(source, (char **) 0, &result)) /* read the source file */
|
||||
fatal("%s: no source file %s\n", prog_name,
|
||||
source ? source : "stdin");
|
||||
init();
|
||||
/* FileName = source; /* needed ??? */
|
||||
FileName = source;
|
||||
LineNumber = 0;
|
||||
#ifndef NOPP
|
||||
WorkingDir = getwdir(source);
|
||||
#endif NOPP
|
||||
PushLex();
|
||||
|
||||
#ifndef NOPP
|
||||
|
|
|
@ -34,7 +34,10 @@ do_option(text)
|
|||
switch(*text++) {
|
||||
|
||||
default:
|
||||
options[text[-1]] = 1; /* flags, debug options etc. */
|
||||
fatal("illegal option: %c", *--text);
|
||||
|
||||
case '-':
|
||||
options[*text] = 1; /* flags, debug options etc. */
|
||||
break;
|
||||
|
||||
case 'C' : /* E option + comment output */
|
||||
|
@ -105,6 +108,7 @@ do_option(text)
|
|||
new = tmp;
|
||||
}
|
||||
}
|
||||
else inctable[inc_pos] = 0;
|
||||
#else NOPP
|
||||
warning("-I option ignored");
|
||||
#endif NOPP
|
||||
|
@ -135,6 +139,10 @@ do_option(text)
|
|||
#endif NOPP
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
options['R'] = 1;
|
||||
break;
|
||||
|
||||
#ifdef USE_TMP
|
||||
case 'T' :
|
||||
if (*text)
|
||||
|
|
|
@ -21,9 +21,11 @@
|
|||
char *strcpy(), *strcat();
|
||||
char *long2str();
|
||||
|
||||
PRIVATE struct macro *ReplaceList; /* list of currently active macros */
|
||||
|
||||
EXPORT int
|
||||
replace(idef)
|
||||
struct idf *idef;
|
||||
register struct idf *idef;
|
||||
{
|
||||
/* replace() is called by the lexical analyzer to perform
|
||||
macro replacement. "idef" is the description of the
|
||||
|
@ -34,14 +36,18 @@ replace(idef)
|
|||
replace() returns 1 if the replacement succeeded and 0 if
|
||||
some error has occurred.
|
||||
*/
|
||||
register struct macro *mac = idef->id_macro;
|
||||
register char c;
|
||||
register char flags = idef->id_macro->mc_flag;
|
||||
char **actpars, **getactuals();
|
||||
char *reptext, *macro2buffer();
|
||||
int size;
|
||||
|
||||
if (idef->id_macro->mc_nps != -1) { /* with parameter list */
|
||||
if (flags & FUNC) {
|
||||
if (mac->mc_flag & NOREPLACE) {
|
||||
lexwarning("macro %s is recursive", idef->id_text);
|
||||
return 0;
|
||||
}
|
||||
if (mac->mc_nps != -1) { /* with parameter list */
|
||||
if (mac->mc_flag & FUNC) {
|
||||
/* must be "defined".
|
||||
Unfortunately, the next assertion
|
||||
will not compile ...
|
||||
|
@ -50,6 +56,12 @@ replace(idef)
|
|||
if (! AccDefined)
|
||||
return 0;
|
||||
}
|
||||
if (++mac->mc_count > 100) {
|
||||
/* 100 must be some number in Parameters */
|
||||
lexwarning("macro %s is assumed recursive",
|
||||
idef->id_text);
|
||||
return 0;
|
||||
}
|
||||
LoadChar(c);
|
||||
c = skipspaces(c);
|
||||
if (c != '(') { /* no replacement if no () */
|
||||
|
@ -59,23 +71,27 @@ replace(idef)
|
|||
return 0;
|
||||
}
|
||||
actpars = getactuals(idef); /* get act.param. list */
|
||||
if (flags & FUNC) {
|
||||
if (mac->mc_flag & FUNC) {
|
||||
struct idf *param = str2idf(*actpars);
|
||||
|
||||
if (param->id_macro)
|
||||
reptext = "\0001";
|
||||
reptext = "1";
|
||||
else
|
||||
reptext = "\0000";
|
||||
InsertText(reptext, 2);
|
||||
reptext = "0";
|
||||
InsertText(reptext, 1);
|
||||
mac->next = ReplaceList;
|
||||
ReplaceList = mac;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if ((flags & PREDEF) && (UnknownIdIsZero == 0)) /* don't replace */
|
||||
return 0;
|
||||
if (flags & FUNC) /* this macro leads to special action */
|
||||
if (mac->mc_flag & FUNC) /* this macro leads to special action */
|
||||
macro_func(idef);
|
||||
if (mac->mc_nps <= 0)
|
||||
mac->mc_flag |= NOREPLACE;
|
||||
reptext = macro2buffer(idef, actpars, &size); /* create input buffer */
|
||||
InsertText(reptext, size);
|
||||
mac->next = ReplaceList;
|
||||
ReplaceList = mac;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -83,24 +99,26 @@ GSTATIC char FilNamBuf[PATHLENGTH];
|
|||
|
||||
PRIVATE
|
||||
macro_func(idef)
|
||||
struct idf *idef;
|
||||
register struct idf *idef;
|
||||
{
|
||||
/* macro_func() performs the special actions needed with some
|
||||
macros. These macros are __FILE__ and __LINE__ which
|
||||
replacement texts must be evaluated at the time they are
|
||||
used.
|
||||
*/
|
||||
register struct macro *mac = idef->id_macro;
|
||||
|
||||
switch (idef->id_text[2]) { /* This switch is very blunt... */
|
||||
case 'F' : /* __FILE__ */
|
||||
FilNamBuf[0] = '"';
|
||||
strcpy(&FilNamBuf[1], FileName);
|
||||
strcat(FilNamBuf, "\"");
|
||||
idef->id_macro->mc_text = FilNamBuf;
|
||||
idef->id_macro->mc_length = strlen(FilNamBuf);
|
||||
mac->mc_text = FilNamBuf;
|
||||
mac->mc_length = strlen(FilNamBuf);
|
||||
break;
|
||||
case 'L' : /* __LINE__ */
|
||||
idef->id_macro->mc_text = long2str((long)LineNumber, 10);
|
||||
idef->id_macro->mc_length = 1;
|
||||
mac->mc_text = long2str((long)LineNumber, 10);
|
||||
mac->mc_length = 1;
|
||||
break;
|
||||
default :
|
||||
crash("(macro_func)");
|
||||
|
@ -125,10 +143,9 @@ macro2buffer(idef, actpars, siztext)
|
|||
*/
|
||||
register int size = 8;
|
||||
register char *text = Malloc(size);
|
||||
register pos = 0;
|
||||
register int pos = 0;
|
||||
register char *ptr = idef->id_macro->mc_text;
|
||||
|
||||
text[pos++] = '\0'; /* allow pushback */
|
||||
while (*ptr) {
|
||||
if (*ptr & FORMALP) { /* non-asc formal param. mark */
|
||||
register int n = *ptr++ & 0177;
|
||||
|
@ -138,7 +155,7 @@ macro2buffer(idef, actpars, siztext)
|
|||
/* copy the text of the actual parameter
|
||||
into the replacement text
|
||||
*/
|
||||
for (p = actpars[n - 1]; *p; p++) {
|
||||
for (p = actpars[n - 1]; p && *p; p++) {
|
||||
text[pos++] = *p;
|
||||
if (pos == size)
|
||||
text = Srealloc(text, size += RSTRSIZE);
|
||||
|
@ -154,4 +171,26 @@ macro2buffer(idef, actpars, siztext)
|
|||
*siztext = pos;
|
||||
return text;
|
||||
}
|
||||
|
||||
EXPORT
|
||||
DoUnstack()
|
||||
{
|
||||
Unstacked++;
|
||||
}
|
||||
|
||||
EXPORT
|
||||
EnableMacros()
|
||||
{
|
||||
register struct macro *p = ReplaceList;
|
||||
|
||||
ASSERT(Unstacked > 0);
|
||||
while (Unstacked > 0) {
|
||||
ASSERT(p != 0);
|
||||
p->mc_flag &= ~NOREPLACE;
|
||||
p->mc_count = 0;
|
||||
p = p->next;
|
||||
Unstacked--;
|
||||
}
|
||||
ReplaceList = p;
|
||||
}
|
||||
#endif NOPP
|
||||
|
|
Loading…
Reference in a new issue