diff --git a/data/local.mk b/data/local.mk
index 50efda39..21106451 100644
--- a/data/local.mk
+++ b/data/local.mk
@@ -34,6 +34,7 @@ dist_skeletons_DATA = \
data/skeletons/lalr1.java \
data/skeletons/location.cc \
data/skeletons/stack.hh \
+ data/skeletons/traceon.m4 \
data/skeletons/variant.hh \
data/skeletons/yacc.c
diff --git a/data/skeletons/bison.m4 b/data/skeletons/bison.m4
index 10bdfcb2..637d2fcb 100644
--- a/data/skeletons/bison.m4
+++ b/data/skeletons/bison.m4
@@ -19,6 +19,27 @@
# along with this program. If not, see .
+
+# m4_gsub(STRING, RE1, SUBST1, RE2, SUBST2, ...)
+# ----------------------------------------------
+# m4 equivalent of
+#
+# $_ = STRING;
+# s/RE1/SUBST1/g;
+# s/RE2/SUBST2/g;
+# ...
+#
+# Really similar to m4_bpatsubsts, but behaves properly with quotes.
+# See m4.at's "Generating Comments". Super inelegant, but so far, I
+# did not find any better solution.
+m4_define([b4_gsub],
+[m4_bpatsubst(m4_bpatsubst(m4_bpatsubst([[[[$1]]]],
+ [$2], [$3]),
+ [$4], [$5]),
+ [$6], [$7])])
+
+
+
## ---------------- ##
## Identification. ##
## ---------------- ##
diff --git a/data/skeletons/c-like.m4 b/data/skeletons/c-like.m4
index fb0dc53b..1e5ab02c 100644
--- a/data/skeletons/c-like.m4
+++ b/data/skeletons/c-like.m4
@@ -17,6 +17,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
+
# _b4_comment(TEXT, OPEN, CONTINUE, END)
# --------------------------------------
# Put TEXT in comment. Avoid trailing spaces: don't indent empty lines.
@@ -27,9 +28,10 @@
#
# Prefix all the output lines with PREFIX.
m4_define([_b4_comment],
-[$2[]m4_bpatsubsts(m4_expand([$1]),
- [[*]/], [*\\/],
- [/[*]], [/\\*], [
+[$2[]b4_gsub(m4_expand([$1]),
+ [[*]/], [*\\/],
+ [/[*]], [/\\*],
+ [
\(.\)], [
$3\1])$4])
diff --git a/data/skeletons/traceon.m4 b/data/skeletons/traceon.m4
new file mode 100644
index 00000000..344d7d1c
--- /dev/null
+++ b/data/skeletons/traceon.m4
@@ -0,0 +1,2 @@
+dnl GNU M4 treats -dV in a position-independent manner.
+m4_debugmode(V)m4_traceon()dnl
diff --git a/src/getargs.c b/src/getargs.c
index 2c65e7b5..cee488c2 100644
--- a/src/getargs.c
+++ b/src/getargs.c
@@ -257,7 +257,8 @@ static const argmatch_trace_doc argmatch_trace_docs[] =
{ "sets", "grammar sets: firsts, nullable etc." },
{ "muscles", "m4 definitions passed to the skeleton" },
{ "tools", "m4 invocation" },
- { "m4", "m4 traces" },
+ { "m4-early", "m4 traces starting from the start" },
+ { "m4", "m4 traces starting from the skeleton evaluation" },
{ "skeleton", "skeleton postprocessing" },
{ "time", "time consumption" },
{ "ielr", "IELR conversion" },
@@ -280,6 +281,7 @@ static const argmatch_trace_arg argmatch_trace_args[] =
{ "sets", trace_sets },
{ "muscles", trace_muscles },
{ "tools", trace_tools },
+ { "m4-early", trace_m4_early },
{ "m4", trace_m4 },
{ "skeleton", trace_skeleton },
{ "time", trace_time },
diff --git a/src/getargs.h b/src/getargs.h
index 524f56bd..70be70a4 100644
--- a/src/getargs.h
+++ b/src/getargs.h
@@ -100,12 +100,13 @@ enum trace
trace_grammar = 1 << 7, /**< Reading, reducing the grammar. */
trace_time = 1 << 8, /**< Time consumption. */
trace_skeleton = 1 << 9, /**< Skeleton postprocessing. */
- trace_m4 = 1 << 10, /**< M4 traces. */
- trace_muscles = 1 << 11, /**< M4 definitions of the muscles. */
- trace_ielr = 1 << 12, /**< IELR conversion. */
- trace_closure = 1 << 13, /**< Input/output of closure(). */
- trace_locations = 1 << 14, /**< Full display of locations. */
- trace_cex = 1 << 15, /**< Counterexample generation */
+ trace_m4_early = 1 << 10, /**< M4 early traces. */
+ trace_m4 = 1 << 11, /**< M4 traces. */
+ trace_muscles = 1 << 12, /**< M4 definitions of the muscles. */
+ trace_ielr = 1 << 13, /**< IELR conversion. */
+ trace_closure = 1 << 14, /**< Input/output of closure(). */
+ trace_locations = 1 << 15, /**< Full display of locations. */
+ trace_cex = 1 << 16, /**< Counterexample generation */
trace_all = ~0 /**< All of the above. */
};
/** What debug items bison displays during its run. */
diff --git a/src/output.c b/src/output.c
index ebe75095..d5e97b6b 100644
--- a/src/output.c
+++ b/src/output.c
@@ -687,6 +687,7 @@ output_skeleton (void)
char *skeldir = xpath_join (datadir, "skeletons");
char *m4sugar = xpath_join (datadir, "m4sugar/m4sugar.m4");
char *m4bison = xpath_join (skeldir, "bison.m4");
+ char *traceon = xpath_join (skeldir, "traceon.m4");
char *skel = (IS_PATH_WITH_DIR (skeleton)
? xstrdup (skeleton)
: xpath_join (skeldir, skeleton));
@@ -698,21 +699,10 @@ output_skeleton (void)
/* Create an m4 subprocess connected to us via two pipes. */
- if (trace_flag & trace_tools)
- fprintf (stderr, "running: %s %s - %s %s\n",
- m4, m4sugar, m4bison, skel);
-
- /* Some future version of GNU M4 (most likely 1.6) may treat the -dV in a
- position-dependent manner. Keep it as the first argument so that all
- files are traced.
-
- See the thread starting at
-
- for details. */
int filter_fd[2];
pid_t pid;
{
- char const *argv[10];
+ char const *argv[11];
int i = 0;
argv[i++] = m4;
@@ -730,15 +720,29 @@ output_skeleton (void)
argv[i++] = "-I";
argv[i++] = datadir;
- if (trace_flag & trace_m4)
+ /* Some future version of GNU M4 (most likely 1.6) may treat the
+ -dV in a position-dependent manner. See the thread starting at
+
+ for details. */
+ if (trace_flag & trace_m4_early)
argv[i++] = "-dV";
argv[i++] = m4sugar;
argv[i++] = "-";
argv[i++] = m4bison;
+ if (trace_flag & trace_m4)
+ argv[i++] = traceon;
argv[i++] = skel;
argv[i++] = NULL;
aver (i <= ARRAY_CARDINALITY (argv));
+ if (trace_flag & trace_tools)
+ {
+ fputs ("running:", stderr);
+ for (int j = 0; argv[j]; ++j)
+ fprintf (stderr, " %s", argv[j]);
+ fputc ('\n', stderr);
+ }
+
/* The ugly cast is because gnulib gets the const-ness wrong. */
pid = create_pipe_bidi ("m4", m4, (char **)(void*)argv, false, true,
true, filter_fd);
@@ -747,6 +751,7 @@ output_skeleton (void)
free (skeldir);
free (m4sugar);
free (m4bison);
+ free (traceon);
free (skel);
if (trace_flag & trace_muscles)
diff --git a/tests/m4.at b/tests/m4.at
index 440e975a..6a2ff83f 100644
--- a/tests/m4.at
+++ b/tests/m4.at
@@ -29,18 +29,44 @@ AT_DATA([input.m4],
[[m4@&t@_include(b4_skeletonsdir/[c.m4])
b4_output_begin([output.txt])
+
+b4_gsub([[abcd]],
+ [a], [b])
+b4_gsub([[abcd]],
+ [a], [b],
+ [b], [c],
+ [c], [d])
+
+_b4_comment([["/* () */"]])
+_b4_comment([["/* ( */"]])
+_b4_comment([["/* ) */"]])
+_b4_comment([["/* [] */"]])
+
b4_comment([["/* () */"]])
b4_comment([["/* ( */"]])
b4_comment([["/* ) */"]])
+b4_comment([["/* [] */"]])
+
b4_output_end([output.txt])
]])
AT_BISON_CHECK([-S ./input.m4 input.y])
AT_CHECK([cat output.txt], [],
-[/* "/\* () *\/" */
+[[
+[bbcd]
+[dddd]
+
+"/\* () *\/"
+"/\* ( *\/"
+"/\* ) *\/"
+"/\* [] *\/"
+
+/* "/\* () *\/" */
/* "/\* ( *\/" */
/* "/\* ) *\/" */
-])
+/* "/\* [] *\/" */
+
+]])
AT_CLEANUP