version using input module and detecting preprocessor loops

This commit is contained in:
ceriel 1986-12-04 16:29:44 +00:00
parent 91aad0b28e
commit 53d6dfcb6b
13 changed files with 239 additions and 599 deletions

View file

@ -21,9 +21,6 @@
/* Data about the token yielded */ /* Data about the token yielded */
struct token dot, ahead, aside; struct token dot, ahead, aside;
unsigned int LineNumber = 0; /* current LineNumber */
char *FileName = 0; /* current filename */
int ReplaceMacros = 1; /* replacing macros */ int ReplaceMacros = 1; /* replacing macros */
int EoiForNewline = 0; /* return EOI upon encountering newline */ int EoiForNewline = 0; /* return EOI upon encountering newline */
int PreProcKeys = 0; /* return preprocessor key */ int PreProcKeys = 0; /* return preprocessor key */
@ -31,6 +28,7 @@ int AccFileSpecifier = 0; /* return filespecifier <...> */
int AccDefined = 0; /* accept "defined(...)" */ int AccDefined = 0; /* accept "defined(...)" */
int UnknownIdIsZero = 0; /* interpret unknown id as integer 0 */ int UnknownIdIsZero = 0; /* interpret unknown id as integer 0 */
int SkipEscNewline = 0; /* how to interpret backslash-newline */ int SkipEscNewline = 0; /* how to interpret backslash-newline */
int Unstacked = 0; /* an unstack is done */
#define MAX_LL_DEPTH 2 #define MAX_LL_DEPTH 2
@ -102,21 +100,28 @@ GetToken(ptok)
char buf[(IDFSIZE > NUMSIZE ? IDFSIZE : NUMSIZE) + 1]; char buf[(IDFSIZE > NUMSIZE ? IDFSIZE : NUMSIZE) + 1];
register int ch, nch; register int ch, nch;
if (! LineNumber) goto firstline;
again: /* rescan the input after an error or replacement */ again: /* rescan the input after an error or replacement */
#ifndef NOPP
if (Unstacked) EnableMacros();
#endif
LoadChar(ch); LoadChar(ch);
go_on: /* rescan, the following character has been read */ go_on: /* rescan, the following character has been read */
if ((ch & 0200) && ch != EOI) /* stop on non-ascii character */ if ((ch & 0200) && ch != EOI) /* stop on non-ascii character */
fatal("non-ascii '\\%03o' read", ch & 0377); fatal("non-ascii '\\%03o' read", ch & 0377);
switch (class(ch)) { /* detect character class */ switch (class(ch)) { /* detect character class */
case STNL: /* newline, vertical space or formfeed */ case STNL: /* newline, vertical space or formfeed */
firstline:
LineNumber++; /* also at vs and ff */ LineNumber++; /* also at vs and ff */
if (EoiForNewline) /* called in control line */ if (EoiForNewline) /* called in control line */
/* a newline in a control line indicates the /* a newline in a control line indicates the
end-of-information of the line. end-of-information of the line.
*/ */
return ptok->tk_symb = EOI; return ptok->tk_symb = EOI;
while (LoadChar(ch), ch == '#') /* a control line follows */ while (LoadChar(ch), ch == '#') { /* a control line follows */
domacro(); domacro();
if (!LineNumber) goto firstline;
}
/* We have to loop here, because in /* We have to loop here, because in
`domacro' the nl, vt or ff is read. The `domacro' the nl, vt or ff is read. The
character following it may again be a `#'. character following it may again be a `#'.
@ -253,6 +258,9 @@ go_on: /* rescan, the following character has been read */
hash = STARTHASH(); hash = STARTHASH();
do { /* read the identifier */ do { /* read the identifier */
if (++pos < idfsize) { if (++pos < idfsize) {
#ifndef NOPP
if (Unstacked) EnableMacros();
#endif
*tg++ = ch; *tg++ = ch;
hash = ENHASH(hash, ch, pos); hash = ENHASH(hash, ch, pos);
} }
@ -485,8 +493,10 @@ string_token(nm, stop_char, plen)
} }
if (ch == '\\') { if (ch == '\\') {
LoadChar(ch); LoadChar(ch);
if (ch == '\n') if (ch == '\n') {
LineNumber++; LineNumber++;
continue;
}
ch = quoted(ch); ch = quoted(ch);
} }
str[pos++] = ch; str[pos++] = ch;

View file

@ -7,6 +7,7 @@
*/ */
#include "nofloat.h" #include "nofloat.h"
#include "file_info.h"
/* the structure of a token: */ /* the structure of a token: */
struct token { struct token {
@ -42,8 +43,6 @@ struct token {
#endif NOFLOAT #endif NOFLOAT
extern struct token dot, ahead, aside; extern struct token dot, ahead, aside;
extern unsigned int LineNumber; /* "LLlex.c" */
extern char *FileName; /* "LLlex.c" */
extern int ReplaceMacros; /* "LLlex.c" */ extern int ReplaceMacros; /* "LLlex.c" */
extern int EoiForNewline; /* "LLlex.c" */ extern int EoiForNewline; /* "LLlex.c" */
@ -52,6 +51,7 @@ extern int AccFileSpecifier; /* "LLlex.c" */
extern int AccDefined; /* "LLlex.c" */ extern int AccDefined; /* "LLlex.c" */
extern int UnknownIdIsZero; /* "LLlex.c" */ extern int UnknownIdIsZero; /* "LLlex.c" */
extern int SkipEscNewline; /* "LLlex.c" */ extern int SkipEscNewline; /* "LLlex.c" */
extern int Unstacked; /* "LLlex.c" */
extern int NoUnstack; /* buffer.c */ extern int NoUnstack; /* buffer.c */

View file

@ -17,21 +17,23 @@ EMELIB = $(EM)/modules/lib/libeme.a
STRLIB = $(EM)/modules/lib/libstr.a STRLIB = $(EM)/modules/lib/libstr.a
PRTLIB = $(EM)/modules/lib/libprint.a PRTLIB = $(EM)/modules/lib/libprint.a
EMMESLIB = $(EM)/modules/lib/libem_mes.a EMMESLIB = $(EM)/modules/lib/libem_mes.a
INPLIB = $(EM)/modules/lib/libinput.a
#CH3LIB = $(EM)/modules/lib/libch3.a #CH3LIB = $(EM)/modules/lib/libch3.a
CH3LIB = CH3LIB =
LIBS = $(CH3LIB) $(EMMESLIB) $(EMKLIB) $(PRTLIB) $(STRLIB) $(SYSLIB) LIBS = $(INPLIB) $(CH3LIB) $(EMMESLIB) $(EMKLIB) $(PRTLIB) $(STRLIB) $(SYSLIB)
ELIBS = $(CH3LIB) $(EMMESLIB) $(EMELIB) $(PRTLIB) $(STRLIB) $(SYSLIB) ELIBS = $(INPLIB) $(CH3LIB) $(EMMESLIB) $(EMELIB) $(PRTLIB) $(STRLIB) $(SYSLIB)
LIB_INCLUDES = $(EM)/modules/h LIB_INCLUDES = -I$(EM)/modules/h -I$(EM)/modules/pkg
EM_INCLUDES = $(EM)/h EM_INCLUDES = -I$(EM)/h
SYSLLIB = $(EM)/modules/lib/llib-lsys.ln SYSLLIB = $(EM)/modules/lib/llib-lsys.ln
EMKLLIB = $(EM)/modules/lib/llib-lemk.ln EMKLLIB = $(EM)/modules/lib/llib-lemk.ln
EMELLIB = $(EM)/modules/lib/llib-leme.ln EMELLIB = $(EM)/modules/lib/llib-leme.ln
STRLLIB = $(EM)/modules/lib/llib-lstr.ln STRLLIB = $(EM)/modules/lib/llib-lstr.ln
PRTLLIB = $(EM)/modules/lib/llib-lprint.ln PRTLLIB = $(EM)/modules/lib/llib-lprint.ln
EMMESLLIB = $(EM)/modules/lib/llib-lmes.ln EMMESLLIB = $(EM)/modules/lib/llib-lmes.ln
INPLLIB = $(EM)/modules/lib/llib-linput.ln
CH3LLIB = $(EM)/modules/lib/llib-lch3.ln CH3LLIB = $(EM)/modules/lib/llib-lch3.ln
LINTLIBS = LINTLIBS =
#LINTLIBS = $(CH3LLIB) $(EMMESLLIB) $(EMKLLIB) $(PRTLLIB) $(STRLLIB) $(SYSLLIB) #LINTLIBS = $(CH3LLIB) $(INPLLIB) $(EMMESLLIB) $(EMKLLIB) $(PRTLLIB) $(STRLLIB) $(SYSLLIB)
# Where to install the compiler and its driver # Where to install the compiler and its driver
CEMCOM = $(DESTINATION)/cemcom CEMCOM = $(DESTINATION)/cemcom
@ -48,7 +50,7 @@ GEN = $(EM)/bin/LLgen
GENOPTIONS = -vv GENOPTIONS = -vv
# Special #defines during compilation # 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! CFLAGS = $(CDEFS) $(COPTIONS) -O# # we cannot pass the COPTIONS to lint!
# Grammar files and their objects # 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 \ GHSRC = botch_free.h dataflow.h debug.h density.h errout.h \
idepth.h idfsize.h ifdepth.h inputtype.h inumlength.h lapbuf.h \ idepth.h idfsize.h ifdepth.h inputtype.h inumlength.h lapbuf.h \
maxincl.h myalloc.h nobitfield.h nofloat.h nopp.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 strsize.h target_sizes.h textsize.h use_tmp.h spec_arith.h static.h
# Other generated files, for 'make clean' only # Other generated files, for 'make clean' only
@ -206,47 +208,47 @@ sim: cfiles
$(SIM) $(SIMFLAGS) `sources $(COBJ)` $(GSRC) $(LSRC) $(SIM) $(SIMFLAGS) `sources $(COBJ)` $(GSRC) $(LSRC)
#AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO #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 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
LLmessage.o: LLlex.h Lpars.h alloc.h arith.h idf.h nofloat.h nopp.h spec_arith.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
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
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 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 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 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 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
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
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 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 tokenname.o: LLlex.h Lpars.h arith.h file_info.h idf.h nofloat.h nopp.h spec_arith.h tokenname.h
init.o: alloc.h class.h idf.h interface.h macro.h nopp.h predefine.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
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 LLmessage.o: LLlex.h Lpars.h alloc.h arith.h file_info.h idf.h nofloat.h nopp.h spec_arith.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 input.o: file_info.h input.h inputtype.h nopp.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 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
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 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 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 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 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 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

View file

@ -42,10 +42,6 @@
#define DENSITY 2 /* see switch.[ch] for an explanation */ #define DENSITY 2 /* see switch.[ch] for an explanation */
!File: predefine.h
#define PREDEFINE "vax,VAX,BSD4_1,bsd4_1"
!File: lapbuf.h !File: lapbuf.h
#define LAPBUF 4096 /* size of macro actual parameter buffer */ #define LAPBUF 4096 /* size of macro actual parameter buffer */
@ -115,7 +111,7 @@
!File: inputtype.h !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 !File: nopp.h

View file

@ -24,6 +24,7 @@
#include "storage.h" #include "storage.h"
IMPORT char *inctable[]; /* list of include directories */ IMPORT char *inctable[]; /* list of include directories */
IMPORT char *getwdir();
PRIVATE char ifstack[IFDEPTH]; /* if-stack: the content of an entry is */ PRIVATE char ifstack[IFDEPTH]; /* if-stack: the content of an entry is */
/* 1 if a corresponding ELSE has been */ /* 1 if a corresponding ELSE has been */
/* encountered. */ /* encountered. */
@ -223,6 +224,7 @@ do_include()
/* do_include() performs the inclusion of a file. /* do_include() performs the inclusion of a file.
*/ */
char *filenm; char *filenm;
char *result;
int tok; int tok;
struct token tk; struct token tk;
@ -235,9 +237,18 @@ do_include()
} }
AccFileSpecifier = 0; AccFileSpecifier = 0;
SkipRestOfLine(); SkipRestOfLine();
if (filenm && !InsertFile(filenm, &inctable[tok == FILESPECIFIER])) inctable[0] = WorkingDir;
if (filenm) {
if (!InsertFile(filenm, &inctable[tok==FILESPECIFIER],&result)){
lexerror("cannot find include file \"%s\"", filenm); lexerror("cannot find include file \"%s\"", filenm);
} }
else {
WorkingDir = getwdir(result);
FileName = result;
LineNumber = 0;
}
}
}
PRIVATE PRIVATE
do_define() do_define()
@ -341,35 +352,31 @@ do_if()
PRIVATE PRIVATE
do_ifdef(how) do_ifdef(how)
{ {
struct idf *id; register struct idf *id;
/* how == 1 : ifdef; how == 0 : ifndef /* how == 1 : ifdef; how == 0 : ifndef
*/ */
push_if(); push_if();
if (id = GetIdentifier()) { if (!(id = GetIdentifier()))
if ( lexerror("illegal #ifdef construction");
(how && !(id && id->id_macro))
|| /* The next test is a shorthand for:
(!how && id && id->id_macro) (how && !id->id_macro) || (!how && id->id_macro)
) /* this id is not defined */ */
if (how ^ (id && id->id_macro != 0))
skip_block(); skip_block();
else else
SkipRestOfLine(); SkipRestOfLine();
} }
else {
lexerror("illegal #ifdef construction");
SkipRestOfLine();
}
}
PRIVATE PRIVATE
do_undef() do_undef()
{ {
struct idf *id; register struct idf *id;
/* Forget a macro definition. */ /* Forget a macro definition. */
if (id = GetIdentifier()) { if (id = GetIdentifier()) {
if (id && id->id_macro) { /* forget the macro */ if (id->id_macro) { /* forget the macro */
free_macro(id->id_macro); free_macro(id->id_macro);
id->id_macro = (struct macro *) 0; id->id_macro = (struct macro *) 0;
} /* else: don't complain */ } /* else: don't complain */
@ -406,14 +413,15 @@ getparams(buf, parbuf)
Note that the '(' has already been eaten. Note that the '(' has already been eaten.
The names of the formal parameters are stored into parbuf. The names of the formal parameters are stored into parbuf.
*/ */
register count = 0; register char **pbuf = &buf[0];
register c; register int c;
register char *ptr = &parbuf[0]; register char *ptr = &parbuf[0];
register char **pbuf2;
LoadChar(c); LoadChar(c);
c = skipspaces(c); c = skipspaces(c);
if (c == ')') { /* no parameters: #define name() */ if (c == ')') { /* no parameters: #define name() */
buf[0] = (char *) 0; *pbuf = (char *) 0;
return 0; return 0;
} }
for (;;) { /* eat the formal parameter list */ for (;;) { /* eat the formal parameter list */
@ -421,7 +429,7 @@ getparams(buf, parbuf)
lexerror("#define: bad formal parameter"); lexerror("#define: bad formal parameter");
return -1; return -1;
} }
buf[count++] = ptr; /* name of the formal */ *pbuf = ptr; /* name of the formal */
*ptr++ = c; *ptr++ = c;
if (ptr >= &parbuf[PARBUFSIZE]) if (ptr >= &parbuf[PARBUFSIZE])
fatal("formal parameter buffer overflow"); fatal("formal parameter buffer overflow");
@ -432,10 +440,22 @@ getparams(buf, parbuf)
fatal("formal parameter buffer overflow"); fatal("formal parameter buffer overflow");
} while (in_idf(c)); } while (in_idf(c));
*(ptr - 1) = '\0'; /* mark end of the name */ *(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); c = skipspaces(c);
if (c == ')') { /* end of the formal parameter list */ if (c == ')') { /* end of the formal parameter list */
buf[count] = (char *) 0; *pbuf = (char *) 0;
return count; return pbuf - buf;
} }
if (c != ',') { if (c != ',') {
lexerror("#define: bad formal parameter list"); lexerror("#define: bad formal parameter list");
@ -444,11 +464,12 @@ getparams(buf, parbuf)
LoadChar(c); LoadChar(c);
c = skipspaces(c); c = skipspaces(c);
} }
/*NOTREACHED*/
} }
EXPORT EXPORT
macro_def(id, text, nformals, length, flags) macro_def(id, text, nformals, length, flags)
struct idf *id; register struct idf *id;
char *text; char *text;
{ {
register struct macro *newdef = id->id_macro; 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 /* macro_def() puts the contents and information of a macro
definition into a structure and stores it into the symbol definition into a structure and stores it into the symbol
table entry belonging to the name of the macro. table entry belonging to the name of the macro.
A warning is given if the definition overwrites another A warning is given if the definition overwrites another.
(unless predefined!)
*/ */
if (newdef) { /* is there a redefinition? */ if (newdef) { /* is there a redefinition? */
if ((newdef->mc_flag & PREDEF) == 0) {
if (macroeq(newdef->mc_text, text)) if (macroeq(newdef->mc_text, text))
return; return;
lexwarning("redefine \"%s\"", id->id_text); lexwarning("redefine \"%s\"", id->id_text);
} /* else: overwrite pre-definition */
} }
else else
id->id_macro = newdef = new_macro(); 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_nps = nformals; /* nr of formals */
newdef->mc_length = length; /* length of repl. text */ newdef->mc_length = length; /* length of repl. text */
newdef->mc_flag = flags; /* special flags */ newdef->mc_flag = flags; /* special flags */
newdef->mc_count = 0;
} }
PRIVATE int PRIVATE int

View 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 */

View file

@ -5,7 +5,6 @@
#ifndef NOPP #ifndef NOPP
#include <system.h> #include <system.h>
#include "predefine.h" /* UF */
#include "alloc.h" #include "alloc.h"
#include "class.h" #include "class.h"
#include "macro.h" #include "macro.h"
@ -57,10 +56,7 @@ init_pp()
} }
/* Initialize __DATE__, __FILE__ and __LINE__ macro /* Initialize __DATE__, __FILE__ and __LINE__ macro
definitions. The compile-time specified predefined macros definitions.
are also predefined: if this file is compiled with
-DPREDEFINE="vax,pdp", the macro definitions "vax" and
"pdp" are predefined macros.
*/ */
/* __DATE__ */ /* __DATE__ */
clock = sys_time(); clock = sys_time();
@ -77,33 +73,5 @@ init_pp()
/* defined(??) */ /* defined(??) */
macro_def(str2idf("defined"), "", 1, 1, FUNC); 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 #endif NOPP

View file

@ -1,427 +1,18 @@
/* $Header$ */ /* $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 "inputtype.h"
#include "interface.h" #include "file_info.h"
#include "arith.h"
#include "LLlex.h"
#include "input.h" #include "input.h"
#include "alloc.h" #define INP_TYPE struct file_info
#define INP_VAR finfo
struct file_info finfo;
#include <inp_pkg.body>
#include "nopp.h"
#ifndef NOPP #ifndef NOPP
#include "idepth.h" char *
#include "debug.h" getwdir(fn)
#include "pathlength.h" char *fn;
#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;
{ {
register char *p; register char *p;
char *strrindex(); char *strrindex();
@ -433,32 +24,31 @@ setwdir(wdir, fn)
} }
if (fn[0] == '\0' || (fn[0] == '/' && p == &fn[0])) /* absolute path */ if (fn[0] == '\0' || (fn[0] == '/' && p == &fn[0])) /* absolute path */
*wdir = "/"; return "";
else else
if (p) { if (p) {
*p = '\0'; *p = '\0';
*wdir = Salloc(fn, p - &fn[0] + 1); fn = Salloc(fn, p - &fn[0] + 1);
*p = '/'; *p = '/';
return fn;
} }
else return ".";
} }
#endif NOPP #endif NOPP
#ifndef NOPP int NoUnstack;
/* mk_filename() concatenates a dir and filename.
*/
GSTATIC char path[PATHLENGTH];
PRIVATE char * AtEoIT()
mk_filename(dir, file)
register char *dir, *file;
{ {
register char *dst = &path[0]; #ifndef NOPP
if (NoUnstack) lexerror("unexpected EOF");
if (!(dir[0] == '.' && dir[1] == '\0')) { DoUnstack();
while (*dst++ = *dir++);
*(dst - 1) = '/';
}
while (*dst++ = *file++);
return &path[0];
}
#endif NOPP #endif NOPP
return 0;
}
AtEoIF()
{
if (NoUnstack) lexerror("unexpected EOF");
return 0;
}

View file

@ -1,13 +1,3 @@
/* $Header$ */ /* $Header$ */
/* INPUT PRIMITIVES */
#define LoadChar(dest) ((dest = *ipp++) || (dest = loadbuf())) #include <inp_pkg.spec>
#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;

View file

@ -9,7 +9,7 @@
*/ */
#define NOFLAG 0 /* no special flags */ #define NOFLAG 0 /* no special flags */
#define FUNC 01 /* function attached */ #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 */ #define FORMALP 0200 /* mask for creating macro formal parameter */
@ -23,6 +23,7 @@ struct macro {
char * mc_text; /* the replacement text */ 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_length; /* length of replacement text */
int mc_count; /* # of "concurrent" invocations*/
char mc_flag; /* marking this macro */ char mc_flag; /* marking this macro */
}; };

View file

@ -34,7 +34,7 @@ char *inctable[MAXINCL] = { /* list for includes */
0 0
}; };
char **WorkingDir = &inctable[0]; extern char *getwdir();
#endif NOPP #endif NOPP
struct sp_id special_ids[] = { struct sp_id special_ids[] = {
@ -90,19 +90,17 @@ main(argc, argv)
#endif NOPP #endif NOPP
/* Note: source file "-" indicates that the source is supplied /* 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! not defined!
*/ */
#ifdef READ_IN_ONE #ifdef INP_READ_IN_ONE
while (argc > 1 && *argv[1] == '-') while (argc > 1 && *argv[1] == '-')
#else READ_IN_ONE #else INP_READ_IN_ONE
while (argc > 1 && *argv[1] == '-' && argv[1][1] != '\0') while (argc > 1 && *argv[1] == '-' && argv[1][1] != '\0')
#endif READ_IN_ONE #endif INP_READ_IN_ONE
{ {
char *par = &argv[1][1]; char *par = &argv[1][1];
if (*par == '-')
par++;
do_option(par); do_option(par);
argc--, argv++; argc--, argv++;
} }
@ -139,6 +137,7 @@ compile(argc, argv)
#ifdef USE_TMP #ifdef USE_TMP
char tmpf[256]; char tmpf[256];
#endif #endif
char *result;
#ifndef NOPP #ifndef NOPP
int pp_only = options['E'] || options['P']; int pp_only = options['E'] || options['P'];
@ -172,11 +171,15 @@ compile(argc, argv)
if (destination && strcmp(destination, "-") == 0) if (destination && strcmp(destination, "-") == 0)
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, fatal("%s: no source file %s\n", prog_name,
source ? source : "stdin"); source ? source : "stdin");
init(); init();
/* FileName = source; /* needed ??? */ FileName = source;
LineNumber = 0;
#ifndef NOPP
WorkingDir = getwdir(source);
#endif NOPP
PushLex(); PushLex();
#ifndef NOPP #ifndef NOPP

View file

@ -34,7 +34,10 @@ do_option(text)
switch(*text++) { switch(*text++) {
default: default:
options[text[-1]] = 1; /* flags, debug options etc. */ fatal("illegal option: %c", *--text);
case '-':
options[*text] = 1; /* flags, debug options etc. */
break; break;
case 'C' : /* E option + comment output */ case 'C' : /* E option + comment output */
@ -105,6 +108,7 @@ do_option(text)
new = tmp; new = tmp;
} }
} }
else inctable[inc_pos] = 0;
#else NOPP #else NOPP
warning("-I option ignored"); warning("-I option ignored");
#endif NOPP #endif NOPP
@ -135,6 +139,10 @@ do_option(text)
#endif NOPP #endif NOPP
break; break;
case 'R':
options['R'] = 1;
break;
#ifdef USE_TMP #ifdef USE_TMP
case 'T' : case 'T' :
if (*text) if (*text)

View file

@ -21,9 +21,11 @@
char *strcpy(), *strcat(); char *strcpy(), *strcat();
char *long2str(); char *long2str();
PRIVATE struct macro *ReplaceList; /* list of currently active macros */
EXPORT int EXPORT int
replace(idef) replace(idef)
struct idf *idef; register struct idf *idef;
{ {
/* replace() is called by the lexical analyzer to perform /* replace() is called by the lexical analyzer to perform
macro replacement. "idef" is the description of the macro replacement. "idef" is the description of the
@ -34,14 +36,18 @@ replace(idef)
replace() returns 1 if the replacement succeeded and 0 if replace() returns 1 if the replacement succeeded and 0 if
some error has occurred. some error has occurred.
*/ */
register struct macro *mac = idef->id_macro;
register char c; register char c;
register char flags = idef->id_macro->mc_flag;
char **actpars, **getactuals(); char **actpars, **getactuals();
char *reptext, *macro2buffer(); char *reptext, *macro2buffer();
int size; int size;
if (idef->id_macro->mc_nps != -1) { /* with parameter list */ if (mac->mc_flag & NOREPLACE) {
if (flags & FUNC) { 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". /* must be "defined".
Unfortunately, the next assertion Unfortunately, the next assertion
will not compile ... will not compile ...
@ -50,6 +56,12 @@ replace(idef)
if (! AccDefined) if (! AccDefined)
return 0; 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); LoadChar(c);
c = skipspaces(c); c = skipspaces(c);
if (c != '(') { /* no replacement if no () */ if (c != '(') { /* no replacement if no () */
@ -59,23 +71,27 @@ replace(idef)
return 0; return 0;
} }
actpars = getactuals(idef); /* get act.param. list */ actpars = getactuals(idef); /* get act.param. list */
if (flags & FUNC) { if (mac->mc_flag & FUNC) {
struct idf *param = str2idf(*actpars); struct idf *param = str2idf(*actpars);
if (param->id_macro) if (param->id_macro)
reptext = "\0001"; reptext = "1";
else else
reptext = "\0000"; reptext = "0";
InsertText(reptext, 2); InsertText(reptext, 1);
mac->next = ReplaceList;
ReplaceList = mac;
return 1; return 1;
} }
} }
if ((flags & PREDEF) && (UnknownIdIsZero == 0)) /* don't replace */ if (mac->mc_flag & FUNC) /* this macro leads to special action */
return 0;
if (flags & FUNC) /* this macro leads to special action */
macro_func(idef); macro_func(idef);
if (mac->mc_nps <= 0)
mac->mc_flag |= NOREPLACE;
reptext = macro2buffer(idef, actpars, &size); /* create input buffer */ reptext = macro2buffer(idef, actpars, &size); /* create input buffer */
InsertText(reptext, size); InsertText(reptext, size);
mac->next = ReplaceList;
ReplaceList = mac;
return 1; return 1;
} }
@ -83,24 +99,26 @@ GSTATIC char FilNamBuf[PATHLENGTH];
PRIVATE PRIVATE
macro_func(idef) macro_func(idef)
struct idf *idef; register struct idf *idef;
{ {
/* macro_func() performs the special actions needed with some /* macro_func() performs the special actions needed with some
macros. These macros are __FILE__ and __LINE__ which macros. These macros are __FILE__ and __LINE__ which
replacement texts must be evaluated at the time they are replacement texts must be evaluated at the time they are
used. used.
*/ */
register struct macro *mac = idef->id_macro;
switch (idef->id_text[2]) { /* This switch is very blunt... */ switch (idef->id_text[2]) { /* This switch is very blunt... */
case 'F' : /* __FILE__ */ case 'F' : /* __FILE__ */
FilNamBuf[0] = '"'; FilNamBuf[0] = '"';
strcpy(&FilNamBuf[1], FileName); strcpy(&FilNamBuf[1], FileName);
strcat(FilNamBuf, "\""); strcat(FilNamBuf, "\"");
idef->id_macro->mc_text = FilNamBuf; mac->mc_text = FilNamBuf;
idef->id_macro->mc_length = strlen(FilNamBuf); mac->mc_length = strlen(FilNamBuf);
break; break;
case 'L' : /* __LINE__ */ case 'L' : /* __LINE__ */
idef->id_macro->mc_text = long2str((long)LineNumber, 10); mac->mc_text = long2str((long)LineNumber, 10);
idef->id_macro->mc_length = 1; mac->mc_length = 1;
break; break;
default : default :
crash("(macro_func)"); crash("(macro_func)");
@ -125,10 +143,9 @@ macro2buffer(idef, actpars, siztext)
*/ */
register int size = 8; register int size = 8;
register char *text = Malloc(size); register char *text = Malloc(size);
register pos = 0; register int pos = 0;
register char *ptr = idef->id_macro->mc_text; register char *ptr = idef->id_macro->mc_text;
text[pos++] = '\0'; /* allow pushback */
while (*ptr) { while (*ptr) {
if (*ptr & FORMALP) { /* non-asc formal param. mark */ if (*ptr & FORMALP) { /* non-asc formal param. mark */
register int n = *ptr++ & 0177; register int n = *ptr++ & 0177;
@ -138,7 +155,7 @@ macro2buffer(idef, actpars, siztext)
/* copy the text of the actual parameter /* copy the text of the actual parameter
into the replacement text into the replacement text
*/ */
for (p = actpars[n - 1]; *p; p++) { for (p = actpars[n - 1]; p && *p; p++) {
text[pos++] = *p; text[pos++] = *p;
if (pos == size) if (pos == size)
text = Srealloc(text, size += RSTRSIZE); text = Srealloc(text, size += RSTRSIZE);
@ -154,4 +171,26 @@ macro2buffer(idef, actpars, siztext)
*siztext = pos; *siztext = pos;
return text; 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 #endif NOPP