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
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
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
#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
#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 */
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;
id = findidf(tk.tk_str);
if (!id) {
error("%s: unknown control", tk.tk_str);
- SkipToNewLine(0);
+ SkipToNewLine();
free(tk.tk_str);
break;
}
*/
if (GetToken(&tk) != INTEGER) {
error("bad #line syntax");
- SkipToNewLine(0);
+ SkipToNewLine();
}
else
do_line((unsigned int)tk.tk_val);
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>]? */
break;
default: /* invalid token following '#' */
error("illegal # line");
- SkipToNewLine(0);
+ SkipToNewLine();
}
return 1;
}
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
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])
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");
}
NoUnstack--;
return;
}
- else SkipToNewLine(0);
+ else SkipToNewLine();
nestlevel--;
break;
}
filenm = (char *)0;
}
AccFileSpecifier = 0;
- SkipToNewLine(0);
+ SkipToNewLine();
inctable[0] = WorkingDir;
if (filenm) {
if (!InsertFile(filenm, &inctable[tok==FILESPECIFIER],&result)){
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 */
}
/* 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++;
}
{
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();
do_else()
{
- if (SkipToNewLine(1)) {
+ if (SkipToNewLine()) {
if (!options['o'])
strict("garbage following #else");
}
do_endif()
{
- if (SkipToNewLine(1)) {
+ if (SkipToNewLine()) {
if (!options['o'])
strict("garbage following #endif");
}
if (how ^ (id && id->id_macro != 0))
skip_block(0);
else
- SkipToNewLine(0);
+ SkipToNewLine();
}
do_undef()
}
} /* else: don't complain */
free(str);
- SkipToNewLine(0);
+ SkipToNewLine();
}
else
error("illegal #undef construction");
return 0;
}
+#define BLANK(ch) ((ch == ' ') || (ch == '\t'))
+
char *
get_text(formals, length)
char *formals[];
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).
*/
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);
}
sys_write(STDOUT, _obuf, OBUFSIZE);
}
+static char *SkipComment();
+extern char options[];
+
preprocess(fn)
char *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);
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 (;;) {
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;
}
}
/*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;
+}
#include "LLlex.h"
#include "class.h"
#include <assert.h>
-#include "lapbuf.h"
-#include "argbuf.h"
+#include "macbuf.h"
#include "replace.h"
extern char *GetIdentifier();
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))
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;
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;
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;
}
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();
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)
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)) != ')' ) {
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)
/* 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
*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 ',' */
}
} 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) {
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))
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 */
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");
}
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;
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;
}
}
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 */
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
-
}
}
-SkipToNewLine(garbage)
- int garbage;
+SkipToNewLine()
{
register int ch;
- register int pstrict = 0;
+ register int garbage = 0;
while ((ch = GetChar()) != '\n') {
if (ch == '/') {
continue;
}
}
- if (garbage && !is_wsp(ch))
- pstrict = 1;
+ if (!is_wsp(ch))
+ garbage = 1;
}
++LineNumber;
- return pstrict;
+ return garbage;
}