diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 000000000..1f0a4d38a --- /dev/null +++ b/.drone.yml @@ -0,0 +1,15 @@ +clone: + depth: 10 +build: + image: teaci/msys32 + pull: true + shell: $$arch + commands: + - if [ $$arch = sh ]; then apt update; apt install build-essential bison flex; fi + - make PREFIX=/tmp/acki +ack + +matrix: + arch: + - sh + #- msys32 + diff --git a/Makefile b/Makefile index d3057fe76..95755a917 100644 --- a/Makefile +++ b/Makefile @@ -15,8 +15,8 @@ ACK_TEMP_DIR = /tmp # install it and just want to run the ACK from the build directory # (/tmp/ack-build/staging, by default), leave this as $(INSDIR). -#PREFIX = /usr/local -PREFIX = $(INSDIR) +PREFIX = /usr/local +#PREFIX = $(INSDIR) # Where do you want to put the object files used when building? diff --git a/lang/cem/cemcom.ansi/BigPars b/lang/cem/cemcom.ansi/BigPars index e3fad8296..6f4b0971d 100644 --- a/lang/cem/cemcom.ansi/BigPars +++ b/lang/cem/cemcom.ansi/BigPars @@ -111,10 +111,6 @@ #define INP_READ_IN_ONE 1 /* read input file in one */ -!File: nopp.h -/*#define NOPP 1 /* if NOT defined, use built-int preprocessor */ - - !File: nobitfield.h /*#define NOBITFIELD 1 /* if NOT defined, implement bitfields */ diff --git a/lang/cem/cemcom.ansi/LLlex.c b/lang/cem/cemcom.ansi/LLlex.c index a25098e08..f0f5d5c24 100644 --- a/lang/cem/cemcom.ansi/LLlex.c +++ b/lang/cem/cemcom.ansi/LLlex.c @@ -5,96 +5,64 @@ /* $Id$ */ /* L E X I C A L A N A L Y Z E R */ -#include -#include -#include "parameters.h" -#include "input.h" -#include "arith.h" -#include "def.h" -#include "macro.h" -#include "idf.h" -#include "LLlex.h" -#include "Lpars.h" -#include "class.h" -#include "sizes.h" -#include "specials.h" /* registration of special identifiers */ +#include +#include +#include "parameters.h" +#include "input.h" +#include "arith.h" +#include "def.h" +#include "macro.h" +#include "idf.h" +#include "LLlex.h" +#include "Lpars.h" +#include "class.h" +#include "sizes.h" +#include "specials.h" /* registration of special identifiers */ /* Data about the token yielded */ struct token dot, ahead, aside; -int token_nmb = 0; /* number of the ahead token */ -int tk_nmb_at_last_syn_err = -5/*ERR_SHADOW*/; - /* token number at last syntax error */ +int token_nmb = 0; /* number of the ahead token */ +int tk_nmb_at_last_syn_err = -5 /*ERR_SHADOW*/; +/* token number at last syntax error */ int idfsize = IDFSIZE; -char sp_occurred[SP_TOTAL+1]; +char sp_occurred[SP_TOTAL + 1]; -#ifndef NOPP -int ReplaceMacros = 1; /* replacing macros */ -int AccDefined = 0; /* accept "defined(...)" */ -int UnknownIdIsZero = 0; /* interpret unknown id as integer 0 */ -int Unstacked = 0; /* an unstack is done */ -extern int InputLevel; -#endif -int AccFileSpecifier = 0; /* return filespecifier <...> */ -int EoiForNewline = 0; /* return EOI upon encountering newline */ -int File_Inserted = 0; /* a file has just been inserted */ -int LexSave = 0; /* last character read by GetChar */ -#define MAX_LL_DEPTH 2 +int AccFileSpecifier = 0; /* return filespecifier <...> */ +int EoiForNewline = 0; /* return EOI upon encountering newline */ +int File_Inserted = 0; /* a file has just been inserted */ +int LexSave = 0; /* last character read by GetChar */ +#define MAX_LL_DEPTH 2 -#define FLG_ESEEN 0x01 /* possibly a floating point number */ -#define FLG_DOTSEEN 0x02 /* certainly a floating point number */ +#define FLG_ESEEN 0x01 /* possibly a floating point number */ +#define FLG_DOTSEEN 0x02 /* certainly a floating point number */ extern arith full_mask[]; #ifdef LINT extern int lint_skip_comment; #endif -#ifndef NOPP -static struct token LexStack[MAX_LL_DEPTH]; -static LexSP = 0; - -void skipcomment(); - -/* In PushLex() the actions are taken in order to initialise or - re-initialise the lexical scanner. - E.g. at the invocation of a sub-parser that uses LLlex(), the - state of the current parser should be saved. -*/ -PushLex() -{ - assert(LexSP < MAX_LL_DEPTH); - assert(ASIDE == 0); /* ASIDE = 0; */ - GetToken(&ahead); - LexStack[LexSP++] = dot; -} - -PopLex() -{ - assert(LexSP > 0); - dot = LexStack[--LexSP]; -} -#endif /* NOPP */ - -int -LLlex() +int LLlex() { /* LLlex() plays the role of Lexical Analyzer for the C parser. - The look-ahead and putting aside of tokens are taken into - account. + The look-ahead and putting aside of tokens are taken into + account. */ - if (ASIDE) { /* a token is put aside */ + if (ASIDE) + { /* a token is put aside */ dot = aside; ASIDE = 0; } - else { /* read ahead and return the old one */ -#ifdef LINT + else + { /* read ahead and return the old one */ +#ifdef LINT lint_comment_ahead(); -#endif /* LINT */ +#endif /* LINT */ dot = ahead; /* the following test is performed due to the dual - task of LLlex(): it is also called for parsing the - restricted constant expression following a #if or - #elif. The newline character causes EOF to be - returned in this case to stop the LLgen parsing task. + task of LLlex(): it is also called for parsing the + restricted constant expression following a #if or + #elif. The newline character causes EOF to be + returned in this case to stop the LLgen parsing task. */ if (DOT != EOI) GetToken(&ahead); @@ -104,32 +72,30 @@ LLlex() return DOT; } +char* string_token(); +arith char_constant(); -char *string_token(); -arith char_constant(); - -int -GetToken(ptok) - register struct token *ptok; +int GetToken(ptok) register struct token* ptok; { /* GetToken() is the actual token recognizer. It calls the - control line interpreter if it encounters a "\n{w}*#" - combination. Macro replacement is also performed if it is - needed. + control line interpreter if it encounters a "\n{w}*#" + combination. Macro replacement is also performed if it is + needed. */ char buf[(IDFSIZE > NUMSIZE ? IDFSIZE : NUMSIZE) + 1]; register int ch, nch; token_nmb++; - if (File_Inserted) { + if (File_Inserted) + { File_Inserted = 0; goto firstline; } -again: /* rescan the input after an error or replacement */ +again: /* rescan the input after an error or replacement */ ch = GetChar(); -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 */ { fatal("non-ascii '\\%03o' read", ch & 0377); @@ -138,370 +104,282 @@ go_on: /* rescan, the following character has been read */ ptok->tk_file = FileName; ptok->tk_line = LineNumber; - switch (class(ch)) { /* detect character class */ - case STNL: /* newline, vertical space or formfeed */ -firstline: - LineNumber++; /* also at vs and ff */ - ptok->tk_file = FileName; - ptok->tk_line = LineNumber; - 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; + switch (class(ch)) + { /* detect character class */ + case STNL: /* newline, vertical space or formfeed */ + firstline: + LineNumber++; /* also at vs and ff */ + ptok->tk_file = FileName; + ptok->tk_line = LineNumber; + 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 ((ch = GetChar()), - (ch == '#' -#ifndef NOPP - || ch == '/' -#endif - || class(ch) == STSKIP)) { - /* blanks are allowed before hashes */ - if (ch == '#') { - /* a control line follows */ - domacro(); -#ifndef NOPP - if (File_Inserted) { - File_Inserted = 0; - goto firstline; + while ((ch = GetChar()), (ch == '#' + || class(ch) == STSKIP)) + { + /* blanks are allowed before hashes */ + if (ch == '#') + { + /* a control line follows */ + domacro(); } - } else if (ch == '/') { - if ((GetChar() == '*') && !InputLevel) { - skipcomment(); - } else { - UnGetChar(); - break; - } -#endif /* NOPP */ } - } /* We have to loop here, because in - `domacro' the nl, vt or ff is read. The - character following it may again be a `#'. + `domacro' the nl, vt or ff is read. The + character following it may again be a `#'. */ - goto go_on; - case STSKIP: /* just skip the skip characters */ - goto again; - case STGARB: /* garbage character */ -#ifndef NOPP -garbage: -#endif - if (040 < ch && ch < 0177) { + goto go_on; + case STSKIP: /* just skip the skip characters */ + goto again; + case STGARB: /* garbage character */ + if (040 < ch && ch < 0177) + { + return ptok->tk_symb = ch; + } + else + { + lexerror("garbage char \\%03o", ch); + } + goto again; + case STSIMP: /* a simple character, no part of compound token*/ return ptok->tk_symb = ch; - } else { - lexerror("garbage char \\%03o", ch); - } - goto again; - case STSIMP: /* a simple character, no part of compound token*/ - return ptok->tk_symb = ch; - case STCOMP: /* maybe the start of a compound token */ - nch = GetChar(); /* character lookahead */ - switch (ch) { - case '!': - if (nch == '=') - return ptok->tk_symb = NOTEQUAL; - break; - case '&': - if (nch == '&') - return ptok->tk_symb = AND; - if (nch == '=') - return ptok->tk_symb = ANDAB; - break; - case '+': - if (nch == '+') - return ptok->tk_symb = PLUSPLUS; - if (nch == '=') - return ptok->tk_symb = PLUSAB; - break; - case '-': - if (nch == '-') - return ptok->tk_symb = MINMIN; - if (nch == '>') - return ptok->tk_symb = ARROW; - if (nch == '=') - return ptok->tk_symb = MINAB; - break; - case '<': - if (AccFileSpecifier) { - UnGetChar(); /* pushback nch */ - ptok->tk_bts = string_token("file specifier", - '>', &(ptok->tk_len)); - return ptok->tk_symb = FILESPECIFIER; + case STCOMP: /* maybe the start of a compound token */ + nch = GetChar(); /* character lookahead */ + switch (ch) + { + case '!': + if (nch == '=') + return ptok->tk_symb = NOTEQUAL; + break; + case '&': + if (nch == '&') + return ptok->tk_symb = AND; + if (nch == '=') + return ptok->tk_symb = ANDAB; + break; + case '+': + if (nch == '+') + return ptok->tk_symb = PLUSPLUS; + if (nch == '=') + return ptok->tk_symb = PLUSAB; + break; + case '-': + if (nch == '-') + return ptok->tk_symb = MINMIN; + if (nch == '>') + return ptok->tk_symb = ARROW; + if (nch == '=') + return ptok->tk_symb = MINAB; + break; + case '<': + if (AccFileSpecifier) + { + UnGetChar(); /* pushback nch */ + ptok->tk_bts = string_token("file specifier", '>', &(ptok->tk_len)); + return ptok->tk_symb = FILESPECIFIER; + } + if (nch == '<') + { + if ((nch = GetChar()) == '=') + return ptok->tk_symb = LEFTAB; + UnGetChar(); + return ptok->tk_symb = LEFT; + } + if (nch == '=') + return ptok->tk_symb = LESSEQ; + break; + case '=': + if (nch == '=') + return ptok->tk_symb = EQUAL; + break; + case '>': + if (nch == '=') + return ptok->tk_symb = GREATEREQ; + if (nch == '>') + { + if ((nch = GetChar()) == '=') + return ptok->tk_symb = RIGHTAB; + UnGetChar(); + return ptok->tk_symb = RIGHT; + } + break; + case '|': + if (nch == '|') + return ptok->tk_symb = OR; + if (nch == '=') + return ptok->tk_symb = ORAB; + break; + case '%': + if (nch == '=') + return ptok->tk_symb = MODAB; + break; + case '*': + if (nch == '=') + return ptok->tk_symb = TIMESAB; + break; + case '^': + if (nch == '=') + return ptok->tk_symb = XORAB; + break; + case '/': + if (nch == '=') + return ptok->tk_symb = DIVAB; + break; + default: + crash("bad class for char 0%o", ch); + /* NOTREACHED */ } - if (nch == '<') { - if ((nch = GetChar()) == '=') - return ptok->tk_symb = LEFTAB; - UnGetChar(); - return ptok->tk_symb = LEFT; - } - if (nch == '=') - return ptok->tk_symb = LESSEQ; - break; - case '=': - if (nch == '=') - return ptok->tk_symb = EQUAL; - break; - case '>': - if (nch == '=') - return ptok->tk_symb = GREATEREQ; - if (nch == '>') { - if ((nch = GetChar()) == '=') - return ptok->tk_symb = RIGHTAB; - UnGetChar(); - return ptok->tk_symb = RIGHT; - } - break; - case '|': - if (nch == '|') - return ptok->tk_symb = OR; - if (nch == '=') - return ptok->tk_symb = ORAB; - break; - case '%': - if (nch == '=') - return ptok->tk_symb = MODAB; - break; - case '*': - if (nch == '=') - return ptok->tk_symb = TIMESAB; - break; - case '^': - if (nch == '=') - return ptok->tk_symb = XORAB; - break; - case '/': -#ifndef NOPP - if (nch == '*' && !InputLevel) { - skipcomment(); - goto again; - } -#endif - if (nch == '=') - return ptok->tk_symb = DIVAB; - break; - default: - crash("bad class for char 0%o", ch); - /* NOTREACHED */ - } - UnGetChar(); - return ptok->tk_symb = ch; - case STCHAR: /* character constant */ - ptok->tk_ival = char_constant("character"); - ptok->tk_fund = INT; - return ptok->tk_symb = INTEGER; - case STSTR: /* string */ - ptok->tk_bts = string_token("string", '"', &(ptok->tk_len)); - ptok->tk_fund = CHAR; /* string of characters */ - return ptok->tk_symb = STRING; - case STELL: /* wide character constant/string prefix */ - nch = GetChar(); - if (nch == '"') { - ptok->tk_bts = string_token("wide character string", - '"', &(ptok->tk_len)); - ptok->tk_fund = WCHAR; /* string of wide characters */ + UnGetChar(); + return ptok->tk_symb = ch; + case STCHAR: /* character constant */ + ptok->tk_ival = char_constant("character"); + ptok->tk_fund = INT; + return ptok->tk_symb = INTEGER; + case STSTR: /* string */ + ptok->tk_bts = string_token("string", '"', &(ptok->tk_len)); + ptok->tk_fund = CHAR; /* string of characters */ return ptok->tk_symb = STRING; - } else if (nch == '\'') { - ptok->tk_ival = char_constant("wide character"); - ptok->tk_fund = INT; - return ptok->tk_symb = INTEGER; - } - UnGetChar(); + case STELL: /* wide character constant/string prefix */ + nch = GetChar(); + if (nch == '"') + { + ptok->tk_bts = string_token("wide character string", '"', &(ptok->tk_len)); + ptok->tk_fund = WCHAR; /* string of wide characters */ + return ptok->tk_symb = STRING; + } + else if (nch == '\'') + { + ptok->tk_ival = char_constant("wide character"); + ptok->tk_fund = INT; + return ptok->tk_symb = INTEGER; + } + UnGetChar(); /* fallthrough */ - case STIDF: - { - register char *tg = &buf[0]; - register int pos = -1; - register struct idf *idef; - extern int idfsize; /* ??? */ -#ifndef NOPP - int NoExpandNext = 0; + case STIDF: + { + register char* tg = &buf[0]; + register int pos = -1; + register struct idf* idef; + extern int idfsize; /* ??? */ + do + { /* read the identifier */ + if (++pos < idfsize) + { + *tg++ = ch; + } + ch = GetChar(); + } while (in_idf(ch)); - if (Unstacked) EnableMacros(); /* unstack macro's when allowed. */ - if (ch == NOEXPM) { - NoExpandNext = 1; - ch = GetChar(); + if (ch != EOI) + UnGetChar(); + *tg++ = '\0'; /* mark the end of the identifier */ + idef = ptok->tk_idf = str2idf(buf, 1); + sp_occurred[idef->id_special] = 1; + idef->id_file = ptok->tk_file; + idef->id_line = ptok->tk_line; + ptok->tk_symb + = (idef->id_reserved + ? idef->id_reserved + : idef->id_def && idef->id_def->df_sc == TYPEDEF ? TYPE_IDENTIFIER + : IDENTIFIER); + return IDENTIFIER; } -#endif - do { /* read the identifier */ - if (++pos < idfsize) { - *tg++ = ch; + case STNUM: /* a numeric constant */ + { + register int siz_left = NUMSIZE - 1; + register char* np = &buf[0]; + int flags = 0; + +#define store(ch) \ + if (--siz_left >= 0) \ + *np++ = ch; + + if (ch == '.') + { + /* An embarrasing ambiguity. We have either a + pp-number, a field operator, an ELLIPSIS or + an error (..). + */ + ch = GetChar(); + if (!is_dig(ch)) + { /* . or ... */ + if (ch == '.') + { + if ((ch = GetChar()) == '.') + return ptok->tk_symb = ELLIPSIS; + UnGetChar(); /* not '.' */ + ChPushBack('.'); /* sigh ... */ + } + else + UnGetChar(); /* not '.' */ + return ptok->tk_symb = '.'; + } + UnGetChar(); + ch = '.'; + flags |= FLG_DOTSEEN; } + store(ch); ch = GetChar(); - } while (in_idf(ch)); - - if (ch != EOI) + while (in_idf(ch) || ch == '.') + { + store(ch); + if (ch == '.') + flags |= FLG_DOTSEEN; + if (ch == 'e' || ch == 'E') + { + flags |= FLG_ESEEN; + ch = GetChar(); + if (ch == '+' || ch == '-') + { + flags |= FLG_DOTSEEN; /* trick */ + store(ch); + ch = GetChar(); + } + } + else + ch = GetChar(); + } + store('\0'); UnGetChar(); - *tg++ = '\0'; /* mark the end of the identifier */ - idef = ptok->tk_idf = str2idf(buf, 1); - sp_occurred[idef->id_special] = 1; - idef->id_file = ptok->tk_file; - idef->id_line = ptok->tk_line; -#ifndef NOPP - if (idef->id_macro && ReplaceMacros && !NoExpandNext) { - if (replace(idef)) - goto again; - } - if (UnknownIdIsZero && idef->id_reserved != SIZEOF) { - ptok->tk_ival = (arith)0; - ptok->tk_fund = INT; + + np = &buf[0]; + ch = *np++; + if (siz_left < 0) + { + lexerror("number too long"); + if ((flags & FLG_DOTSEEN) + || (flags & FLG_ESEEN && !(ch == '0' && (*np == 'x' || *np == 'X')))) + { + ptok->tk_fval = Salloc("0.0", (unsigned)4); + ptok->tk_fund = DOUBLE; + return ptok->tk_symb = FLOATING; + } + ptok->tk_ival = 1; + ptok->tk_fund = ULONG; + ptok->tk_symb = INTEGER; + } + /* Now, the pp-number must be converted into a token */ + if ((flags & FLG_DOTSEEN) + || (flags & FLG_ESEEN && !(ch == '0' && (*np == 'x' || *np == 'X')))) + { + strflt2tok(&buf[0], ptok); + return ptok->tk_symb = FLOATING; + } + strint2tok(&buf[0], ptok); return ptok->tk_symb = INTEGER; } -#endif /* NOPP */ - ptok->tk_symb = ( - idef->id_reserved - ? idef->id_reserved - : idef->id_def && idef->id_def->df_sc == TYPEDEF - ? TYPE_IDENTIFIER - : IDENTIFIER - ); - return IDENTIFIER; - } - case STNUM: /* a numeric constant */ - { - register int siz_left = NUMSIZE - 1; - register char *np = &buf[0]; - int flags = 0; - -#define store(ch) if (--siz_left >= 0) \ - *np++ = ch; - - if (ch == '.') { - /* An embarrasing ambiguity. We have either a - pp-number, a field operator, an ELLIPSIS or - an error (..). - */ - ch = GetChar(); - if (!is_dig(ch)) { /* . or ... */ - if (ch == '.') { - if ((ch = GetChar()) == '.') - return ptok->tk_symb = ELLIPSIS; - UnGetChar(); /* not '.' */ - ChPushBack('.'); /* sigh ... */ - } else - UnGetChar(); /* not '.' */ - return ptok->tk_symb = '.'; - } - UnGetChar(); - ch = '.'; - flags |= FLG_DOTSEEN; - } - store(ch); - ch = GetChar(); - while(in_idf(ch) || ch == '.') { - store(ch); - if (ch == '.') flags |= FLG_DOTSEEN; - if (ch == 'e' || ch == 'E') { - flags |= FLG_ESEEN; - ch = GetChar(); - if (ch == '+' || ch == '-') { - flags |= FLG_DOTSEEN; /* trick */ - store(ch); - ch = GetChar(); - } - } else ch = GetChar(); - } - store('\0'); - UnGetChar(); - - np = &buf[0]; - ch = *np++; - if (siz_left < 0) { - lexerror("number too long"); - if ((flags & FLG_DOTSEEN) - || (flags & FLG_ESEEN - && !(ch == '0' - && (*np == 'x' || *np == 'X')))) { - ptok->tk_fval = Salloc("0.0", (unsigned) 4); - ptok->tk_fund = DOUBLE; - return ptok->tk_symb = FLOATING; - } - ptok->tk_ival = 1; - ptok->tk_fund = ULONG; - ptok->tk_symb = INTEGER; - } - /* Now, the pp-number must be converted into a token */ - if ((flags & FLG_DOTSEEN) - || (flags & FLG_ESEEN - && !(ch == '0' && (*np == 'x' || *np == 'X')))) { - strflt2tok(&buf[0], ptok); - return ptok->tk_symb = FLOATING; - } - strint2tok(&buf[0], ptok); - return ptok->tk_symb = INTEGER; - } - case STEOI: /* end of text on source file */ - return ptok->tk_symb = EOI; -#ifndef NOPP - case STMSPEC: - if (!InputLevel) goto garbage; - if (ch == TOKSEP) goto again; - /* fallthrough shouldn't happen */ -#endif - default: /* this cannot happen */ - crash("bad class for char 0%o", ch); + case STEOI: /* end of text on source file */ + return ptok->tk_symb = EOI; + default: /* this cannot happen */ + crash("bad class for char 0%o", ch); } /*NOTREACHED*/ } -#ifndef NOPP -void -skipcomment() -{ - /* The last character read has been the '*' of '/_*'. The - characters, except NL and EOI, between '/_*' and the first - occurring '*_/' are not interpreted. - NL only affects the LineNumber. EOI is not legal. - - Important note: it is not possible to stop skipping comment - beyond the end-of-file of an included file. - EOI is returned by LoadChar only on encountering EOF of the - top-level file... - */ - register int c, oldc = '\0'; - - NoUnstack++; - c = GetChar(); -#ifdef LINT - if (! lint_skip_comment) { - lint_start_comment(); - lint_comment_char(c); - } -#endif /* LINT */ - do { - while (c != '*') { - if (class(c) == STNL) { - ++LineNumber; - } else if (c == EOI) { - NoUnstack--; -#ifdef LINT - if (! lint_skip_comment) lint_end_comment(); -#endif /* LINT */ - return; - } - oldc = c; - c = GetChar(); -#ifdef LINT - if (! lint_skip_comment) lint_comment_char(c); -#endif /* LINT */ - } /* last Character seen was '*' */ - c = GetChar(); - if ( c != '/' && oldc == '/') - lexwarning("comment inside comment ?"); - oldc = '*'; -#ifdef LINT - if (! lint_skip_comment) lint_comment_char(c); -#endif /* LINT */ - } while (c != '/'); -#ifdef LINT - if (! lint_skip_comment) lint_end_comment(); -#endif /* LINT */ - NoUnstack--; -} -#endif /* NOPP */ - -arith -char_constant(nm) - char *nm; +arith char_constant(nm) char* nm; { register arith val = 0; register int ch; @@ -511,20 +389,23 @@ char_constant(nm) if (ch == '\'') lexerror("%s constant too short", nm); else - while (ch != '\'') { - if (ch == '\n') { - lexerror("newline in %s constant", nm); - LineNumber++; - break; + while (ch != '\'') + { + if (ch == '\n') + { + lexerror("newline in %s constant", nm); + LineNumber++; + break; + } + if (ch == '\\') + ch = quoted(GetChar()); + if (ch >= 128) + ch -= 256; + if (size < (int)int_size) + val |= ch << 8 * size; + size++; + ch = GetChar(); } - if (ch == '\\') - ch = quoted(GetChar()); - if (ch >= 128) ch -= 256; - if (size < (int)int_size) - val |= ch << 8 * size; - size++; - ch = GetChar(); - } if (size > 1) lexstrict("%s constant includes more than one character", nm); if (size > (int)int_size) @@ -532,24 +413,25 @@ char_constant(nm) return val; } -char * -string_token(nm, stop_char, plen) - char *nm; - int *plen; +char* string_token(nm, stop_char, plen) char* nm; +int* plen; { register int ch; register int str_size; - register char *str = Malloc((unsigned) (str_size = ISTRSIZE)); + register char* str = Malloc((unsigned)(str_size = ISTRSIZE)); register int pos = 0; - + ch = GetChar(); - while (ch != stop_char) { - if (ch == '\n') { + while (ch != stop_char) + { + if (ch == '\n') + { lexerror("newline in %s", nm); LineNumber++; break; } - if (ch == EOI) { + if (ch == EOI) + { lexerror("end-of-file inside %s", nm); break; } @@ -557,7 +439,7 @@ string_token(nm, stop_char, plen) ch = quoted(GetChar()); str[pos++] = ch; if (pos == str_size) - str = Realloc(str, (unsigned) (str_size += RSTRSIZE)); + str = Realloc(str, (unsigned)(str_size += RSTRSIZE)); ch = GetChar(); } str[pos++] = '\0'; /* for filenames etc. */ @@ -565,213 +447,163 @@ string_token(nm, stop_char, plen) return str; } -int -quoted(ch) - register int ch; -{ +int quoted(ch) register int ch; +{ /* quoted() replaces an escaped character sequence by the - character meant. + character meant. */ /* first char after backslash already in ch */ - if (!is_oct(ch)) { /* a quoted char */ - switch (ch) { - case 'n': - ch = '\n'; - break; - case 't': - ch = '\t'; - break; - case 'b': - ch = '\b'; - break; - case 'r': - ch = '\r'; - break; - case 'f': - ch = '\f'; - break; - case 'a': /* alert */ - ch = '\007'; - break; - case 'v': /* vertical tab */ - ch = '\013'; - break; - case 'x': /* quoted hex */ + if (!is_oct(ch)) + { /* a quoted char */ + switch (ch) { - register int hex = 0; - register int vch; + case 'n': + ch = '\n'; + break; + case 't': + ch = '\t'; + break; + case 'b': + ch = '\b'; + break; + case 'r': + ch = '\r'; + break; + case 'f': + ch = '\f'; + break; + case 'a': /* alert */ + ch = '\007'; + break; + case 'v': /* vertical tab */ + ch = '\013'; + break; + case 'x': /* quoted hex */ + { + register int hex = 0; + register int vch; - for (;;) { - ch = GetChar(); - if ((vch = hex_val(ch)) == -1) - break; - hex = hex * 16 + vch; + for (;;) + { + ch = GetChar(); + if ((vch = hex_val(ch)) == -1) + break; + hex = hex * 16 + vch; + } + UnGetChar(); + ch = hex; } - UnGetChar(); - ch = hex; - } } } - else { /* a quoted octal */ + else + { /* a quoted octal */ register int oct = 0, cnt = 0; - do { - oct = oct*8 + (ch-'0'); + do + { + oct = oct * 8 + (ch - '0'); ch = GetChar(); } while (is_oct(ch) && ++cnt < 3); UnGetChar(); ch = oct; } - return ch&0377; + return ch & 0377; } - -int -hex_val(ch) - register int ch; +int hex_val(ch) register int ch; { - return is_dig(ch) ? ch - '0' - : is_hex(ch) ? (ch - 'a' + 10) & 017 - : -1; + return is_dig(ch) ? ch - '0' : is_hex(ch) ? (ch - 'a' + 10) & 017 : -1; } - -int -GetChar() +int GetChar() { /* The routines GetChar and trigraph parses the trigraph - sequences and removes occurences of \\\n. + sequences and removes occurences of \\\n. */ register int ch; -#ifndef NOPP -again: -#endif LoadChar(ch); - -#ifndef NOPP - /* possible trigraph sequence */ - if (ch == '?') - ch = trigraph(); - - /* \ is removed from the input stream */ - if (ch == '\\') { - LoadChar(ch); - if (ch == '\n') { - ++LineNumber; - goto again; - } - PushBack(); - ch = '\\'; - } -#endif - return(LexSave = ch); + return (LexSave = ch); } -#ifndef NOPP -int -trigraph() -{ - register int ch; - - LoadChar(ch); - if (ch == '?') { - LoadChar(ch); - switch (ch) { /* its a trigraph */ - case '=': - ch = '#'; - return(ch); - case '(': - ch = '['; - return(ch); - case '/': - ch = '\\'; - return(ch); - case ')': - ch = ']'; - return(ch); - case '\'': - ch = '^'; - return(ch); - case '<': - ch = '{'; - return(ch); - case '!': - ch = '|'; - return(ch); - case '>': - ch = '}'; - return(ch); - case '-': - ch = '~'; - return(ch); - } - PushBack(); - } - PushBack(); - return('?'); -} -#endif - /* strflt2tok only checks the syntax of the floating-point number and * selects the right type for the number. */ -strflt2tok(fltbuf, ptok) -char fltbuf[]; -struct token *ptok; +strflt2tok(fltbuf, ptok) char fltbuf[]; +struct token* ptok; { - register char *cp = fltbuf; + register char* cp = fltbuf; int malformed = 0; - while (is_dig(*cp)) cp++; - if (*cp == '.') { + while (is_dig(*cp)) cp++; - while (is_dig(*cp)) cp++; + if (*cp == '.') + { + cp++; + while (is_dig(*cp)) + cp++; } - if (*cp == 'e' || *cp == 'E') { + if (*cp == 'e' || *cp == 'E') + { cp++; if (*cp == '+' || *cp == '-') cp++; - if (!is_dig(*cp)) malformed++; - while (is_dig(*cp)) cp++; + if (!is_dig(*cp)) + malformed++; + while (is_dig(*cp)) + cp++; } - if (*cp == 'f' || *cp == 'F') { - if (*(cp + 1)) malformed++; + if (*cp == 'f' || *cp == 'F') + { + if (*(cp + 1)) + malformed++; *cp = '\0'; ptok->tk_fund = FLOAT; - } else if (*cp == 'l' || *cp == 'L') { - if (*(cp + 1)) malformed++; + } + else if (*cp == 'l' || *cp == 'L') + { + if (*(cp + 1)) + malformed++; *cp = '\0'; ptok->tk_fund = LNGDBL; - } else { - if (*cp) malformed++; + } + else + { + if (*cp) + malformed++; ptok->tk_fund = DOUBLE; } - if (malformed) { + if (malformed) + { lexerror("malformed floating constant"); - ptok->tk_fval = Salloc("0.0", (unsigned) 4); - } else { - ptok->tk_fval = Salloc(fltbuf, (unsigned) (cp - fltbuf + 1)); + ptok->tk_fval = Salloc("0.0", (unsigned)4); + } + else + { + ptok->tk_fval = Salloc(fltbuf, (unsigned)(cp - fltbuf + 1)); } } -strint2tok(intbuf, ptok) -char intbuf[]; -struct token *ptok; +strint2tok(intbuf, ptok) char intbuf[]; +struct token* ptok; { - register char *cp = intbuf; + register char* cp = intbuf; int base = 10; arith val = 0, dig, ubound; int uns_flg = 0, lng_flg = 0, malformed = 0, ovfl = 0; int fund; assert(*cp != '-'); - if (*cp == '0') { + if (*cp == '0') + { cp++; - if (*cp == 'x' || *cp == 'X') { + if (*cp == 'x' || *cp == 'X') + { cp++; base = 16; - } else base = 8; + } + else + base = 8; } /* The upperbound will be the same as when computed with * max_unsigned_arith / base (since base is even). The problem here @@ -779,68 +611,99 @@ struct token *ptok; */ ubound = max_arith / (base / 2); - while (is_hex(*cp)) { + while (is_hex(*cp)) + { dig = hex_val(*cp); - if (dig >= base) { - malformed++; /* ignore */ + if (dig >= base) + { + malformed++; /* ignore */ } - else { - if (val < 0 || val > ubound) ovfl++; + else + { + if (val < 0 || val > ubound) + ovfl++; val *= base; - if (val < 0 && val + dig >= 0) ovfl++; + if (val < 0 && val + dig >= 0) + ovfl++; val += dig; } cp++; } - while (*cp) { - if (*cp == 'l' || *cp == 'L') lng_flg++; - else if (*cp == 'u' || *cp == 'U') uns_flg++; - else break; + while (*cp) + { + if (*cp == 'l' || *cp == 'L') + lng_flg++; + else if (*cp == 'u' || *cp == 'U') + uns_flg++; + else + break; cp++; } - if (*cp) { - malformed++; + if (*cp) + { + malformed++; } - if (malformed) { - lexerror("malformed %s integer constant", - (base == 10 ? "decimal" - : (base == 8 ? "octal" - : "hexadecimal"))); - } else { + if (malformed) + { + lexerror( + "malformed %s integer constant", + (base == 10 ? "decimal" : (base == 8 ? "octal" : "hexadecimal"))); + } + else + { if (lng_flg > 1) lexerror("only one long suffix allowed"); if (uns_flg > 1) lexerror("only one unsigned suffix allowed"); } - if (ovfl) { + if (ovfl) + { lexwarning("overflow in constant"); fund = ULONG; - } else if (!lng_flg && (val & full_mask[(int)int_size]) == val) { - if (val >= 0 && val <= max_int) { + } + else if (!lng_flg && (val & full_mask[(int)int_size]) == val) + { + if (val >= 0 && val <= max_int) + { fund = INT; - } else if (int_size == long_size) { + } + else if (int_size == long_size) + { fund = UNSIGNED; - } else if (base == 10 && !uns_flg) + } + else if (base == 10 && !uns_flg) fund = LONG; - else fund = UNSIGNED; - } else if((val & full_mask[(int)long_size]) == val) { - if (val >= 0) fund = LONG; - else fund = ULONG; - } else { /* sizeof(arith) is greater than long_size */ + else + fund = UNSIGNED; + } + else if ((val & full_mask[(int)long_size]) == val) + { + if (val >= 0) + fund = LONG; + else + fund = ULONG; + } + else + { /* sizeof(arith) is greater than long_size */ assert(arith_size > long_size); lexwarning("constant too large for target machine"); /* cut the size to prevent further complaints */ val &= full_mask[(int)long_size]; fund = ULONG; } - if (lng_flg) { + if (lng_flg) + { /* fund can't be INT */ - if (fund == UNSIGNED) fund = ULONG; + if (fund == UNSIGNED) + fund = ULONG; } - if (uns_flg) { - if (fund == INT) fund = UNSIGNED; - else if (fund == LONG) fund = ULONG; + if (uns_flg) + { + if (fund == INT) + fund = UNSIGNED; + else if (fund == LONG) + fund = ULONG; } ptok->tk_fund = fund; ptok->tk_ival = val; diff --git a/lang/cem/cemcom.ansi/LLlex.h b/lang/cem/cemcom.ansi/LLlex.h index 90b003954..678149d9f 100644 --- a/lang/cem/cemcom.ansi/LLlex.h +++ b/lang/cem/cemcom.ansi/LLlex.h @@ -43,12 +43,6 @@ extern struct token dot, ahead, aside; extern int token_nmb; /* number of the ahead token */ extern int tk_nmb_at_last_syn_err; /* token number at last syntax error */ -#ifndef NOPP -extern int ReplaceMacros; /* "LLlex.c" */ -extern int AccDefined; /* "LLlex.c" */ -extern int Unstacked; /* "LLlex.c" */ -extern int UnknownIdIsZero; /* "LLlex.c" */ -#endif /* NOPP */ extern int EoiForNewline; /* "LLlex.c" */ extern int AccFileSpecifier; /* "LLlex.c" */ extern int File_Inserted; /* "LLlex.c" */ diff --git a/lang/cem/cemcom.ansi/SmallPars b/lang/cem/cemcom.ansi/SmallPars index 3e3d00d98..4ef50e48e 100644 --- a/lang/cem/cemcom.ansi/SmallPars +++ b/lang/cem/cemcom.ansi/SmallPars @@ -111,10 +111,6 @@ /*#define INP_READ_IN_ONE 1 /* read input file in one */ -!File: nopp.h -#define NOPP 1 /* if NOT defined, use built-int preprocessor */ - - !File: nobitfield.h /*#define NOBITFIELD 1 /* if NOT defined, implement bitfields */ diff --git a/lang/cem/cemcom.ansi/build.lua b/lang/cem/cemcom.ansi/build.lua index 35ecbe3ef..8d9f0d6c0 100644 --- a/lang/cem/cemcom.ansi/build.lua +++ b/lang/cem/cemcom.ansi/build.lua @@ -111,7 +111,6 @@ cprogram { "./field.c", "./fltcstoper.c", "./idf.c", - "./init.c", "./input.c", "./l_comment.c", "./l_ev_ord.c", @@ -124,7 +123,6 @@ cprogram { "./options.c", "./pragma.c", "./proto.c", - "./replace.c", "./skip.c", "./stab.c", "./stack.c", diff --git a/lang/cem/cemcom.ansi/domacro.c b/lang/cem/cemcom.ansi/domacro.c index b1c4f5df3..d6fc4c501 100644 --- a/lang/cem/cemcom.ansi/domacro.c +++ b/lang/cem/cemcom.ansi/domacro.c @@ -5,811 +5,41 @@ /* $Id$ */ /* PREPROCESSOR: CONTROLLINE INTERPRETER */ -#include -#include -#include -#include "parameters.h" -#include "idf.h" -#include "arith.h" -#include "LLlex.h" -#include "Lpars.h" -#include "input.h" -#include "replace.h" +#include +#include +#include +#include "parameters.h" +#include "idf.h" +#include "arith.h" +#include "LLlex.h" +#include "Lpars.h" +#include "input.h" -#ifndef NOPP -#include -#include "class.h" -#include "macro.h" #ifdef DBSYMTAB -#include -#include -int IncludeLevel = 0; +#include +#include +int IncludeLevel = 0; #endif extern char options[]; -extern char **inctable; /* list of include directories */ -extern char *getwdir(); -char ifstack[IFDEPTH]; /* if-stack: the content of an entry is */ - /* 1 if a corresponding ELSE has been */ - /* encountered. */ -int nestlevel = -1; - -void macro_def(); -void do_define(); - -struct idf * -GetIdentifier(skiponerr) - int skiponerr; /* skip the rest of the line on error */ +struct idf* GetIdentifier(skiponerr) int skiponerr; /* skip the rest of the line on error */ { /* returns a pointer to the descriptor of the identifier that is - read from the input stream. When the input doe not contain - an identifier, the rest of the line is skipped when - skiponerr is on, and a null-pointer is returned. - The substitution of macros is disabled. - */ - int tmp = UnknownIdIsZero; - int tok; - struct token tk; - - UnknownIdIsZero = ReplaceMacros = 0; - tok = GetToken(&tk); - ReplaceMacros = 1; - UnknownIdIsZero = tmp; - if (tok != IDENTIFIER) { - if (skiponerr && tok != EOI) SkipToNewLine(); - return (struct idf *)0; - } - return tk.tk_idf; -} - -/* domacro() is the control line interpreter. The '#' has already - been read by the lexical analyzer by which domacro() is called. - The token appearing directly after the '#' is obtained by calling - the basic lexical analyzing function GetToken() and is interpreted - to perform the action belonging to that token. - An error message is produced when the token is not recognized, - i.e. it is not one of "define" .. "undef" , integer or newline. -*/ -domacro() -{ - struct token tk; /* the token itself */ - int toknum; - - EoiForNewline = 1; - ReplaceMacros = 0; - toknum = GetToken(&tk); - ReplaceMacros = 1; - switch(toknum) { /* select control line action */ - case IDENTIFIER: /* is it a macro keyword? */ - switch (tk.tk_idf->id_resmac) { - case K_DEFINE: /* "define" */ - do_define(); - break; - case K_ELIF: /* "elif" */ - do_elif(); - break; - case K_ELSE: /* "else" */ - do_else(); - break; - case K_ENDIF: /* "endif" */ - do_endif(); - break; - case K_IF: /* "if" */ - do_if(); - break; - case K_IFDEF: /* "ifdef" */ - do_ifdef(1); - break; - case K_IFNDEF: /* "ifndef" */ - do_ifdef(0); - break; - case K_INCLUDE: /* "include" */ - do_include(); - break; - case K_LINE: /* "line" */ - /* set LineNumber and FileName according to - the arguments. - */ - if (GetToken(&tk) != INTEGER) { - lexerror("bad #line syntax"); - SkipToNewLine(); - } - else - do_line((unsigned int)tk.tk_ival); - break; - case K_ERROR: /* "error" */ - do_error(); - break; - case K_PRAGMA: /* "pragma" */ - do_pragma(); - break; - case K_UNDEF: /* "undef" */ - do_undef((struct idf *) 0); - break; - default: - /* invalid word seen after the '#' */ - lexerror("%s: unknown control", tk.tk_idf->id_text); - SkipToNewLine(); - } - break; - case INTEGER: /* # []? */ - do_line((unsigned int)tk.tk_ival); - break; - case EOI: /* only `#' on this line: do nothing, ignore */ - break; - default: /* invalid token following '#' */ - lexerror("illegal # line"); - SkipToNewLine(); - } - EoiForNewline = 0; -} - -#ifdef LINT -int lint_skip_comment; -#endif - -void -skip_block(to_endif) -int to_endif; -{ - /* skip_block() skips the input from - 1) a false #if, #ifdef, #ifndef or #elif until the - corresponding #elif (resulting in true), #else or - #endif is read. - 2) a #else corresponding to a true #if, #ifdef, - #ifndef or #elif until the corresponding #endif is - seen. - */ - register int ch; - register int skiplevel = nestlevel; /* current nesting level */ - struct token tk; - int toknum; - -#ifdef LINT - lint_skip_comment++; -#endif - NoUnstack++; - for (;;) { - ch = GetChar(); /* read first character after newline */ - while (class(ch) == STSKIP) - ch = GetChar(); - if (ch != '#') { - if (ch == EOI) { - NoUnstack--; -#ifdef LINT - lint_skip_comment--; -#endif - return; - } - /* A possible '/' is not pushed back */ - if (ch == '/') { - ch = GetChar(); - if (ch != '*') UnGetChar(); - else { - skipcomment(); - continue; - } - } else UnGetChar(); - SkipToNewLine(); - continue; - } - ReplaceMacros = 0; - toknum = GetToken(&tk); - ReplaceMacros = 1; - if (toknum != IDENTIFIER) { - if (toknum != INTEGER) { - lexerror("illegal # line"); - } - SkipToNewLine(); - continue; - } - /* an IDENTIFIER: look for #if, #ifdef and #ifndef - without interpreting them. - Interpret #else, #elif and #endif if they occur - on the same level. - */ - switch(tk.tk_idf->id_resmac) { - default: - case K_UNKNOWN: - /* invalid word seen after the '#' */ - lexwarning("%s: unknown control", tk.tk_idf->id_text); - /* fallthrough */ - case K_DEFINE: - case K_ERROR: - case K_INCLUDE: - case K_LINE: - case K_PRAGMA: - case K_UNDEF: - case K_FILE: - SkipToNewLine(); - break; - case K_IF: - case K_IFDEF: - case K_IFNDEF: - push_if(); - SkipToNewLine(); - break; - case K_ELIF: - if (ifstack[nestlevel]) - lexerror("#elif after #else"); - if (!to_endif && nestlevel == skiplevel) { - nestlevel--; - push_if(); - if (ifexpr()) { - NoUnstack--; -#ifdef LINT - lint_skip_comment--; -#endif - return; - } - } - else SkipToNewLine(); /* otherwise done in ifexpr() */ - break; - case K_ELSE: - if (ifstack[nestlevel]) - lexerror("#else after #else"); - ++(ifstack[nestlevel]); - if (!to_endif && nestlevel == skiplevel) { - if (SkipToNewLine()) { - if (!options['o']) - lexstrict("garbage following #else"); - } - NoUnstack--; -#ifdef LINT - lint_skip_comment--; -#endif - return; - } - else SkipToNewLine(); - break; - case K_ENDIF: - assert(nestlevel > nestlow); - if (nestlevel == skiplevel) { - if (SkipToNewLine()) { - if (!options['o']) - lexstrict("garbage following #endif"); - } - nestlevel--; - NoUnstack--; -#ifdef LINT - lint_skip_comment--; -#endif - return; - } - else SkipToNewLine(); - nestlevel--; - break; - } - } -} - - -ifexpr() -{ - /* ifexpr() returns whether the restricted constant - expression following #if or #elif evaluates to true. This - is done by calling the LLgen generated subparser for - constant expressions. The result of this expression will - be given in the extern long variable "ifval". - */ - extern arith ifval; - int errors = err_occurred; - - ifval = (arith)0; - AccDefined = 1; - UnknownIdIsZero = 1; - PushLex(); /* NEW parser */ - If_expr(); /* invoke constant expression parser */ - PopLex(); /* OLD parser */ - AccDefined = 0; - UnknownIdIsZero = 0; - return (errors == err_occurred) && (ifval != (arith)0); -} - -do_include() -{ - /* do_include() performs the inclusion of a file. - */ - char *filenm; - char *result; - int tok; - struct token tk; - - AccFileSpecifier = 1; - if (((tok = GetToken(&tk)) == FILESPECIFIER) || tok == STRING) - filenm = tk.tk_bts; - else { - lexerror("bad include syntax"); - filenm = (char *)0; - } - AccFileSpecifier = 0; - if (SkipToNewLine()) { - lexerror("bad include syntax"); - } - inctable[0] = WorkingDir; - if (filenm) { - if (!InsertFile(filenm, &inctable[tok==FILESPECIFIER],&result)){ - lexerror("cannot open include file \"%s\"", filenm); - add_dependency(filenm); - free(filenm); - } - else { - add_dependency(result); - WorkingDir = getwdir(result); - File_Inserted = 1; - FileName = result; - LineNumber = 0; - nestlow = nestlevel; -#ifdef DBSYMTAB - IncludeLevel++; - if (options['g']) { - C_ms_stb_cst(FileName, N_BINCL, 0, (arith) 0); - } -#endif /* DBSYMTAB */ - if (result != filenm) free(filenm); - } - } -} - -void -do_define() -{ - /* do_define() interprets a #define control line. - */ - struct idf *id; /* the #defined identifier's descriptor */ - int nformals = -1; /* keep track of the number of formals */ - char *formals[NPARAMS]; /* pointers to the names of the formals */ - char parbuf[PARBUFSIZE]; /* names of formals */ - char *repl_text; /* start of the replacement text */ - int length; /* length of the replacement text */ - register ch; - char *get_text(); - - /* read the #defined macro's name */ - if (!(id = GetIdentifier(1))) { - lexerror("illegal #define line"); - return; - } - /* there is a formal parameter list if the identifier is - followed immediately by a '('. - */ - ch = GetChar(); - if (ch == '(') { - if ((nformals = getparams(formals, parbuf)) == -1) { - SkipToNewLine(); - return; /* an error occurred */ - } - ch = GetChar(); - } - /* read the replacement text if there is any */ - ch = skipspaces(ch,0); /* find first character of the text */ - assert(ch != EOI); - /* UnGetChar() is not right when replacement starts with a '/' */ - ChPushBack(ch); - repl_text = get_text((nformals > 0) ? formals : 0, &length); - macro_def(id, repl_text, nformals, length, NOFLAG); - LineNumber++; -} - -push_if() -{ - if (nestlevel >= IFDEPTH) - fatal("too many nested #if/#ifdef/#ifndef"); - else - ifstack[++nestlevel] = 0; -} - -do_elif() -{ - if (nestlevel <= nestlow) { - lexerror("#elif without corresponding #if"); - SkipToNewLine(); - } - else { /* restart at this level as if a #if is detected. */ - if (ifstack[nestlevel]) { - lexerror("#elif after #else"); - SkipToNewLine(); - } - nestlevel--; - push_if(); - skip_block(1); - } -} - -do_else() -{ - if (SkipToNewLine()) - if (!options['o']) - lexstrict("garbage following #else"); - if (nestlevel <= nestlow) - lexerror("#else without corresponding #if"); - else { /* mark this level as else-d */ - if (ifstack[nestlevel]) { - lexerror("#else after #else"); - } - ++(ifstack[nestlevel]); - skip_block(1); - } -} - -do_endif() -{ - if (SkipToNewLine()) { - if (!options['o']) - lexstrict("garbage following #endif"); - } - if (nestlevel <= nestlow) { - lexerror("#endif without corresponding #if"); - } - else nestlevel--; -} - -do_if() -{ - push_if(); - if (!ifexpr()) /* a false #if/#elif expression */ - skip_block(0); -} - -do_ifdef(how) -{ - register struct idf *id; - - /* how == 1 : ifdef; how == 0 : ifndef - */ - push_if(); - if (!(id = GetIdentifier(1))) - lexerror("illegal #ifdef construction"); - else if (SkipToNewLine()) - if (!options['o']) - lexstrict("garbage following #%s ", - how ? "ifdef" : "ifndef"); - - /* The next test is a shorthand for: - (how && !id->id_macro) || (!how && id->id_macro) - */ - if (how ^ (id && id->id_macro != 0)) - skip_block(0); -} - -/* argidf != NULL when the undef came from a -U option */ -do_undef(argidf) - struct idf *argidf; -{ - register struct idf *id = argidf; - - /* Forget a macro definition. */ - if (id || (id = GetIdentifier(1))) { - if (id->id_macro) { /* forget the macro */ - if (id->id_macro->mc_flag & NOUNDEF) { - lexerror("it is not allowed to undef %s", id->id_text); - } else { - free(id->id_macro->mc_text); - free_macro(id->id_macro); - id->id_macro = (struct macro *) 0; - } - } /* else: don't complain */ - if (!argidf) { - if (SkipToNewLine()) - if (!options['o']) - lexstrict("garbage following #undef"); - } - } - else - lexerror("illegal #undef construction"); -} - -do_error() -{ - int len; - char *get_text(); - char *bp = get_text((char **) 0, &len); - - lexerror("user error: %s", bp); - free(bp); - LineNumber++; -} - -int -getparams(buf, parbuf) - char *buf[]; - char parbuf[]; -{ - /* getparams() reads the formal parameter list of a macro - definition. - The number of parameters is returned. - As a formal parameter list is expected when calling this - routine, -1 is returned if an error is detected, for - example: - #define one(1), where 1 is not an identifier. - Note that the '(' has already been eaten. - The names of the formal parameters are stored into parbuf. - */ - register char **pbuf = &buf[0]; - register int c; - register char *ptr = &parbuf[0]; - register char **pbuf2; - - c = GetChar(); - c = skipspaces(c,0); - if (c == ')') { /* no parameters: #define name() */ - *pbuf = (char *) 0; - return 0; - } - for (;;) { /* eat the formal parameter list */ - if (class(c) != STIDF && class(c) != STELL) { - lexerror("#define: bad formal parameter"); - return -1; - } - *pbuf = ptr; /* name of the formal */ - *ptr++ = c; - if (ptr >= &parbuf[PARBUFSIZE]) - fatal("formal parameter buffer overflow"); - do { /* eat the identifier name */ - c = GetChar(); - *ptr++ = c; - if (ptr >= &parbuf[PARBUFSIZE]) - 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)) { - lexerror("formal parameter \"%s\" already used", - *pbuf); - } - } - - pbuf++; - c = skipspaces(c,0); - if (c == ')') { /* end of the formal parameter list */ - *pbuf = (char *) 0; - return pbuf - buf; - } - if (c != ',') { - lexerror("#define: bad formal parameter list"); - return -1; - } - c = GetChar(); - c = skipspaces(c,0); - } - /*NOTREACHED*/ -} - -void -macro_def(id, text, nformals, length, flags) - register struct idf *id; - char *text; -{ - register struct macro *newdef = id->id_macro; - - /* 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. - An error is given if there was already a definition - */ - if (newdef) { /* is there a redefinition? */ - if (newdef->mc_flag & NOUNDEF) { - lexerror("it is not allowed to redefine %s", id->id_text); - } else if (!macroeq(newdef->mc_text, text)) - lexerror("illegal redefine of \"%s\"", id->id_text); - free(text); - return; - } - id->id_macro = newdef = new_macro(); - newdef->mc_text = text; /* replacement text */ - newdef->mc_nps = nformals; /* nr of formals */ - newdef->mc_length = length; /* length of repl. text */ - newdef->mc_flag = flags; /* special flags */ -} - -int -find_name(nm, index) - char *nm, *index[]; -{ - /* find_name() returns the index of "nm" in the namelist - "index" if it can be found there. 0 is returned if it is - not there. - */ - register char **ip = &index[0]; - - while (*ip) - if (strcmp(nm, *ip++) == 0) - return ip - &index[0]; - /* arrived here, nm is not in the name list. */ - return 0; -} - -#define BLANK(ch) ((ch == ' ') || (ch == '\t')) - -char * -get_text(formals, length) - char *formals[]; - int *length; -{ - /* get_text() copies the replacement text of a macro - definition with zero, one or more parameters, thereby - substituting each formal parameter by a special character - (non-ascii: 0200 & (order-number in the formal parameter - list)) in order to substitute this character later by the - actual parameter. The replacement text is copied into - itself because the copied text will contain fewer or the - same amount of characters. The length of the replacement - text is returned. - - Implementation: - finite automaton : we are interested in - 1- white space, sequences must be mapped onto 1 single - blank. - 2- identifiers, since they might be replaced by some - actual parameter. - 3- strings and character constants, since replacing - variables within them is illegal, and white-space is - significant. - 4- comment, same as for 1 - Other tokens will not be seen as such. - */ - register int c; - struct repl repls; - register struct repl *repl = &repls; - int blank = 0; - - c = GetChar(); - - repl->r_ptr = repl->r_text = Malloc(repl->r_size = ITEXTSIZE); - *repl->r_ptr = '\0'; - while ((c != EOI) && (class(c) != STNL)) { - if (BLANK(c)) { - blank++; - c = GetChar(); - continue; - } - - if (c == '\'' || c == '"') { - register int delim = c; - - if (blank) { - blank = 0; - add2repl(repl, ' '); - } - do { - add2repl(repl, c); - if (c == '\\') add2repl(repl, GetChar()); - c = GetChar(); - } while (c != delim && c != EOI && class(c) != STNL); - if (c == EOI || class(c) == STNL) { - lexstrict("unclosed opening %c", delim); - break; - } - add2repl(repl, c); - c = GetChar(); - } else if (c == '/') { - c = GetChar(); - if (c == '*') { - skipcomment(); - blank++; - c = GetChar(); - continue; - } - if (blank) { - blank = 0; - add2repl(repl, ' '); - } - add2repl(repl, '/'); - } else if (formals - && (class(c) == STIDF || class(c) == STELL)) { - char id_buf[IDFSIZE + 1]; - register char *idp = id_buf; - int n; - - /* read identifier: it may be a formal parameter */ - *idp++ = c; - do { - c = GetChar(); - if (idp <= &id_buf[IDFSIZE]) - *idp++ = c; - } while (in_idf(c)); - *--idp = '\0'; - - if (blank) { - blank = 0; - add2repl(repl, ' '); - } - /* construct the formal parameter mark or identifier */ - if (n = find_name(id_buf, formals)) - add2repl(repl, FORMALP | (char) n); - else { - idp = id_buf; - while (*idp) add2repl(repl, *idp++); - } - } else if (class(c) == STNUM) { - if (blank) { - blank = 0; - add2repl(repl, ' '); - } - add2repl(repl, c); - if (c == '.') { - c = GetChar(); - if (class(c) != STNUM) { - continue; - } - add2repl(repl, c); - } - c = GetChar(); - while(in_idf(c) || c == '.') { - add2repl(repl, c); - if((c = GetChar()) == 'e' || c == 'E') { - add2repl(repl, c); - c = GetChar(); - if (c == '+' || c == '-') { - add2repl(repl, c); - c = GetChar(); - } - } - } - } else { - if (blank) { - blank = 0; - add2repl(repl, ' '); - } - add2repl(repl, c); - c = GetChar(); - } - } - *length = repl->r_ptr - repl->r_text; - return Realloc(repl->r_text, (unsigned)(repl->r_ptr - repl->r_text +1)); -} - -/* macroeq() decides whether two macro replacement texts are - identical. This version compares the texts, which occur - as strings, without taking care of the leading and trailing - blanks (spaces and tabs). -*/ -macroeq(s, t) - register char *s, *t; -{ - - /* skip leading spaces */ - while (BLANK(*s)) s++; - while (BLANK(*t)) t++; - /* first non-blank encountered in both strings */ - /* The actual comparison loop: */ - while (*s && *s == *t) - s++, t++; - /* two cases are possible when arrived here: */ - if (*s == '\0') { /* *s == '\0' */ - while (BLANK(*t)) t++; - return *t == '\0'; - } - else { /* *s != *t */ - while (BLANK(*s)) s++; - while (BLANK(*t)) t++; - return (*s == '\0') && (*t == '\0'); - } -} -#else /* NOPP */ - -struct idf * -GetIdentifier(skiponerr) - int skiponerr; /* skip the rest of the line on error */ -{ - /* returns a pointer to the descriptor of the identifier that is - read from the input stream. When the input does not contain - an identifier, the rest of the line is skipped when - skiponerr is on, and a null-pointer is returned. - The substitution of macros is disabled. + read from the input stream. When the input does not contain + an identifier, the rest of the line is skipped when + skiponerr is on, and a null-pointer is returned. + The substitution of macros is disabled. */ int tok; struct token tk; tok = GetToken(&tk); - if (tok != IDENTIFIER) { - if (skiponerr && tok != EOI) SkipToNewLine(); - return (struct idf *)0; + if (tok != IDENTIFIER) + { + if (skiponerr && tok != EOI) + SkipToNewLine(); + return (struct idf*)0; } return tk.tk_idf; } @@ -820,14 +50,18 @@ domacro() struct token tk; EoiForNewline = 1; - if ((tok = GetToken(&tk)) == IDENTIFIER) { - if (! strcmp(tk.tk_idf->id_text, "pragma")) { + if ((tok = GetToken(&tk)) == IDENTIFIER) + { + if (!strcmp(tk.tk_idf->id_text, "pragma")) + { do_pragma(); EoiForNewline = 0; return; } - } else if (tok == INTEGER) { - do_line((unsigned int) tk.tk_ival); + } + else if (tok == INTEGER) + { + do_line((unsigned int)tk.tk_ival); EoiForNewline = 0; return; } @@ -835,24 +69,24 @@ domacro() EoiForNewline = 0; SkipToNewLine(); } -#endif /* NOPP */ - -do_line(l) - unsigned int l; +do_line(l) unsigned int l; { struct token tk; int t = GetToken(&tk); - if (t != EOI) SkipToNewLine(); - LineNumber = l; /* the number of the next input line */ - if (t == STRING) { /* is there a filespecifier? */ - /* - * Do not attempt to free the old string, since it might - * be used in a def structure. - */ + if (t != EOI) + SkipToNewLine(); + LineNumber = l; /* the number of the next input line */ + if (t == STRING) + { /* is there a filespecifier? */ +/* + * Do not attempt to free the old string, since it might + * be used in a def structure. + */ #ifdef DBSYMTAB - if (options['g'] && strcmp(FileName, tk.tk_bts) != 0) { + if (options['g'] && strcmp(FileName, tk.tk_bts) != 0) + { C_ms_std(tk.tk_bts, N_SOL, 0); } #endif /* DBSYMTAB */ diff --git a/lang/cem/cemcom.ansi/dumpidf.c b/lang/cem/cemcom.ansi/dumpidf.c index e5d6d0941..7782d0bb4 100644 --- a/lang/cem/cemcom.ansi/dumpidf.c +++ b/lang/cem/cemcom.ansi/dumpidf.c @@ -106,15 +106,6 @@ dumpidf(idf, opt) if (!idf) return; -#ifndef NOPP - if ((opt&1) && idf->id_macro) { - if (!started++) { - newline(); - print("%s:", idf->id_text); - } - print(" macro"); - } -#endif /* NOPP */ if ((opt&2) && idf->id_reserved) { if (!started++) { newline(); diff --git a/lang/cem/cemcom.ansi/idf.str b/lang/cem/cemcom.ansi/idf.str index fab968321..06caa7f3e 100644 --- a/lang/cem/cemcom.ansi/idf.str +++ b/lang/cem/cemcom.ansi/idf.str @@ -8,10 +8,6 @@ #include "parameters.h" struct id_u { -#ifndef NOPP - struct macro *idd_macro; - int idd_resmac; /* if nonzero: keyword of macroproc. */ -#endif /* NOPP */ int idd_reserved; /* non-zero for reserved words */ char *idd_file; /* file containing the occurrence */ unsigned int idd_line; /* line number of the occurrence */ @@ -36,14 +32,5 @@ struct id_u { #include -#ifndef NOPP -struct dependency { - struct dependency *next; - struct idf *dep_idf; -}; - -/* ALLOCDEF "dependency" 10 */ -#endif /* NOPP */ - extern int level; extern struct idf *gen_idf(); diff --git a/lang/cem/cemcom.ansi/init.c b/lang/cem/cemcom.ansi/init.c deleted file mode 100644 index 3b3403aa4..000000000 --- a/lang/cem/cemcom.ansi/init.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. - * See the copyright notice in the ACK home directory, in the file "Copyright". - */ -/* $Id$ */ -/* PREPROCESSOR: INITIALIZATION ROUTINES */ - -#include -#include -#include -#include "parameters.h" - -#ifndef NOPP -#include -#include -#include -#include "idf.h" -#include "class.h" -#include "macro.h" - -extern char *sprint(); - -struct mkey { - char *mk_reserved; - int mk_key; -} mkey[] = { - {"define", K_DEFINE}, - {"elif", K_ELIF}, - {"else", K_ELSE}, - {"endif", K_ENDIF}, - {"error", K_ERROR}, - {"if", K_IF}, - {"ifdef", K_IFDEF}, - {"ifndef", K_IFNDEF}, - {"include", K_INCLUDE}, - {"line", K_LINE}, - {"pragma", K_PRAGMA}, - {"undef", K_UNDEF}, - {0, K_UNKNOWN} -}; - -init_pp() -{ - static char *months[12] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }; - time_t clock; - static char dbuf[30]; - static char tbuf[30]; - struct tm *tp; - - /* Initialise the control line keywords (if, include, define, etc) - Although the lexical analyzer treats them as identifiers, the - control line handler can recognize them as keywords by the - id_resmac field of the identifier. - */ - { - register struct mkey *mk = &mkey[0]; - - while (mk->mk_reserved) { - register struct idf *idf = str2idf(mk->mk_reserved, 0); - - if (idf->id_resmac) - fatal("maximum identifier length insufficient"); - idf->id_resmac = mk->mk_key; - mk++; - } - } - - /* Initialize __LINE__, __FILE__, __DATE__, __TIME__, - and __STDC__ macro definitions. - */ - clock = time(NULL); - tp = localtime(&clock); - - /* __DATE__ */ - sprint(dbuf, "\"%s %02d %d\"", months[tp->tm_mon], - tp->tm_mday, tp->tm_year+1900); - if (tp->tm_mday < 10) dbuf[5] = ' '; /* hack */ - macro_def(str2idf("__DATE__", 0), dbuf, -1, strlen(dbuf), NOUNDEF); - - /* __TIME__ */ - sprint(tbuf, "\"%02d:%02d:%02d\"", tp->tm_hour, tp->tm_min, tp->tm_sec); - macro_def(str2idf("__TIME__", 0), tbuf, -1, strlen(tbuf), NOUNDEF); - - /* __LINE__ */ - macro_def(str2idf("__LINE__", 0), "0", -1, 1, NOUNDEF | FUNC); - - /* __FILE__ */ - macro_def(str2idf("__FILE__", 0), "", -1, 1, NOUNDEF | FUNC); - - /* __STDC__ */ - macro_def(str2idf("__STDC__", 0), "1", -1, 1, NOUNDEF); - - /* defined(??) */ - macro_def(str2idf("defined", 0), "", 1, 1, NOUNDEF | FUNC); -} -#endif /* NOPP */ diff --git a/lang/cem/cemcom.ansi/input.c b/lang/cem/cemcom.ansi/input.c index 2b652b64f..dea9a4892 100644 --- a/lang/cem/cemcom.ansi/input.c +++ b/lang/cem/cemcom.ansi/input.c @@ -18,50 +18,10 @@ struct file_info finfo; #include #include -#ifndef NOPP -#ifdef DBSYMTAB -#include -#include -extern int IncludeLevel; -extern char options[]; -#endif - -char * -getwdir(fn) - register char *fn; -{ - register char *p; - char *strrchr(); - - p = strrchr(fn, '/'); - while (p && *(p + 1) == '\0') { /* remove trailing /'s */ - *p = '\0'; - p = strrchr(fn, '/'); - } - - if (fn[0] == '\0' || (fn[0] == '/' && p == &fn[0])) /* absolute path */ - return ""; - if (p) { - *p = '\0'; - fn = Salloc(fn,(unsigned) (p - &fn[0] + 1)); - *p = '/'; - return fn; - } - return ""; -} - -int InputLevel; -extern int nestlevel; -#endif /* NOPP */ - int NoUnstack; AtEoIT() { -#ifndef NOPP - InputLevel--; - unstackrepl(); -#endif /* NOPP */ return 0; } @@ -69,22 +29,6 @@ extern char *source; AtEoIF() { -#ifndef NOPP - if (nestlevel != nestlow) lexwarning("missing #endif"); - else -#endif /* NOPP */ if (NoUnstack) lexerror("unexpected EOF"); -#ifndef NOPP - nestlevel = nestlow; -#ifdef DBSYMTAB - if (options['g'] && IncludeLevel > 0) { - C_ms_stb_cst(FileName, N_EINCL, 0, (arith) 0); - } - IncludeLevel--; -#endif - /* We don't free WorkingDir and FileName here because the rest of the - * compiler may be holding pointers to them for displaying error messages. - */ -#endif /* NOPP */ return 0; } diff --git a/lang/cem/cemcom.ansi/macro.str b/lang/cem/cemcom.ansi/macro.str index f229cac9b..6f96c3d8f 100644 --- a/lang/cem/cemcom.ansi/macro.str +++ b/lang/cem/cemcom.ansi/macro.str @@ -6,47 +6,3 @@ /* PREPROCESSOR: DEFINITION OF MACRO DESCRIPTOR */ #include "parameters.h" - -#ifndef NOPP -/* The flags of the mc_flag field of the macro structure. Note that - these flags can be set simultaneously. -*/ -#define NOFLAG 0 /* no special flags */ -#define FUNC 0x1 /* function attached */ -#define NOUNDEF 0x2 /* reserved macro */ -#define NOREPLACE 0x4 /* prevent recursion */ - -#define FORMALP 0200 /* mask for creating macro formal parameter */ - -/* The macro descriptor is very simple, except the fact that the - mc_text, which points to the replacement text, contains the - non-ascii characters \201, \202, etc, indicating the position of a - formal parameter in this text. -*/ -struct macro { - struct macro *next; - char * mc_text; /* the replacement text */ - int mc_nps; /* number of formal parameters */ - int mc_length; /* length of replacement text */ - char mc_flag; /* marking this macro */ -}; - -/* ALLOCDEF "macro" 20 */ - -/* `token' numbers of keywords of command-line processor -*/ -#define K_UNKNOWN 0 -#define K_DEFINE 1 -#define K_ELIF 2 -#define K_ELSE 3 -#define K_ENDIF 4 -#define K_ERROR 5 -#define K_IF 6 -#define K_IFDEF 7 -#define K_IFNDEF 8 -#define K_INCLUDE 9 -#define K_LINE 10 -#define K_PRAGMA 11 -#define K_UNDEF 12 -#define K_FILE 100 /* for dependency generator */ -#endif /* NOPP */ diff --git a/lang/cem/cemcom.ansi/main.c b/lang/cem/cemcom.ansi/main.c index f521453ba..d8e951af3 100644 --- a/lang/cem/cemcom.ansi/main.c +++ b/lang/cem/cemcom.ansi/main.c @@ -29,19 +29,6 @@ extern struct tokenname tkidf[]; extern char *symbol2str(); extern char options[128]; -#ifndef NOPP -int inc_pos = 1; /* place where next -I goes */ -int inc_total = 0; -int inc_max; -char **inctable; - -extern int do_dependencies; -extern char *dep_file; -static File *dep_fd = STDOUT; - -extern char *getwdir(); -#endif /* NOPP */ - struct sp_id special_ids[] = { {"__setjmp", SP_SETJMP}, /* non-local goto's are registered */ {0, 0} @@ -74,10 +61,6 @@ int union_align = AL_UNION; #endif /* NOCROSS */ -#ifndef NOPP -arith ifval; /* ifval will contain the result of the #if expression */ -#endif /* NOPP */ - char *prog_name; main(argc, argv) @@ -86,17 +69,6 @@ main(argc, argv) /* parse and interpret the command line options */ prog_name = argv[0]; -#ifndef NOPP - inctable = (char **) Malloc(10 * sizeof(char *)); - inctable[0] = ""; - inctable[1] = 0; - inctable[2] = 0; - inc_total = 3; - inc_max = 10; - - init_pp(); /* initialise the preprocessor macros */ -#endif /* NOPP */ - /* Note: source file "-" indicates that the source is supplied as standard input. This is only allowed if INP_READ_IN_ONE is not defined! @@ -122,83 +94,10 @@ main(argc, argv) if (options['m']) Info(); #endif /* DEBUG */ -#ifndef NOPP - if (do_dependencies) { - extern char *source; - - list_dependencies(source); - } -#endif sys_stop(err_occurred ? S_EXIT : S_END); /*NOTREACHED*/ } -#ifndef NOPP - -struct dependency *file_head; -extern char *strrchr(); - -list_dependencies(source) -char *source; -{ - register struct dependency *p = file_head; - - if (source) { - register char *s = strrchr(source, '.'); - - if (s && *(s+1)) { - s++; - *s++ = 'o'; - *s = '\0'; - /* the source may be in another directory than the - * object generated, so don't include the pathname - * leading to it. - */ - if (s = strrchr(source, '/')) { - source = s + 1; - } - } - else source = 0; - } - if (dep_file && !sys_open(dep_file, OP_WRITE, &dep_fd)) { - fatal("could not open %s", dep_file); - } - while (p) { - dependency(p->dep_idf->id_text, source); - p = p->next; - } -} - -add_dependency(s) -char *s; -{ - register struct idf *p = str2idf(s, 1); - - if (! p->id_resmac) { - register struct dependency *q = new_dependency(); - - p->id_resmac = K_FILE; - q->dep_idf = p; - q->next = file_head; - file_head = q; - } -} - -void -dependency(s, source) -char *s, *source; -{ - if (options['i'] && !strncmp(s, "/usr/include/", 13)) { - return; - } - if (options['m'] && source) { - fprint(dep_fd, "%s: %s\n", source, s); - } - else fprint(dep_fd, "%s\n", s); -} - -#endif /* NOPP */ - char *source = 0; #ifdef GEN_NM_LIST @@ -213,19 +112,10 @@ compile(argc, argv) register char *destination = 0; #endif /* LINT */ -#ifdef DEBUG -#ifndef NOPP - int pp_only = options['E'] || options['P'] || options['C']; -#endif /* NOPP */ -#endif - switch (argc) { case 1: #ifndef LINT #ifdef DEBUG -#ifndef NOPP - if (!pp_only) -#endif /* NOPP */ #endif fatal("%s: destination file not specified", prog_name); #endif /* LINT */ @@ -277,20 +167,7 @@ compile(argc, argv) : 0); #endif /* LINT */ -#ifndef NOPP - WorkingDir = getwdir(source); - PushLex(); /* initialize lex machine */ -#else /* NOPP */ GetToken(&ahead); -#endif /* NOPP */ - -#ifdef DEBUG -#ifndef NOPP - if (pp_only) /* run the preprocessor as if it is stand-alone */ - preprocess(); - else -#endif /* NOPP */ -#endif /* DEBUG */ { /* compile the source text */ C_program(); @@ -311,9 +188,6 @@ compile(argc, argv) dumpidftab("end of main", options['f'] ? 7 : 0); #endif /* DEBUG */ } -#ifndef NOPP - PopLex(); -#endif /* NOPP */ } init() @@ -395,76 +269,6 @@ init_specials(si) } #ifdef DEBUG -#ifndef NOPP -preprocess() -{ - /* preprocess() is the "stand-alone" preprocessor which - consecutively calls the lexical analyzer LLlex() to get - the tokens and prints them in a suitable way. - */ - static unsigned int lastlineno = 0; - static char *lastfilenm = ""; - - while (LLlex() != EOI) { - if (lastlineno != dot.tk_line) { - if (strcmp(lastfilenm, dot.tk_file) == 0) { - if (dot.tk_line - lastlineno <= 1) { - lastlineno++; - print("\n"); - } - else { - lastlineno = dot.tk_line; - if (!options['P']) - print("\n#line %ld \"%s\"\n", - lastlineno, - lastfilenm - ); - } - } - else { - lastfilenm = dot.tk_file; - lastlineno = dot.tk_line; - if (!options['P']) - print("\n#line %ld \"%s\"\n", - lastlineno, lastfilenm); - } - } - else - if (strcmp(lastfilenm, dot.tk_file) != 0) { - lastfilenm = dot.tk_file; - if (!options['P']) - print("\n#line %ld \"%s\"\n", - lastlineno, lastfilenm); - } - switch (DOT) { - case IDENTIFIER: - case TYPE_IDENTIFIER: - print("%s ", dot.tk_idf->id_text); - break; - case STRING: - { - char sbuf[1024]; /* a transient buffer */ - - print("\"%s\" ", bts2str(dot.tk_bts, dot.tk_len - - 1, sbuf)); - break; - } - case INTEGER: - print("%ld ", dot.tk_ival); - break; - case FLOATING: - print("%s ", dot.tk_fval); - break; - case EOI: - case EOF: - return; - default: /* very expensive... */ - print("%s ", symbol2str(DOT)); - } - } -} -#endif /* NOPP */ - Info() { extern int cnt_string_cst, cnt_formal, diff --git a/lang/cem/cemcom.ansi/options.c b/lang/cem/cemcom.ansi/options.c index a23ff3405..c0b411934 100644 --- a/lang/cem/cemcom.ansi/options.c +++ b/lang/cem/cemcom.ansi/options.c @@ -16,16 +16,6 @@ #include "sizes.h" #include "align.h" -#ifndef NOPP -extern char **inctable; -extern int inc_pos; -extern int inc_max; -extern int inc_total; -int do_dependencies = 0; -char *dep_file = 0; - -#endif /* NOPP */ - char options[128]; /* one for every char */ #ifdef LINT char loptions[128]; /* one for every char */ @@ -60,18 +50,6 @@ next_option: /* to allow combined one-char options */ goto next_option; #ifndef LINT -#ifndef NOPP - case 'A' : /* Amake dependency generation */ - do_dependencies = 1; - if (*text) { - dep_file = text; - } - break; - case 'i': - case 'm': - options[opt] = 1; - break; -#endif /* NOPP */ #endif /* LINT */ #ifdef DBSYMTAB case 'g': /* symbol table for debugger */ @@ -110,64 +88,6 @@ next_option: /* to allow combined one-char options */ goto next_option; #endif /* LINT */ -#ifndef NOPP - case 'D' : { /* -Dname : predefine name */ - register char *cp = text, *name, *mactext; - unsigned maclen; - - if (class(*cp) != STIDF && class(*cp) != STELL) { - error("identifier missing in -D%s", text); - break; - } - - name = cp; - - while (*cp && in_idf(*cp)) { - ++cp; - } - - if (!*cp) { /* -Dname */ - maclen = 1; - mactext = Salloc("1", 2); - } - else - if (*cp == '=') { /* -Dname=text */ - *cp++ = '\0'; /* end of name */ - maclen = (unsigned) strlen(cp); - mactext = Salloc(cp, maclen + 1); - } - else { /* -Dname?? */ - error("malformed option -D%s", text); - break; - } - - macro_def(str2idf(name, 0), mactext, -1, (int)maclen, NOFLAG); - break; - } - - case 'I' : /* -Ipath : insert "path" into include list */ - if (*text) { - int i; - register char *new = text; - - if (inc_total >= inc_max) { - inctable = (char **) - Realloc((char *)inctable, - (unsigned)((inc_max+=10)*sizeof(char *))); - } - - for (i = inc_pos++; i < inc_total ; i++) { - char *tmp = inctable[i]; - - inctable[i] = new; - new = tmp; - } - inc_total++; - } - else inctable[inc_pos] = 0; - break; -#endif /* NOPP */ - case 'M': /* maximum identifier length */ idfsize = txt2int(&text); if (*text || idfsize <= 0) @@ -197,12 +117,6 @@ next_option: /* to allow combined one-char options */ break; } -#ifndef NOPP - case 'U' : /* -Uname : undefine predefined */ - if (*text) do_undef(str2idf(text, 0)); - break; -#endif /* NOPP */ - #ifndef LINT #ifndef NOCROSS case 'V' : /* set object sizes and alignment requirements */ diff --git a/lang/cem/cemcom.ansi/program.g b/lang/cem/cemcom.ansi/program.g index 861c97b2e..631603cff 100644 --- a/lang/cem/cemcom.ansi/program.g +++ b/lang/cem/cemcom.ansi/program.g @@ -61,10 +61,6 @@ #include "l_lint.h" #endif /* LINT */ -#ifndef NOPP -extern arith ifval; -#endif /* NOPP */ - extern error(); } @@ -75,14 +71,6 @@ control_if_expression : constant_expression(&exprX) { -#ifndef NOPP - register struct expr *expr = exprX; - if (expr->ex_flags & EX_SIZEOF) - expr_error(expr, - "sizeof not allowed in preprocessor"); - ifval = expr->VL_VALUE; - free_expression(expr); -#endif /* NOPP */ } ; diff --git a/lang/cem/cemcom.ansi/replace.c b/lang/cem/cemcom.ansi/replace.c deleted file mode 100644 index a1c53f32b..000000000 --- a/lang/cem/cemcom.ansi/replace.c +++ /dev/null @@ -1,808 +0,0 @@ -/* - * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. - * See the copyright notice in the ACK home directory, in the file "Copyright". - */ -/* $Id$ */ -/* M A C R O R E P L A C E M E N T */ - -#include -#include -#include -#include "parameters.h" - -#ifndef NOPP - -#include -#include -#include "idf.h" -#include "input.h" -#include "macro.h" -#include "arith.h" -#include "LLlex.h" -#include "class.h" -#include "replace.h" - -extern struct idf *GetIdentifier(); -extern int InputLevel; -struct repl *ReplaceList; /* list of currently active macros */ - -void macro2buffer(); -void getactuals(); -void expand_defined(); - -int -replace(idf) - register struct idf *idf; -{ - /* replace is called by the lexical analyzer to perform - macro replacement. The routine actualy functions as a - higher interface to the real thing: expand_macro(). - */ - struct repl *repl; - - if (!(idf->id_macro)) return 0; - if (idf->id_macro->mc_flag & NOREPLACE) - return 0; - repl = new_repl(); - repl->r_ptr = repl->r_text = Malloc(repl->r_size = LAPBUF); - repl->r_args = new_args(); - repl->r_idf = idf; - if (!expand_macro(repl, idf)) - return 0; - InputLevel++; - InsertText(repl->r_text, (int)(repl->r_ptr - repl->r_text)); - idf->id_macro->mc_flag |= NOREPLACE; - repl->r_level = InputLevel; - repl->next = ReplaceList; - ReplaceList = repl; - return 1; -} - -unstackrepl() -{ - Unstacked++; -} - -freeargs(args) - struct args *args; -{ - register int i; - - /* We must don't know how many parameters were specified, so be - * prepared to free all NPARAMS parameters. - * When an expvec is !0, the rawvec will also be !0. - * When an expvec is 0, all remaining vectors will also be 0. - */ - for (i = 0; i < NPARAMS; i++) { - if (args->a_expvec[i]) { - free(args->a_expvec[i]); - free(args->a_rawvec[i]); - } else break; - } - free_args(args); -} - -EnableMacros() -{ - register struct repl *r = ReplaceList, *prev = 0; - - assert(Unstacked > 0); - while(r) { - struct repl *nxt = r->next; - - if (r->r_level > InputLevel) { - r->r_idf->id_macro->mc_flag &= ~NOREPLACE; - if (!prev) ReplaceList = nxt; - else prev->next = nxt; - free(r->r_text); - freeargs(r->r_args); - free_repl(r); - } - else prev = r; - r = nxt; - } - Unstacked = 0; -} - -expand_macro(repl, idf) - register struct repl *repl; - register struct idf *idf; -{ - /* expand_macro() does the actual macro replacement. - "idf" is a description of the identifier which - caused the replacement. - If the identifier represents a function-like macro - call, the number of actual parameters is checked - against the number of formal parameters. Note that - in ANSI C the parameters are expanded first; - this is done by calling getactuals(). - When the possible parameters are expanded, the replace- - ment list associated with "idf" is expanded. - expand_macro() returns 1 if the replacement succeeded - and 0 if some error occurred. - - A special case is "defined". This acts as a unary operator - on a single, unexpanded identifier, which may be surrounded - by parenthesis. The function expand_defined() handles this. - */ - register struct macro *mac = idf->id_macro; - struct args *args = repl->r_args; - register int ch; - - if (mac->mc_nps != -1) { /* with parameter list */ - if (mac->mc_flag & FUNC) { - /* the following assertion won't compile: - assert(!strcmp("defined", idf->id_text)); - expand the assert macro by hand (??? dirty, temporary) - */ -#ifdef DEBUG - if (strcmp("defined", idf->id_text)) - crash("in %s, %u: assertion %s failed", - __FILE__, __LINE__ - 2, - "strcmp(\"defined\", idf->id_text)"); -#endif - if (!AccDefined) return 0; - expand_defined(repl); - return 1; - } - - ch = GetChar(); - ch = skipspaces(ch,1); - if (ch != '(') { /* no replacement if no () */ - ChPushBack(ch); - return 0; - } else - getactuals(repl, idf); - - } - - if (mac->mc_flag & FUNC) /* this macro leads to special action */ - macro_func(idf); - - macro2buffer(repl, idf, args); - - /* According to the ANSI definition: - - #define a + - a+b; --> + + b ; - - 'a' must be substituded, but the result should be - three tokens: + + ID. Therefore a token separator is - inserted after the replacement. - */ - if (repl->r_text == repl->r_ptr || *(repl->r_ptr - 1) != TOKSEP) { - add2repl(repl, TOKSEP); - } - return 1; -} - -void -expand_defined(repl) - register struct repl *repl; -{ - register int ch = GetChar(); - struct idf *id; - int parens = 0; - - ch = skipspaces(ch, 0); - - if (ch == '(') { - parens++; - ch = GetChar(); - ch = skipspaces(ch, 0); - } - if ((class(ch) != STIDF) && (class(ch) != STELL)) { - error("identifier missing"); - if (parens && ch != ')') error(") missing"); - if (!parens || ch != ')') ChPushBack(ch); - add2repl(repl, '0'); - return; - } - ChPushBack(ch); - id = GetIdentifier(0); - assert(id || class(ch) == STELL); - ch = GetChar(); - ch = skipspaces(ch, 0); - if (parens && ch != ')') error(") missing"); - if (!parens || ch != ')') ChPushBack(ch); - add2repl(repl, (id && id->id_macro) ? '1' : '0'); - add2repl(repl, ' '); -} - -newarg(args) - struct args *args; -{ - args->a_expptr = args->a_expbuf = Malloc(args->a_expsize = ARGBUF); - args->a_rawptr = args->a_rawbuf = Malloc(args->a_rawsize = ARGBUF); -} - -void -getactuals(repl, idf) - struct repl *repl; - register struct idf *idf; -{ - /* Get the actual parameters from the input stream. - The hard part is done by actual(), only comma's and - other syntactic trivialities are checked here. - */ - register struct args *args = repl->r_args; - register int nps = idf->id_macro->mc_nps; - register int argcnt; - register int ch; - - argcnt = 0; - newarg(args); - if ((ch = GetChar()) != ')') { - UnGetChar(); - while ((ch = actual(repl)) != ')' ) { - if (ch != ',') { - lexerror("illegal macro call"); - return; - } - stash(repl, '\0', 1); - args->a_expvec[argcnt] = args->a_expbuf; - args->a_rawvec[argcnt] = args->a_rawbuf; - ++argcnt; - if (argcnt == STDC_NPARAMS) - lexstrict("number of parameters exceeds ANSI standard"); - if (argcnt >= NPARAMS) - fatal("argument vector overflow"); - newarg(args); - } - stash(repl, '\0', 1); - args->a_expvec[argcnt] = args->a_expbuf; - args->a_rawvec[argcnt] = args->a_rawbuf; - ++argcnt; - } - if (argcnt < nps) - lexerror("too few macro arguments"); - else if (argcnt > nps) - lexerror("too many macro arguments"); -} - -saveraw(repl) -struct repl *repl; -{ - register struct repl *nrepl = ReplaceList; - register struct args *ap = nrepl->r_args; - register char *p; - - /* stash identifier name */ - for (p = nrepl->r_idf->id_text; *p != '\0'; p++) - stash(repl, *p, -1); - - /* The following code deals with expanded function - like macro calls. It makes the following code - work: - - #define def(a,b) x(a,b) - #define glue(a,b) a ## b - - glue(abc,def(a,b)) - - Results in: - - abcdef(a,b); - */ - if (ap->a_rawvec[0]) { - /* stash arguments */ - register int i; - - for (i = 0; ap->a_rawvec[i] != (char *)0; i++) { - if (i == 0) stash(repl, '(', -1); - else stash(repl, ',', -1); - for (p = ap->a_rawvec[i]; *p != '\0'; p++) - stash(repl, *p, -1); - } - stash(repl, ')', -1); - } -} - -int -actual(repl) - struct repl *repl; -{ - /* This routine deals with the scanning of an actual parameter. - It keeps in account the opening and closing brackets, - preprocessor numbers, strings and character constants. - */ - register int ch = 0; - register int level = 0, nostashraw = 0; - int lastch; - static int Unstacked_missed; - - while (1) { - lastch = ch; - ch = GetChar(); - - if (nostashraw - && nostashraw >= Unstacked_missed) { - nostashraw -= Unstacked_missed; - Unstacked_missed = 0; - } - if (Unstacked) { - nostashraw -= Unstacked; - if (nostashraw < 0) { - Unstacked_missed = -nostashraw; - nostashraw = 0; - } - EnableMacros(); - } - if (class(ch) == STIDF || class(ch) == STELL) { - /* Scan a preprocessor identifier token. If the - token is a macro, it is expanded first. - */ - char buf[(IDFSIZE > NUMSIZE ? IDFSIZE : NUMSIZE) + 1]; - register char *p = buf; - register struct idf *idef; - register int pos = -1; - extern int idfsize; - int NoExpandMacro; - - if (ch == NOEXPM) { - NoExpandMacro= 1; - ch = GetChar(); - } else NoExpandMacro = 0; - - do { - if (++pos < idfsize) { - *p++ = ch; - } - ch = GetChar(); - } while (in_idf(ch)); - *p++ = '\0'; - ch = '\0'; /* It could be an unstashed TOKSEP */ - UnGetChar(); - - /* When the identifier has an associated macro - replacement list, it's expanded. - */ - idef = findidf(buf); - if (!idef || NoExpandMacro || !replace(idef)) { - if (NoExpandMacro - || (idef && idef->id_macro - && (idef->id_macro->mc_flag & NOREPLACE))) - stash(repl, NOEXPM, !nostashraw); - for (p = buf; *p != '\0'; p++) - stash(repl, *p, !nostashraw); - } else { - if (!nostashraw) saveraw(repl); - nostashraw++; - } - } else if (class(ch) == STNUM) { - /* a preprocessing number has the following - regular expression: - [0-9|"."[0-9]]{[0-9"."a-zA-Z_]|{[Ee][+-]}}* - */ - stash(repl, ch, !nostashraw); - if (ch == '.') { - ch = GetChar(); - if (class(ch) != STNUM) { - ch = '\0'; /* It could be an unstashed TOKSEP */ - UnGetChar(); - continue; - } - else stash(repl, ch, !nostashraw); - } - ch = GetChar(); - while (in_idf(ch) || ch == '.') { - stash(repl, ch, !nostashraw); - if ((ch = GetChar()) == 'e' || ch == 'E') { - stash(repl, ch, !nostashraw); - ch = GetChar(); - if (ch == '+' || ch == '-') { - stash(repl, ch, !nostashraw); - ch = GetChar(); - } - } - } - ch = '\0'; /* It could be an unstashed TOKSEP */ - UnGetChar(); - } else if (ch == '(') { - /* a comma may occur between parentheses */ - level++; - stash(repl, ch, !nostashraw); - } else if (ch == ')') { - level--; - /* closing parenthesis of macro call */ - if (level < 0) return ')'; - stash(repl, ch, !nostashraw); - } else if (ch == ',') { - if (level <= 0) { /* comma separator for next argument */ - if (level) - lexerror("unbalanced parenthesis"); - if (!nostashraw) - return ','; /* ??? */ - } - stash(repl, ch, !nostashraw); - } else if (ch == '\n') { - /* newlines are accepted as white spaces */ - LineNumber++; - /* This piece of code needs some explanation: - consider the call of a macro defined as: - #define sum(a,b) (a+b) - in the following form: - sum( - /_* comment *_/ #include phone_number - ,2); - in which case the include must be handled - interpreted as such. - */ - -a_new_line: ch = GetChar(); - while (class(ch) == STSKIP || ch == '/') { - if (ch == '/') { - if ((ch = GetChar()) == '*' && !InputLevel) { - skipcomment(); - stash(repl, ' ', !nostashraw); - ch = GetChar(); - continue; - } else { - UnGetChar(); - ch = '/'; - } - stash(repl, '/', !nostashraw); - break; - } else ch = GetChar(); - } - - if (ch == '#') { - domacro(); - /* Clear File_Inserted since domacro could - * be called again, which calls GetToken(). - */ - File_Inserted = 0; - goto a_new_line; - } else if (ch == EOI) { - lexerror("unterminated macro call"); - return ')'; - } - if (ch != '/') { - UnGetChar(); - ch = ' '; - stash(repl, ' ', !nostashraw); - } - } else if (ch == '/') { - /* comments are treated as one white space token */ - if ((ch = GetChar()) == '*' && !InputLevel) { - skipcomment(); - stash(repl, ' ', !nostashraw); - } else { - UnGetChar(); - ch = '/'; - stash(repl, '/', !nostashraw); - } - } else if (ch == '\'' || ch == '"') { - /* Strings are considered as ONE token, thus no - replacement within strings. - */ - register int match = ch; - - stash(repl, ch, !nostashraw); - while ((ch = GetChar()) != EOI) { - if (ch == match) - break; - if (ch == '\\') { - stash(repl, ch, !nostashraw); - ch = GetChar(); - } else if (ch == '\n') { - lexerror("newline in string"); - LineNumber++; - stash(repl, match, !nostashraw); - break; - } - stash(repl, ch, !nostashraw); - } - if (ch != match) { - lexerror("unterminated macro call"); - return ')'; - } - stash(repl, ch, !nostashraw); - } else { - if (lastch == TOKSEP && ch == TOKSEP) continue; - stash(repl, ch, !nostashraw); - } - } -} - -macro_func(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; - static char FilNamBuf[PATHLENGTH]; - - switch (idef->id_text[2]) { - case 'F': /* __FILE__ */ - FilNamBuf[0] = '"'; - strcpy(&FilNamBuf[1], FileName); - strcat(FilNamBuf, "\""); - mac->mc_text = FilNamBuf; - mac->mc_length = strlen(FilNamBuf); - break; - case 'L': /* __LINE__ */ - mac->mc_text = long2str((long)LineNumber, 10); - mac->mc_length = strlen(mac->mc_text); - break; - default: - crash("(macro_func)"); - /*NOTREACHED*/ - } -} - -void -macro2buffer(repl, idf, args) - register struct repl *repl; - register struct idf *idf; - register struct args *args; -{ - /* macro2buffer expands the replacement list and places the - result onto the replacement buffer. It deals with the # - and ## operators, and inserts the actual parameters. - The argument buffer contains the raw argument (needed - for the ## operator), and the expanded argument (for - all other parameter substitutions). - - The grammar of the replacement list is: - - repl_list: TOKEN repl_list - | PARAMETER repl_list - | '#' PARAMETER - | TOKEN '##' TOKEN - | PARAMETER '##' TOKEN - | TOKEN '##' PARAMETER - | PARAMETER '##' PARAMETER - ; - - As the grammar indicates, we could make a DFA and - use this finite state machine for the replacement - list parsing (inserting the arguments, etc.). - - Currently we go through the replacement list in a - linear fashion. This is VERY expensive, something - smarter should be done (but even a DFA is O(|s|)). - */ - register char *ptr = idf->id_macro->mc_text; - int err = 0; - int func = idf->id_macro->mc_nps != -1; - char *stringify(); - - assert(ptr[idf->id_macro->mc_length] == '\0'); - while (*ptr) { - if (*ptr == '\'' || *ptr == '"') { - register int delim = *ptr; - - do { - add2repl(repl, *ptr); - if (*ptr == '\\') - add2repl(repl, *++ptr); - if (*ptr == '\0') { - lexerror("unterminated string"); - return; - } - ptr++; - } while (*ptr != delim || *ptr == '\0'); - add2repl(repl, *ptr++); - } else if (*ptr == '#' && (func || *(ptr+1) == '#')) { - if (*++ptr == '#') { - register int tmpindex; - /* ## - paste operator */ - ptr++; - - /* trim the actual replacement list */ - --repl->r_ptr; - while (repl->r_ptr >= repl->r_text - && is_wsp(*repl->r_ptr)) - --repl->r_ptr; - - /* ## occurred at the beginning of the replacement list. - */ - if (repl->r_ptr < repl->r_text) { - err = 1; - break; - } - - if (repl->r_ptr >= repl->r_text - && *repl->r_ptr == TOKSEP) - --repl->r_ptr; - - ++repl->r_ptr; - tmpindex = repl->r_ptr - repl->r_text; - /* tmpindex can be 0 */ - - /* skip space in macro replacement list */ - while ((*ptr & FORMALP) == 0 && is_wsp(*ptr)) - ptr++; - - /* ## occurred at the end of the replacement list. - */ - if (*ptr & FORMALP) { - register int n = *ptr++ & 0177; - register char *p; - - assert(n > 0); - p = args->a_rawvec[n-1]; - if (p) { /* else macro argument missing */ - while (is_wsp(*p)) p++; - if (*p == NOEXPM) p++; - while (*p) - add2repl(repl, *p++); - } - while (tmpindex > 0 - && in_idf(repl->r_text[tmpindex])) - tmpindex--; - if (tmpindex >= 0 - && repl->r_text[tmpindex] == NOEXPM) - repl->r_text[tmpindex] = TOKSEP; - } else if (*ptr == '\0') { - err = 1; - break; - } else { - if (in_idf(*ptr)) { - tmpindex--; - while (tmpindex > 0 - && in_idf(repl->r_text[tmpindex])) - tmpindex--; - if (tmpindex >= 0 - && repl->r_text[tmpindex] == NOEXPM) - repl->r_text[tmpindex] = TOKSEP; - } - } - } else { /* # operator */ - ptr = stringify(repl, ptr, args); - } - } else if (*ptr & FORMALP) { - /* insert actual parameter */ - register int n = *ptr++ & 0177; - register char *p, *q; - - assert(n > 0); - - /* This is VERY dirty, we look ahead for the - ## operator. If it's found we use the raw - argument buffer instead of the expanded - one. - */ - for (p = ptr; (*p & FORMALP) == 0 && is_wsp(*p); p++) - /* EMPTY */; - if (*p == '#' && p[1] == '#') - q = args->a_rawvec[n-1]; - else - q = args->a_expvec[n-1]; - - if (q) /* else macro argument missing */ - while (*q) - add2repl(repl, *q++); - - if (repl->r_text == repl->r_ptr || *(repl->r_ptr - 1) != TOKSEP) - add2repl(repl, TOKSEP); - } else { - add2repl(repl, *ptr++); - } - } - if (err) - lexerror("illegal use of the ## operator"); -} - -char * -stringify(repl, ptr, args) - register struct repl *repl; - register char *ptr; - register struct args *args; -{ - /* If a parameter is immediately preceded by a # token - both are replaced by a single string literal that - contains the spelling of the token sequence for the - corresponding argument. - Each occurrence of white space between the argument's - tokens become a single space character in the string - literal. White spaces before the first token and after - the last token comprising the argument are deleted. - To retain the original spelling we insert backslashes - as appropriate. We only escape backslashes if they - occure within string tokens. - */ - register int space = 1; /* skip leading spaces */ - register int delim = 0; /* string or character constant delim */ - register int backslash = 0; /* last character was a \ */ - - /* skip spaces macro replacement list */ - while ((*ptr & FORMALP) == 0 && is_wsp(*ptr)) - ptr++; - - if (*ptr & FORMALP) { - register int n = *ptr++ & 0177; - register char *p; - - assert(n != 0); - p = args->a_rawvec[n-1]; - add2repl(repl, '"'); - while (*p) { - if (is_wsp(*p)) { - if (!space) { - space = 1; - add2repl(repl, ' '); - } - p++; - continue; - } - space = 0; - - if (!delim && (*p == '"' || *p == '\'')) - delim = *p; - else if (*p == delim && !backslash) - delim = 0; - backslash = *p == '\\'; - if (*p == '"' || (delim && *p == '\\')) - add2repl(repl, '\\'); - if (*p == TOKSEP || *p == NOEXPM) p++; - else add2repl(repl, *p++); - } - - /* trim spaces in the replacement list */ - for (--repl->r_ptr; is_wsp(*repl->r_ptr); repl->r_ptr--) - /* EMPTY */; - ++repl->r_ptr; /* oops, one to far */ - add2repl(repl, '"'); - } else - error("illegal use of # operator"); - return ptr; -} - -/* The following routine is also called from domacro.c. - */ -add2repl(repl, ch) - register struct repl *repl; - int ch; -{ - register int index = repl->r_ptr - repl->r_text; - - assert(index < repl->r_size); - if (index + 2 >= repl->r_size) { - repl->r_text = Realloc(repl->r_text, (unsigned) (repl->r_size <<= 1)); - repl->r_ptr = repl->r_text + index; - } - *repl->r_ptr++ = ch; - *repl->r_ptr = '\0'; -} - -/* If the variable stashraw is negative, we must only stash into the raw - * buffer. If the variable is zero, we must only stash into the expanded - * buffer. Otherwise, we must use both buffers. - */ -stash(repl, ch, stashraw) - struct repl *repl; - register int ch; - int stashraw; -{ - /* Stash characters into the macro expansion buffer. - */ - register struct args *args = repl->r_args; - register int index = args->a_expptr - args->a_expbuf; - - if (stashraw >= 0) { - assert(index < args->a_expsize); - if (index + 1 >= args->a_expsize) { - args->a_expbuf = Realloc(args->a_expbuf, - (unsigned) (args->a_expsize <<= 1)); - args->a_expptr = args->a_expbuf + index; - } - *args->a_expptr++ = ch; - } - - if (stashraw) { - index = args->a_rawptr - args->a_rawbuf; - assert(index < args->a_rawsize); - if (index + 1 >= args->a_rawsize) { - args->a_rawbuf = Realloc(args->a_rawbuf, - (unsigned)(args->a_rawsize <<= 1)); - args->a_rawptr = args->a_rawbuf + index; - } - *args->a_rawptr++ = ch; - } -} -#endif /* NOPP */ diff --git a/lang/cem/cemcom.ansi/replace.str b/lang/cem/cemcom.ansi/replace.str deleted file mode 100644 index d936fe31d..000000000 --- a/lang/cem/cemcom.ansi/replace.str +++ /dev/null @@ -1,51 +0,0 @@ -/* - * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. - * See the copyright notice in the ACK home directory, in the file "Copyright". - */ -/* $Id$ */ -/* DEFINITIONS FOR THE MACRO REPLACEMENT ROUTINES */ - -struct repl { - struct repl *next; - struct idf *r_idf; /* name of the macro */ - struct args *r_args; /* replacement parameters */ - int r_level; /* level of insertion */ - int r_size; /* current size of replacement buffer */ - char *r_ptr; /* replacement text index pointer */ - char *r_text; /* replacement text */ -}; - -/* ALLOCDEF "repl" 4 */ - -#define NO_REPL (struct repl *)0 - -/* The implementation of the ## operator is currently very clumsy. - When the the ## operator is used the arguments are taken from - the raw buffer; this buffer contains a precise copy of the - original argument. The fully expanded copy is in the arg buffer. - The two copies are here explicitely because: - - #define ABC f() - #define ABCD 2 - #define g(x, y) x ## y + h(x) - - g(ABC, D); // gives: 2 + h(f()) - - In this case we need two copies: one raw copy for the pasting - operator, and an expanded one as argument for h(). -*/ -struct args { - char *a_expptr; /* expanded argument index pointer */ - char *a_expbuf; /* expanded argument buffer pointer */ - int a_expsize; /* current size of expanded buffer */ - char *a_expvec[NPARAMS]; /* expanded argument vector */ - char *a_rawptr; /* raw argument index pointer */ - char *a_rawbuf; /* raw argument buffer pointer */ - int a_rawsize; /* current size of raw buffer */ - char *a_rawvec[NPARAMS]; /* raw argument vector */ -}; - -/* ALLOCDEF "args" 2 */ - -#define NO_ARGS (struct args *)0 - diff --git a/lang/cem/cemcom.ansi/skip.c b/lang/cem/cemcom.ansi/skip.c index d4a67142e..b617f08e9 100644 --- a/lang/cem/cemcom.ansi/skip.c +++ b/lang/cem/cemcom.ansi/skip.c @@ -5,100 +5,23 @@ /* $Id$ */ /* PREPROCESSOR: INPUT SKIP FUNCTIONS */ -#include "parameters.h" -#include "arith.h" -#include "LLlex.h" -#include "class.h" -#include "input.h" +#include "parameters.h" +#include "arith.h" +#include "LLlex.h" +#include "class.h" +#include "input.h" -#ifndef NOPP -extern int InputLevel; - -int -skipspaces(ch, skipnl) - register int ch; -{ - /* skipspaces() skips any white space and returns the first - non-space character. - */ - register int nlseen = 0; - - for (;;) { - while (class(ch) == STSKIP) - ch = GetChar(); - if (skipnl && class(ch) == STNL) { - ch = GetChar(); - LineNumber++; - nlseen++; - continue; - } - if (ch == TOKSEP && InputLevel) { - ch = GetChar(); - continue; - } - - /* \\\n are handled by trigraph */ - - if (ch == '/') { - ch = GetChar(); - if (ch == '*' && !InputLevel) { - skipcomment(); - ch = GetChar(); - } - else { - UnGetChar(); - return '/'; - } - } - else if (nlseen && ch == '#') { - domacro(); - ch = GetChar(); - } else - return ch; - } -} -#endif /* NOPP */ SkipToNewLine() { register int ch; register int garbage = 0; -#ifndef NOPP - register int delim = 0; -#endif - while ((ch = GetChar()) != '\n') { -#ifndef NOPP - if (delim) { - if (ch == '\\') { - if (GetChar() == '\n') break; - } else if (ch == delim) { - delim = 0; - } - continue; - } - else if (ch == '\'' || ch == '\"') { - delim = ch; - garbage = 1; - } else if (ch == '/') { - if (GetChar() == '*' - && !InputLevel - ) { - skipcomment(); - continue; - } - else UnGetChar(); - } - else if (ch == TOKSEP && InputLevel) { - continue; - } -#endif + while ((ch = GetChar()) != '\n') + { if (!is_wsp(ch)) garbage = 1; } -#ifndef NOPP - if (delim) strict("unclosed opening %c", delim); -#endif ++LineNumber; return garbage; } diff --git a/lang/cem/cpp.ansi/LLlex.c b/lang/cem/cpp.ansi/LLlex.c index a0ec21a0f..40c6c57dc 100644 --- a/lang/cem/cpp.ansi/LLlex.c +++ b/lang/cem/cpp.ansi/LLlex.c @@ -5,350 +5,412 @@ /* $Id$ */ /* L E X I C A L A N A L Y Z E R */ -#include "parameters.h" +#include "parameters.h" -#include -#include -#include "input.h" -#include "arith.h" -#include "macro.h" -#include "idf.h" -#include "LLlex.h" -#include "Lpars.h" -#include "class.h" -#include "bits.h" +#include +#include +#include "input.h" +#include "arith.h" +#include "macro.h" +#include "idf.h" +#include "LLlex.h" +#include "Lpars.h" +#include "class.h" +#include "bits.h" -#define BUFSIZ 1024 +#define BUFSIZ 1024 struct token dot; -int ReplaceMacros = 1; /* replacing macros */ -int AccDefined = 0; /* accept "defined(...)" */ -int UnknownIdIsZero = 0; /* interpret unknown id as integer 0 */ -int Unstacked = 0; /* an unstack is done */ -int AccFileSpecifier = 0; /* return filespecifier <...> */ -int LexSave = 0; /* last character read by GetChar */ -extern int InputLevel; /* # of current macro expansions */ +int ReplaceMacros = 1; /* replacing macros */ +int AccDefined = 0; /* accept "defined(...)" */ +int UnknownIdIsZero = 0; /* interpret unknown id as integer 0 */ +int Unstacked = 0; /* an unstack is done */ +int AccFileSpecifier = 0; /* return filespecifier <...> */ +int LexSave = 0; /* last character read by GetChar */ +extern int InputLevel; /* # of current macro expansions */ -extern char *string_token(); -extern arith char_constant(); -#define FLG_ESEEN 0x01 /* possibly a floating point number */ -#define FLG_DOTSEEN 0x02 /* certainly a floating point number */ +extern char* string_token(); +extern arith char_constant(); +#define FLG_ESEEN 0x01 /* possibly a floating point number */ +#define FLG_DOTSEEN 0x02 /* certainly a floating point number */ void skipcomment(); +void skiplinecomment(void); -int -LLlex() +int LLlex() { return (DOT != EOF) ? GetToken(&dot) : EOF; } - -int -GetToken(ptok) - register struct token *ptok; +int GetToken(ptok) register struct token* ptok; { /* GetToken() is the actual token recognizer. It calls the - control line interpreter if it encounters a "\n{w}*#" - combination. Macro replacement is also performed if it is - needed. + control line interpreter if it encounters a "\n{w}*#" + combination. Macro replacement is also performed if it is + needed. */ char buf[BUFSIZ]; register int ch, nch; -again: /* rescan the input after an error or replacement */ +again: /* rescan the input after an error or replacement */ ch = GetChar(); /* rescan, the following character has been read */ if ((ch & 0200) && ch != EOI) /* stop on non-ascii character */ fatal("non-ascii '\\%03o' read", ch & 0377); /* keep track of the place of the token in the file */ - switch (class(ch)) { /* detect character class */ - case STNL: /* newline, vertical space or formfeed */ - LineNumber++; - return ptok->tk_symb = EOF; - case STSKIP: /* just skip the skip characters */ - goto again; - case STGARB: /* garbage character */ -garbage: - if (040 < ch && ch < 0177) - error("garbage char %c", ch); - else - error("garbage char \\%03o", ch); - goto again; - case STSIMP: /* a simple character, no part of compound token*/ - return ptok->tk_symb = ch; - case STCOMP: /* maybe the start of a compound token */ - nch = GetChar(); /* character lookahead */ - switch (ch) { - case '!': - if (nch == '=') - return ptok->tk_symb = NOTEQUAL; - UnGetChar(); + switch (class(ch)) + { /* detect character class */ + case STNL: /* newline, vertical space or formfeed */ + LineNumber++; + return ptok->tk_symb = EOF; + case STSKIP: /* just skip the skip characters */ + goto again; + case STGARB: /* garbage character */ + garbage: + if (040 < ch && ch < 0177) + error("garbage char %c", ch); + else + error("garbage char \\%03o", ch); + goto again; + case STSIMP: /* a simple character, no part of compound token*/ return ptok->tk_symb = ch; - case '&': - if (nch == '&') - return ptok->tk_symb = AND; - else if (nch == '=') - return ptok->tk_symb = ANDAB; - UnGetChar(); - return ptok->tk_symb = ch; - case '+': - if (nch == '+') - return ptok->tk_symb = PLUSPLUS; - else if (nch == '=') - return ptok->tk_symb = PLUSAB; - UnGetChar(); - return ptok->tk_symb = ch; - case '-': - if (nch == '-') - return ptok->tk_symb = MINMIN; - else if (nch == '>') - return ptok->tk_symb = ARROW; - else if (nch == '=') - return ptok->tk_symb = MINAB; - UnGetChar(); - return ptok->tk_symb = ch; - case '<': - if (AccFileSpecifier) { - UnGetChar(); /* pushback nch */ - ptok->tk_str = - string_token("file specifier", '>'); - return ptok->tk_symb = FILESPECIFIER; - } else if (nch == '<') { - if ((nch = GetChar()) == '=') - return ptok->tk_symb = LEFTAB; - UnGetChar(); - return ptok->tk_symb = LEFT; - } else if (nch == '=') - return ptok->tk_symb = LESSEQ; - UnGetChar(); - return ptok->tk_symb = ch; - case '=': - if (nch == '=') - return ptok->tk_symb = EQUAL; - UnGetChar(); - return ptok->tk_symb = ch; - case '>': - if (nch == '=') - return ptok->tk_symb = GREATEREQ; - else if (nch == '>') { - if ((nch = GetChar()) == '=') - return ptok->tk_symb = RIGHTAB; - UnGetChar(); - return ptok->tk_symb = RIGHT; + case STCOMP: /* maybe the start of a compound token */ + nch = GetChar(); /* character lookahead */ + switch (ch) + { + case '!': + if (nch == '=') + return ptok->tk_symb = NOTEQUAL; + UnGetChar(); + return ptok->tk_symb = ch; + case '&': + if (nch == '&') + return ptok->tk_symb = AND; + else if (nch == '=') + return ptok->tk_symb = ANDAB; + UnGetChar(); + return ptok->tk_symb = ch; + case '+': + if (nch == '+') + return ptok->tk_symb = PLUSPLUS; + else if (nch == '=') + return ptok->tk_symb = PLUSAB; + UnGetChar(); + return ptok->tk_symb = ch; + case '-': + if (nch == '-') + return ptok->tk_symb = MINMIN; + else if (nch == '>') + return ptok->tk_symb = ARROW; + else if (nch == '=') + return ptok->tk_symb = MINAB; + UnGetChar(); + return ptok->tk_symb = ch; + case '<': + if (AccFileSpecifier) + { + UnGetChar(); /* pushback nch */ + ptok->tk_str = string_token("file specifier", '>'); + return ptok->tk_symb = FILESPECIFIER; + } + else if (nch == '<') + { + if ((nch = GetChar()) == '=') + return ptok->tk_symb = LEFTAB; + UnGetChar(); + return ptok->tk_symb = LEFT; + } + else if (nch == '=') + return ptok->tk_symb = LESSEQ; + UnGetChar(); + return ptok->tk_symb = ch; + case '=': + if (nch == '=') + return ptok->tk_symb = EQUAL; + UnGetChar(); + return ptok->tk_symb = ch; + case '>': + if (nch == '=') + return ptok->tk_symb = GREATEREQ; + else if (nch == '>') + { + if ((nch = GetChar()) == '=') + return ptok->tk_symb = RIGHTAB; + UnGetChar(); + return ptok->tk_symb = RIGHT; + } + UnGetChar(); + return ptok->tk_symb = ch; + case '|': + if (nch == '|') + return ptok->tk_symb = OR; + else if (nch == '=') + return ptok->tk_symb = ORAB; + UnGetChar(); + return ptok->tk_symb = ch; + case '%': + if (nch == '=') + return ptok->tk_symb = MODAB; + UnGetChar(); + return ptok->tk_symb = ch; + case '*': + if (nch == '=') + return ptok->tk_symb = TIMESAB; + UnGetChar(); + return ptok->tk_symb = ch; + case '^': + if (nch == '=') + return ptok->tk_symb = XORAB; + UnGetChar(); + return ptok->tk_symb = ch; + case '/': + if (!InputLevel) + { + if (nch == '*') + { + skipcomment(); + goto again; + } + else if (nch == '/') + { + skiplinecomment(); + goto again; + } + } + else if (nch == '=') + return ptok->tk_symb = DIVAB; + UnGetChar(); + return ptok->tk_symb = ch; + default: + crash("bad class for char 0%o", ch); + /* NOTREACHED */ } - UnGetChar(); - return ptok->tk_symb = ch; - case '|': - if (nch == '|') - return ptok->tk_symb = OR; - else if (nch == '=') - return ptok->tk_symb = ORAB; - UnGetChar(); - return ptok->tk_symb = ch; - case '%': - if (nch == '=') - return ptok->tk_symb = MODAB; - UnGetChar(); - return ptok->tk_symb = ch; - case '*': - if (nch == '=') - return ptok->tk_symb = TIMESAB; - UnGetChar(); - return ptok->tk_symb = ch; - case '^': - if (nch == '=') - return ptok->tk_symb = XORAB; - UnGetChar(); - return ptok->tk_symb = ch; - case '/': - if (nch == '*' && !InputLevel) { - skipcomment(); - goto again; - } - else if (nch == '=') - return ptok->tk_symb = DIVAB; - UnGetChar(); - return ptok->tk_symb = ch; - default: - crash("bad class for char 0%o", ch); - /* NOTREACHED */ - } - case STCHAR: /* character constant */ - ptok->tk_val = char_constant("character"); - return ptok->tk_symb = INTEGER; - case STSTR: /* string */ - ptok->tk_str = string_token("string", '"'); - return ptok->tk_symb = STRING; - case STELL: /* wide character constant/string prefix */ - nch = GetChar(); - if (nch == '"') { - ptok->tk_str = - string_token("wide character string", '"'); + case STCHAR: /* character constant */ + ptok->tk_val = char_constant("character"); + return ptok->tk_symb = INTEGER; + case STSTR: /* string */ + ptok->tk_str = string_token("string", '"'); return ptok->tk_symb = STRING; - } else if (nch == '\'') { - ptok->tk_val = char_constant("wide character"); - return ptok->tk_symb = INTEGER; - } - UnGetChar(); + case STELL: /* wide character constant/string prefix */ + nch = GetChar(); + if (nch == '"') + { + ptok->tk_str = string_token("wide character string", '"'); + return ptok->tk_symb = STRING; + } + else if (nch == '\'') + { + ptok->tk_val = char_constant("wide character"); + return ptok->tk_symb = INTEGER; + } + UnGetChar(); /* fallthrough */ - case STIDF: - { - extern int idfsize; /* ??? */ - register char *tg = &buf[0]; - register char *maxpos = &buf[idfsize]; - int NoExpandNext = 0; + case STIDF: + { + extern int idfsize; /* ??? */ + register char* tg = &buf[0]; + register char* maxpos = &buf[idfsize]; + int NoExpandNext = 0; -#define tstmac(bx) if (!(bits[ch] & bx)) goto nomac -#define cpy *tg++ = ch -#define load (ch = GetChar()); if (!in_idf(ch)) goto endidf +#define tstmac(bx) \ + if (!(bits[ch] & bx)) \ + goto nomac +#define cpy *tg++ = ch +#define load \ + (ch = GetChar()); \ + if (!in_idf(ch)) \ + goto endidf - if (Unstacked) EnableMacros(); /* unstack macro's when allowed. */ - if (ch == NOEXPM) { - NoExpandNext = 1; - ch = GetChar(); - } + if (Unstacked) + EnableMacros(); /* unstack macro's when allowed. */ + if (ch == NOEXPM) + { + NoExpandNext = 1; + ch = GetChar(); + } #ifdef DOBITS - cpy; tstmac(bit0); load; - cpy; tstmac(bit1); load; - cpy; tstmac(bit2); load; - cpy; tstmac(bit3); load; - cpy; tstmac(bit4); load; - cpy; tstmac(bit5); load; - cpy; tstmac(bit6); load; - cpy; tstmac(bit7); load; -#endif - for(;;) { - if (tg < maxpos) { - cpy; - - } + cpy; + tstmac(bit0); load; - } - endidf: - /*if (ch != EOI) UnGetChar();*/ - UnGetChar(); - *tg++ = '\0'; /* mark the end of the identifier */ - if (ReplaceMacros) { - register struct idf *idef = findidf(buf); - - if (idef && idef->id_macro && !NoExpandNext) { - if (replace(idef)) - goto again; + cpy; + tstmac(bit1); + load; + cpy; + tstmac(bit2); + load; + cpy; + tstmac(bit3); + load; + cpy; + tstmac(bit4); + load; + cpy; + tstmac(bit5); + load; + cpy; + tstmac(bit6); + load; + cpy; + tstmac(bit7); + load; +#endif + for (;;) + { + if (tg < maxpos) + { + cpy; + } + load; } - } + endidf: + /*if (ch != EOI) UnGetChar();*/ + UnGetChar(); + *tg++ = '\0'; /* mark the end of the identifier */ + if (ReplaceMacros) + { + register struct idf* idef = findidf(buf); - nomac: /* buf can already be null-terminated. soit */ - ch = GetChar(); - while (in_idf(ch)) { - if (tg < maxpos) *tg++ = ch; - ch = GetChar(); - } - UnGetChar(); - *tg++ = '\0'; /* mark the end of the identifier */ - - NoExpandNext = 0; - if (UnknownIdIsZero) { - ptok->tk_val = (arith)0; - return ptok->tk_symb = INTEGER; - } - ptok->tk_str = Malloc((unsigned)(tg - buf)); - strcpy(ptok->tk_str, buf); - return IDENTIFIER; - } - case STNUM: /* a numeric constant */ - { /* it may only be an integer constant */ - register int base = 10, vch; - register arith val = 0; - int ovfl = 0; - arith ubound = max_arith/(base/2); - - /* Since the preprocessor only knows integers and has - * nothing to do with ellipsis we just return when the - * pp-number starts with a '.' - */ - if (ch == '.') { - return ptok->tk_symb = ch; - } - if (ch == '0') { - ch = GetChar(); - if (ch == 'x' || ch == 'X') { - base = 16; - ch = GetChar(); - } else { - base = 8; + if (idef && idef->id_macro && !NoExpandNext) + { + if (replace(idef)) + goto again; + } } - } - while ((vch = val_in_base(ch, base)) >= 0) { - if (val < 0 || val > ubound) ovfl++; - val *= base; - if (val < 0 && val + vch >= 0) ovfl++; - val += vch; + nomac: /* buf can already be null-terminated. soit */ ch = GetChar(); - } - ptok->tk_unsigned = 0; - if (ch == 'u' || ch == 'U') { - ptok->tk_unsigned = 1; - ch = GetChar(); - if (ch == 'l' || ch == 'L') { + while (in_idf(ch)) + { + if (tg < maxpos) + *tg++ = ch; ch = GetChar(); } + UnGetChar(); + *tg++ = '\0'; /* mark the end of the identifier */ + + NoExpandNext = 0; + if (UnknownIdIsZero) + { + ptok->tk_val = (arith)0; + return ptok->tk_symb = INTEGER; + } + ptok->tk_str = Malloc((unsigned)(tg - buf)); + strcpy(ptok->tk_str, buf); + return IDENTIFIER; } - else if (ch == 'l' || ch == 'L') { - ch = GetChar(); - if (ch == 'u' || ch == 'U') { + case STNUM: /* a numeric constant */ + { /* it may only be an integer constant */ + register int base = 10, vch; + register arith val = 0; + int ovfl = 0; + arith ubound = max_arith / (base / 2); + + /* Since the preprocessor only knows integers and has + * nothing to do with ellipsis we just return when the + * pp-number starts with a '.' + */ + if (ch == '.') + { + return ptok->tk_symb = ch; + } + if (ch == '0') + { + ch = GetChar(); + if (ch == 'x' || ch == 'X') + { + base = 16; + ch = GetChar(); + } + else + { + base = 8; + } + } + while ((vch = val_in_base(ch, base)) >= 0) + { + if (val < 0 || val > ubound) + ovfl++; + val *= base; + if (val < 0 && val + vch >= 0) + ovfl++; + val += vch; + ch = GetChar(); + } + ptok->tk_unsigned = 0; + if (ch == 'u' || ch == 'U') + { ptok->tk_unsigned = 1; ch = GetChar(); + if (ch == 'l' || ch == 'L') + { + ch = GetChar(); + } } + else if (ch == 'l' || ch == 'L') + { + ch = GetChar(); + if (ch == 'u' || ch == 'U') + { + ptok->tk_unsigned = 1; + ch = GetChar(); + } + } + if (ovfl) + { + warning("overflow in constant"); + ptok->tk_unsigned = 1; + } + else if (val < 0) + { + /* give warning??? */ + ptok->tk_unsigned = 1; + } + UnGetChar(); + ptok->tk_val = val; + return ptok->tk_symb = INTEGER; } - if (ovfl) { - warning("overflow in constant"); - ptok->tk_unsigned = 1; - } - else if (val < 0) { - /* give warning??? */ - ptok->tk_unsigned = 1; - } - UnGetChar(); - ptok->tk_val = val; - return ptok->tk_symb = INTEGER; - } - case STEOI: /* end of text on source file */ - return ptok->tk_symb = EOF; - case STMSPEC: - if (!InputLevel) goto garbage; - if (ch == TOKSEP) goto again; + case STEOI: /* end of text on source file */ + return ptok->tk_symb = EOF; + case STMSPEC: + if (!InputLevel) + goto garbage; + if (ch == TOKSEP) + goto again; /* fallthrough shouldn't happen */ - default: /* this cannot happen */ - crash("bad class for char 0%o", ch); + default: /* this cannot happen */ + crash("bad class for char 0%o", ch); } /*NOTREACHED*/ } -void -skipcomment() +void skipcomment() { /* The last character read has been the '*' of '/_*'. The - characters, except NL and EOI, between '/_*' and the first - occurring '*_/' are not interpreted. - NL only affects the LineNumber. EOI is not legal. + characters, except NL and EOI, between '/_*' and the first + occurring '*_/' are not interpreted. + NL only affects the LineNumber. EOI is not legal. - Important note: it is not possible to stop skipping comment - beyond the end-of-file of an included file. - EOI is returned by LoadChar only on encountering EOF of the - top-level file... + Important note: it is not possible to stop skipping comment + beyond the end-of-file of an included file. + EOI is returned by LoadChar only on encountering EOF of the + top-level file... */ register int c; NoUnstack++; c = GetChar(); - do { - while (c != '*') { - if (class(c) == STNL) { + do + { + while (c != '*') + { + if (class(c) == STNL) + { ++LineNumber; - } else if (c == EOI) { + } + else if (c == EOI) + { NoUnstack--; return; } @@ -359,9 +421,23 @@ skipcomment() NoUnstack--; } -arith -char_constant(nm) - char *nm; +void skiplinecomment(void) +{ + /* The last character read has been the '/' of '//'. We read + and discard all characters up to but not including the next + NL. */ + + for (;;) { + int c = GetChar(); + if ((class(c) == STNL) || (c == EOI)) + { + UnGetChar(); + break; + } + } +} + +arith char_constant(nm) char* nm; { register arith val = 0; register int ch; @@ -371,20 +447,23 @@ char_constant(nm) if (ch == '\'') error("%s constant too short", nm); else - while (ch != '\'') { - if (ch == '\n') { - error("newline in %s constant", nm); - LineNumber++; - break; + while (ch != '\'') + { + if (ch == '\n') + { + error("newline in %s constant", nm); + LineNumber++; + break; + } + if (ch == '\\') + ch = quoted(GetChar()); + if (ch >= 128) + ch -= 256; + if (size < sizeof(arith)) + val |= ch << (8 * size); + size++; + ch = GetChar(); } - if (ch == '\\') - ch = quoted(GetChar()); - if (ch >= 128) ch -= 256; - if (size < sizeof(arith)) - val |= ch << (8 * size); - size++; - ch = GetChar(); - } if (size > sizeof(arith)) error("%s constant too long", nm); else if (size > 1) @@ -392,23 +471,24 @@ char_constant(nm) return val; } -char * -string_token(nm, stop_char) - char *nm; +char* string_token(nm, stop_char) char* nm; { register int ch; register int str_size; - register char *str = Malloc((unsigned) (str_size = ISTRSIZE)); + register char* str = Malloc((unsigned)(str_size = ISTRSIZE)); register int pos = 0; - + ch = GetChar(); - while (ch != stop_char) { - if (ch == '\n') { + while (ch != stop_char) + { + if (ch == '\n') + { error("newline in %s", nm); LineNumber++; break; } - if (ch == EOI) { + if (ch == EOI) + { error("end-of-file inside %s", nm); break; } @@ -424,91 +504,89 @@ string_token(nm, stop_char) return str; } -int -quoted(ch) - register int ch; -{ +int quoted(ch) register int ch; +{ /* quoted() replaces an escaped character sequence by the - character meant. + character meant. */ /* first char after backslash already in ch */ - if (!is_oct(ch)) { /* a quoted char */ - switch (ch) { - case 'n': - ch = '\n'; - break; - case 't': - ch = '\t'; - break; - case 'b': - ch = '\b'; - break; - case 'r': - ch = '\r'; - break; - case 'f': - ch = '\f'; - break; - case 'a': /* alert */ - ch = '\007'; - break; - case 'v': /* vertical tab */ - ch = '\013'; - break; - case 'x': /* quoted hex */ + if (!is_oct(ch)) + { /* a quoted char */ + switch (ch) { - register int hex = 0; - register int vch; + case 'n': + ch = '\n'; + break; + case 't': + ch = '\t'; + break; + case 'b': + ch = '\b'; + break; + case 'r': + ch = '\r'; + break; + case 'f': + ch = '\f'; + break; + case 'a': /* alert */ + ch = '\007'; + break; + case 'v': /* vertical tab */ + ch = '\013'; + break; + case 'x': /* quoted hex */ + { + register int hex = 0; + register int vch; - for (;;) { - ch = GetChar(); - if (vch = val_in_base(ch, 16), vch == -1) - break; - hex = hex * 16 + vch; + for (;;) + { + ch = GetChar(); + if (vch = val_in_base(ch, 16), vch == -1) + break; + hex = hex * 16 + vch; + } + UnGetChar(); + ch = hex; } - UnGetChar(); - ch = hex; } - } - } else { /* a quoted octal */ + } + else + { /* a quoted octal */ register int oct = 0, cnt = 0; - do { - oct = oct*8 + (ch-'0'); + do + { + oct = oct * 8 + (ch - '0'); ch = GetChar(); } while (is_oct(ch) && ++cnt < 3); UnGetChar(); ch = oct; } - return ch&0377; + return ch & 0377; } - -int -val_in_base(ch, base) - register int ch; +int val_in_base(ch, base) register int ch; { - switch (base) { - case 8: - return (is_dig(ch) && ch < '9') ? ch - '0' : -1; - case 10: - return is_dig(ch) ? ch - '0' : -1; - case 16: - return is_dig(ch) ? ch - '0' - : is_hex(ch) ? (ch - 'a' + 10) & 017 - : -1; - default: - fatal("(val_in_base) illegal base value %d", base); - /* NOTREACHED */ + switch (base) + { + case 8: + return (is_dig(ch) && ch < '9') ? ch - '0' : -1; + case 10: + return is_dig(ch) ? ch - '0' : -1; + case 16: + return is_dig(ch) ? ch - '0' : is_hex(ch) ? (ch - 'a' + 10) & 017 : -1; + default: + fatal("(val_in_base) illegal base value %d", base); + /* NOTREACHED */ } } - -int -GetChar() +int GetChar() { /* The routines GetChar and trigraph parses the trigraph - sequences and removes occurences of \\\n. + sequences and removes occurences of \\\n. */ register int ch; @@ -520,58 +598,60 @@ again: ch = trigraph(); /* \\\n are removed from the input stream */ - if (ch == '\\') { + if (ch == '\\') + { LoadChar(ch); - if (ch == '\n') { + if (ch == '\n') + { ++LineNumber; goto again; } PushBack(); ch = '\\'; } - return(LexSave = ch); + return (LexSave = ch); } - -int -trigraph() +int trigraph() { register int ch; LoadChar(ch); - if (ch == '?') { + if (ch == '?') + { LoadChar(ch); - switch (ch) { /* its a trigraph */ - case '=': - ch = '#'; - return(ch); - case '(': - ch = '['; - return(ch); - case '/': - ch = '\\'; - return(ch); - case ')': - ch = ']'; - return(ch); - case '\'': - ch = '^'; - return(ch); - case '<': - ch = '{'; - return(ch); - case '!': - ch = '|'; - return(ch); - case '>': - ch = '}'; - return(ch); - case '-': - ch = '~'; - return(ch); + switch (ch) + { /* its a trigraph */ + case '=': + ch = '#'; + return (ch); + case '(': + ch = '['; + return (ch); + case '/': + ch = '\\'; + return (ch); + case ')': + ch = ']'; + return (ch); + case '\'': + ch = '^'; + return (ch); + case '<': + ch = '{'; + return (ch); + case '!': + ch = '|'; + return (ch); + case '>': + ch = '}'; + return (ch); + case '-': + ch = '~'; + return (ch); } PushBack(); } PushBack(); - return('?'); + return ('?'); } diff --git a/lang/cem/cpp.ansi/domacro.c b/lang/cem/cpp.ansi/domacro.c index 193610a6f..39c2d8482 100644 --- a/lang/cem/cpp.ansi/domacro.c +++ b/lang/cem/cpp.ansi/domacro.c @@ -5,47 +5,45 @@ /* $Id$ */ /* PREPROCESSOR: CONTROLLINE INTERPRETER */ -#include -#include -#include -#include "arith.h" -#include "LLlex.h" -#include "Lpars.h" -#include "idf.h" -#include "input.h" +#include +#include +#include +#include "arith.h" +#include "LLlex.h" +#include "Lpars.h" +#include "idf.h" +#include "input.h" -#include "parameters.h" -#include -#include "class.h" -#include "macro.h" -#include "bits.h" -#include "replace.h" +#include "parameters.h" +#include +#include "class.h" +#include "macro.h" +#include "bits.h" +#include "replace.h" extern char options[]; -extern char **inctable; /* list of include directories */ -extern char *getwdir(); -char ifstack[IFDEPTH]; /* if-stack: the content of an entry is */ - /* 1 if a corresponding ELSE has been */ - /* encountered. */ +extern char** inctable; /* list of include directories */ +extern char* getwdir(); +char ifstack[IFDEPTH]; /* if-stack: the content of an entry is */ +/* 1 if a corresponding ELSE has been */ +/* encountered. */ -int nestlevel = -1; -int svnestlevel[30] = {-1}; -int nestcount; +int nestlevel = -1; +int svnestlevel[30] = { -1 }; +int nestcount; extern int do_preprocess; void macro_def(); void do_define(); -char * -GetIdentifier(skiponerr) - int skiponerr; /* skip the rest of the line on error */ +char* GetIdentifier(skiponerr) int skiponerr; /* skip the rest of the line on error */ { /* Returns a pointer to the identifier that is read from the - input stream. When the input does not contain an - identifier, the rest of the line is skipped when skiponerr - is on, and a null-pointer is returned. - The substitution of macros is disabled. - Remember that on end-of-line EOF is returned. + input stream. When the input does not contain an + identifier, the rest of the line is skipped when skiponerr + is on, and a null-pointer is returned. + The substitution of macros is disabled. + Remember that on end-of-line EOF is returned. */ int tmp = UnknownIdIsZero; int tok; @@ -55,232 +53,263 @@ GetIdentifier(skiponerr) tok = GetToken(&tk); ReplaceMacros = 1; UnknownIdIsZero = tmp; - if (tok != IDENTIFIER) { - if (skiponerr && tok != EOF) SkipToNewLine(); - return (char *)0; + if (tok != IDENTIFIER) + { + if (skiponerr && tok != EOF) + SkipToNewLine(); + return (char*)0; } return tk.tk_str; } /* domacro() is the control line interpreter. The '#' has already - been read by the lexical analyzer by which domacro() is called. - The token appearing directly after the '#' is obtained by calling - the basic lexical analyzing function GetToken() and is interpreted - to perform the action belonging to that token. - An error message is produced when the token is not recognized. - Pragma's are handled by do_pragma(). They are passed on to the - compiler. + been read by the lexical analyzer by which domacro() is called. + The token appearing directly after the '#' is obtained by calling + the basic lexical analyzing function GetToken() and is interpreted + to perform the action belonging to that token. + An error message is produced when the token is not recognized. + Pragma's are handled by do_pragma(). They are passed on to the + compiler. */ domacro() { - struct token tk; /* the token itself */ - register struct idf *id; + struct token tk; /* the token itself */ + register struct idf* id; int toknum; ReplaceMacros = 0; toknum = GetToken(&tk); ReplaceMacros = 1; - switch(toknum) { /* select control line action */ - case IDENTIFIER: /* is it a macro keyword? */ - id = findidf(tk.tk_str); - if (!id) { - error("%s: unknown control", tk.tk_str); - SkipToNewLine(); - free(tk.tk_str); - break; - } - free(tk.tk_str); - switch (id->id_resmac) { - case K_DEFINE: /* "define" */ - do_define(); - break; - case K_ELIF: /* "elif" */ - do_elif(); - break; - case K_ELSE: /* "else" */ - do_else(); - break; - case K_ENDIF: /* "endif" */ - do_endif(); - break; - case K_IF: /* "if" */ - do_if(); - break; - case K_IFDEF: /* "ifdef" */ - do_ifdef(1); - break; - case K_IFNDEF: /* "ifndef" */ - do_ifdef(0); - break; - case K_INCLUDE: /* "include" */ - do_include(); - break; - case K_LINE: /* "line" */ - /* set LineNumber and FileName according to - the arguments. - */ - if (GetToken(&tk) != INTEGER) { - error("bad #line syntax"); + switch (toknum) + { /* select control line action */ + case IDENTIFIER: /* is it a macro keyword? */ + id = findidf(tk.tk_str); + if (!id) + { + error("%s: unknown control", tk.tk_str); SkipToNewLine(); + free(tk.tk_str); + break; + } + free(tk.tk_str); + switch (id->id_resmac) + { + case K_DEFINE: /* "define" */ + do_define(); + break; + case K_ELIF: /* "elif" */ + do_elif(); + break; + case K_ELSE: /* "else" */ + do_else(); + break; + case K_ENDIF: /* "endif" */ + do_endif(); + break; + case K_IF: /* "if" */ + do_if(); + break; + case K_IFDEF: /* "ifdef" */ + do_ifdef(1); + break; + case K_IFNDEF: /* "ifndef" */ + do_ifdef(0); + break; + case K_INCLUDE: /* "include" */ + do_include(); + break; + case K_LINE: /* "line" */ + /* set LineNumber and FileName according to + the arguments. + */ + if (GetToken(&tk) != INTEGER) + { + error("bad #line syntax"); + SkipToNewLine(); + } + else + do_line((unsigned int)tk.tk_val); + break; + case K_ERROR: /* "error" */ + do_error(); + break; + case K_PRAGMA: /* "pragma" */ + do_pragma(); + break; + case K_UNDEF: /* "undef" */ + do_undef((char*)0); + break; + default: + /* invalid word seen after the '#' */ + error("%s: unknown control", id->id_text); + SkipToNewLine(); } - else - do_line((unsigned int)tk.tk_val); break; - case K_ERROR: /* "error" */ - do_error(); + case INTEGER: /* # []? */ + do_line((unsigned int)tk.tk_val); break; - case K_PRAGMA: /* "pragma" */ - do_pragma(); + case EOF: /* only `#' on this line: do nothing, ignore */ break; - case K_UNDEF: /* "undef" */ - do_undef((char *)0); - break; - default: - /* invalid word seen after the '#' */ - error("%s: unknown control", id->id_text); + default: /* invalid token following '#' */ + error("illegal # line"); SkipToNewLine(); - } - break; - case INTEGER: /* # []? */ - do_line((unsigned int)tk.tk_val); - break; - case EOF: /* only `#' on this line: do nothing, ignore */ - break; - default: /* invalid token following '#' */ - error("illegal # line"); - SkipToNewLine(); } } -void -skip_block(to_endif) -int to_endif; +void skip_block(to_endif) int to_endif; { /* skip_block() skips the input from - 1) a false #if, #ifdef, #ifndef or #elif until the - corresponding #elif (resulting in true), #else or - #endif is read. - 2) a #else corresponding to a true #if, #ifdef, - #ifndef or #elif until the corresponding #endif is - seen. + 1) a false #if, #ifdef, #ifndef or #elif until the + corresponding #elif (resulting in true), #else or + #endif is read. + 2) a #else corresponding to a true #if, #ifdef, + #ifndef or #elif until the corresponding #endif is + seen. */ register int ch; register int skiplevel = nestlevel; /* current nesting level */ struct token tk; int toknum; - struct idf *id; + struct idf* id; NoUnstack++; - for (;;) { - ch = GetChar(); /* read first character after newline */ + for (;;) + { + ch = GetChar(); /* read first character after newline */ while (class(ch) == STSKIP) ch = GetChar(); - if (ch != '#') { - if (ch == EOI) { + if (ch != '#') + { + if (ch == EOI) + { NoUnstack--; return; } - if (ch == '/') { - if (ch != '*') UnGetChar(); - else { + if (ch == '/') + { + ch = GetChar(); + if (ch == '*') + { skipcomment(); continue; } - } else UnGetChar(); + else if (ch == '/') + { + skiplinecomment(); + continue; + } + else + UnGetChar(); + } + else + UnGetChar(); SkipToNewLine(); continue; } ReplaceMacros = 0; toknum = GetToken(&tk); ReplaceMacros = 1; - if (toknum != IDENTIFIER) { - if (toknum != INTEGER) { + if (toknum != IDENTIFIER) + { + if (toknum != INTEGER) + { error("illegal # line"); } SkipToNewLine(); continue; } /* an IDENTIFIER: look for #if, #ifdef and #ifndef - without interpreting them. - Interpret #else, #elif and #endif if they occur - on the same level. + without interpreting them. + Interpret #else, #elif and #endif if they occur + on the same level. */ id = findidf(tk.tk_str); - if (id == (struct idf *)0) { + if (id == (struct idf*)0) + { /* invalid word seen after the '#' */ warning("%s: unknown control", tk.tk_str); } free(tk.tk_str); - if (id == (struct idf *)0) continue; - switch(id->id_resmac) { - case K_DEFINE: - case K_ERROR: - case K_INCLUDE: - case K_LINE: - case K_PRAGMA: - case K_UNDEF: - case K_FILE: - SkipToNewLine(); - break; - case K_IF: - case K_IFDEF: - case K_IFNDEF: - push_if(); - SkipToNewLine(); - break; - case K_ELIF: - if (ifstack[nestlevel]) - error("#elif after #else"); - if (!to_endif && nestlevel == skiplevel) { - nestlevel--; + if (id == (struct idf*)0) + continue; + switch (id->id_resmac) + { + case K_DEFINE: + case K_ERROR: + case K_INCLUDE: + case K_LINE: + case K_PRAGMA: + case K_UNDEF: + case K_FILE: + SkipToNewLine(); + break; + case K_IF: + case K_IFDEF: + case K_IFNDEF: push_if(); - if (ifexpr()) { + SkipToNewLine(); + break; + case K_ELIF: + if (ifstack[nestlevel]) + error("#elif after #else"); + if (!to_endif && nestlevel == skiplevel) + { + nestlevel--; + push_if(); + if (ifexpr()) + { + NoUnstack--; + return; + } + } + else + SkipToNewLine(); /* otherwise done in ifexpr() */ + break; + case K_ELSE: + if (ifstack[nestlevel]) + error("#else after #else"); + ++(ifstack[nestlevel]); + if (!to_endif && nestlevel == skiplevel) + { + if (SkipToNewLine()) + { + if (!options['o']) + strict("garbage following #else"); + } NoUnstack--; return; } - } - else SkipToNewLine(); /* otherwise done in ifexpr() */ - break; - case K_ELSE: - if (ifstack[nestlevel]) - error("#else after #else"); - ++(ifstack[nestlevel]); - if (!to_endif && nestlevel == skiplevel) { - if (SkipToNewLine()) { - if (!options['o']) - strict("garbage following #else"); - } - NoUnstack--; - return; - } - else SkipToNewLine(); - break; - case K_ENDIF: - assert(nestlevel > svnestlevel[nestcount]); - if (nestlevel == skiplevel) { - if (SkipToNewLine()) { - if (!options['o']) - strict("garbage following #endif"); + else + SkipToNewLine(); + break; + case K_ENDIF: + assert(nestlevel > svnestlevel[nestcount]); + if (nestlevel == skiplevel) + { + if (SkipToNewLine()) + { + if (!options['o']) + strict("garbage following #endif"); + } + nestlevel--; + NoUnstack--; + return; } + else + SkipToNewLine(); nestlevel--; - NoUnstack--; - return; - } - else SkipToNewLine(); - nestlevel--; - break; + break; } } } - ifexpr() { /* ifexpr() returns whether the restricted constant - expression following #if or #elif evaluates to true. This - is done by calling the LLgen generated subparser for - constant expressions. The result of this expression will - be given in the extern long variable "ifval". + expression following #if or #elif evaluates to true. This + is done by calling the LLgen generated subparser for + constant expressions. The result of this expression will + be given in the extern long variable "ifval". */ extern arith ifval; int errors = err_occurred; @@ -288,8 +317,8 @@ ifexpr() ifval = (arith)0; AccDefined = 1; UnknownIdIsZero = 1; - DOT = 0; /* tricky */ - If_expr(); /* invoke constant expression parser */ + DOT = 0; /* tricky */ + If_expr(); /* invoke constant expression parser */ AccDefined = 0; UnknownIdIsZero = 0; return (errors == err_occurred) && (ifval != (arith)0); @@ -299,30 +328,37 @@ do_include() { /* do_include() performs the inclusion of a file. */ - char *filenm; - char *result; + char* filenm; + char* result; int tok; struct token tk; AccFileSpecifier = 1; if (((tok = GetToken(&tk)) == FILESPECIFIER) || tok == STRING) filenm = tk.tk_str; - else { + else + { error("bad include syntax"); - filenm = (char *)0; + filenm = (char*)0; } AccFileSpecifier = 0; - if (SkipToNewLine()) { + if (SkipToNewLine()) + { error("bad include syntax"); } inctable[0] = WorkingDir; - if (filenm) { - if (!InsertFile(filenm, &inctable[tok==FILESPECIFIER],&result)){ - if (do_preprocess) error("cannot open include file \"%s\"", filenm); - else warning("cannot open include file \"%s\"", filenm); + if (filenm) + { + if (!InsertFile(filenm, &inctable[tok == FILESPECIFIER], &result)) + { + if (do_preprocess) + error("cannot open include file \"%s\"", filenm); + else + warning("cannot open include file \"%s\"", filenm); add_dependency(filenm); } - else { + else + { add_dependency(result); WorkingDir = getwdir(result); svnestlevel[++nestcount] = nestlevel; @@ -332,41 +368,43 @@ do_include() } } -void -do_define() +void do_define() { /* do_define() interprets a #define control line. */ - register char *str; /* the #defined identifier's descriptor */ - int nformals = -1; /* keep track of the number of formals */ - char *formals[NPARAMS]; /* pointers to the names of the formals */ - char parbuf[PARBUFSIZE]; /* names of formals */ - char *repl_text; /* start of the replacement text */ - int length; /* length of the replacement text */ + register char* str; /* the #defined identifier's descriptor */ + int nformals = -1; /* keep track of the number of formals */ + char* formals[NPARAMS]; /* pointers to the names of the formals */ + char parbuf[PARBUFSIZE]; /* names of formals */ + char* repl_text; /* start of the replacement text */ + int length; /* length of the replacement text */ register ch; - char *get_text(); + char* get_text(); /* read the #defined macro's name */ - if (!(str = GetIdentifier(1))) { + if (!(str = GetIdentifier(1))) + { error("#define: illegal macro name"); return; } /* there is a formal parameter list if the identifier is - followed immediately by a '('. + followed immediately by a '('. */ ch = GetChar(); - if (ch == '(') { - if ((nformals = getparams(formals, parbuf)) == -1) { + if (ch == '(') + { + if ((nformals = getparams(formals, parbuf)) == -1) + { SkipToNewLine(); free(str); - return; /* an error occurred */ + return; /* an error occurred */ } ch = GetChar(); } /* read the replacement text if there is any */ - ch = skipspaces(ch,0); /* find first character of the text */ + ch = skipspaces(ch, 0); /* find first character of the text */ assert(ch != EOI); - /* UnGetChar() is not right when replacement starts with a '/' */ + /* UnGetChar() is not right when replacement starts with a '/' */ ChPushBack(ch); repl_text = get_text((nformals > 0) ? formals : 0, &length); macro_def(str2idf(str, 0), repl_text, nformals, length, NOFLAG); @@ -383,12 +421,15 @@ push_if() do_elif() { - if (nestlevel <= svnestlevel[nestcount]) { + if (nestlevel <= svnestlevel[nestcount]) + { error("#elif without corresponding #if"); SkipToNewLine(); } - else { /* restart at this level as if a #if is detected. */ - if (ifstack[nestlevel]) { + else + { /* restart at this level as if a #if is detected. */ + if (ifstack[nestlevel]) + { error("#elif after #else"); SkipToNewLine(); } @@ -400,14 +441,17 @@ do_elif() do_else() { - if (SkipToNewLine()) { + if (SkipToNewLine()) + { if (!options['o']) strict("garbage following #else"); } if (nestlevel <= svnestlevel[nestcount]) error("#else without corresponding #if"); - else { /* mark this level as else-d */ - if (ifstack[nestlevel]) { + else + { /* mark this level as else-d */ + if (ifstack[nestlevel]) + { error("#else after #else"); } ++(ifstack[nestlevel]); @@ -417,72 +461,84 @@ do_else() do_endif() { - if (SkipToNewLine()) { + if (SkipToNewLine()) + { if (!options['o']) strict("garbage following #endif"); } - if (nestlevel <= svnestlevel[nestcount]) { + if (nestlevel <= svnestlevel[nestcount]) + { error("#endif without corresponding #if"); } - else nestlevel--; + else + nestlevel--; } do_if() { push_if(); - if (!ifexpr()) /* a false #if/#elif expression */ + if (!ifexpr()) /* a false #if/#elif expression */ skip_block(0); } do_ifdef(how) { - register struct idf *id; - register char *str; + register struct idf* id; + register char* str; /* how == 1 : ifdef; how == 0 : ifndef */ push_if(); - if (!(str = GetIdentifier(1))) { + if (!(str = GetIdentifier(1))) + { error("illegal #ifdef construction"); - id = (struct idf *)0; - } else { + id = (struct idf*)0; + } + else + { id = findidf(str); free(str); } - if (SkipToNewLine()) { + if (SkipToNewLine()) + { if (str && !options['o']) - strict("garbage following #%s ", - how ? "ifdef" : "ifndef"); + strict("garbage following #%s ", how ? "ifdef" : "ifndef"); } /* The next test is a shorthand for: - (how && !id->id_macro) || (!how && id->id_macro) + (how && !id->id_macro) || (!how && id->id_macro) */ if (how ^ (id && id->id_macro != 0)) skip_block(0); } /* argstr != NULL when the undef came from a -U option */ -do_undef(argstr) - char *argstr; +do_undef(argstr) char* argstr; { - register struct idf *id; - register char *str = argstr; + register struct idf* id; + register char* str = argstr; /* Forget a macro definition. */ - if (str || (str = GetIdentifier(1))) { - if ((id = findidf(str)) && id->id_macro) { - if (id->id_macro->mc_flag & NOUNDEF) { + if (str || (str = GetIdentifier(1))) + { + if ((id = findidf(str)) && id->id_macro) + { + if (id->id_macro->mc_flag & NOUNDEF) + { error("it is not allowed to #undef %s", str); - } else { + } + else + { free(id->id_macro->mc_text); free_macro(id->id_macro); - id->id_macro = (struct macro *) 0; + id->id_macro = (struct macro*)0; } } /* else: don't complain */ - if (!argstr){ + if (!argstr) + { free(str); - if (SkipToNewLine()) { + if (SkipToNewLine()) + { if (!options['o']) strict("garbage following #undef"); } @@ -495,106 +551,117 @@ do_undef(argstr) do_error() { int len; - char *get_text(); - char *bp = get_text((char **) 0, &len); + char* get_text(); + char* bp = get_text((char**)0, &len); error("user error: %s", bp); free(bp); LineNumber++; } -int -getparams(buf, parbuf) - char *buf[]; - char parbuf[]; +int getparams(buf, parbuf) char* buf[]; +char parbuf[]; { /* getparams() reads the formal parameter list of a macro - definition. - The number of parameters is returned. - As a formal parameter list is expected when calling this - routine, -1 is returned if an error is detected, for - example: - #define one(1), where 1 is not an identifier. - Note that the '(' has already been eaten. - The names of the formal parameters are stored into parbuf. + definition. + The number of parameters is returned. + As a formal parameter list is expected when calling this + routine, -1 is returned if an error is detected, for + example: + #define one(1), where 1 is not an identifier. + Note that the '(' has already been eaten. + The names of the formal parameters are stored into parbuf. */ - register char **pbuf = &buf[0]; + register char** pbuf = &buf[0]; register int c; - register char *ptr = &parbuf[0]; - register char **pbuf2; + register char* ptr = &parbuf[0]; + register char** pbuf2; c = GetChar(); - c = skipspaces(c,0); - if (c == ')') { /* no parameters: #define name() */ - *pbuf = (char *) 0; + c = skipspaces(c, 0); + if (c == ')') + { /* no parameters: #define name() */ + *pbuf = (char*)0; return 0; } - for (;;) { /* eat the formal parameter list */ - if (class(c) != STIDF && class(c) != STELL) { + for (;;) + { /* eat the formal parameter list */ + if (class(c) != STIDF && class(c) != STELL) + { error("#define: bad formal parameter"); return -1; } - *pbuf = ptr; /* name of the formal */ + *pbuf = ptr; /* name of the formal */ *ptr++ = c; if (ptr >= &parbuf[PARBUFSIZE]) fatal("formal parameter buffer overflow"); - do { /* eat the identifier name */ + do + { /* eat the identifier name */ c = GetChar(); *ptr++ = c; if (ptr >= &parbuf[PARBUFSIZE]) fatal("formal parameter buffer overflow"); } 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 ... + 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); + for (pbuf2 = pbuf - 1; pbuf2 >= &buf[0]; pbuf2--) + { + if (!strcmp(*pbuf2, *pbuf)) + { + warning("formal parameter \"%s\" already used", *pbuf); } } pbuf++; - c = skipspaces(c,0); - if (c == ')') { /* end of the formal parameter list */ - *pbuf = (char *) 0; + c = skipspaces(c, 0); + if (c == ')') + { /* end of the formal parameter list */ + *pbuf = (char*)0; return pbuf - buf; } - if (c != ',') { + if (c != ',') + { error("#define: bad formal parameter list"); return -1; } c = GetChar(); - c = skipspaces(c,0); + c = skipspaces(c, 0); } /*NOTREACHED*/ } -void -macro_def(id, text, nformals, length, flags) - register struct idf *id; - char *text; +void macro_def(id, text, nformals, length, flags) register struct idf* id; +char* text; { - register struct macro *newdef = id->id_macro; + register struct macro* newdef = id->id_macro; /* 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. - An error is given if there was already a definition + definition into a structure and stores it into the symbol + table entry belonging to the name of the macro. + An error is given if there was already a definition */ - if (newdef) { /* is there a redefinition? */ - if (newdef->mc_flag & NOUNDEF) { + if (newdef) + { /* is there a redefinition? */ + if (newdef->mc_flag & NOUNDEF) + { error("it is not allowed to redefine %s", id->id_text); - } else if (!macroeq(newdef->mc_text, text)) + } + else if (!macroeq(newdef->mc_text, text)) error("illegal redefine of \"%s\"", id->id_text); free(text); return; - } else { + } + else + { #ifdef DOBITS - register char *p = id->id_text; -#define setbit(bx) if (!*p) goto go_on; bits[*p++] |= (bx) + register char* p = id->id_text; +#define setbit(bx) \ + if (!*p) \ + goto go_on; \ + bits[*p++] |= (bx) setbit(bit0); setbit(bit1); setbit(bit2); @@ -608,21 +675,19 @@ macro_def(id, text, nformals, length, flags) #endif id->id_macro = newdef = new_macro(); } - newdef->mc_text = text; /* replacement text */ - newdef->mc_nps = nformals; /* nr of formals */ - newdef->mc_length = length; /* length of repl. text */ - newdef->mc_flag = flags; /* special flags */ + newdef->mc_text = text; /* replacement text */ + newdef->mc_nps = nformals; /* nr of formals */ + newdef->mc_length = length; /* length of repl. text */ + newdef->mc_flag = flags; /* special flags */ } -int -find_name(nm, index) - char *nm, *index[]; +int find_name(nm, index) char *nm, *index[]; { /* find_name() returns the index of "nm" in the namelist - "index" if it can be found there. 0 is returned if it is - not there. + "index" if it can be found there. 0 is returned if it is + not there. */ - register char **ip = &index[0]; + register char** ip = &index[0]; while (*ip) if (strcmp(nm, *ip++) == 0) @@ -631,135 +696,167 @@ find_name(nm, index) return 0; } -#define BLANK(ch) ((ch == ' ') || (ch == '\t')) +#define BLANK(ch) ((ch == ' ') || (ch == '\t')) -char * -get_text(formals, length) - char *formals[]; - int *length; +char* get_text(formals, length) char* formals[]; +int* length; { /* get_text() copies the replacement text of a macro - definition with zero, one or more parameters, thereby - substituting each formal parameter by a special character - (non-ascii: 0200 & (order-number in the formal parameter - list)) in order to substitute this character later by the - actual parameter. The replacement text is copied into - itself because the copied text will contain fewer or the - same amount of characters. The length of the replacement - text is returned. + definition with zero, one or more parameters, thereby + substituting each formal parameter by a special character + (non-ascii: 0200 & (order-number in the formal parameter + list)) in order to substitute this character later by the + actual parameter. The replacement text is copied into + itself because the copied text will contain fewer or the + same amount of characters. The length of the replacement + text is returned. - Implementation: - finite automaton : we are interested in - 1- white space, sequences must be mapped onto 1 single - blank. - 2- identifiers, since they might be replaced by some - actual parameter. - 3- strings and character constants, since replacing - variables within them is illegal, and white-space is - significant. - 4- comment, same as for 1 - Other tokens will not be seen as such. + Implementation: + finite automaton : we are interested in + 1- white space, sequences must be mapped onto 1 single + blank. + 2- identifiers, since they might be replaced by some + actual parameter. + 3- strings and character constants, since replacing + variables within them is illegal, and white-space is + significant. + 4- comment, same as for 1 + Other tokens will not be seen as such. */ register int c; struct repl repls; - register struct repl *repl = &repls; + register struct repl* repl = &repls; int blank = 0; c = GetChar(); repl->r_ptr = repl->r_text = Malloc((unsigned)(repl->r_size = ITEXTSIZE)); *repl->r_ptr = '\0'; - while ((c != EOI) && (class(c) != STNL)) { - if (BLANK(c)) { + while ((c != EOI) && (class(c) != STNL)) + { + if (BLANK(c)) + { blank++; c = GetChar(); continue; } - if (c == '\'' || c == '"') { + if (c == '\'' || c == '"') + { register int delim = c; - if (blank) { + if (blank) + { blank = 0; add2repl(repl, ' '); } - do { + do + { add2repl(repl, c); - if (c == '\\') add2repl(repl, GetChar()); + if (c == '\\') + add2repl(repl, GetChar()); c = GetChar(); } while (c != delim && c != EOI && class(c) != STNL); - if (c != delim) { + if (c != delim) + { strict("unclosed opening %c", delim); break; } add2repl(repl, c); c = GetChar(); - } else if (c == '/') { + } + else if (c == '/') + { c = GetChar(); - if (c == '*') { + if (c == '*') + { skipcomment(); blank++; c = GetChar(); continue; - } - if (blank) { + } + else if (c == '/') + { + skiplinecomment(); + blank++; + c = GetChar(); + continue; + } + if (blank) + { blank = 0; add2repl(repl, ' '); } add2repl(repl, '/'); - } else if (formals - && (class(c) == STIDF || class(c) == STELL)) { + } + else if (formals && (class(c) == STIDF || class(c) == STELL)) + { char id_buf[IDFSIZE + 1]; - register char *idp = id_buf; + register char* idp = id_buf; int n; /* read identifier: it may be a formal parameter */ *idp++ = c; - do { + do + { c = GetChar(); if (idp <= &id_buf[IDFSIZE]) *idp++ = c; } while (in_idf(c)); *--idp = '\0'; - if (blank) { + if (blank) + { blank = 0; add2repl(repl, ' '); } /* construct the formal parameter mark or identifier */ if (n = find_name(id_buf, formals)) - add2repl(repl, FORMALP | (char) n); - else { + add2repl(repl, FORMALP | (char)n); + else + { idp = id_buf; - while (*idp) add2repl(repl, *idp++); + while (*idp) + add2repl(repl, *idp++); } - } else if (class(c) == STNUM) { - if (blank) { + } + else if (class(c) == STNUM) + { + if (blank) + { blank = 0; add2repl(repl, ' '); } add2repl(repl, c); - if (c == '.') { + if (c == '.') + { c = GetChar(); - if (class(c) != STNUM) { + if (class(c) != STNUM) + { continue; } add2repl(repl, c); } c = GetChar(); - while(in_idf(c) || c == '.') { + while (in_idf(c) || c == '.') + { add2repl(repl, c); - if((c = GetChar()) == 'e' || c == 'E') { + if ((c = GetChar()) == 'e' || c == 'E') + { add2repl(repl, c); c = GetChar(); - if (c == '+' || c == '-') { + if (c == '+' || c == '-') + { add2repl(repl, c); c = GetChar(); } } } - } else { - if (blank) { + } + else + { + if (blank) + { blank = 0; add2repl(repl, ' '); } @@ -768,45 +865,51 @@ get_text(formals, length) } } *length = repl->r_ptr - repl->r_text; - return Realloc(repl->r_text, (unsigned)(repl->r_ptr - repl->r_text +1)); + return Realloc(repl->r_text, (unsigned)(repl->r_ptr - repl->r_text + 1)); } /* macroeq() decides whether two macro replacement texts are - identical. This version compares the texts, which occur - as strings, without taking care of the leading and trailing - blanks (spaces and tabs). + identical. This version compares the texts, which occur + as strings, without taking care of the leading and trailing + blanks (spaces and tabs). */ -macroeq(s, t) - register char *s, *t; +macroeq(s, t) register char* s, *t; { - + /* skip leading spaces */ - while (BLANK(*s)) s++; - while (BLANK(*t)) t++; + while (BLANK(*s)) + s++; + while (BLANK(*t)) + t++; /* first non-blank encountered in both strings */ /* The actual comparison loop: */ while (*s && *s == *t) s++, t++; /* two cases are possible when arrived here: */ - if (*s == '\0') { /* *s == '\0' */ - while (BLANK(*t)) t++; + if (*s == '\0') + { /* *s == '\0' */ + while (BLANK(*t)) + t++; return *t == '\0'; } - else { /* *s != *t */ - while (BLANK(*s)) s++; - while (BLANK(*t)) t++; + else + { /* *s != *t */ + while (BLANK(*s)) + s++; + while (BLANK(*t)) + t++; return (*s == '\0') && (*t == '\0'); } } -do_line(l) - unsigned int l; +do_line(l) unsigned int l; { struct token tk; int t = GetToken(&tk); - if (t != EOF) SkipToNewLine(); - LineNumber = l; /* the number of the next input line */ - if (t == STRING) /* is there a filespecifier? */ + if (t != EOF) + SkipToNewLine(); + LineNumber = l; /* the number of the next input line */ + if (t == STRING) /* is there a filespecifier? */ FileName = tk.tk_str; } diff --git a/lang/cem/cpp.ansi/preprocess.c b/lang/cem/cpp.ansi/preprocess.c index 3d26b18e0..ed8119cf5 100644 --- a/lang/cem/cpp.ansi/preprocess.c +++ b/lang/cem/cpp.ansi/preprocess.c @@ -5,92 +5,113 @@ /* $Id$ */ /* PREPROCESSOR DRIVER */ -#include -#include -#include -#include -#include "input.h" -#include "parameters.h" -#include "arith.h" -#include "LLlex.h" -#include "class.h" -#include "macro.h" -#include "idf.h" -#include "bits.h" +#include +#include +#include +#include +#include "input.h" +#include "parameters.h" +#include "arith.h" +#include "LLlex.h" +#include "class.h" +#include "macro.h" +#include "idf.h" +#include "bits.h" -char _obuf[OBUFSIZE]; +char _obuf[OBUFSIZE]; #ifdef DOBITS -char bits[128]; +char bits[128]; #endif extern int InputLevel; -extern char *sprint(); +extern char* sprint(); Xflush() { sys_write(STDOUT, _obuf, OBUFSIZE); } -static char *SkipComment(); +static char* SkipComment(); extern char options[]; /* #pragma directives are saved here and passed to the compiler later on. */ -struct prag_info { - int pr_linnr; - char *pr_fil; - char *pr_text; +struct prag_info +{ + int pr_linnr; + char* pr_fil; + char* pr_text; }; -static struct prag_info *pragma_tab; +static struct prag_info* pragma_tab; static int pragma_nr; do_pragma() { register int size = ITEXTSIZE; - char *cur_line = Malloc((unsigned)size); - register char *c_ptr = cur_line; + char* cur_line = Malloc((unsigned)size); + register char* c_ptr = cur_line; register int c = GetChar(); register int delim = 0; - while(c != '\n') { - if (c_ptr + 1 - cur_line == size) { + while (c != '\n') + { + if (c_ptr + 1 - cur_line == size) + { cur_line = Realloc(cur_line, (unsigned)(size + ITEXTSIZE)); c_ptr = cur_line + size - 1; size += ITEXTSIZE; } - if (delim) { - if (c == delim) { + if (delim) + { + if (c == delim) + { delim = 0; } - else if (c == '\\') { + else if (c == '\\') + { *c_ptr++ = c; c = GetChar(); - if (c == '\n') break; + if (c == '\n') + break; } } - else if (c == '\'' || c == '"') { + else if (c == '\'' || c == '"') + { delim = c; } - else if (c == '/') { - if ((c = GetChar()) != '*' || InputLevel) { + else if (c == '/') + { + if (!InputLevel) + { + c = GetChar(); + if (c == '*') + { + skipcomment(); + continue; + } + else if (c == '/') + { + skiplinecomment(); + continue; + } *c_ptr++ = '/'; } - else { - skipcomment(); - continue; - } } *c_ptr++ = c; c = GetChar(); } *c_ptr = '\0'; - if (!pragma_nr) { - pragma_tab = (struct prag_info *)Malloc(sizeof(struct prag_info)); - } else { - pragma_tab = (struct prag_info *)Realloc((char *)pragma_tab - , (unsigned)(sizeof(struct prag_info) * (pragma_nr+1))); + if (!pragma_nr) + { + pragma_tab = (struct prag_info*)Malloc(sizeof(struct prag_info)); } - if (delim) { + else + { + pragma_tab = (struct prag_info*)Realloc( + (char*)pragma_tab, (unsigned)(sizeof(struct prag_info) * (pragma_nr + 1))); + } + if (delim) + { error("unclosed opening %c", delim); } pragma_tab[pragma_nr].pr_linnr = LineNumber; @@ -102,138 +123,188 @@ do_pragma() char Xbuf[256]; -void -preprocess(fn) - char *fn; +void preprocess(fn) char* fn; { register int c; - register char *op = _obuf; - register char *ob = &_obuf[OBUFSIZE]; + register char* op = _obuf; + register char* ob = &_obuf[OBUFSIZE]; int lineno = 0; int startline; -#define flush(X) (sys_write(STDOUT,_obuf,X)) -#define echo(ch) if (op == ob) { Xflush(); op = _obuf; } *op++ = (ch); -#define newline() op--; while (op >= _obuf && (*op == ' ' || *op == '\t')) op--; op++; echo('\n') +#define flush(X) (sys_write(STDOUT, _obuf, X)) +#define echo(ch) \ + if (op == ob) \ + { \ + Xflush(); \ + op = _obuf; \ + } \ + *op++ = (ch); +#define newline() \ + op--; \ + while (op >= _obuf && (*op == ' ' || *op == '\t')) \ + op--; \ + op++; \ + echo('\n') - if (!options['P']) { + if (!options['P']) + { /* Generate a line directive communicating the source filename */ - register char *p = Xbuf; + register char* p = Xbuf; - sprint(p, "%s 1 \"%s\"\n", - LINE_PREFIX, - FileName); - while (*p) { + sprint(p, "%s 1 \"%s\"\n", LINE_PREFIX, FileName); + while (*p) + { echo(*p++); } } -#define do_line_dir(lineno, fn) \ - if (lineno != LineNumber || fn != FileName) { \ - fn = FileName; \ - lineno = LineNumber; \ - if (! options['P']) { \ - register char *p = Xbuf; \ - sprint(Xbuf, "%s %d \"%s\"\n", \ - LINE_PREFIX, \ - (int)LineNumber, \ - FileName); \ - op--; \ - while (op >= _obuf \ - && (class(*op) == STSKIP \ - || *op == '\n')) op--; \ - op++; \ - newline(); \ - while (*p) { \ - echo(*p++); \ - } \ - } \ - } +#define do_line_dir(lineno, fn) \ + if (lineno != LineNumber || fn != FileName) \ + { \ + fn = FileName; \ + lineno = LineNumber; \ + if (!options['P']) \ + { \ + register char* p = Xbuf; \ + sprint(Xbuf, "%s %d \"%s\"\n", LINE_PREFIX, (int)LineNumber, FileName); \ + op--; \ + while (op >= _obuf && (class(*op) == STSKIP || *op == '\n')) \ + op--; \ + op++; \ + newline(); \ + while (*p) \ + { \ + echo(*p++); \ + } \ + } \ + } - for (;;) { + for (;;) + { LineNumber++; lineno++; startline = 1; c = GetChar(); - while (startline) { - /* first flush the saved pragma's */ - if (pragma_nr) { + while (startline) + { + /* first flush the saved pragma's */ + if (pragma_nr) + { register int i = 0; int LiNo = LineNumber; - char *FiNam = FileName; - - while (i < pragma_nr) { - register char *c_ptr = "#pragma"; - - LineNumber = pragma_tab[i].pr_linnr; - FileName = pragma_tab[i].pr_fil; - do_line_dir(lineno, fn); - while (*c_ptr) { echo(*c_ptr++); } - c_ptr = pragma_tab[i].pr_text; - while (*c_ptr) { echo(*c_ptr++); } - newline(); lineno++; - free(pragma_tab[i].pr_text); - i++; + char* FiNam = FileName; + + while (i < pragma_nr) + { + register char* c_ptr = "#pragma"; + + LineNumber = pragma_tab[i].pr_linnr; + FileName = pragma_tab[i].pr_fil; + do_line_dir(lineno, fn); + while (*c_ptr) + { + echo(*c_ptr++); + } + c_ptr = pragma_tab[i].pr_text; + while (*c_ptr) + { + echo(*c_ptr++); + } + newline(); + lineno++; + free(pragma_tab[i].pr_text); + i++; } - free((char *) pragma_tab); - pragma_tab = (struct prag_info *)0; + free((char*)pragma_tab); + pragma_tab = (struct prag_info*)0; pragma_nr = 0; LineNumber = LiNo; FileName = FiNam; do_line_dir(lineno, fn); - } + } - - while (class(c) == STSKIP || c == '/') { - if (c == '/') { - if (!InputLevel) { - c = GetChar(); - if (c == '*') { - op = SkipComment(op, &lineno); - if (!op) return; - if (!options['C']) { echo(' '); } - c = GetChar(); - continue; + while (class(c) == STSKIP || c == '/') + { + if (c == '/') + { + if (!InputLevel) + { + c = GetChar(); + if (c == '*') + { + op = SkipComment(op, &lineno); + if (!op) + return; + if (!options['C']) + { + echo(' '); + } + c = GetChar(); + continue; + } + else if (c == '/') + { + skiplinecomment(); + c = GetChar(); + continue; + } + UnGetChar(); + c = '/'; } - UnGetChar(); - c = '/'; - } - break; + break; } echo(c); c = GetChar(); - } + } - if (c == '#') { + if (c == '#') + { domacro(); lineno++; newline(); do_line_dir(lineno, fn); c = GetChar(); - } else startline = 0; + } + else + startline = 0; } do_line_dir(lineno, fn); - for (;;) { + for (;;) + { /* illegal character */ - if (c & 0200) { - if (c == EOI) { + if (c & 0200) + { + if (c == EOI) + { newline(); - flush((int)(op-_obuf)); + flush((int)(op - _obuf)); return; } fatal("non-ascii character read"); } /* comments */ - if (c == '/' && !InputLevel) { + if (c == '/' && !InputLevel) + { c = GetChar(); - if (c == '*') { + if (c == '*') + { op = SkipComment(op, &lineno); - if (!op) return; - if (!options['C']) { echo(' '); } + if (!op) + return; + if (!options['C']) + { + echo(' '); + } + c = GetChar(); + continue; + } + else if (c == '/') + { + skiplinecomment(); c = GetChar(); continue; } @@ -242,164 +313,221 @@ preprocess(fn) } /* switch on character */ - switch(class(c)) { - case STNL: - newline(); - break; - case STSTR: - case STCHAR: + switch (class(c)) + { + case STNL: + newline(); + break; + case STSTR: + case STCHAR: { - register int stopc = c; - int escaped; + register int stopc = c; + int escaped; - do { - escaped = 0; - echo(c); - c = GetChar(); - if (c == '\n') { - /* the compiler will complain */ - break; - } - else if (c == EOI) { - newline(); - flush((int)(op-_obuf)); - return; - } - if (c == '\\') { + do + { + escaped = 0; echo(c); c = GetChar(); - if (c == '\n') { - ++LineNumber; - lineno++; - } else escaped = 1; - } - } while (escaped || c != stopc); - echo(c); - if (c == '\n') - break; /* Don't eat # */ - c = GetChar(); - continue; - } - case STNUM: - /* The following code is quit ugly. This because - * ..3 == . .3 , whereas ...3 == ... 3 - */ - echo(c); - if (c == '.') { + if (c == '\n') + { + /* the compiler will complain */ + break; + } + else if (c == EOI) + { + newline(); + flush((int)(op - _obuf)); + return; + } + if (c == '\\') + { + echo(c); + c = GetChar(); + if (c == '\n') + { + ++LineNumber; + lineno++; + } + else + escaped = 1; + } + } while (escaped || c != stopc); + echo(c); + if (c == '\n') + break; /* Don't eat # */ c = GetChar(); - if (c == '.') { - if ((c = GetChar()) == '.') { - echo('.'); echo('.'); + continue; + } + case STNUM: + /* The following code is quit ugly. This because + * ..3 == . .3 , whereas ...3 == ... 3 + */ + echo(c); + if (c == '.') + { + c = GetChar(); + if (c == '.') + { + if ((c = GetChar()) == '.') + { + echo('.'); + echo('.'); + c = GetChar(); + continue; + } + UnGetChar(); + c = '.'; + continue; + } + else if (!is_dig(c)) + { + continue; + } + else + { + echo(c); + } + } + c = GetChar(); + while (in_idf(c) || c == '.') + { + echo(c); + if (c == 'e' || c == 'E') + { + c = GetChar(); + if (c == '+' || c == '-') + { + echo(c); + c = GetChar(); + } + } + else + c = GetChar(); + } + continue; + case STELL: + c = GetChar(); + UnGetChar(); + if (c == '"' || c == '\'') + { + echo('L'); + continue; + } + c = 'L'; + case STIDF: + { + extern int idfsize; /* ??? */ + char buf[IDFSIZE + 1]; + register char* tg = &buf[0]; + register char* maxpos = &buf[idfsize]; + register struct idf* idef; + int NoExpandNext = 0; + +#define tstmac(bx) \ + if (!(bits[c] & bx)) \ + goto nomac +#define cpy *tg++ = c +#define load \ + c = GetChar(); \ + if (!in_idf(c)) \ + goto endidf + + /* unstack macro's when allowed. */ + if (Unstacked) + EnableMacros(); + if (c == NOEXPM) + { + NoExpandNext = 1; + c = GetChar(); + } + +#ifdef DOBITS + cpy; + tstmac(bit0); + load; + cpy; + tstmac(bit1); + load; + cpy; + tstmac(bit2); + load; + cpy; + tstmac(bit3); + load; + cpy; + tstmac(bit4); + load; + cpy; + tstmac(bit5); + load; + cpy; + tstmac(bit6); + load; + cpy; + tstmac(bit7); + load; +#endif + + for (;;) + { + if (tg < maxpos) + { + cpy; + } + load; + } + endidf: + if (c != EOF) + UnGetChar(); + *tg = '\0'; /* mark the end of the identifier */ + if ((idef = findidf(buf)) && idef->id_macro && ReplaceMacros && !NoExpandNext) + { + if (replace(idef)) + { + echo(' '); c = GetChar(); continue; } - UnGetChar(); - c = '.'; - continue; - } else if (!is_dig(c)) { - continue; - } else { echo(c); } - } - c = GetChar(); - while (in_idf(c) || c == '.') { - echo(c); - if (c == 'e' || c == 'E') { - c = GetChar(); - if (c == '+' || c == '-') { - echo(c); - c = GetChar(); + tg = buf; + while (*tg) + { + echo(*tg++); } - } else c = GetChar(); - } - continue; - case STELL: - c = GetChar(); - UnGetChar(); - if (c == '"' || c == '\'') { - echo('L'); - continue; - } - c = 'L'; - case STIDF: { - extern int idfsize; /* ??? */ - char buf[IDFSIZE + 1]; - register char *tg = &buf[0]; - register char *maxpos = &buf[idfsize]; - register struct idf *idef; - int NoExpandNext = 0; - -#define tstmac(bx) if (!(bits[c] & bx)) goto nomac -#define cpy *tg++ = c -#define load c = GetChar(); if (!in_idf(c)) goto endidf - - /* unstack macro's when allowed. */ - if (Unstacked) - EnableMacros(); - if (c == NOEXPM) { - NoExpandNext = 1; - c = GetChar(); - } - -#ifdef DOBITS - cpy; tstmac(bit0); load; - cpy; tstmac(bit1); load; - cpy; tstmac(bit2); load; - cpy; tstmac(bit3); load; - cpy; tstmac(bit4); load; - cpy; tstmac(bit5); load; - cpy; tstmac(bit6); load; - cpy; tstmac(bit7); load; -#endif - - for(;;) { - if (tg < maxpos) { - cpy; - } - load; - } - endidf: - if (c != EOF) UnGetChar(); - *tg = '\0'; /* mark the end of the identifier */ - if ((idef = findidf(buf)) - && idef->id_macro - && ReplaceMacros && !NoExpandNext) { - if (replace(idef)) { - echo(' '); c = GetChar(); + if (in_idf(c)) + { + echo(' '); + } continue; } + nomac: + *tg = '\0'; tg = buf; - while (*tg) { + while (*tg) + { echo(*tg++); } c = GetChar(); - if (in_idf(c)) { echo(' '); } + while (in_idf(c)) + { + echo(c); + c = GetChar(); + } continue; } - nomac: - *tg = '\0'; - tg = buf; - while (*tg) { - echo(*tg++); - } - c = GetChar(); - while (in_idf(c)) { + case STMSPEC: + if (InputLevel) + { + echo(' '); /* seperate tokens */ + c = GetChar(); + continue; + } + /* else fallthrough */ + default: echo(c); c = GetChar(); - } - continue; - } - case STMSPEC: - if (InputLevel) { - echo(' '); /* seperate tokens */ - c = GetChar(); continue; - } - /* else fallthrough */ - default: - echo(c); - c = GetChar(); - continue; } break; } @@ -407,49 +535,60 @@ preprocess(fn) /*NOTREACHED*/ } -static char * -SkipComment(op, lineno) -char *op; -int *lineno; +static char* SkipComment(op, lineno) char* op; +int* lineno; { - char *ob = &_obuf[OBUFSIZE]; + char* ob = &_obuf[OBUFSIZE]; register int c, oldc = '\0'; NoUnstack++; - if (options['C']) { + if (options['C']) + { echo('/'); echo('*'); } c = GetChar(); - for(;;) { - if (c == EOI) { + for (;;) + { + if (c == EOI) + { newline(); flush((int)(op - _obuf)); op = 0; break; } - if (options['C']) { + if (options['C']) + { echo(c); } - if (c == '\n') { + if (c == '\n') + { ++LineNumber; ++*lineno; - if (!options['C']) { + if (!options['C']) + { echo(c); } } - if (c == '*') { + if (c == '*') + { c = GetChar(); - if (c == '/') { - if (options['C']) { + if (c == '/') + { + if (options['C']) + { echo(c); } - break; /* for(;;) */ - } else if (oldc == '/') { + break; /* for(;;) */ + } + else if (oldc == '/') + { warning("comment inside comment ?"); } oldc = '*'; - } else { + } + else + { oldc = c; c = GetChar(); } diff --git a/lang/cem/cpp.ansi/skip.c b/lang/cem/cpp.ansi/skip.c index e9990ced2..1783562bb 100644 --- a/lang/cem/cpp.ansi/skip.c +++ b/lang/cem/cpp.ansi/skip.c @@ -5,53 +5,64 @@ /* $Id$ */ /* PREPROCESSOR: INPUT SKIP FUNCTIONS */ -#include "arith.h" -#include "LLlex.h" -#include "class.h" -#include "input.h" +#include "arith.h" +#include "LLlex.h" +#include "class.h" +#include "input.h" extern int InputLevel; -int -skipspaces(ch, skipnl) - register int ch; +int skipspaces(ch, skipnl) register int ch; { /* skipspaces() skips any white space and returns the first - non-space character. + non-space character. */ register int nlseen = 0; - for (;;) { + for (;;) + { while (class(ch) == STSKIP) ch = GetChar(); - if (skipnl && class(ch) == STNL) { + if (skipnl && class(ch) == STNL) + { ch = GetChar(); LineNumber++; nlseen++; continue; } - if (ch == TOKSEP && InputLevel) { + if (ch == TOKSEP && InputLevel) + { ch = GetChar(); continue; } /* \\\n are handled by trigraph */ - if (ch == '/') { + if (ch == '/') + { ch = GetChar(); - if (ch == '*' && !InputLevel) { + if (ch == '*' && !InputLevel) + { skipcomment(); ch = GetChar(); } - else { + else if (ch == '/' && !InputLevel) + { + skiplinecomment(); + ch = GetChar(); + } + else + { UnGetChar(); return '/'; } } - else if (nlseen && ch == '#') { + else if (nlseen && ch == '#') + { domacro(); ch = GetChar(); - } else + } + else return ch; } } @@ -62,31 +73,54 @@ SkipToNewLine() register int garbage = 0; register int delim = 0; - while ((ch = GetChar()) != '\n') { - if (delim) { - if (ch == '\\') { - if (GetChar() == '\n') break; - } else if (ch == delim) { + while ((ch = GetChar()) != '\n') + { + if (delim) + { + if (ch == '\\') + { + if (GetChar() == '\n') + break; + } + else if (ch == delim) + { delim = 0; } continue; - } else if (ch == '\'' || ch == '\"') { + } + else if (ch == '\'' || ch == '\"') + { delim = ch; garbage = 1; - } else if (ch == '/') { - if (GetChar() == '*' && !InputLevel) { - skipcomment(); - continue; - } - else UnGetChar(); } - else if (ch == TOKSEP && InputLevel) { + else if (ch == '/') + { + if (!InputLevel) + { + int nch = GetChar(); + if (nch == '*') + { + skipcomment(); + continue; + } + else if (nch == '/') + { + skiplinecomment(); + continue; + } + else + UnGetChar(); + } + } + else if (ch == TOKSEP && InputLevel) + { continue; } if (!is_wsp(ch)) garbage = 1; } - if (delim) strict("unclosed opening %c", delim); + if (delim) + strict("unclosed opening %c", delim); ++LineNumber; return garbage; } diff --git a/lang/cem/libcc.ansi/sys/exit/exit.c b/lang/cem/libcc.ansi/sys/exit/exit.c index 7f861321f..d16db6c3b 100644 --- a/lang/cem/libcc.ansi/sys/exit/exit.c +++ b/lang/cem/libcc.ansi/sys/exit/exit.c @@ -15,8 +15,8 @@ int __funccnt = 0; void exit(int status) { /* "Called in reversed order of their registration" */ - while (__funccnt >= 0) - (*__functab[__funccnt])(); + while (__funccnt) + (*__functab[--__funccnt])(); _exit(status); } diff --git a/lib/descr/fe b/lib/descr/fe index 189701c96..673270c2d 100644 --- a/lib/descr/fe +++ b/lib/descr/fe @@ -72,18 +72,8 @@ name cem mapflag -V* CEM_F={CEM_F?} -V* rts .c need .c + prep always args \ - {CPP_F?} \ - -D__{ARCH} -D__{PLATFORM} \ - -D__ACK \ - {SYSINCLUDES?} \ - {C_INCLUDES} \ - {INCLUDES?} \ - ({ANSI_C?.xx}:.xx=-D{ARCH} \ - -DEM_WSIZE={w} -DEM_PSIZE={p} \ - -DEM_SSIZE={s} -DEM_LSIZE={l} -DEM_FSIZE={f} -DEM_DSIZE={d}) \ - -D_EM_WSIZE={w} -D_EM_PSIZE={p} \ - -D_EM_SSIZE={s} -D_EM_LSIZE={l} -D_EM_FSIZE={f} -D_EM_DSIZE={d} \ -Vw{w}.{wa}i{w}.{wa}p{p}.{pa}f{f}.{fa}s{s}.{sa}l{l}.{la}d{d}.{da}x{x}.{xa} \ {CC_ALIGN?} \ {CEM_F?} {LFLAG?} < > diff --git a/modules/src/input/inp_pkg.body b/modules/src/input/inp_pkg.body index 6de4a5268..0bc80804d 100644 --- a/modules/src/input/inp_pkg.body +++ b/modules/src/input/inp_pkg.body @@ -340,6 +340,28 @@ InsertText(text, length) return 1; } +#define RAWLOAD(dest) \ + ((void)((dest = *_ipp++) || (dest = loadbuf()))) + +/* Reads the next character, converting CRLF into LF. */ +int +loadchar(void) +{ + int ch; + RAWLOAD(ch); + if (ch == '\r') + { + RAWLOAD(ch); + if (ch != '\n') + { + /* Oops, this isn't a CRLF; put back the char we just read. */ + ChPushBack(ch); + } + ch = '\n'; + } + return ch; +} + /* 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. diff --git a/modules/src/input/inp_pkg.spec b/modules/src/input/inp_pkg.spec index c349fa896..1b12a3f49 100644 --- a/modules/src/input/inp_pkg.spec +++ b/modules/src/input/inp_pkg.spec @@ -20,7 +20,7 @@ /* INPUT PRIMITIVES */ -#define LoadChar(dest) ((void)((dest = *_ipp++) || (dest = loadbuf()))) +#define LoadChar(dest) (dest = loadchar()) #define PushBack() (--_ipp) #define ChPushBack(ch) (*--_ipp = (ch)) @@ -31,6 +31,7 @@ extern char *_ipp; +_PROTOTYPE(int loadchar, (void)); _PROTOTYPE(int loadbuf, (void)); _PROTOTYPE(int AtEoIT, (void)); _PROTOTYPE(int AtEoIF, (void)); diff --git a/util/int/moncalls.c b/util/int/moncalls.c index 9e7b954ea..ca4a42fcc 100644 --- a/util/int/moncalls.c +++ b/util/int/moncalls.c @@ -47,6 +47,14 @@ struct timeb { /* non-existing; we use an ad-hoc definition */ #include "warn.h" #include "mem.h" +/* Detect supported system calls. */ + +#if !defined __CYGWIN__ +#define HAS_ACCT 1 +#else +#define HAS_ACCT 0 +#endif + #define INPUT 0 #define OUTPUT 1 @@ -914,15 +922,22 @@ moncall() case 51: /* Acct */ dsp1 = pop_ptr(); - if (!savestr(0, dsp1) || acct(buf[0]) == -1) { + #if HAS_ACCT + if (!savestr(0, dsp1) || acct(buf[0]) == -1) { + push_err(); + LOG(("@m4 Acct: failed, dsp1 = %lu, errno = %d", + dsp1, errno)); + } + else { + push_int(0); + LOG(("@m9 Acct: succeeded, dsp1 = %lu", dsp1)); + } + #else + einval(WMPXIMP); push_err(); - LOG(("@m4 Acct: failed, dsp1 = %lu, errno = %d", - dsp1, errno)); - } - else { - push_int(0); - LOG(("@m9 Acct: succeeded, dsp1 = %lu", dsp1)); - } + LOG(("@m4 Acct: failed, request = %d, dsp1 = %lu, errno = %d", + request, dsp1, errno)); + #endif break; case 54: /* Ioctl */