[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
m4_dumpdef [was: add m4_stack_foreach and m4_stack_foreach_lifo]
From: |
Eric Blake |
Subject: |
m4_dumpdef [was: add m4_stack_foreach and m4_stack_foreach_lifo] |
Date: |
Tue, 28 Oct 2008 20:08:40 +0000 (UTC) |
User-agent: |
Loom/3.14 (http://gmane.org/) |
Eric Blake <ebb9 <at> byu.net> writes:
> > Ok. But no m4_dumpdefs, because it writes on stderr and confuses
> > autom4te.
>
> Ouch. So it does (if you aren't using m4.git's master branch).
> At any rate, we _have_ to override m4_dumpdef to use m4_errprint, if
> we don't want autom4te to crash like it did (at least override it for
> 1.4.x, using the __m4_version__ check also in use for
> _m4_defn/m4_foreach/...).
> So I will go ahead and write a patch for that.
Here's m4_dumpdef, in two patches, tested with both m4 1.4.x and m4.git
master. The second patch is merely an optimization pass that uses m4_map_args
instead of m4_foreach.
For the second patch, this was my testcase for m4_combine before:
$ time echo 'm4_divert[]m4_len(m4_combine(.,m4_dquote(1m4_for(i,1,200,,[,i])),
-m4_for(i,1,200,,[,i])))m4_newline[]m4_debugmode(xt)m4_debugmode' |
m4 -Ilib m4sugar/m4sugar.m4 -
277891
m4trace: -1- id 410459: m4_debugmode
0m2.155s
and after the swap to m4_map_args (it really IS more efficient than m4_foreach):
$ time ...
277891
m4trace: -1- id 287777: m4_debugmode
0m1.717s
Identical results, but roughly 30% fewer macro expansions and correspondingly
faster execution.
>From 0b08f40fc7956f03209e8c8d7fa72c0e4a3bf32b Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Tue, 28 Oct 2008 12:14:06 -0600
Subject: [PATCH] Override m4 1.4.x dumpdef, as it breaks autom4te.
* lib/m4sugar/m4sugar.m4 (m4_dumpdef): New implementation.
* doc/autoconf.texi (Redefined M4 Macros) <m4_dumpdef>: Mention
semantic differences as well as m4_dumpdefs.
* NEWS: Likewise.
* tests/m4sugar.at (m4@&address@hidden): New test.
Signed-off-by: Eric Blake <address@hidden>
---
ChangeLog | 10 ++++++++++
NEWS | 2 +-
doc/autoconf.texi | 15 +++++++++++++--
lib/m4sugar/m4sugar.m4 | 25 +++++++++++++++++++++----
tests/m4sugar.at | 36 ++++++++++++++++++++++++++++++++++++
5 files changed, 81 insertions(+), 7 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 720f4b0..82f3ce3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2008-10-28 Eric Blake <address@hidden>
+ Override m4 1.4.x dumpdef, as it breaks autom4te.
+ * lib/m4sugar/m4sugar.m4 (m4_dumpdef): New implementation.
+ (m4_copy): Formatting touchup.
+ * doc/autoconf.texi (Redefined M4 Macros) <m4_dumpdef>: Mention
+ semantic differences as well as m4_dumpdefs.
+ * NEWS: Likewise.
+ * tests/m4sugar.at (m4@&address@hidden): New test.
+
+2008-10-28 Eric Blake <address@hidden>
+
Allow m4sugar to be used without autom4te, such as in bison.
* lib/m4sugar/m4sugar.m4 (m4_text_wrap, m4_qlen): Document that
alternate escape sequences can be used.
diff --git a/NEWS b/NEWS
index 1f969b1..e22559f 100644
--- a/NEWS
+++ b/NEWS
@@ -17,7 +17,7 @@ GNU Autoconf NEWS - User visible changes.
m4_set_map
** The following m4sugar macros are documented now:
- m4_copy m4_rename
+ m4_copy m4_dumpdefs m4_rename
** The following documented m4sh macros are new:
AS_LINENO_PREPARE AS_ME_PREPARE AS_VAR_APPEND AS_VAR_ARITH
diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index c1427a6..d315ebb 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -10272,7 +10272,6 @@ Redefined M4 Macros
@msindex{decr}
@msindex{define}
@msindex{divnum}
address@hidden
@msindex{errprint}
@msindex{esyscmd}
@msindex{eval}
@@ -10304,7 +10303,6 @@ Redefined M4 Macros
@item m4_decr
@item m4_define
@item m4_divnum
address@hidden m4_dumpdef
@item m4_errprint
@item m4_esyscmd
@item m4_eval
@@ -10404,6 +10402,19 @@ Redefined M4 Macros
diversion stack.
@end defmac
address@hidden m4_dumpdef (@address@hidden)
address@hidden m4_dumpdefs (@var{name})
address@hidden
address@hidden
address@hidden is like the M4 builtin, except that this version
+requires at least one argument, output always goes to standard error
+rather than the current debug file, and an error is issued if any
address@hidden is undefined. @code{m4_dumpdefs} is a convenience macro that
+takes exactly one @var{name}, and calls @code{m4_dumpdef} for all of the
address@hidden stack of definitions, starting with the current, and
+silently does nothing if @var{name} is undefined.
address@hidden defmac
+
@defmac m4_exit (@var{exit-status})
@msindex{exit}
This macro corresponds to @code{m4exit}.
diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4
index a17776c..608c2f2 100644
--- a/lib/m4sugar/m4sugar.m4
+++ b/lib/m4sugar/m4sugar.m4
@@ -539,8 +539,8 @@ m4_define([_m4_bpatsubsts],
# involved in the implementation of m4_stack_foreach and m4_curry.
m4_define([m4_copy],
[m4_ifdef([$2], [m4_fatal([$0: won't overwrite defined macro: $2])],
- [m4_stack_foreach([$1], [m4_curry([m4_pushdef], [$2])])m4_ifdef
([m4_location($1)],
-[m4_define([m4_location($2)], m4_location)])])])
+ [m4_stack_foreach([$1], [m4_curry([m4_pushdef], [$2])])])]dnl
+[m4_ifdef([m4_location($1)], [m4_define([m4_location($2)], m4_location)])])
# m4_define_default(MACRO, VALUE)
@@ -596,6 +596,24 @@ m4_define([m4_defn],
[m4_foreach([_m4_macro], address@hidden,
[$0(_m4_defn([_m4_macro]))])])])
+# m4_dumpdef(NAME...)
+# -------------------
+# In m4 1.4.x, dumpdef writes to the current debugfile, rather than
+# stderr. This in turn royally confuses autom4te; so we follow the
+# lead of newer m4 and always dump to stderr. Unlike the original,
+# this version requires an argument, since there is no convenient way
+# in m4 1.4.x to grab the names of all defined macros. Newer m4
+# always dumps to stderr, regardless of the current debugfile; it also
+# provides m4symbols as a way to grab all current macro names. But
+# dumpdefs is not frequently called, so we don't need to worry about
+# conditionally using these newer features.
+m4_define([m4_dumpdef],
+[m4_if([$#], [0], [m4_fatal([$0: missing argument])],
+ [$#], [1], [m4_ifdef([$1], [m4_errprintn(
+ [$1: ]m4_dquote(_m4_defn([$1])))], [m4_fatal([$0: undefined macro: $1])])],
+ [m4_foreach([_m4_macro], address@hidden,
[$0(_m4_defn([_m4_macro]))])])])
+
+
# m4_dumpdefs(NAME)
# -----------------
# Similar to `m4_dumpdef(NAME)', but if NAME was m4_pushdef'ed, display its
@@ -603,8 +621,7 @@ m4_define([m4_defn],
#
# This macro cheats, because it relies on the current definition of NAME
# while the second argument of m4_stack_foreach_lifo is evaluated (which
-# would be undefined according to the API). If m4_dumpdef is ever rewritten
-# not to use the builtin, revisit this.
+# would be undefined according to the API).
m4_define([m4_dumpdefs],
[m4_stack_foreach_lifo([$1], [m4_dumpdef([$1])m4_ignore])])
diff --git a/tests/m4sugar.at b/tests/m4sugar.at
index 10ebbd8..af4c4d5 100644
--- a/tests/m4sugar.at
+++ b/tests/m4sugar.at
@@ -151,6 +151,42 @@ a b c
AT_CLEANUP
+## ------------ ##
+## m4_dumpdef. ##
+## ------------ ##
+
+AT_SETUP([m4@&address@hidden)
+
+AT_KEYWORDS([m4@&address@hidden)
+
+# Ensure that m4sugar dies when dereferencing undefined macros.
+
+AT_DATA_M4SUGAR([script.4s],
+[[m4_define([good], [yep])
+m4_dumpdef([good], [oops])
+]])
+
+AT_CHECK_M4SUGAR([-o-], 1, [], [stderr])
+AT_CHECK([grep '^good: \[[yep\]]$' stderr], [0], [ignore])
+AT_CHECK([grep 'm4@&address@hidden: undefined.*oops' stderr], [0], [ignore])
+
+# Check that pushdef stacks can be dumped.
+AT_CHECK_M4SUGAR_TEXT([[m4_divert_push([KILL])
+m4_pushdef([a], [1])
+m4_pushdef([a], [2])
+m4_dumpdef([a])
+m4_dumpdefs([a])
+m4_dumpdefs([oops])
+m4_divert_pop([KILL])dnl
+]], [],
+[[a: [2]
+a: [2]
+a: [1]
+]])
+
+AT_CLEANUP
+
+
## --------- ##
## m4_warn. ##
## --------- ##
--
1.6.0.2
>From 2376807bbdf93208068dc4febfba2bda003b1f1a Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Tue, 28 Oct 2008 13:44:53 -0600
Subject: [PATCH] Use m4_map_args in more places.
* lib/m4sugar/m4sugar.m4 (m4_defn, m4_dumpdef, m4_popdef)
(m4_undefine, m4_combine): Use m4_map_args, rather than
m4_foreach.
Signed-off-by: Eric Blake <address@hidden>
---
ChangeLog | 7 +++++++
lib/m4sugar/m4sugar.m4 | 14 +++++++-------
2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 82f3ce3..0451fa9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2008-10-28 Eric Blake <address@hidden>
+ Use m4_map_args in more places.
+ * lib/m4sugar/m4sugar.m4 (m4_defn, m4_dumpdef, m4_popdef)
+ (m4_undefine, m4_combine): Use m4_map_args, rather than
+ m4_foreach.
+
+2008-10-28 Eric Blake <address@hidden>
+
Override m4 1.4.x dumpdef, as it breaks autom4te.
* lib/m4sugar/m4sugar.m4 (m4_dumpdef): New implementation.
(m4_copy): Formatting touchup.
diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4
index 608c2f2..9c24dac 100644
--- a/lib/m4sugar/m4sugar.m4
+++ b/lib/m4sugar/m4sugar.m4
@@ -593,7 +593,7 @@ m4_define([m4_defn],
[m4_if([$#], [0], [[$0]],
[$#], [1], [m4_ifdef([$1], [_m4_defn([$1])],
[m4_fatal([$0: undefined macro: $1])])],
- [m4_foreach([_m4_macro], address@hidden,
[$0(_m4_defn([_m4_macro]))])])])
+ [m4_map_args([$0], $@)])])
# m4_dumpdef(NAME...)
@@ -611,7 +611,7 @@ m4_define([m4_dumpdef],
[m4_if([$#], [0], [m4_fatal([$0: missing argument])],
[$#], [1], [m4_ifdef([$1], [m4_errprintn(
[$1: ]m4_dquote(_m4_defn([$1])))], [m4_fatal([$0: undefined macro: $1])])],
- [m4_foreach([_m4_macro], address@hidden,
[$0(_m4_defn([_m4_macro]))])])])
+ [m4_map_args([$0], $@)])])
# m4_dumpdefs(NAME)
@@ -638,7 +638,7 @@ m4_define([m4_popdef],
[m4_if([$#], [0], [[$0]],
[$#], [1], [m4_ifdef([$1], [_m4_popdef([$1])],
[m4_fatal([$0: undefined macro: $1])])],
- [m4_foreach([_m4_macro], address@hidden,
[$0(_m4_defn([_m4_macro]))])])])
+ [m4_map_args([$0], $@)])])
# m4_shiftn(N, ...)
@@ -699,7 +699,7 @@ m4_define([m4_undefine],
[m4_if([$#], [0], [[$0]],
[$#], [1], [m4_ifdef([$1], [_m4_undefine([$1])],
[m4_fatal([$0: undefined macro: $1])])],
- [m4_foreach([_m4_macro], address@hidden,
[$0(_m4_defn([_m4_macro]))])])])
+ [m4_map_args([$0], $@)])])
# _m4_wrap(PRE, POST)
# -------------------
@@ -2144,9 +2144,9 @@ m4_define([m4_combine],
[m4_pushdef([m4_Separator], [m4_define([m4_Separator],
_m4_defn([m4_echo]))])]]dnl
[[m4_foreach([m4_Prefix], [$2],
- [m4_foreach([m4_Suffix], ]m4_dquote(m4_dquote(m4_shift3($@)))[,
- [m4_Separator([$1])[]_m4_defn([m4_Prefix])[$3]_m4_defn(
- [m4_Suffix])])])]]dnl
+ [m4_map_args([m4_Separator([$1])]m4_dquote(_m4_defn(
+ [m4_Prefix]))[[$3]m4_echo],
+ ]]m4_dquote(m4_dquote(m4_shift3($@)))[[)])]]dnl
[[_m4_popdef([m4_Separator])])])
--
1.6.0.2