From: eck Date: Wed, 22 Nov 1989 12:59:15 +0000 (+0000) Subject: fixed bugs, added dynamic buffer allocation X-Git-Tag: release-5-5~2049 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=f9fadbf045e4441f5dc635b125e045ae4b9f5ae0;p=ack.git fixed bugs, added dynamic buffer allocation --- diff --git a/lang/cem/cpp.ansi/LLmessage.c b/lang/cem/cpp.ansi/LLmessage.c index c5b80e929..2bc1147b0 100644 --- a/lang/cem/cpp.ansi/LLmessage.c +++ b/lang/cem/cpp.ansi/LLmessage.c @@ -16,7 +16,7 @@ LLmessage(tk) { error("garbage at end of line"); else if (tk) { error("%s missing", symbol2str(tk)); - if (DOT != EOF) SkipToNewLine(0); + if (DOT != EOF) SkipToNewLine(); DOT = EOF; } else diff --git a/lang/cem/cpp.ansi/Makefile b/lang/cem/cpp.ansi/Makefile index 117964cc4..50089c3f6 100644 --- a/lang/cem/cpp.ansi/Makefile +++ b/lang/cem/cpp.ansi/Makefile @@ -65,8 +65,8 @@ STRSRC = macro.str replace.str GSTRSRC = macro.h replace.h # .h files generated by `make hfiles'; PLEASE KEEP THIS UP-TO-DATE! -GHSRC = errout.h idfsize.h ifdepth.h lapbuf.h \ - nparams.h numsize.h obufsize.h argbuf.h \ +GHSRC = errout.h idfsize.h ifdepth.h macbuf.h \ + nparams.h numsize.h obufsize.h \ parbufsize.h pathlength.h strsize.h textsize.h \ botch_free.h debug.h inputtype.h dobits.h line_prefix.h @@ -222,14 +222,13 @@ preprocess.o: line_prefix.h preprocess.o: macro.h preprocess.o: obufsize.h replace.o: LLlex.h -replace.o: argbuf.h replace.o: class.h replace.o: file_info.h replace.o: idf.h replace.o: idfsize.h replace.o: input.h replace.o: inputtype.h -replace.o: lapbuf.h +replace.o: macbuf.h replace.o: macro.h replace.o: nparams.h replace.o: numsize.h diff --git a/lang/cem/cpp.ansi/Parameters b/lang/cem/cpp.ansi/Parameters index ce2c3671c..33f9347e0 100644 --- a/lang/cem/cpp.ansi/Parameters +++ b/lang/cem/cpp.ansi/Parameters @@ -25,12 +25,9 @@ #define IFDEPTH 256 /* maximum number of nested if-constructions */ -!File: lapbuf.h -#define LAPBUF 4096 /* size of macro actual parameter buffer */ - - -!File: argbuf.h -#define ARGBUF 2048 /* sizeof of macro actual parameter buffer */ +!File: macbuf.h +#define LAPBUF 128 /* initial size of macro replacement buffer */ +#define ARGBUF 128 /* initial size of macro parameter buffer(s) */ !File: strsize.h diff --git a/lang/cem/cpp.ansi/domacro.c b/lang/cem/cpp.ansi/domacro.c index e844d99c8..da5f519f3 100644 --- a/lang/cem/cpp.ansi/domacro.c +++ b/lang/cem/cpp.ansi/domacro.c @@ -22,6 +22,8 @@ #include "class.h" #include "macro.h" #include "bits.h" +#include "macbuf.h" +#include "replace.h" extern char options[]; extern char **inctable; /* list of include directories */ @@ -54,7 +56,7 @@ GetIdentifier(skiponerr) ReplaceMacros = 1; UnknownIdIsZero = tmp; if (tok != IDENTIFIER) { - if (skiponerr && tok != EOF) SkipToNewLine(0); + if (skiponerr && tok != EOF) SkipToNewLine(); return (char *)0; } return tk.tk_str; @@ -85,7 +87,7 @@ domacro() id = findidf(tk.tk_str); if (!id) { error("%s: unknown control", tk.tk_str); - SkipToNewLine(0); + SkipToNewLine(); free(tk.tk_str); break; } @@ -121,7 +123,7 @@ domacro() */ if (GetToken(&tk) != INTEGER) { error("bad #line syntax"); - SkipToNewLine(0); + SkipToNewLine(); } else do_line((unsigned int)tk.tk_val); @@ -131,14 +133,13 @@ domacro() break; case K_PRAGMA: /* "pragma" */ return 0; /* this is for the compiler */ - break; case K_UNDEF: /* "undef" */ do_undef(); break; default: /* invalid word seen after the '#' */ error("%s: unknown control", id->id_text); - SkipToNewLine(0); + SkipToNewLine(); } break; case INTEGER: /* # []? */ @@ -148,7 +149,7 @@ domacro() break; default: /* invalid token following '#' */ error("illegal # line"); - SkipToNewLine(0); + SkipToNewLine(); } return 1; } @@ -180,15 +181,21 @@ int to_endif; NoUnstack--; return; } - UnGetChar(); - SkipToNewLine(0); + if (ch == '/') { + if (ch != '*') UnGetChar(); + else { + skipcomment(); + continue; + } + } else UnGetChar(); + SkipToNewLine(); continue; } ReplaceMacros = 0; toknum = GetToken(&tk); ReplaceMacros = 1; if (toknum != IDENTIFIER) { - SkipToNewLine(0); + SkipToNewLine(); continue; } /* an IDENTIFIER: look for #if, #ifdef and #ifndef @@ -200,13 +207,13 @@ int to_endif; free(tk.tk_str); switch(id->id_resmac) { default: - SkipToNewLine(0); + SkipToNewLine(); break; case K_IF: case K_IFDEF: case K_IFNDEF: push_if(); - SkipToNewLine(0); + SkipToNewLine(); break; case K_ELIF: if (ifstack[nestlevel]) @@ -219,26 +226,26 @@ int to_endif; return; } } - else SkipToNewLine(0); /* otherwise done in ifexpr() */ + 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(1)) { + if (SkipToNewLine()) { if (!options['o']) strict("garbage following #else"); } NoUnstack--; return; } - else SkipToNewLine(0); + else SkipToNewLine(); break; case K_ENDIF: assert(nestlevel > svnestlevel[nestcount]); if (nestlevel == skiplevel) { - if (SkipToNewLine(1)) { + if (SkipToNewLine()) { if (!options['o']) strict("garbage following #endif"); } @@ -246,7 +253,7 @@ int to_endif; NoUnstack--; return; } - else SkipToNewLine(0); + else SkipToNewLine(); nestlevel--; break; } @@ -292,7 +299,7 @@ do_include() filenm = (char *)0; } AccFileSpecifier = 0; - SkipToNewLine(0); + SkipToNewLine(); inctable[0] = WorkingDir; if (filenm) { if (!InsertFile(filenm, &inctable[tok==FILESPECIFIER],&result)){ @@ -326,12 +333,12 @@ do_define() 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) { - SkipToNewLine(0); + SkipToNewLine(); free(str); return; /* an error occurred */ } @@ -340,17 +347,8 @@ do_define() /* read the replacement text if there is any */ ch = skipspaces(ch,0); /* find first character of the text */ assert(ch != EOI); - if (class(ch) == STNL) { - /* Treat `#define something' as `#define something ""' - */ - repl_text = Malloc(1); - *repl_text = '\0'; - length = 0; - } - else { - UnGetChar(); - repl_text = get_text((nformals > 0) ? formals : 0, &length); - } + UnGetChar(); + repl_text = get_text((nformals > 0) ? formals : 0, &length); macro_def(str2idf(str, 0), repl_text, nformals, length, NOFLAG); LineNumber++; } @@ -367,12 +365,12 @@ do_elif() { if (nestlevel <= svnestlevel[nestcount]) { error("#elif without corresponding #if"); - SkipToNewLine(0); + SkipToNewLine(); } else { /* restart at this level as if a #if is detected. */ if (ifstack[nestlevel]) { error("#elif after #else"); - SkipToNewLine(0); + SkipToNewLine(); } nestlevel--; push_if(); @@ -382,7 +380,7 @@ do_elif() do_else() { - if (SkipToNewLine(1)) { + if (SkipToNewLine()) { if (!options['o']) strict("garbage following #else"); } @@ -399,7 +397,7 @@ do_else() do_endif() { - if (SkipToNewLine(1)) { + if (SkipToNewLine()) { if (!options['o']) strict("garbage following #endif"); } @@ -438,7 +436,7 @@ do_ifdef(how) if (how ^ (id && id->id_macro != 0)) skip_block(0); else - SkipToNewLine(0); + SkipToNewLine(); } do_undef() @@ -458,7 +456,7 @@ do_undef() } } /* else: don't complain */ free(str); - SkipToNewLine(0); + SkipToNewLine(); } else error("illegal #undef construction"); @@ -604,6 +602,8 @@ find_name(nm, index) return 0; } +#define BLANK(ch) ((ch == ' ') || (ch == '\t')) + char * get_text(formals, length) char *formals[]; @@ -614,101 +614,111 @@ get_text(formals, length) 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 + 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 + same amount of characters. The length of the replacement text is returned. Implementation: - finite automaton : we are only interested in - identifiers, because they might be replaced by some actual - parameter. Other tokens will not be seen as such. + 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; - register unsigned text_size; - char *text = Malloc(text_size = ITEXTSIZE); - register int pos = 0; + struct repl repls; + register struct repl *repl = &repls; + int blank = 0; c = GetChar(); + repl->r_ptr = repl->r_text = Malloc(repl->r_size = ITEXTSIZE); while ((c != EOI) && (class(c) != STNL)) { + if (BLANK(c)) { + if (!blank++) add2repl(repl, ' '); + c = GetChar(); + continue; + } + if (c == '\'' || c == '"') { register int delim = c; do { - /* being careful, as ever */ - if (pos+3 >= text_size) - text = Srealloc(text, text_size <<= 1); - text[pos++] = c; - if (c == '\\') - text[pos++] = GetChar(); + add2repl(repl, c); + if (c == '\\') add2repl(repl, GetChar()); c = GetChar(); } while (c != delim && c != EOI && class(c) != STNL); - text[pos++] = c; + add2repl(repl, c); c = GetChar(); - } - else - if (c == '/') { + } else if (c == '/') { c = GetChar(); - if (pos+1 >= text_size) - text = Srealloc(text, text_size <<= 1); if (c == '*') { skipcomment(); - text[pos++] = ' '; + if (!blank++) add2repl(repl,' '); c = GetChar(); - } - else - text[pos++] = '/'; - } - else - if (formals && (class(c) == STIDF || class(c) == STELL)) { + continue; /* skip zero'ing of blank */ + } else add2repl(repl, '/'); + } else if (formals + && (class(c) == STIDF || class(c) == STELL)) { char id_buf[IDFSIZE + 1]; - register id_size = 0; - register n; + register char *idp = id_buf; + int n; /* read identifier: it may be a formal parameter */ - id_buf[id_size++] = c; + *idp++ = c; do { c = GetChar(); - if (id_size <= IDFSIZE) - id_buf[id_size++] = c; + if (idp <= &id_buf[IDFSIZE]) + *idp++ = c; } while (in_idf(c)); - id_buf[--id_size] = '\0'; - if (n = find_name(id_buf, formals)) { - /* construct the formal parameter mark */ - if (pos+1 >= text_size) - text = Srealloc(text, - text_size <<= 1); - text[pos++] = FORMALP | (char) n; - } + *--idp = '\0'; + + /* construct the formal parameter mark or identifier */ + if (n = find_name(id_buf, formals)) + add2repl(repl, FORMALP | (char) n); else { - register char *ptr = &id_buf[0]; - - while (pos + id_size >= text_size) - text_size <<= 1; - text = Realloc(text, text_size); - while (text[pos++] = *ptr++) - /* EMPTY */ ; - pos--; + idp = id_buf; + while (*idp) add2repl(repl, *idp++); + } + } else if (class(c) == STNUM) { + add2repl(repl, c); + if (c == '.') { + c = GetChar(); + if (class(c) != STNUM) { + blank = 0; continue; + } + add2repl(repl, c); } - } - else { - if (pos+1 >= text_size) - text = Realloc(text, text_size <<= 1); - text[pos++] = 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 { + add2repl(repl, c); c = GetChar(); } + blank = 0; } - text[pos++] = '\0'; - text = Realloc(text, pos); - *length = pos - 1; - return text; + *length = repl->r_ptr - repl->r_text; + return Realloc(repl->r_text, repl->r_ptr - repl->r_text + 1); } -#define BLANK(ch) ((ch == ' ') || (ch == '\t')) - /* macroeq() decides whether two macro replacement texts are - identical. This version compares the texts, which occur + identical. This version compares the texts, which occur as strings, without taking care of the leading and trailing blanks (spaces and tabs). */ @@ -739,9 +749,10 @@ do_line(l) unsigned int l; { struct token tk; + int t = GetToken(&tk); - LineNumber = l - 1; /* the number of the next input line */ - if (GetToken(&tk) == STRING) /* is there a filespecifier? */ + SkipToNewLine(); + LineNumber = l; /* the number of the next input line */ + if (t == STRING) /* is there a filespecifier? */ FileName = tk.tk_str; - SkipToNewLine(0); } diff --git a/lang/cem/cpp.ansi/preprocess.c b/lang/cem/cpp.ansi/preprocess.c index 50f78db97..ba5524d55 100644 --- a/lang/cem/cpp.ansi/preprocess.c +++ b/lang/cem/cpp.ansi/preprocess.c @@ -28,6 +28,9 @@ Xflush() sys_write(STDOUT, _obuf, OBUFSIZE); } +static char *SkipComment(); +extern char options[]; + preprocess(fn) char *fn; { @@ -36,7 +39,7 @@ preprocess(fn) register char *ob = &_obuf[OBUFSIZE]; char Xbuf[256]; int lineno = 0; - extern char options[]; + int startline; #define flush(X) (sys_write(STDOUT,_obuf,X)) #define echo(ch) if (op == ob) { Xflush(); op = _obuf; } *op++ = (ch); @@ -75,33 +78,47 @@ preprocess(fn) for (;;) { LineNumber++; lineno++; + startline = 1; c = GetChar(); - while (class(c) == STSKIP) { + while (startline) { + 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; + } + UnGetChar(); + c = '/'; + } + break; + } echo(c); c = GetChar(); - } + } - while (c == '#') { + if (c == '#') { if (!domacro()) { /* pass pragma's to compiler */ - register char *p = "#pragma"; + register char *p = "#pragma"; - do_line(lineno, fn); + do_line(lineno, fn); - while(*p) { - echo(*p++); - } - while ((c = GetChar()) != EOI) { - if (class(c) == STNL) break; - echo(c); - } + while(*p) { + echo(*p++); + } + while ((c = GetChar()) != EOI) { + if (class(c) == STNL) break; + echo(c); + } } lineno++; newline(); c = GetChar(); - while (class(c) == STSKIP) { - echo(c); - c = GetChar(); - } + } else startline = 0; } do_line(lineno, fn); for (;;) { @@ -120,43 +137,9 @@ preprocess(fn) if (c == '/' && !InputLevel) { c = GetChar(); if (c == '*') { - NoUnstack++; - if (options['C']) { - echo('/'); - echo('*'); - } - for (;;) { - c = GetChar(); - if (c == '\n') { - ++LineNumber; - ++lineno; - echo(c); - } - else if (c == EOI) { - newline(); - flush(op - _obuf); - return; - } - else if (c == '*') { - if (options['C']) { - echo(c); - } - c = GetChar(); - if (c == '/') { - if (options['C']) { - echo(c); - } - break; - } - else { - UnGetChar(); - } - } - else if (options['C']) { - echo(c); - } - } - NoUnstack--; + op = SkipComment(op, &lineno); + if (!op) return; + if (!options['C']) echo(' '); c = GetChar(); continue; } @@ -329,3 +312,48 @@ preprocess(fn) } /*NOTREACHED*/ } + +static char * +SkipComment(op, lineno) +char *op; +int *lineno; +{ + char *ob = &_obuf[OBUFSIZE]; + register int c; + + NoUnstack++; + if (options['C']) { + echo('/'); + echo('*'); + } + c = GetChar(); + for(;;) { + if (c == EOI) { + newline(); + flush(op - _obuf); + op = 0; + break; + } + if (options['C']) { + echo(c); + } + if (c == '\n') { + ++LineNumber; + ++*lineno; + if (!options['C']) { + echo(c); + } + } + if (c == '*') { + c = GetChar(); + if (c == '/') { + if (options['C']) { + echo(c); + } + break; /* for(;;) */ + } + } else c = GetChar(); + } + NoUnstack--; + return op; +} diff --git a/lang/cem/cpp.ansi/replace.c b/lang/cem/cpp.ansi/replace.c index 7cd3d574c..418f8e74c 100644 --- a/lang/cem/cpp.ansi/replace.c +++ b/lang/cem/cpp.ansi/replace.c @@ -18,8 +18,7 @@ #include "LLlex.h" #include "class.h" #include -#include "lapbuf.h" -#include "argbuf.h" +#include "macbuf.h" #include "replace.h" extern char *GetIdentifier(); @@ -40,7 +39,7 @@ replace(idf) if (idf->id_macro->mc_flag & NOREPLACE) return 0; repl = new_repl(); - repl->r_ptr = repl->r_text; + 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)) @@ -59,6 +58,25 @@ 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; @@ -71,7 +89,8 @@ EnableMacros() r->r_idf->id_macro->mc_flag &= ~NOREPLACE; if (!prev) ReplaceList = nxt; else prev->next = nxt; - free_args(r->r_args); + free(r->r_text); + freeargs(r->r_args); free_repl(r); } else prev = r; @@ -136,15 +155,10 @@ expand_macro(repl, idf) a+b; --> + + b ; 'a' must be substituded, but the result should be - three tokens: + + ID. Because this preprocessor is - character based, we have a problem. - For now: just insert a space after all tokens, - until ANSI fixes this flaw. - ^^^^^^^^^^^^^^^^^^^^^^^^^^ tsk tsk tsk + three tokens: + + ID. Therefore a token separator is + inserted after the replacement. */ - if (*repl->r_ptr != TOKSEP) *repl->r_ptr++ = TOKSEP; - *repl->r_ptr = '\0'; - + if (*(repl->r_ptr -1) != TOKSEP) add2repl(repl, TOKSEP); return 1; } @@ -167,8 +181,7 @@ expand_defined(repl) error("identifier missing"); if (parens && ch != ')') error(") missing"); if (!parens || ch != ')') UnGetChar(); - *repl->r_ptr++ = '0'; - *repl->r_ptr = '\0'; + add2repl(repl,'0'); return; } UnGetChar(); @@ -181,8 +194,14 @@ expand_defined(repl) ch = skipspaces(ch, 0); if (parens && ch != ')') error(") missing"); if (!parens || ch != ')') UnGetChar(); - *repl->r_ptr++ = (id && id->id_macro) ? '1' : '0'; - *repl->r_ptr = '\0'; + add2repl(repl, (id && id->id_macro) ? '1' : '0'); +} + +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); } getactuals(repl, idf) @@ -199,8 +218,7 @@ getactuals(repl, idf) register int ch; argcnt = 0; - args->a_expvec[0] = args->a_expptr = &args->a_expbuf[0]; - args->a_rawvec[0] = args->a_rawptr = &args->a_rawbuf[0]; + newarg(args); if ((ch = GetChar()) != ')') { UnGetChar(); while ((ch = actual(repl)) != ')' ) { @@ -209,15 +227,18 @@ getactuals(repl, idf) return; } stash(repl, '\0', 1); + args->a_expvec[argcnt] = args->a_expbuf; + args->a_rawvec[argcnt] = args->a_rawbuf; ++argcnt; - args->a_expvec[argcnt] = args->a_expptr; - args->a_rawvec[argcnt] = args->a_rawptr; if (argcnt == STDC_NPARAMS) strict("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) @@ -236,7 +257,7 @@ struct repl *repl; /* stash identifier name */ for (p = nrepl->r_idf->id_text; *p != '\0'; p++) - *args->a_rawptr++ = *p; + stash(repl, *p, -1); /* The following code deals with expanded function like macro calls. It makes the following code @@ -258,8 +279,8 @@ struct repl *repl; *args->a_rawptr++ = '('; for (i = 0; ap->a_rawvec[i] != (char *)0; i++) { for (p = ap->a_rawvec[i]; *p != '\0'; p++) - *args->a_rawptr++ = *p; - *args->a_rawptr++ = ','; + stash(repl, *p, -1); + stash(repl, ',', -1); } *(args->a_rawptr-1) = ')'; /* delete last ',' */ } @@ -373,27 +394,44 @@ actual(repl) } else if (ch == '\n') { /* newlines are accepted as white spaces */ LineNumber++; - while ((ch = GetChar()), class(ch) == STSKIP) - /* EMPTY */; - /* 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( - #include phone_number + /_* comment *_/ #include phone_number ,2); in which case the include must be handled interpreted as such. */ + + 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(); else if (ch == EOI) { error("unterminated macro call"); return ')'; } - UnGetChar(); - stash(repl, ' ', !nostashraw); + if (ch != '/') { + UnGetChar(); + stash(repl, ' ', !nostashraw); + } } else if (ch == '/') { /* comments are treated as one white space token */ if ((ch = GetChar()) == '*' && !InputLevel) { @@ -496,53 +534,50 @@ macro2buffer(repl, idf, args) smarter should be done (but even a DFA is O(|s|)). */ register char *ptr = idf->id_macro->mc_text; - register char *tmpptr; int err = 0; char *stringify(); while (*ptr) { - assert(repl->r_ptr < &(repl->r_text[LAPBUF])); if (*ptr == '\'' || *ptr == '"') { register int delim = *ptr; do { - *repl->r_ptr++ = *ptr; + add2repl(repl, *ptr); if (*ptr == '\\') - *repl->r_ptr++ = *++ptr; + add2repl(repl, *++ptr); if (*ptr == '\0') { error("unterminated string"); - *repl->r_ptr = '\0'; return; } ptr++; } while (*ptr != delim || *ptr == '\0'); - *repl->r_ptr++ = *ptr++; + add2repl(repl, *ptr++); } else if (*ptr == '#') { if (*++ptr == '#') { + register int tmpindex; /* ## - paste operator */ ptr++; /* trim the actual replacement list */ --repl->r_ptr; - while (is_wsp(*repl->r_ptr) - && repl->r_ptr >= repl->r_text) - --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. + /* ## occurred at the beginning of the replacement list. */ - if (repl->r_ptr == repl->r_text - && is_wsp(*repl->r_ptr)) { + if (repl->r_ptr < repl->r_text) { err = 1; break; } - while(*repl->r_ptr == TOKSEP - && repl->r_ptr >= repl->r_text) - --repl->r_ptr; + if (repl->r_ptr >= repl->r_text + && *repl->r_ptr == TOKSEP); + --repl->r_ptr; - tmpptr = 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)) @@ -557,27 +592,29 @@ macro2buffer(repl, idf, args) assert(n > 0); p = args->a_rawvec[n-1]; if (p) { /* else macro argument missing */ - while (is_wsp(*p)) - p++; + while (is_wsp(*p)) p++; if (*p == NOEXPM) p++; while (*p) - *repl->r_ptr++ = *p++; - } - if (in_idf(*tmpptr + 1)) { - while (in_idf(*tmpptr) - && tmpptr >= repl->r_text) - tmpptr--; - if (*tmpptr == NOEXPM) *tmpptr = TOKSEP; + 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)) { - while (in_idf(*tmpptr) - && tmpptr >= repl->r_text) - tmpptr--; - if (*tmpptr == NOEXPM) *tmpptr = TOKSEP; + 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 */ @@ -601,17 +638,15 @@ macro2buffer(repl, idf, args) else q = args->a_expvec[n-1]; - p = repl->r_ptr; if (q) /* else macro argument missing */ while (*q) - *repl->r_ptr++ = *q++; + add2repl(repl, *q++); - if (*repl->r_ptr != TOKSEP) - *repl->r_ptr++ = TOKSEP; + if (*(repl->r_ptr-1) != TOKSEP) + add2repl(repl, TOKSEP); } else - *repl->r_ptr++ = *ptr++; + add2repl(repl, *ptr++); } - *repl->r_ptr = '\0'; if (err) error("illegal use of ## operator"); } @@ -648,12 +683,12 @@ stringify(repl, ptr, args) assert(n != 0); p = args->a_rawvec[n-1]; - *repl->r_ptr++ = '"'; + add2repl(repl, '"'); while (*p) { if (is_wsp(*p)) { if (!space) { space = 1; - *repl->r_ptr++ = ' '; + add2repl(repl, ' '); } p++; continue; @@ -666,38 +701,67 @@ stringify(repl, ptr, args) delim = 0; backslash = *p == '\\'; if (*p == '"' || (delim && *p == '\\')) - *repl->r_ptr++ = '\\'; + add2repl(repl, '\\'); if (*p == TOKSEP || *p == NOEXPM) p++; - else *repl->r_ptr++ = *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 = '"'; - ++repl->r_ptr; /* oops, one to far */ + ++repl->r_ptr; /* oops, one to far */ + add2repl(repl, '"'); } else error("illegal use of # operator"); - *repl->r_ptr = '\0'; 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; + + if (index + 1 >= repl->r_size) { + repl->r_text = Realloc(repl->r_text, 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; + struct repl *repl; + register int ch; + int stashraw; { - /* Stash characters into the macro expansion buffer. - */ + /* Stash characters into the macro expansion buffer. + */ register struct args *args = repl->r_args; - - if (args->a_expptr >= &(args->a_expbuf[ARGBUF])) - fatal("macro argument buffer overflow"); - *args->a_expptr++ = ch; - + register int index = args->a_expptr - args->a_expbuf; + + if (stashraw >= 0) { + if (index + 1 >= args->a_expsize) { + args->a_expbuf = Realloc(args->a_expbuf, + args->a_expsize <<= 1); + args->a_expptr = args->a_expbuf + index; + } + *args->a_expptr++ = ch; + } + if (stashraw) { - if (args->a_rawptr >= &(args->a_rawbuf[ARGBUF])) - fatal("raw macro argument buffer overflow"); + index = args->a_rawptr - args->a_rawbuf; + if (index + 1 >= args->a_rawsize) { + args->a_rawbuf = Realloc(args->a_rawbuf, + args->a_rawsize <<= 1); + args->a_rawptr = args->a_rawbuf + index; + } *args->a_rawptr++ = ch; } } diff --git a/lang/cem/cpp.ansi/replace.str b/lang/cem/cpp.ansi/replace.str index 61ed6fc0e..3d7d6887b 100644 --- a/lang/cem/cpp.ansi/replace.str +++ b/lang/cem/cpp.ansi/replace.str @@ -10,8 +10,9 @@ struct repl { struct idf *r_idf; /* name of the macro */ struct args *r_args; /* replacement parameters */ int r_level; /* level of insertion */ - char *r_ptr; /* replacement text pointer */ - char r_text[LAPBUF]; /* replacement text */ + int r_size; /* current size of replacement buffer */ + char *r_ptr; /* replacement text index pointer */ + char *r_text; /* replacement text */ }; /* ALLOCDEF "repl" 4 */ @@ -34,15 +35,16 @@ struct repl { operator, and an expanded one as argument for h(). */ struct args { - char *a_expptr; /* expanded argument pointer */ + 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_expbuf[ARGBUF]; /* expanded argument buffer space */ - char *a_rawptr; /* raw argument pointer */ + 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 */ - char a_rawbuf[ARGBUF]; /* raw argument buffer space */ }; /* ALLOCDEF "args" 2 */ #define NO_ARGS (struct args *)0 - diff --git a/lang/cem/cpp.ansi/skip.c b/lang/cem/cpp.ansi/skip.c index 25781bacb..5433b90f7 100644 --- a/lang/cem/cpp.ansi/skip.c +++ b/lang/cem/cpp.ansi/skip.c @@ -56,11 +56,10 @@ skipspaces(ch, skipnl) } } -SkipToNewLine(garbage) - int garbage; +SkipToNewLine() { register int ch; - register int pstrict = 0; + register int garbage = 0; while ((ch = GetChar()) != '\n') { if (ch == '/') { @@ -69,9 +68,9 @@ SkipToNewLine(garbage) continue; } } - if (garbage && !is_wsp(ch)) - pstrict = 1; + if (!is_wsp(ch)) + garbage = 1; } ++LineNumber; - return pstrict; + return garbage; }