summaryrefslogtreecommitdiffstats
path: root/usr.bin/m4/main.c
diff options
context:
space:
mode:
authorjmallett <jmallett@FreeBSD.org>2002-04-19 17:26:21 +0000
committerjmallett <jmallett@FreeBSD.org>2002-04-19 17:26:21 +0000
commitb38bbfea3be32adfe5798450f00bbcf0cbed5804 (patch)
treee50607d075b4fa99ab7d040c1f22f13cfc865fff /usr.bin/m4/main.c
parente0dd7499cbc447a80e58137ec3f5c98184a72d10 (diff)
downloadFreeBSD-src-b38bbfea3be32adfe5798450f00bbcf0cbed5804.zip
FreeBSD-src-b38bbfea3be32adfe5798450f00bbcf0cbed5804.tar.gz
Bring OpenBSD m4(1) off of the OPENBSD vendor branch, and add the -s option,
$FreeBSD$ identifiers, and fix initialisation to stderr to happen in a function as stderr is not the same in CURRENT as in OpenBSD. Reviewed by: obrien
Diffstat (limited to 'usr.bin/m4/main.c')
-rw-r--r--usr.bin/m4/main.c584
1 files changed, 398 insertions, 186 deletions
diff --git a/usr.bin/m4/main.c b/usr.bin/m4/main.c
index 8201016..34020e9 100644
--- a/usr.bin/m4/main.c
+++ b/usr.bin/m4/main.c
@@ -1,3 +1,6 @@
+/* $OpenBSD: main.c,v 1.52 2002/02/16 21:27:48 millert Exp $ */
+/* $NetBSD: main.c,v 1.12 1997/02/08 23:54:49 cgd Exp $ */
+
/*-
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
@@ -34,19 +37,12 @@
* SUCH DAMAGE.
*/
-#ifndef lint
-static const char copyright[] =
-"@(#) Copyright (c) 1989, 1993\n\
- The Regents of the University of California. All rights reserved.\n";
-#endif /* not lint */
-
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/6/93";
-#endif
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 1989, 1993\n\
+ The Regents of the University of California. All rights reserved.\n");
+__SCCSID("@(#)main.c 8.1 (Berkeley) 6/6/93");
+__RCSID_SOURCE("$OpenBSD: main.c,v 1.52 2002/02/16 21:27:48 millert Exp $");
+__FBSDID("$FreeBSD$");
/*
* main.c
@@ -55,115 +51,149 @@ static const char rcsid[] =
*/
#include <sys/types.h>
-#include <ctype.h>
-#include <err.h>
+#include <assert.h>
#include <signal.h>
+#include <errno.h>
+#include <unistd.h>
#include <stdio.h>
-#include <stdlib.h>
+#include <ctype.h>
#include <string.h>
-#include <unistd.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <err.h>
#include "mdef.h"
#include "stdd.h"
#include "extern.h"
#include "pathnames.h"
ndptr hashtab[HASHSIZE]; /* hash table for macros etc. */
-unsigned char buf[BUFSIZE]; /* push-back buffer */
-unsigned char *bufbase = buf; /* the base for current ilevel */
-unsigned char *bbase[MAXINP]; /* the base for each ilevel */
-unsigned char *bp = buf; /* first available character */
-unsigned char *endpbb = buf+BUFSIZE; /* end of push-back buffer */
-stae mstack[STACKMAX+1]; /* stack of m4 machine */
-char strspace[STRSPMAX+1]; /* string space for evaluation */
-char *ep = strspace; /* first free char in strspace */
-char *endest= strspace+STRSPMAX;/* end of string space */
+stae *mstack; /* stack of m4 machine */
+char *sstack; /* shadow stack, for string space extension */
+static size_t STACKMAX; /* current maximum size of stack */
int sp; /* current m4 stack pointer */
int fp; /* m4 call frame pointer */
-FILE *infile[MAXINP]; /* input file stack (0=stdin) */
-char *inname[MAXINP]; /* names of these input files */
-int inlineno[MAXINP]; /* current number in each input*/
-FILE *outfile[MAXOUT]; /* diversion array(0=bitbucket)*/
+struct input_file infile[MAXINP];/* input file stack (0=stdin) */
+char *inname[MAXINP]; /* names of these input files */
+int inlineno[MAXINP]; /* current number in each input file */
+FILE **outfile; /* diversion array(0=bitbucket)*/
+int maxout;
FILE *active; /* active output file pointer */
-char *m4temp; /* filename for diversions */
-char *m4dir; /* directory for diversions */
int ilevel = 0; /* input file stack pointer */
int oindex = 0; /* diversion index.. */
char *null = ""; /* as it says.. just a null.. */
char *m4wraps = ""; /* m4wrap string default.. */
-char lquote = LQUOTE; /* left quote character (`) */
-char rquote = RQUOTE; /* right quote character (') */
-char scommt = SCOMMT; /* start character for comment */
-char ecommt = ECOMMT; /* end character for comment */
+char lquote[MAXCCHARS+1] = {LQUOTE}; /* left quote character (`) */
+char rquote[MAXCCHARS+1] = {RQUOTE}; /* right quote character (') */
+char scommt[MAXCCHARS+1] = {SCOMMT}; /* start character for comment */
+char ecommt[MAXCCHARS+1] = {ECOMMT}; /* end character for comment */
int synccpp; /* Line synchronisation for C preprocessor */
int chscratch; /* Scratch space for gpbc() macro */
struct keyblk keywrds[] = { /* m4 keywords to be installed */
- "include", INCLTYPE,
- "sinclude", SINCTYPE,
- "define", DEFITYPE,
- "defn", DEFNTYPE,
- "divert", DIVRTYPE,
- "expr", EXPRTYPE,
- "eval", EXPRTYPE,
- "substr", SUBSTYPE,
- "ifelse", IFELTYPE,
- "ifdef", IFDFTYPE,
- "len", LENGTYPE,
- "incr", INCRTYPE,
- "decr", DECRTYPE,
- "dnl", DNLNTYPE,
- "changequote", CHNQTYPE,
- "changecom", CHNCTYPE,
- "index", INDXTYPE,
+ { "include", INCLTYPE },
+ { "sinclude", SINCTYPE },
+ { "define", DEFITYPE },
+ { "defn", DEFNTYPE },
+ { "divert", DIVRTYPE | NOARGS },
+ { "expr", EXPRTYPE },
+ { "eval", EXPRTYPE },
+ { "substr", SUBSTYPE },
+ { "ifelse", IFELTYPE },
+ { "ifdef", IFDFTYPE },
+ { "len", LENGTYPE },
+ { "incr", INCRTYPE },
+ { "decr", DECRTYPE },
+ { "dnl", DNLNTYPE | NOARGS },
+ { "changequote", CHNQTYPE | NOARGS },
+ { "changecom", CHNCTYPE | NOARGS },
+ { "index", INDXTYPE },
#ifdef EXTENDED
- "paste", PASTTYPE,
- "spaste", SPASTYPE,
+ { "paste", PASTTYPE },
+ { "spaste", SPASTYPE },
+ /* Newer extensions, needed to handle gnu-m4 scripts */
+ { "indir", INDIRTYPE},
+ { "builtin", BUILTINTYPE},
+ { "patsubst", PATSTYPE},
+ { "regexp", REGEXPTYPE},
+ { "esyscmd", ESYSCMDTYPE},
+ { "__file__", FILENAMETYPE | NOARGS},
+ { "__line__", LINETYPE | NOARGS},
#endif
- "popdef", POPDTYPE,
- "pushdef", PUSDTYPE,
- "dumpdef", DUMPTYPE,
- "shift", SHIFTYPE,
- "translit", TRNLTYPE,
- "undefine", UNDFTYPE,
- "undivert", UNDVTYPE,
- "divnum", DIVNTYPE,
- "maketemp", MKTMTYPE,
- "errprint", ERRPTYPE,
- "m4wrap", M4WRTYPE,
- "m4exit", EXITTYPE,
- "syscmd", SYSCTYPE,
- "sysval", SYSVTYPE,
-
-#ifdef unix
- "unix", MACRTYPE,
+ { "popdef", POPDTYPE },
+ { "pushdef", PUSDTYPE },
+ { "dumpdef", DUMPTYPE | NOARGS },
+ { "shift", SHIFTYPE | NOARGS },
+ { "translit", TRNLTYPE },
+ { "undefine", UNDFTYPE },
+ { "undivert", UNDVTYPE | NOARGS },
+ { "divnum", DIVNTYPE | NOARGS },
+ { "maketemp", MKTMTYPE },
+ { "errprint", ERRPTYPE | NOARGS },
+ { "m4wrap", M4WRTYPE | NOARGS },
+ { "m4exit", EXITTYPE | NOARGS },
+ { "syscmd", SYSCTYPE },
+ { "sysval", SYSVTYPE | NOARGS },
+ { "traceon", TRACEONTYPE | NOARGS },
+ { "traceoff", TRACEOFFTYPE | NOARGS },
+
+#if defined(unix) || defined(__unix__)
+ { "unix", SELFTYPE | NOARGS },
#else
#ifdef vms
- "vms", MACRTYPE,
+ { "vms", SELFTYPE | NOARGS },
#endif
#endif
};
#define MAXKEYS (sizeof(keywrds)/sizeof(struct keyblk))
-void macro();
-void initkwds();
+extern int optind;
+extern char *optarg;
+
+#define MAXRECORD 50
+static struct position {
+ char *name;
+ unsigned long line;
+} quotes[MAXRECORD], paren[MAXRECORD];
+
+static void record(struct position *, int);
+static void dump_stack(struct position *, int);
+
+static void macro(void);
+static void initkwds(void);
+static ndptr inspect(int, char *);
+static int do_look_ahead(int, const char *);
+
+static void enlarge_stack(void);
+
+int main(int, char *[]);
int
main(argc,argv)
int argc;
char *argv[];
{
- register int c;
- register int n;
+ int c;
+ int n;
char *p;
- register FILE *ifp;
+
+ traceout = stderr;
if (signal(SIGINT, SIG_IGN) != SIG_IGN)
signal(SIGINT, onintr);
initkwds();
+ initspaces();
+ STACKMAX = INITSTACKMAX;
+
+ mstack = (stae *)xalloc(sizeof(stae) * STACKMAX);
+ sstack = (char *)xalloc(STACKMAX);
- while ((c = getopt(argc, argv, "D:U:s")) != -1)
+ maxout = 0;
+ outfile = NULL;
+ resizedivs(MAXOUT);
+
+ while ((c = getopt(argc, argv, "gst:d:D:U:o:I:")) != -1)
switch(c) {
case 'D': /* define something..*/
@@ -174,12 +204,27 @@ main(argc,argv)
*p++ = EOS;
dodefine(optarg, p);
break;
+ case 'I':
+ addtoincludepath(optarg);
+ break;
case 'U': /* undefine... */
remhash(optarg, TOP);
break;
+ case 'g':
+ mimic_gnu = 1;
+ break;
+ case 'd':
+ set_trace_flags(optarg);
+ break;
case 's':
synccpp = 1;
break;
+ case 't':
+ mark_traced(optarg, 1);
+ break;
+ case 'o':
+ trace_file(optarg);
+ break;
case '?':
usage();
}
@@ -188,19 +233,12 @@ main(argc,argv)
argv += optind;
active = stdout; /* default active output */
- if ((p = strdup(_PATH_DIVDIRNAME)) == NULL)
- err(1, "strdup");
-
- /* filename for diversions */
- m4dir = mkdtemp(p);
- err_set_exit(cleanup);
- (void) asprintf(&m4temp, "%s/%s", m4dir, _PATH_DIVNAME);
-
bbase[0] = bufbase;
if (!argc) {
sp = -1; /* stack pointer initialized */
fp = 0; /* frame pointer initialized */
- infile[0] = stdin; /* default input (naturally) */
+ set_input(infile+0, stdin, "stdin");
+ /* default input (naturally) */
if ((inname[0] = strdup("-")) == NULL)
err(1, NULL);
inlineno[0] = 1;
@@ -209,64 +247,92 @@ main(argc,argv)
} else
for (; argc--; ++argv) {
p = *argv;
- if (p[0] == '-' && p[1] == '\0')
- ifp = stdin;
- else if ((ifp = fopen(p, "r")) == NULL)
+ if (p[0] == '-' && p[1] == EOS)
+ set_input(infile, stdin, "stdin");
+ else if (fopen_trypath(infile, p) == NULL)
err(1, "%s", p);
sp = -1;
- fp = 0;
- infile[0] = ifp;
+ fp = 0;
if ((inname[0] = strdup(p)) == NULL)
err(1, NULL);
inlineno[0] = 1;
emitline();
macro();
- if (ifp != stdin)
- (void)fclose(ifp);
+ release_input(infile);
}
if (*m4wraps) { /* anything for rundown ?? */
ilevel = 0; /* in case m4wrap includes.. */
bufbase = bp = buf; /* use the entire buffer */
- putback(EOF); /* eof is a must !! */
pbstr(m4wraps); /* user-defined wrapup act */
macro(); /* last will and testament */
}
if (active != stdout)
active = stdout; /* reset output just in case */
- for (n = 1; n < MAXOUT; n++) /* default wrap-up: undivert */
+ for (n = 1; n < maxout; n++) /* default wrap-up: undivert */
if (outfile[n] != NULL)
getdiv(n);
/* remove bitbucket if used */
- cleanup(0);
+ if (outfile[0] != NULL) {
+ (void) fclose(outfile[0]);
+ }
+
return 0;
}
-ndptr inspect();
+/*
+ * Look ahead for `token'.
+ * (on input `t == token[0]')
+ * Used for comment and quoting delimiters.
+ * Returns 1 if `token' present; copied to output.
+ * 0 if `token' not found; all characters pushed back
+ */
+static int
+do_look_ahead(t, token)
+ int t;
+ const char *token;
+{
+ int i;
+
+ assert((unsigned char)t == (unsigned char)token[0]);
+
+ for (i = 1; *++token; i++) {
+ t = gpbc();
+ if (t == EOF || (unsigned char)t != (unsigned char)*token) {
+ putback(t);
+ while (--i)
+ putback(*--token);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+#define LOOK_AHEAD(t, token) (t != EOF && \
+ (unsigned char)(t)==(unsigned char)(token)[0] && \
+ do_look_ahead(t,token))
/*
* macro - the work horse..
*/
-void
-macro() {
- char token[MAXTOK];
- register char *s;
- register int t, l;
- register ndptr p;
- register int nlpar;
+static void
+macro()
+{
+ char token[MAXTOK+1];
+ int t, l;
+ ndptr p;
+ int nlpar;
cycle {
- if ((t = gpbc()) == '_' || (t != EOF && isalpha(t))) {
- putback(t);
- if ((p = inspect(s = token)) == nil) {
- if (sp < 0)
- while (*s)
- putc(*s++, active);
- else
- while (*s)
- chrsave(*s++);
- }
+ t = gpbc();
+ if (t == '_' || isalpha(t)) {
+ p = inspect(t, token);
+ if (p != nil)
+ putback(l = gpbc());
+ if (p == nil || (l != LPAREN &&
+ (p->type & NEEDARGS) != 0))
+ outputstr(token);
else {
/*
* real thing.. First build a call frame:
@@ -278,58 +344,93 @@ macro() {
/*
* now push the string arguments:
*/
- pushs(p->defn); /* defn string */
- pushs(p->name); /* macro name */
- pushs(ep); /* start next..*/
-
- putback(l = gpbc());
- if (l != LPAREN) { /* add bracks */
- putback(RPAREN);
- putback(LPAREN);
+ pushs1(p->defn); /* defn string */
+ pushs1(p->name); /* macro name */
+ pushs(ep); /* start next..*/
+
+ if (l != LPAREN && PARLEV == 0) {
+ /* no bracks */
+ chrsave(EOS);
+
+ if (sp == STACKMAX)
+ errx(1, "internal stack overflow");
+ eval((const char **) mstack+fp+1, 2,
+ CALTYP);
+
+ ep = PREVEP; /* flush strspace */
+ sp = PREVSP; /* previous sp.. */
+ fp = PREVFP; /* rewind stack...*/
}
}
- }
- else if (t == EOF) {
- if (sp > -1)
- errx(1, "unexpected end of input");
+ } else if (t == EOF) {
+ if (sp > -1) {
+ warnx( "unexpected end of input, unclosed parenthesis:");
+ dump_stack(paren, PARLEV);
+ exit(1);
+ }
if (ilevel <= 0)
break; /* all done thanks.. */
- --ilevel;
- (void) fclose(infile[ilevel+1]);
+ release_input(infile+ilevel--);
free(inname[ilevel+1]);
bufbase = bbase[ilevel];
emitline();
continue;
}
/*
- * non-alpha single-char token seen..
+ * non-alpha token possibly seen..
* [the order of else if .. stmts is important.]
*/
- else if (t == lquote) { /* strip quotes */
- nlpar = 1;
+ else if (LOOK_AHEAD(t,lquote)) { /* strip quotes */
+ nlpar = 0;
+ record(quotes, nlpar++);
+ /*
+ * Opening quote: scan forward until matching
+ * closing quote has been found.
+ */
do {
- if ((l = gpbc()) == rquote)
- nlpar--;
- else if (l == lquote)
- nlpar++;
- else if (l == EOF)
- errx(1, "missing right quote");
- if (nlpar > 0) {
- if (sp < 0)
- putc(l, active);
+
+ l = gpbc();
+ if (LOOK_AHEAD(l,rquote)) {
+ if (--nlpar > 0)
+ outputstr(rquote);
+ } else if (LOOK_AHEAD(l,lquote)) {
+ record(quotes, nlpar++);
+ outputstr(lquote);
+ } else if (l == EOF) {
+ if (nlpar == 1)
+ warnx("unclosed quote:");
else
- chrsave(l);
+ warnx("%d unclosed quotes:", nlpar);
+ dump_stack(quotes, nlpar);
+ exit(1);
+ } else {
+ if (nlpar > 0) {
+ if (sp < 0)
+ putc(l, active);
+ else
+ CHRSAVE(l);
+ }
}
}
while (nlpar != 0);
}
- else if (sp < 0) { /* not in a macro at all */
- if (t == scommt) { /* comment handling here */
+ else if (sp < 0 && LOOK_AHEAD(t, scommt)) {
+ fputs(scommt, active);
+
+ for(;;) {
+ t = gpbc();
+ if (LOOK_AHEAD(t, ecommt)) {
+ fputs(ecommt, active);
+ break;
+ }
+ if (t == EOF)
+ break;
putc(t, active);
- while ((t = gpbc()) != ecommt)
- putc(t, active);
}
+ }
+
+ else if (sp < 0) { /* not in a macro at all */
putc(t, active); /* output directly.. */
}
@@ -338,10 +439,10 @@ macro() {
case LPAREN:
if (PARLEV > 0)
chrsave(t);
- while ((l = gpbc()) != EOF && isspace(l))
+ while (isspace(l = gpbc()))
; /* skip blank, tab, nl.. */
putback(l);
- PARLEV++;
+ record(paren, PARLEV++);
break;
case RPAREN:
@@ -353,10 +454,8 @@ macro() {
if (sp == STACKMAX)
errx(1, "internal stack overflow");
- if (CALTYP == MACRTYPE)
- expand((char **) mstack+fp+1, sp-fp);
- else
- eval((char **) mstack+fp+1, sp-fp, CALTYP);
+ eval((const char **) mstack+fp+1, sp-fp,
+ CALTYP);
ep = PREVEP; /* flush strspace */
sp = PREVSP; /* previous sp.. */
@@ -367,7 +466,7 @@ macro() {
case COMMA:
if (PARLEV == 1) {
chrsave(EOS); /* new argument */
- while ((l = gpbc()) != EOF && isspace(l))
+ while (isspace(l = gpbc()))
;
putback(l);
pushs(ep);
@@ -376,71 +475,184 @@ macro() {
break;
default:
- chrsave(t); /* stack the char */
+ if (LOOK_AHEAD(t, scommt)) {
+ char *p;
+ for (p = scommt; *p; p++)
+ chrsave(*p);
+ for(;;) {
+ t = gpbc();
+ if (LOOK_AHEAD(t, ecommt)) {
+ for (p = ecommt; *p; p++)
+ chrsave(*p);
+ break;
+ }
+ if (t == EOF)
+ break;
+ CHRSAVE(t);
+ }
+ } else
+ CHRSAVE(t); /* stack the char */
break;
}
}
}
+/*
+ * output string directly, without pushing it for reparses.
+ */
+void
+outputstr(s)
+ const char *s;
+{
+ if (sp < 0)
+ while (*s)
+ putc(*s++, active);
+ else
+ while (*s)
+ CHRSAVE(*s++);
+}
+
/*
* build an input token..
* consider only those starting with _ or A-Za-z. This is a
* combo with lookup to speed things up.
*/
-ndptr
-inspect(tp)
-register char *tp;
+static ndptr
+inspect(c, tp)
+ int c;
+ char *tp;
{
- register int c;
- register char *name = tp;
- register char *etp = tp+MAXTOK;
- register ndptr p;
- register unsigned long h = 0;
-
- while ((c = gpbc()) != EOF && (isalnum(c) || c == '_') && tp < etp)
+ char *name = tp;
+ char *etp = tp+MAXTOK;
+ ndptr p;
+ unsigned int h;
+
+ h = *tp++ = c;
+
+ while ((isalnum(c = gpbc()) || c == '_') && tp < etp)
h = (h << 5) + h + (*tp++ = c);
- putback(c);
- if (tp == etp)
- errx(1, "token too long");
-
+ if (c != EOF)
+ PUTBACK(c);
*tp = EOS;
+ /* token is too long, it won't match anything, but it can still
+ * be output. */
+ if (tp == ep) {
+ outputstr(name);
+ while (isalnum(c = gpbc()) || c == '_') {
+ if (sp < 0)
+ putc(c, active);
+ else
+ CHRSAVE(c);
+ }
+ *name = EOS;
+ return nil;
+ }
- for (p = hashtab[h%HASHSIZE]; p != nil; p = p->nxtptr)
- if (STREQ(name, p->name))
+ for (p = hashtab[h % HASHSIZE]; p != nil; p = p->nxtptr)
+ if (h == p->hv && STREQ(name, p->name))
break;
return p;
}
/*
- * initkwds - initialise m4 keywords as fast as possible.
+ * initkwds - initialise m4 keywords as fast as possible.
* This very similar to install, but without certain overheads,
- * such as calling lookup. Malloc is not used for storing the
- * keyword strings, since we simply use the static pointers
+ * such as calling lookup. Malloc is not used for storing the
+ * keyword strings, since we simply use the static pointers
* within keywrds block.
*/
-void
-initkwds() {
- register int i;
- register int h;
- register ndptr p;
+static void
+initkwds()
+{
+ size_t i;
+ unsigned int h;
+ ndptr p;
for (i = 0; i < MAXKEYS; i++) {
h = hash(keywrds[i].knam);
- if ((p = malloc(sizeof(struct ndblock))) == NULL)
- err(1, "malloc");
- p->nxtptr = hashtab[h];
- hashtab[h] = p;
- p->name = keywrds[i].knam;
+ p = (ndptr) xalloc(sizeof(struct ndblock));
+ p->nxtptr = hashtab[h % HASHSIZE];
+ hashtab[h % HASHSIZE] = p;
+ p->name = xstrdup(keywrds[i].knam);
p->defn = null;
- p->type = keywrds[i].ktyp | STATIC;
+ p->hv = h;
+ p->type = keywrds[i].ktyp & TYPEMASK;
+ if ((keywrds[i].ktyp & NOARGS) == 0)
+ p->type |= NEEDARGS;
+ }
+}
+
+/* Look up a builtin type, even if overridden by the user */
+int
+builtin_type(key)
+ const char *key;
+{
+ int i;
+
+ for (i = 0; i != MAXKEYS; i++)
+ if (STREQ(keywrds[i].knam, key))
+ return keywrds[i].ktyp;
+ return -1;
+}
+
+char *
+builtin_realname(n)
+ int n;
+{
+ int i;
+
+ for (i = 0; i != MAXKEYS; i++)
+ if (((keywrds[i].ktyp ^ n) & TYPEMASK) == 0)
+ return keywrds[i].knam;
+ return NULL;
+}
+
+static void
+record(t, lev)
+ struct position *t;
+ int lev;
+{
+ if (lev < MAXRECORD) {
+ t[lev].name = CURRENT_NAME;
+ t[lev].line = CURRENT_LINE;
}
}
+static void
+dump_stack(t, lev)
+ struct position *t;
+ int lev;
+{
+ int i;
+
+ for (i = 0; i < lev; i++) {
+ if (i == MAXRECORD) {
+ fprintf(stderr, " ...\n");
+ break;
+ }
+ fprintf(stderr, " %s at line %lu\n",
+ t[i].name, t[i].line);
+ }
+}
+
+
+static void
+enlarge_stack()
+{
+ STACKMAX *= 2;
+ mstack = realloc(mstack, sizeof(stae) * STACKMAX);
+ sstack = realloc(sstack, STACKMAX);
+ if (mstack == NULL || sstack == NULL)
+ errx(1, "Evaluation stack overflow (%lu)",
+ (unsigned long)STACKMAX);
+}
+
/* Emit preprocessor #line directive if -s option used. */
void
emitline(void)
{
+
if (synccpp)
fprintf(active, "#line %d \"%s\"\n", inlineno[ilevel],
- inname[ilevel]);
+ inname[ilevel]);
}
OpenPOWER on IntegriCloud