summaryrefslogtreecommitdiff
path: root/usr.bin/m4
diff options
context:
space:
mode:
authorMarc Espie <espie@cvs.openbsd.org>2005-03-02 10:12:16 +0000
committerMarc Espie <espie@cvs.openbsd.org>2005-03-02 10:12:16 +0000
commit0881d45f2f57f4fe554eaf02317176e510800e2d (patch)
tree332bf8c544401d4cec97025f523e2814ea21cd3e /usr.bin/m4
parent3abe8debbffa05857cb7deaa65dd547295859d50 (diff)
let m4wrap handle multiple wraps, both in normal and gnu-mode.
based on Noah Misch's bug report. okay otto, jmc.
Diffstat (limited to 'usr.bin/m4')
-rw-r--r--usr.bin/m4/eval.c25
-rw-r--r--usr.bin/m4/extern.h7
-rw-r--r--usr.bin/m4/m4.18
-rw-r--r--usr.bin/m4/main.c27
4 files changed, 55 insertions, 12 deletions
diff --git a/usr.bin/m4/eval.c b/usr.bin/m4/eval.c
index e2484d42729..87e036ab27a 100644
--- a/usr.bin/m4/eval.c
+++ b/usr.bin/m4/eval.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: eval.c,v 1.54 2005/01/31 16:06:54 robert Exp $ */
+/* $OpenBSD: eval.c,v 1.55 2005/03/02 10:12:15 espie Exp $ */
/* $NetBSD: eval.c,v 1.7 1996/11/10 21:21:29 pk Exp $ */
/*
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)eval.c 8.2 (Berkeley) 4/27/95";
#else
-static char rcsid[] = "$OpenBSD: eval.c,v 1.54 2005/01/31 16:06:54 robert Exp $";
+static char rcsid[] = "$OpenBSD: eval.c,v 1.55 2005/03/02 10:12:15 espie Exp $";
#endif
#endif /* not lint */
@@ -72,6 +72,7 @@ static void gnu_dochq(const char *[], int);
static void dochq(const char *[], int);
static void gnu_dochc(const char *[], int);
static void dochc(const char *[], int);
+static void dom4wrap(const char *);
static void dodiv(int);
static void doundiv(const char *[], int);
static void dosub(const char *[], int);
@@ -434,7 +435,8 @@ expand_builtin(const char *argv[], int argc, int td)
* dom4wrap - set up for
* wrap-up/wind-down activity
*/
- m4wraps = (argc > 2) ? xstrdup(argv[2]) : null;
+ if (argc > 2)
+ dom4wrap(argv[2]);
break;
case EXITTYPE:
@@ -806,6 +808,23 @@ dochc(const char *argv[], int argc)
}
/*
+ * dom4wrap - expand text at EOF
+ */
+static void
+dom4wrap(const char *text)
+{
+ if (wrapindex >= maxwraps) {
+ if (maxwraps == 0)
+ maxwraps = 16;
+ else
+ maxwraps *= 2;
+ m4wraps = xrealloc(m4wraps, maxwraps * sizeof(*m4wraps),
+ "too many m4wraps");
+ }
+ m4wraps[wrapindex++] = xstrdup(text);
+}
+
+/*
* dodivert - divert the output to a temporary file
*/
static void
diff --git a/usr.bin/m4/extern.h b/usr.bin/m4/extern.h
index 6e84878694e..b8d87281ad8 100644
--- a/usr.bin/m4/extern.h
+++ b/usr.bin/m4/extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: extern.h,v 1.39 2003/11/17 17:12:10 espie Exp $ */
+/* $OpenBSD: extern.h,v 1.40 2005/03/02 10:12:15 espie Exp $ */
/* $NetBSD: extern.h,v 1.3 1996/01/13 23:25:24 pk Exp $ */
/*-
@@ -159,7 +159,10 @@ extern char *bbase[]; /* buffer base per ilevel */
extern char ecommt[MAXCCHARS+1];/* end character for comment */
extern char *ep; /* first free char in strspace */
extern char lquote[MAXCCHARS+1];/* left quote character (`) */
-extern char *m4wraps; /* m4wrap string default. */
+extern char **m4wraps; /* m4wrap string default. */
+extern int maxwraps; /* size of m4wraps array */
+extern int wrapindex; /* current index in m4wraps */
+
extern char *null; /* as it says.. just a null. */
extern char rquote[MAXCCHARS+1];/* right quote character (') */
extern char scommt[MAXCCHARS+1];/* start character for comment */
diff --git a/usr.bin/m4/m4.1 b/usr.bin/m4/m4.1
index 72827891d2e..c5ade9f0a7a 100644
--- a/usr.bin/m4/m4.1
+++ b/usr.bin/m4/m4.1
@@ -1,4 +1,4 @@
-.\" @(#) $OpenBSD: m4.1,v 1.37 2004/05/25 20:24:24 jmc Exp $
+.\" @(#) $OpenBSD: m4.1,v 1.38 2005/03/02 10:12:15 espie Exp $
.\"
.\" Copyright (c) 1989, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -138,6 +138,7 @@ Activate GNU-m4 compatibility mode.
In this mode, changequote with
two empty parameters deactivates quotes, translit handles simple character
ranges (e.g., a-z), regular expressions mimic emacs behavior,
+multiple m4wrap calls are handled as a stack,
and the number of diversions is unlimited.
.It Fl s
Output line synchronization directives, suitable for
@@ -294,6 +295,11 @@ usually for cleanup purposes (e.g.,
.Ic m4wrap("cleanup(tempfile)")
causes the macro cleanup to be
invoked after all other processing is done).
+.Pp
+Multiple calls to
+.Fn m4wrap
+get inserted in sequence at the final
+.Dv EOF .
.It Fn maketemp template
Invokes
.Xr mkstemp 3
diff --git a/usr.bin/m4/main.c b/usr.bin/m4/main.c
index 21825bc28dd..9690338820b 100644
--- a/usr.bin/m4/main.c
+++ b/usr.bin/m4/main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.c,v 1.65 2005/01/20 23:47:04 espie Exp $ */
+/* $OpenBSD: main.c,v 1.66 2005/03/02 10:12:15 espie Exp $ */
/* $NetBSD: main.c,v 1.12 1997/02/08 23:54:49 cgd Exp $ */
/*-
@@ -43,7 +43,7 @@ static char copyright[] =
#if 0
static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/6/93";
#else
-static char rcsid[] = "$OpenBSD: main.c,v 1.65 2005/01/20 23:47:04 espie Exp $";
+static char rcsid[] = "$OpenBSD: main.c,v 1.66 2005/03/02 10:12:15 espie Exp $";
#endif
#endif /* not lint */
@@ -83,7 +83,9 @@ FILE *active; /* active output file pointer */
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 **m4wraps = NULL; /* m4wraps array. */
+int maxwraps = 0; /* size of m4wraps array */
+int wrapindex = 0; /* current offset in m4wraps */
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 */
@@ -258,11 +260,24 @@ main(int argc, char *argv[])
release_input(infile);
}
- if (*m4wraps) { /* anything for rundown ?? */
+ if (wrapindex) {
+ int i;
+
ilevel = 0; /* in case m4wrap includes.. */
bufbase = bp = buf; /* use the entire buffer */
- pbstr(m4wraps); /* user-defined wrapup act */
- macro(); /* last will and testament */
+ if (mimic_gnu) {
+ while (wrapindex != 0) {
+ for (i = 0; i < wrapindex; i++)
+ pbstr(m4wraps[i]);
+ wrapindex =0;
+ macro();
+ }
+ } else {
+ for (i = 0; i < wrapindex; i++) {
+ pbstr(m4wraps[i]);
+ macro();
+ }
+ }
}
if (active != stdout)