autoconf-patches
[Top][All Lists]
Advanced

[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







reply via email to

[Prev in Thread] Current Thread [Next in Thread]