From: ceriel Date: Thu, 4 Dec 1986 16:29:44 +0000 (+0000) Subject: version using input module and detecting preprocessor loops X-Git-Tag: release-5-5~5123 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=53d6dfcb6bffe22b669f5b9f82e28969720dc2c4;p=ack.git version using input module and detecting preprocessor loops --- diff --git a/lang/cem/cemcom/LLlex.c b/lang/cem/cemcom/LLlex.c index 84d5b29d5..e8b245cce 100644 --- a/lang/cem/cemcom/LLlex.c +++ b/lang/cem/cemcom/LLlex.c @@ -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; diff --git a/lang/cem/cemcom/LLlex.h b/lang/cem/cemcom/LLlex.h index 569a2e907..c01aaf46d 100644 --- a/lang/cem/cemcom/LLlex.h +++ b/lang/cem/cemcom/LLlex.h @@ -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 */ diff --git a/lang/cem/cemcom/Makefile.erik b/lang/cem/cemcom/Makefile.erik index c247c546f..d7f9352f1 100644 --- a/lang/cem/cemcom/Makefile.erik +++ b/lang/cem/cemcom/Makefile.erik @@ -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 +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 +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 -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 -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 +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 +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 -symbol2str.o: Lpars.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 -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 +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 diff --git a/lang/cem/cemcom/Parameters b/lang/cem/cemcom/Parameters index 6de92789f..5466fb21a 100644 --- a/lang/cem/cemcom/Parameters +++ b/lang/cem/cemcom/Parameters @@ -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 diff --git a/lang/cem/cemcom/domacro.c b/lang/cem/cemcom/domacro.c index b3d32151a..fe2f9f1ee 100644 --- a/lang/cem/cemcom/domacro.c +++ b/lang/cem/cemcom/domacro.c @@ -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 diff --git a/lang/cem/cemcom/file_info.h b/lang/cem/cemcom/file_info.h new file mode 100644 index 000000000..1cb1db035 --- /dev/null +++ b/lang/cem/cemcom/file_info.h @@ -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 */ diff --git a/lang/cem/cemcom/init.c b/lang/cem/cemcom/init.c index 2c0b6a6cb..20c120e25 100644 --- a/lang/cem/cemcom/init.c +++ b/lang/cem/cemcom/init.c @@ -5,7 +5,6 @@ #ifndef NOPP #include -#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 diff --git a/lang/cem/cemcom/input.c b/lang/cem/cemcom/input.c index fd6de2393..c36250374 100644 --- a/lang/cem/cemcom/input.c +++ b/lang/cem/cemcom/input.c @@ -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 -#include "nopp.h" -#include "inputtype.h" -#include "interface.h" -#include "arith.h" -#include "LLlex.h" -#include "input.h" -#include "alloc.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 +#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 +#include "nopp.h" #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]; +#ifndef NOPP + if (NoUnstack) lexerror("unexpected EOF"); + DoUnstack(); +#endif NOPP + return 0; +} - if (!(dir[0] == '.' && dir[1] == '\0')) { - while (*dst++ = *dir++); - *(dst - 1) = '/'; - } - while (*dst++ = *file++); - return &path[0]; +AtEoIF() +{ + if (NoUnstack) lexerror("unexpected EOF"); + return 0; } -#endif NOPP diff --git a/lang/cem/cemcom/input.h b/lang/cem/cemcom/input.h index 111856226..aa22fff0b 100644 --- a/lang/cem/cemcom/input.h +++ b/lang/cem/cemcom/input.h @@ -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 diff --git a/lang/cem/cemcom/macro.str b/lang/cem/cemcom/macro.str index 34a62dd58..ef3243278 100644 --- a/lang/cem/cemcom/macro.str +++ b/lang/cem/cemcom/macro.str @@ -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 */ }; diff --git a/lang/cem/cemcom/main.c b/lang/cem/cemcom/main.c index b9fa69171..28d67c2b7 100644 --- a/lang/cem/cemcom/main.c +++ b/lang/cem/cemcom/main.c @@ -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 diff --git a/lang/cem/cemcom/options.c b/lang/cem/cemcom/options.c index d862e0f7d..38525c0f9 100644 --- a/lang/cem/cemcom/options.c +++ b/lang/cem/cemcom/options.c @@ -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) diff --git a/lang/cem/cemcom/replace.c b/lang/cem/cemcom/replace.c index 21c98c060..169f0a161 100644 --- a/lang/cem/cemcom/replace.c +++ b/lang/cem/cemcom/replace.c @@ -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