fixed bugs, added dynamic buffer allocation
authoreck <none@none>
Wed, 22 Nov 1989 12:59:15 +0000 (12:59 +0000)
committereck <none@none>
Wed, 22 Nov 1989 12:59:15 +0000 (12:59 +0000)
lang/cem/cpp.ansi/LLmessage.c
lang/cem/cpp.ansi/Makefile
lang/cem/cpp.ansi/Parameters
lang/cem/cpp.ansi/domacro.c
lang/cem/cpp.ansi/preprocess.c
lang/cem/cpp.ansi/replace.c
lang/cem/cpp.ansi/replace.str
lang/cem/cpp.ansi/skip.c

index c5b80e9..2bc1147 100644 (file)
@@ -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
index 117964c..50089c3 100644 (file)
@@ -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
index ce2c367..33f9347 100644 (file)
 #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
index e844d99..da5f519 100644 (file)
@@ -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:           /* # <integer> [<filespecifier>]?       */
@@ -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);
 }
index 50f78db..ba5524d 100644 (file)
@@ -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;
+}
index 7cd3d57..418f8e7 100644 (file)
@@ -18,8 +18,7 @@
 #include       "LLlex.h"
 #include       "class.h"
 #include       <assert.h>
-#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;
        }
 }
index 61ed6fc..3d7d688 100644 (file)
@@ -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
-
index 25781ba..5433b90 100644 (file)
@@ -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;
 }