autoconf-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] add m4_stack_foreach and m4_stack_foreach_lifo


From: Paolo Bonzini
Subject: [PATCH] add m4_stack_foreach and m4_stack_foreach_lifo
Date: Tue, 28 Oct 2008 12:57:31 +0100

This patch extracts the pushdef-stack manipulation code of m4_copy into
new general-purpose macros.  The resulting m4_copy implementation is quite
elegant, using m4_curry to push new definitions.

The disadvantage is that more macros cannot be copied with m4_copy,
including m4_curry and m4_stack_foreach.

The next patch will use the macros to implement the m4 diversion and
expansion stacks in a nicer way, and without possibly quadratic behavior.

Ok?

Paolo

2008-10-28  Paolo Bonzini  <address@hidden>

        * lib/m4sugar/m4sugar.m4 (_m4_stack_reverse): New from _m4_copy.
        (m4_stack_foreach, m4_stack_foreach_lifo): New.
        (m4_copy): Use m4_stack_foreach and m4_curry.
        * tests/m4sugar.at (m4_stack_foreach): New test.
---
 lib/m4sugar/m4sugar.m4 |   37 ++++++++++++++++++++++++++-----------
 tests/m4sugar.at       |   45 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 71 insertions(+), 11 deletions(-)

diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4
index 22c38e8..8d0a772 100644
--- a/lib/m4sugar/m4sugar.m4
+++ b/lib/m4sugar/m4sugar.m4
@@ -527,6 +527,28 @@ m4_define([_m4_bpatsubsts],
           m4_shift3($@))])])
 
 
+# m4_stack_foreach(MACRO, FUNC)
+# m4_stack_foreach_lifo(MACRO, FUNC)
+# -----------------------------
+# Pass each stacked definition of MACRO to the one-argument macro FUNC.
+# m4_stack_foreach proceeds in FIFO order, while m4_stack_foreach_lifo
+# processes the topmost definitions first.
+#
+# The recursive worker _m4_stack_reverse destructively swaps the order of a
+# stack.  We use a temporary stack, and swap directions twice.  Some macros
+# simply can't be examined with this method: namely, anything involved
+# in the implementation of _m4_stack_reverse.
+m4_define([_m4_stack_reverse],
+[m4_ifdef([$1], [m4_pushdef([$2], _m4_defn([$1]))$3[]_m4_popdef([$1])$0($@)])])
+
+m4_define([m4_stack_foreach],
+[_m4_stack_reverse([$1], [m4_tmp])]dnl
+[_m4_stack_reverse([m4_tmp], [$1], [$2(_m4_defn([m4_tmp]))])])
+
+m4_define([m4_stack_foreach_lifo],
+[_m4_stack_reverse([$1], [m4_tmp], [$2(_m4_defn([m4_tmp]))])]dnl
+[_m4_stack_reverse([m4_tmp], [$1])])
+
 # m4_copy(SRC, DST)
 # -----------------
 # Define the pushdef stack DST as a copy of the pushdef stack SRC;
@@ -535,19 +557,12 @@ m4_define([_m4_bpatsubsts],
 # includes one-shot initialization that is later popped to the normal
 # definition.
 #
-# The recursive worker destructively swaps the order of a stack.  We
-# use a temporary stack, and swap directions twice, using the third
-# argument to restore the original stack.
-#
-# Some macros simply can't be renamed with this method: namely,
-# anything involved in the implementation of _m4_copy.
+# Some macros simply can't be renamed with this method: namely, anything
+# 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])],
-         [_$0([$1], [m4_tmp])_$0([m4_tmp], [$2],
-  [m4_pushdef([$1], _m4_defn([m4_tmp]))])m4_ifdef([m4_location($1)],
-  [m4_define([m4_location($2)], m4_location)])])])
-m4_define([_m4_copy],
-[m4_ifdef([$1], [m4_pushdef([$2], _m4_defn([$1]))$3[]_m4_popdef([$1])$0($@)])])
+         [m4_stack_foreach([$1], [m4_curry([m4_pushdef], 
[$2])])m4_ifdef([m4_location($1)],
+[m4_define([m4_location($2)], m4_location)])])])
 
 
 # m4_define_default(MACRO, VALUE)
diff --git a/tests/m4sugar.at b/tests/m4sugar.at
index 959b209..32f07dd 100644
--- a/tests/m4sugar.at
+++ b/tests/m4sugar.at
@@ -37,6 +37,51 @@ AT_CHECK_M4SUGAR([-o-],, [$2], [$3])
 ])# AT_CHECK_M4SUGAR_TEXT
 
 
+## ------------------ ##
+## m4_stack_foreach.  ##
+## ------------------ ##
+
+AT_SETUP([m4@&address@hidden)
+
+AT_KEYWORDS([m4@&address@hidden m4@&address@hidden m4@&address@hidden 
m4@&address@hidden)
+
+# Test the semantics of macros to walk stacked macro definitions.
+AT_CHECK_M4SUGAR_TEXT([[dnl
+m4_pushdef([abc], [def])dnl
+m4_pushdef([abc], [ghi])dnl
+m4_pushdef([abc], [jkl])dnl
+m4_stack_foreach([abc], [m4_n])
+abc
+m4_stack_foreach_lifo([abc], [m4_n])
+m4_stack_foreach([abc], [m4_n])
+m4_copy([abc], [foo])dnl
+m4_stack_foreach([foo], [m4_n])
+m4_stack_foreach_lifo([foo], [m4_n])]],
+[[def
+ghi
+jkl
+
+jkl
+jkl
+ghi
+def
+
+def
+ghi
+jkl
+
+def
+ghi
+jkl
+
+jkl
+ghi
+def
+]])
+
+AT_CLEANUP
+
+
 ## --------- ##
 ## m4_defn.  ##
 ## --------- ##
-- 
1.5.5





reply via email to

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