autoconf-commit
[Top][All Lists]
Advanced

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

[SCM] GNU Autoconf source repository branch, master, updated. v2.63-165-


From: Eric Blake
Subject: [SCM] GNU Autoconf source repository branch, master, updated. v2.63-165-gb07a2b3
Date: Thu, 06 Nov 2008 03:39:20 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Autoconf source repository".

http://git.sv.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=b07a2b3d74f02078b409f70666853a353f95dd94

The branch, master has been updated
       via  b07a2b3d74f02078b409f70666853a353f95dd94 (commit)
       via  4e009d522870613c74305ad49e6cc548133b6bab (commit)
       via  a8c4be749a992c2e9c2f0a59336f964f4cce6d4f (commit)
       via  641487fb34b8bb642ece91340d9fa2a57d75d9ee (commit)
       via  aae086a2f71b316f2f29ad6ad3d45a8c69fffe3c (commit)
       via  1329287eb793d45ae2375414c0ec2fc17b10871d (commit)
       via  9a79ba954dc5d47e4508a2c76048d53afe436974 (commit)
      from  ee0d4bd36b0ba4b58df9aca7208dfe25682fc1bb (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit b07a2b3d74f02078b409f70666853a353f95dd94
Author: Eric Blake <address@hidden>
Date:   Wed Nov 5 17:11:15 2008 -0700

    Add m4_map_args_w.
    
    * lib/m4sugar/m4sugar.m4 (m4_map_args_w): New macro, undocumented
    for now.
    (_m4_split): Allow user control over separator.
    (m4_split): Adjust caller.
    (m4_foreach_w, m4_append_uniq_w, _m4_text_wrap): Rewrite to use
    m4_map_args_w.
    * tests/m4sugar.at (m4@&address@hidden): Augment test keywords.
    (M4 loops): Test new interface.
    
    Signed-off-by: Eric Blake <address@hidden>

commit 4e009d522870613c74305ad49e6cc548133b6bab
Author: Eric Blake <address@hidden>
Date:   Wed Nov 5 12:09:00 2008 -0700

    Use m4_set_map_sep in more places.
    
    * lib/m4sugar/m4sugar.m4 (m4_set_difference, m4_set_intersection)
    (m4_set_union): Use m4_set_map_sep rather than m4_set_foreach.
    * doc/autoconf.texi (Set manipulation Macros) <m4_set_map>:
    Enhance documentation.
    <m4_set_foreach>: Mention faster alternative.
    (Looping constructs) <m4_foreach>: Likewise.
    
    Signed-off-by: Eric Blake <address@hidden>

commit a8c4be749a992c2e9c2f0a59336f964f4cce6d4f
Author: Eric Blake <address@hidden>
Date:   Wed Nov 5 11:47:04 2008 -0700

    Unify m4_set_foreach and m4_set_map.
    
    * lib/m4sugar/m4sugar.m4 (m4_set_map_sep): New macro, undocumented
    for now.
    (m4_set_contents, m4_set_foreach, m4_set_list, m4_set_listc)
    (m4_set_map): Adjust callers.
    
    Signed-off-by: Eric Blake <address@hidden>

commit 641487fb34b8bb642ece91340d9fa2a57d75d9ee
Author: Eric Blake <address@hidden>
Date:   Wed Nov 5 11:12:42 2008 -0700

    Use _m4_foreach in more places.
    
    * lib/m4sugar/foreach.m4 (m4_dquote_elt, m4_join, m4_joinall)
    (_m4_minmax, m4_set_add_all): Use _m4_foreach instead of
    m4_foreach.
    * lib/m4sugar/m4sugar.m4 (_m4_joinall): Use m4_map_args_sep
    instead of m4_foreach or m4_map_args.
    
    Signed-off-by: Eric Blake <address@hidden>

commit aae086a2f71b316f2f29ad6ad3d45a8c69fffe3c
Author: Eric Blake <address@hidden>
Date:   Wed Nov 5 07:15:56 2008 -0700

    Unify _m4_foreach and _m4_map.
    
    * lib/m4sugar/m4sugar.m4 (_m4_map): Delete, merged with...
    (_m4_foreach): ...this.
    (m4_foreach, m4_map, m4_mapall, m4_map_sep, _m4_mapall_sep)
    (m4_map_args, m4_map_args_sep): Adjust callers.
    * lib/m4sugar/foreach.m4 (_m4_map): Rename...
    (_m4_foreach): ...to this, overwriting old definition.
    
    Signed-off-by: Eric Blake <address@hidden>

commit 1329287eb793d45ae2375414c0ec2fc17b10871d
Author: Eric Blake <address@hidden>
Date:   Mon Nov 3 17:17:38 2008 -0700

    Add m4_map_args_sep, undocumented for now.
    
    * lib/m4sugar/m4sugar.m4 (m4_map_args_sep): New macro.
    (_m4_map): Change API to cover more of m4_map*.
    * lib/m4sugar/foreach.m4 (_m4_map): Adjust to new API.
    (m4_map_args): Delete.
    * tests/m4sugar.at (m4@&address@hidden and m4@&address@hidden): Enhance
    test.
    
    Signed-off-by: Eric Blake <address@hidden>

commit 9a79ba954dc5d47e4508a2c76048d53afe436974
Author: Eric Blake <address@hidden>
Date:   Tue Nov 4 12:35:09 2008 -0700

    Improve m4_for performance.
    
    * lib/m4sugar/m4sugar.m4 (_m4_for): Alter API to make it easier to
    avoid m4_define by some clients.
    (m4_for): Adjust caller.
    * lib/m4sugar/foreach.m4 (_m4_foreach, m4_case, m4_bmatch)
    (_m4_cond, _m4_bpatsubsts, _m4_shiftn, m4_do, m4_reverse)
    (_m4_map, m4_map_args, m4_map_args_pair, _m4_list_pad)
    (_m4_list_cmp): Likewise.
    
    Signed-off-by: Eric Blake <address@hidden>

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog              |   60 ++++++++++++
 doc/autoconf.texi      |   14 ++-
 lib/m4sugar/foreach.m4 |  191 ++++++++++++++++++---------------------
 lib/m4sugar/m4sugar.m4 |  238 ++++++++++++++++++++++++++----------------------
 tests/m4sugar.at       |   23 ++++-
 5 files changed, 304 insertions(+), 222 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 10e7b12..e6686fc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,63 @@
+2008-11-05  Eric Blake  <address@hidden>
+
+       Add m4_map_args_w.
+       * lib/m4sugar/m4sugar.m4 (m4_map_args_w): New macro, undocumented
+       for now.
+       (_m4_split): Allow user control over separator.
+       (m4_split): Adjust caller.
+       (m4_foreach_w, m4_append_uniq_w, _m4_text_wrap): Rewrite to use
+       m4_map_args_w.
+       * tests/m4sugar.at (m4@&address@hidden): Augment test keywords.
+       (M4 loops): Test new interface.
+
+       Use m4_set_map_sep in more places.
+       * lib/m4sugar/m4sugar.m4 (m4_set_difference, m4_set_intersection)
+       (m4_set_union): Use m4_set_map_sep rather than m4_set_foreach.
+       * doc/autoconf.texi (Set manipulation Macros) <m4_set_map>:
+       Enhance documentation.
+       <m4_set_foreach>: Mention faster alternative.
+       (Looping constructs) <m4_foreach>: Likewise.
+
+       Unify m4_set_foreach and m4_set_map.
+       * lib/m4sugar/m4sugar.m4 (m4_set_map_sep): New macro, undocumented
+       for now.
+       (m4_set_contents, m4_set_foreach, m4_set_list, m4_set_listc)
+       (m4_set_map): Adjust callers.
+
+       Use _m4_foreach in more places.
+       * lib/m4sugar/foreach.m4 (m4_dquote_elt, m4_join, m4_joinall)
+       (_m4_minmax, m4_set_add_all): Use _m4_foreach instead of
+       m4_foreach.
+       * lib/m4sugar/m4sugar.m4 (_m4_joinall): Use m4_map_args_sep
+       instead of m4_foreach or m4_map_args.
+
+       Unify _m4_foreach and _m4_map.
+       * lib/m4sugar/m4sugar.m4 (_m4_map): Delete, merged with...
+       (_m4_foreach): ...this.
+       (m4_foreach, m4_map, m4_mapall, m4_map_sep, _m4_mapall_sep)
+       (m4_map_args, m4_map_args_sep): Adjust callers.
+       * lib/m4sugar/foreach.m4 (_m4_map): Rename...
+       (_m4_foreach): ...to this, overwriting old definition.
+
+2008-11-04  Eric Blake  <address@hidden>
+
+       Add m4_map_args_sep, undocumented for now.
+       * lib/m4sugar/m4sugar.m4 (m4_map_args_sep): New macro.
+       (_m4_map): Change API to cover more of m4_map*.
+       * lib/m4sugar/foreach.m4 (_m4_map): Adjust to new API.
+       (m4_map_args): Delete.
+       * tests/m4sugar.at (m4@&address@hidden and m4@&address@hidden): Enhance
+       test.
+
+       Improve m4_for performance.
+       * lib/m4sugar/m4sugar.m4 (_m4_for): Alter API to make it easier to
+       avoid m4_define by some clients.
+       (m4_for): Adjust caller.
+       * lib/m4sugar/foreach.m4 (_m4_foreach, m4_case, m4_bmatch)
+       (_m4_cond, _m4_bpatsubsts, _m4_shiftn, m4_do, m4_reverse)
+       (_m4_map, m4_map_args, m4_map_args_pair, _m4_list_pad)
+       (_m4_list_cmp): Likewise.
+
 2008-11-04  Eric Blake  <address@hidden>
 
        Adjust expected output.
diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index bc46d77..e114992 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -10921,6 +10921,9 @@ m4_foreach([myvar], [[foo], [bar, baz]],
 @result{}echo foo
 @result{}echo bar, baz
 @end example
+
+Note that for some forms of @var{expression}, it may be faster to use
address@hidden
 @end defmac
 
 @anchor{m4_foreach_w}
@@ -11786,7 +11789,8 @@ unspecified if @var{action} recursively lists the 
contents of @var{set}
 in any way other than removing the element currently contained in
 @var{variable}.  This macro is faster than the corresponding
 @code{m4_foreach(address@hidden,
-m4_indir([m4_dquote]m4_set_listc(address@hidden)), address@hidden)}.
+m4_indir([m4_dquote]m4_set_listc(address@hidden)), address@hidden)},
+although @code{m4_set_map} might be faster still.
 
 @example
 m4_set_add_all([a]m4_for([i], [1], [5], [], [,i]))
@@ -11847,9 +11851,11 @@ For each element in the set @var{set}, expand 
@var{action} with a single
 argument of the set element.  Behavior is unspecified if @var{action}
 recursively lists the contents of @var{set} (although listing other sets
 is acceptable), or if it modifies the set in any way other than removing
-the element passed as an argument.  This macro is faster than the
-corresponding
address@hidden(address@hidden(address@hidden))}.
+the element passed as an argument.  This macro is faster than either
+corresponding counterpart of
address@hidden(address@hidden(address@hidden))} or
address@hidden(address@hidden, [var],
address@hidden(m4_defn([var]))])}.
 @end defmac
 
 @defmac m4_set_remove (@var{set}, @var{value}, @ovar{if-present}, @
diff --git a/lib/m4sugar/foreach.m4 b/lib/m4sugar/foreach.m4
index 9dc02e1..d9ebfe0 100644
--- a/lib/m4sugar/foreach.m4
+++ b/lib/m4sugar/foreach.m4
@@ -79,29 +79,29 @@
 #
 # Please keep this file in sync with m4sugar.m4.
 
-# m4_foreach(VARIABLE, LIST, EXPRESSION)
-# --------------------------------------
-# Expand EXPRESSION assigning each value of the LIST to VARIABLE.
-# LIST should have the form `item_1, item_2, ..., item_n', i.e. the
-# whole list must *quoted*.  Quote members too if you don't want them
-# to be expanded.
+# _m4_foreach(PRE, POST, IGNORED, ARG...)
+# ---------------------------------------
+# Form the common basis of the m4_foreach and m4_map macros.  For each
+# ARG, expand PRE[ARG]POST[].  The IGNORED argument makes recursion
+# easier, and must be supplied rather than implicit.
 #
 # This version minimizes the number of times that $@ is evaluated by
-# using m4_for to generate a boilerplate into VARIABLE then passing $@
-# to that temporary macro.  Thus, the recursion is done in m4_for
-# without reparsing any user input, and is not quadratic.  For an idea
-# of how this works, note that m4_foreach(i,[1,2],[i]) defines i to be
-#   m4_define([$1],[$3])$2[]m4_define([$1],[$4])$2[]m4_popdef([i])
-# then calls i([i],[i],[1],[2]).
-m4_define([m4_foreach],
-[m4_if([$2], [], [], [_$0([$1], [$3], $2)])])
-
+# using m4_for to generate a boilerplate into _m4_f then passing $@ to
+# that temporary macro.  Thus, the recursion is done in m4_for without
+# reparsing any user input, and is not quadratic.  For an idea of how
+# this works, note that m4_foreach(i,[1,2],[i]) calls
+#   _m4_foreach([m4_define([i],],[)i],[],[1],[2])
+# which defines _m4_f:
+#   $1[$4]$2[]$1[$5]$2[]_m4_popdef([_m4_f])
+# then calls _m4_f([m4_define([i],],[)i],[],[1],[2]) for a net result:
+#   m4_define([i],[1])i[]m4_define([i],[2])i[]_m4_popdef([_m4_f]).
 m4_define([_m4_foreach],
-[m4_define([$1], m4_pushdef([$1])_m4_for([$1], [3], [$#], [1],
-    [$0_([1], [2], _m4_defn([$1]))])[m4_popdef([$1])])m4_indir([$1], $@)])
+[m4_if([$#], [3], [],
+       [m4_pushdef([_m4_f], _m4_for([4], [$#], [1],
+   [$0_([1], [2],], [)])[_m4_popdef([_m4_f])])_m4_f($@)])])
 
 m4_define([_m4_foreach_],
-[[m4_define([$$1], [$$3])$$2[]]])
+[[$$1[$$3]$$2[]]])
 
 # m4_case(SWITCH, VAL1, IF-VAL1, VAL2, IF-VAL2, ..., DEFAULT)
 # -----------------------------------------------------------
@@ -116,11 +116,14 @@ m4_define([_m4_foreach_],
 #   m4_if([$1],[$2],[$3],[$1],[$4],[$5],_m4_popdef([_m4_case])[$6])
 m4_define([m4_case],
 [m4_if(m4_eval([$# <= 2]), [1], [$2],
-[m4_pushdef([_$0], [m4_if(]m4_for([_m4_count], [2], m4_decr([$#]), [2],
-     [_$0_([1], _m4_count, m4_incr(_m4_count))])[_m4_popdef(
+[m4_pushdef([_$0], [m4_if(]_m4_for([2], m4_eval([($# - 1) / 2 * 2]), [2],
+     [_$0_(], [)])[_m4_popdef(
         [_$0])]m4_dquote($m4_eval([($# + 1) & ~1]))[)])_$0($@)])])
 
 m4_define([_m4_case_],
+[$0_([1], [$1], m4_incr([$1]))])
+
+m4_define([_m4_case__],
 [[[$$1],[$$2],[$$3],]])
 
 # m4_bmatch(SWITCH, RE1, VAL1, RE2, VAL2, ..., DEFAULT)
@@ -144,15 +147,18 @@ m4_define([m4_bmatch],
 [m4_if([$#], 0, [m4_fatal([$0: too few arguments: $#])],
        [$#], 1, [m4_fatal([$0: too few arguments: $#: $1])],
        [$#], 2, [$2],
-       [m4_define([_m4_b], m4_pushdef([_m4_b])[m4_define([_m4_b],
-  _m4_defn([_$0]))]_m4_for([_m4_b], [3], m4_eval([($# + 1) / 2 * 2 - 1]),
-  [2], [_$0_([1], m4_decr(_m4_b), _m4_b)])[_m4_b([], [],]m4_dquote(
-  [$]m4_incr(_m4_b))[_m4_popdef([_m4_b]))])m4_unquote(_m4_b($@))])])
+       [m4_pushdef([_m4_b], [m4_define([_m4_b],
+  _m4_defn([_$0]))]_m4_for([3], m4_eval([($# + 1) / 2 * 2 - 1]),
+  [2], [_$0_(], [)])[_m4_b([], [],]m4_dquote([$]m4_eval(
+  [($# + 1) / 2 * 2]))[_m4_popdef([_m4_b]))])m4_unquote(_m4_b($@))])])
 
 m4_define([_m4_bmatch],
 [m4_if(m4_bregexp([$1], [$2]), [-1], [], [[$3]m4_define([$0])])])
 
 m4_define([_m4_bmatch_],
+[$0_([1], m4_decr([$1]), [$1])])
+
+m4_define([_m4_bmatch__],
 [[_m4_b([$$1], [$$2], [$$3])]])
 
 
@@ -172,12 +178,15 @@ m4_define([_m4_bmatch_],
 #   [[$m]m4_define([_m4_c])])])_m4_c([[$m+1]]_m4_popdef([_m4_c]))
 # We invoke m4_unquote(_m4_c($@)), for concatenation with later text.
 m4_define([_m4_cond],
-[m4_define([_m4_c], m4_pushdef([_m4_c])[m4_define([_m4_c],
-  _m4_defn([m4_unquote]))]_m4_for([_m4_c], [2], m4_eval([$# / 3 * 3 - 1]), [3],
-  [$0_(m4_decr(_m4_c), _m4_c, m4_incr(_m4_c))])[_m4_c(]m4_dquote(m4_dquote(
+[m4_pushdef([_m4_c], [m4_define([_m4_c],
+  _m4_defn([m4_unquote]))]_m4_for([2], m4_eval([$# / 3 * 3 - 1]), [3],
+  [$0_(], [)])[_m4_c(]m4_dquote(m4_dquote(
   [$]m4_eval([$# / 3 * 3 + 1])))[_m4_popdef([_m4_c]))])m4_unquote(_m4_c($@))])
 
 m4_define([_m4_cond_],
+[$0_(m4_decr([$1]), [$1], m4_incr([$1]))])
+
+m4_define([_m4_cond__],
 [[_m4_c([m4_if(($$1), [($$2)], [[$$3]m4_define([_m4_c])])])]])
 
 # m4_bpatsubsts(STRING, RE1, SUBST1, RE2, SUBST2, ...)
@@ -198,11 +207,14 @@ m4_define([_m4_cond_],
 #   m4_bpatsubst(m4_dquote(_m4_defn([_m4_p])), [$m-1], [$m]))m4_unquote(
 #   _m4_defn([_m4_p])_m4_popdef([_m4_p]))
 m4_define([_m4_bpatsubsts],
-[m4_define([_m4_p], m4_pushdef([_m4_p])[m4_define([_m4_p],
-  ]m4_dquote([$]1)[)]_m4_for([_m4_p], [3], [$#], [2], [$0_(m4_decr(_m4_p),
-  _m4_p)])[m4_unquote(_m4_defn([_m4_p])_m4_popdef([_m4_p]))])_m4_p($@)])
+[m4_pushdef([_m4_p], [m4_define([_m4_p],
+  ]m4_dquote([$]1)[)]_m4_for([3], [$#], [2], [$0_(],
+  [)])[m4_unquote(_m4_defn([_m4_p])_m4_popdef([_m4_p]))])_m4_p($@)])
 
 m4_define([_m4_bpatsubsts_],
+[$0_(m4_decr([$1]), [$1])])
+
+m4_define([_m4_bpatsubsts__],
 [[m4_define([_m4_p],
 m4_bpatsubst(m4_dquote(_m4_defn([_m4_p])), [$$1], [$$2]))]])
 
@@ -215,9 +227,9 @@ m4_bpatsubst(m4_dquote(_m4_defn([_m4_p])), [$$1], [$$2]))]])
 #   ,[$5],[$6],...,[$m]_m4_popdef([_m4_s])
 # before calling m4_shift(_m4_s($@)).
 m4_define([_m4_shiftn],
-[m4_if(m4_incr([$1]), [$#], [], [m4_define([_m4_s],
-          m4_pushdef([_m4_s])_m4_for([_m4_s], m4_eval([$1 + 2]), [$#], [1],
-  [[,]m4_dquote([$]_m4_s)])[_m4_popdef([_m4_s])])m4_shift(_m4_s($@))])])
+[m4_if(m4_incr([$1]), [$#], [], [m4_pushdef([_m4_s],
+  _m4_for(m4_eval([$1 + 2]), [$#], [1],
+  [[,]m4_dquote($], [)])[_m4_popdef([_m4_s])])m4_shift(_m4_s($@))])])
 
 # m4_do(STRING, ...)
 # ------------------
@@ -229,16 +241,16 @@ m4_define([_m4_shiftn],
 #   $1[]$2[]...[]$n[]_m4_popdef([_m4_do])
 m4_define([m4_do],
 [m4_if([$#], [0], [],
-       [m4_define([_$0], m4_pushdef([_$0])_m4_for([_$0], [1], [$#], [1],
-                 [$_$0[[]]])[_m4_popdef([_$0])])_$0($@)])])
+       [m4_pushdef([_$0], _m4_for([1], [$#], [1],
+                  [$], [[[]]])[_m4_popdef([_$0])])_$0($@)])])
 
 # m4_dquote_elt(ARGS)
 # -------------------
 # Return ARGS as an unquoted list of double-quoted arguments.
 #
-# m4_foreach to the rescue.  It's easier to shift off the leading comma.
+# _m4_foreach to the rescue.
 m4_define([m4_dquote_elt],
-[m4_shift(m4_foreach([_m4_elt], address@hidden, 
[,m4_dquote(_m4_defn([_m4_elt]))]))])
+[m4_if([$#], [0], [], [[[$1]]_m4_foreach([,m4_dquote(], [)], $@)])])
 
 # m4_reverse(ARGS)
 # ----------------
@@ -248,44 +260,10 @@ m4_define([m4_dquote_elt],
 #   [$m], [$m-1], ..., [$2], [$1]_m4_popdef([_m4_r])
 m4_define([m4_reverse],
 [m4_if([$#], [0], [], [$#], [1], [[$1]],
-[m4_define([_m4_r], m4_dquote([$$#])m4_pushdef([_m4_r])_m4_for([_m4_r],
-      m4_decr([$#]), [1], [-1],
-    [[, ]m4_dquote([$]_m4_r)])[_m4_popdef([_m4_r])])_m4_r($@)])])
+[m4_pushdef([_m4_r], [[$$#]]_m4_for(m4_decr([$#]), [1], [-1],
+    [[, ]m4_dquote($], [)])[_m4_popdef([_m4_r])])_m4_r($@)])])
 
 
-# m4_map(MACRO, LIST)
-# -------------------
-# Invoke MACRO($1), MACRO($2) etc. where $1, $2... are the elements
-# of LIST.  $1, $2... must in turn be lists, appropriate for m4_apply.
-#
-# m4_map/m4_map_sep only execute once; the speedup comes in fixing
-# _m4_map.  The mismatch in () is intentional, since $1 supplies the
-# opening `(' (but it sure looks odd!).  Build the temporary _m4_m:
-#   $1, [$3])$1, [$4])...$1, [$m])_m4_popdef([_m4_m])
-m4_define([_m4_map],
-[m4_if([$#], [2], [],
-       [m4_define([_m4_m], m4_pushdef([_m4_m])_m4_for([_m4_m], [3], [$#], [1],
-   [$0_([1], _m4_m)])[_m4_popdef([_m4_m])])_m4_m($@)])])
-
-m4_define([_m4_map_],
-[[$$1, [$$2])]])
-
-# m4_map_args(EXPRESSION, ARG...)
-# -------------------------------
-# Expand EXPRESSION([ARG]) for each argument.  More efficient than
-# m4_foreach([var], [ARG...], [EXPRESSION(m4_defn([var]))])
-#
-# Invoke the temporary macro _m4_map_args, defined as:
-#   $1([$2])[]$1([$3])[]...$1([$m])[]_m4_popdef([_m4_map_args])
-m4_define([m4_map_args],
-[m4_if([$#], [0], [m4_fatal([$0: too few arguments: $#])],
-       [$#], [1], [],
-       [m4_define([_$0], m4_pushdef([_$0])_m4_for([_$0], [2], [$#], [1],
-   [_$0_([1], _$0)])[_m4_popdef([_$0])])_$0($@)])])
-
-m4_define([_m4_map_args_],
-[[$$1([$$2])[]]])
-
 # m4_map_args_pair(EXPRESSION, [END-EXPR = EXPRESSION], ARG...)
 # -------------------------------------------------------------
 # Perform a pairwise grouping of consecutive ARGs, by expanding
@@ -301,11 +279,14 @@ m4_define([m4_map_args_pair],
        [$#], [1], [m4_fatal([$0: too few arguments: $#: $1])],
        [$#], [2], [],
        [$#], [3], [m4_default([$2], [$1])([$3])[]],
-       [m4_define([_$0], m4_pushdef([_$0])_m4_for([_$0], [3],
-   m4_eval([$# / 2 * 2 - 1]), [2], [_$0_([1], _$0, m4_incr(_$0))])_$0_end(
+       [m4_pushdef([_$0], _m4_for([3],
+   m4_eval([$# / 2 * 2 - 1]), [2], [_$0_(], [)])_$0_end(
    [1], [2], [$#])[_m4_popdef([_$0])])_$0($@)])])
 
 m4_define([_m4_map_args_pair_],
+[$0_([1], [$1], m4_incr([$1]))])
+
+m4_define([_m4_map_args_pair__],
 [[$$1([$$2], [$$3])[]]])
 
 m4_define([_m4_map_args_pair_end],
@@ -318,23 +299,23 @@ m4_define([_m4_map_args_pair_end],
 #
 # Use a self-modifying separator, since we don't know how many
 # arguments might be skipped before a separator is first printed, but
-# be careful if the separator contains $.  m4_foreach to the rescue.
+# be careful if the separator contains $.  _m4_foreach to the rescue.
 m4_define([m4_join],
 [m4_pushdef([_m4_sep], [m4_define([_m4_sep], _m4_defn([m4_echo]))])]dnl
-[m4_foreach([_m4_arg], [m4_shift($@)],
-           [m4_ifset([_m4_arg], [_m4_sep([$1])_m4_defn([_m4_arg])])])]dnl
-[_m4_popdef([_m4_sep])])
+[_m4_foreach([_$0([$1],], [)], $@)_m4_popdef([_m4_sep])])
+
+m4_define([_m4_join],
+[m4_if([$2], [], [], [_m4_sep([$1])[$2]])])
 
 # m4_joinall(SEP, ARG1, ARG2...)
 # ------------------------------
 # Produce ARG1SEPARG2...SEPARGn.  An empty ARG results in back-to-back SEP.
 # No expansion is performed on SEP or ARGs.
 #
-# A bit easier than m4_join.  m4_foreach to the rescue.
+# A bit easier than m4_join.  _m4_foreach to the rescue.
 m4_define([m4_joinall],
 [[$2]m4_if(m4_eval([$# <= 2]), [1], [],
-          [m4_foreach([_m4_arg], [m4_shift2($@)],
-                      [[$1]_m4_defn([_m4_arg])])])])
+          [_m4_foreach([$1], [], m4_shift($@))])])
 
 # m4_list_cmp(A, B)
 # -----------------
@@ -348,24 +329,26 @@ m4_define([m4_joinall],
 # is found.  For example, m4_list_cmp([1], [1,2]) creates _m4_cmp as
 #   m4_if(m4_eval([($1) != ($3)]), [1], [m4_cmp([$1], [$3])],
 #         m4_eval([($2) != ($4)]), [1], [m4_cmp([$2], [$4])],
-#         [0]_m4_popdef([_m4_cmp], [_m4_size]))
-# then calls _m4_cmp([1+0], [0], [1], [2+0])
+#         [0]_m4_popdef([_m4_cmp]))
+# then calls _m4_cmp([1+0], [0*2], [1], [2+0])
 m4_define([_m4_list_cmp_raw],
-[m4_if([$1], [$2], 0, [m4_pushdef(
-     [_m4_size])_m4_list_cmp($1+0_m4_list_pad(m4_count($1), m4_count($2)),
-                            $2+0_m4_list_pad(m4_count($2), m4_count($1)))])])
+[m4_if([$1], [$2], 0,
+       [_m4_list_cmp($1+0_m4_list_pad(m4_count($1), m4_count($2)),
+                    $2+0_m4_list_pad(m4_count($2), m4_count($1)))])])
 
 m4_define([_m4_list_pad],
 [m4_if(m4_eval($1 < $2), [1],
-       [_m4_for([_m4_size], m4_incr([$1]), [$2], [1], [,0])])])
+       [_m4_for(m4_incr([$1]), [$2], [1], [,0*])])])
 
 m4_define([_m4_list_cmp],
-[m4_define([_m4_size], m4_eval([$# >> 1]))]dnl
-[m4_define([_m4_cmp], m4_pushdef([_m4_cmp])[m4_if(]_m4_for([_m4_cmp],
-   [1], _m4_size, [1], [$0_(_m4_cmp, m4_eval(_m4_cmp + _m4_size))])[
-      [0]_m4_popdef([_m4_cmp], [_m4_size]))])_m4_cmp($@)])
+[m4_pushdef([_m4_cmp], [m4_if(]_m4_for(
+   [1], m4_eval([$# >> 1]), [1], [$0_(], [,]m4_eval([$# >> 1])[)])[
+      [0]_m4_popdef([_m4_cmp]))])_m4_cmp($@)])
 
 m4_define([_m4_list_cmp_],
+[$0_([$1], m4_eval([$1 + $2]))])
+
+m4_define([_m4_list_cmp__],
 [[m4_eval([($$1) != ($$2)]), [1], [m4_cmp([$$1], [$$2])],
 ]])
 
@@ -375,12 +358,12 @@ m4_define([_m4_list_cmp_],
 # Return the decimal value of the maximum (or minimum) in a series of
 # integer expressions.
 #
-# m4_foreach to the rescue; we only need to replace _m4_minmax.  Here,
+# _m4_foreach to the rescue; we only need to replace _m4_minmax.  Here,
 # we need a temporary macro to track the best answer so far, so that
 # the foreach expression is tractable.
 m4_define([_m4_minmax],
-[m4_pushdef([_m4_best], m4_eval([$2]))m4_foreach([_m4_arg], [m4_shift2($@)],
-    [m4_define([_m4_best], $1(_m4_best, _m4_defn([_m4_arg])))])]dnl
+[m4_pushdef([_m4_best], m4_eval([$2]))_m4_foreach(
+  [m4_define([_m4_best], $1(_m4_best,], [))], m4_shift($@))]dnl
 [_m4_best[]_m4_popdef([_m4_best])])
 
 # m4_set_add_all(SET, VALUE...)
@@ -388,15 +371,15 @@ m4_define([_m4_minmax],
 # Add each VALUE into SET.  This is O(n) in the number of VALUEs, and
 # can be faster than calling m4_set_add for each VALUE.
 #
-# m4_foreach to the rescue.  If no deletions have occurred, then avoid
-# the speed penalty of m4_set_add.
+# _m4_foreach to the rescue.  If no deletions have occurred, then
+# avoid the speed penalty of m4_set_add.
 m4_define([m4_set_add_all],
 [m4_if([$#], [0], [], [$#], [1], [],
        [m4_define([_m4_set_size($1)], m4_eval(m4_set_size([$1])
-         + m4_len(m4_foreach([_m4_arg], [m4_shift($@)],
-    m4_ifdef([_m4_set_cleanup($1)],
-            [[m4_set_add([$1], _m4_defn([_m4_arg]))]],
-            [[m4_ifdef([_m4_set([$1],]_m4_defn([_m4_arg])[)], [],
-                       [m4_define([_m4_set([$1],]_m4_defn([_m4_arg])[)],
-                                  [1])m4_pushdef([_m4_set([$1])],
-       _m4_defn([_m4_arg]))-])]])))))])])
+         + m4_len(_m4_foreach(m4_ifdef([_m4_set_cleanup($1)],
+  [[m4_set_add]], [[_$0]])[([$1],], [)], $@))))])])
+
+m4_define([_m4_set_add_all],
+[m4_ifdef([_m4_set([$1],$2)], [],
+         [m4_define([_m4_set([$1],$2)],
+                    [1])m4_pushdef([_m4_set([$1])], [$2])-])])
diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4
index 71533a1..2a0d7ce 100644
--- a/lib/m4sugar/m4sugar.m4
+++ b/lib/m4sugar/m4sugar.m4
@@ -920,31 +920,29 @@ m4_define([m4_unquote], [$*])
 # VARIABLE names.  Changing VARIABLE inside EXPRESSION will not impact
 # the number of iterations.
 #
-# Uses _m4_defn for speed, and avoid dnl in the macro body.
+# Uses _m4_defn for speed, and avoid dnl in the macro body.  Factor
+# the _m4_for call so that EXPRESSION is only parsed once.
 m4_define([m4_for],
 [m4_pushdef([$1], m4_eval([$2]))]dnl
 [m4_cond([m4_eval(([$3]) > ([$2]))], 1,
           [m4_pushdef([_m4_step], m4_eval(m4_default_quoted([$4],
-             1)))m4_assert(_m4_step > 0)_$0([$1], _m4_defn([$1]),
-  m4_eval((([$3]) - ([$2])) / _m4_step * _m4_step + ([$2])),
-  _m4_step, [$5])],
+             1)))m4_assert(_m4_step > 0)_$0(_m4_defn([$1]),
+  m4_eval((([$3]) - ([$2])) / _m4_step * _m4_step + ([$2])), _m4_step,],
         [m4_eval(([$3]) < ([$2]))], 1,
           [m4_pushdef([_m4_step], m4_eval(m4_default_quoted([$4],
-             -1)))m4_assert(_m4_step < 0)_$0([$1], _m4_defn([$1]),
-  m4_eval((([$2]) - ([$3])) / -(_m4_step) * _m4_step + ([$2])),
-  _m4_step, [$5])],
-        [m4_pushdef([_m4_step])$5])[]]dnl
-[m4_popdef([_m4_step], [$1])])
+             -1)))m4_assert(_m4_step < 0)_$0(_m4_defn([$1]),
+  m4_eval((([$2]) - ([$3])) / -(_m4_step) * _m4_step + ([$2])), _m4_step,],
+        [m4_pushdef([_m4_step])_$0(_m4_defn([$1]), _m4_defn([$1]), 0,])]dnl
+[[m4_define([$1],], [)$5])m4_popdef([_m4_step], [$1])])
 
-
-# _m4_for(VARIABLE, COUNT, LAST, STEP, EXPRESSION)
-# ------------------------------------------------
+# _m4_for(COUNT, LAST, STEP, PRE, POST)
+# -------------------------------------
 # Core of the loop, no consistency checks, all arguments are plain
-# numbers.  Define VARIABLE to COUNT, expand EXPRESSION, then alter
-# COUNT by STEP and iterate if COUNT is not LAST.
+# numbers.  Expand PRE[COUNT]POST, then alter COUNT by STEP and
+# iterate if COUNT is not LAST.
 m4_define([_m4_for],
-[m4_define([$1], [$2])$5[]m4_if([$2], [$3], [],
-      [$0([$1], m4_eval([$2 + $4]), [$3], [$4], [$5])])])
+[$4[$1]$5[]m4_if([$1], [$2], [],
+                [$0(m4_eval([$1 + $3]), [$2], [$3], [$4], [$5])])])
 
 
 # Implementing `foreach' loops in m4 is much more tricky than it may
@@ -1054,22 +1052,29 @@ m4_define([_m4_for],
 # more memory for expansion.  So, rather than directly compare $2 against
 # [] and use m4_car/m4_cdr for recursion, we instead unbox the list (which
 # requires swapping the argument order in the helper), insert an ignored
-# third argument, and use m4_shift3 to detect when recursion is complete.
-#
-# Please keep foreach.m4 in sync with any adjustments made here.
+# third argument, and use m4_shift3 to detect when recursion is complete,
+# at which point this looks very much like m4_map_args.
 m4_define([m4_foreach],
 [m4_if([$2], [], [],
-       [m4_pushdef([$1])_$0([$1], [$3], [], $2)m4_popdef([$1])])])
+       [m4_pushdef([$1])_$0([m4_define([$1],], [)$3], [],
+  $2)m4_popdef([$1])])])
 
+# _m4_foreach(PRE, POST, IGNORED, ARG...)
+# ---------------------------------------
+# Form the common basis of the m4_foreach and m4_map macros.  For each
+# ARG, expand PRE[ARG]POST[].  The IGNORED argument makes recursion
+# easier, and must be supplied rather than implicit.
+#
+# Please keep foreach.m4 in sync with any adjustments made here.
 m4_define([_m4_foreach],
 [m4_if([$#], [3], [],
-       [m4_define([$1], [$4])$2[]$0([$1], [$2], m4_shift3($@))])])
+       [$1[$4]$2[]$0([$1], [$2], m4_shift3($@))])])
 
 
 # m4_foreach_w(VARIABLE, LIST, EXPRESSION)
 # ----------------------------------------
-#
-# Like m4_foreach, but the list is whitespace separated.
+# Like m4_foreach, but the list is whitespace separated.  Depending on
+# EXPRESSION, it may be more efficient to use m4_map_args_w.
 #
 # This macro is robust to active symbols:
 #    m4_foreach_w([Var], [ active
@@ -1077,8 +1082,11 @@ m4_define([_m4_foreach],
 #    ive  ], [-Var-])end
 #    => -active--b--active-end
 #
+# This used to use a slower implementation based on m4_foreach:
+#   m4_foreach([$1], m4_split(m4_normalize([$2]), [ ]), [$3])
 m4_define([m4_foreach_w],
-[m4_foreach([$1], m4_split(m4_normalize([$2]), [ ]), [$3])])
+[m4_pushdef([$1])m4_map_args_w([$2],
+  [m4_define([$1],], [)$3])m4_popdef([$1])])
 
 
 # m4_map(MACRO, LIST)
@@ -1091,19 +1099,15 @@ m4_define([m4_foreach_w],
 #
 # Since LIST may be quite large, we want to minimize how often it
 # appears in the expansion.  Rather than use m4_car/m4_cdr iteration,
-# we unbox the list, ignore the second argument, and use m4_shift2 to
-# detect the end of recursion.  The mismatch in () is intentional; see
-# _m4_map.  For m4_map, an empty list behaves like an empty sublist
-# and gets ignored; for m4_mapall, we must special-case the empty
-# list.
-#
-# Please keep foreach.m4 in sync with any adjustments made here.
+# we unbox the list, and use _m4_foreach for iteration.  For m4_map,
+# an empty list behaves like an empty sublist and gets ignored; for
+# m4_mapall, we must special-case the empty list.
 m4_define([m4_map],
-[_m4_map([_m4_apply([$1]], [], $2)])
+[_m4_foreach([_m4_apply([$1],], [)], [], $2)])
 
 m4_define([m4_mapall],
 [m4_if([$2], [], [],
-       [_m4_map([m4_apply([$1]], [], $2)])])
+       [_m4_foreach([m4_apply([$1],], [)], [], $2)])])
 
 
 # m4_map_sep(MACRO, SEPARATOR, LIST)
@@ -1125,39 +1129,24 @@ m4_define([m4_mapall],
 # helper macro and use that as the separator instead.
 m4_define([m4_map_sep],
 [m4_pushdef([m4_Sep], [m4_define([m4_Sep], _m4_defn([m4_unquote]))])]dnl
-[_m4_map([_m4_apply([m4_Sep([$2])[]$1]], [], $3)m4_popdef([m4_Sep])])
+[_m4_foreach([_m4_apply([m4_Sep([$2])[]$1],], [)], [], $3)m4_popdef([m4_Sep])])
 
 m4_define([m4_mapall_sep],
 [m4_if([$3], [], [], [_$0([$1], [$2], $3)])])
 
 m4_define([_m4_mapall_sep],
-[m4_apply([$1], [$3])_m4_map([m4_apply([$2[]$1]], m4_shift2($@))])
-
-# _m4_map(PREFIX, IGNORED, SUBLIST, ...)
-# --------------------------------------
-# Common implementation for all four m4_map variants.  The mismatch in
-# the number of () is intentional.  PREFIX must supply a form of
-# m4_apply, the open `(', and the MACRO to be applied.  Each iteration
-# then appends `,', the current SUBLIST and the closing `)', then
-# recurses to the next SUBLIST.  IGNORED is an aid to ending recursion
-# efficiently.
-#
-# Please keep foreach.m4 in sync with any adjustments made here.
-m4_define([_m4_map],
-[m4_if([$#], [2], [],
-       [$1, [$3])$0([$1], m4_shift2($@))])])
+[m4_apply([$1], [$3])_m4_foreach([m4_apply([$2[]$1],], [)], m4_shift2($@))])
 
 # m4_map_args(EXPRESSION, ARG...)
 # -------------------------------
 # Expand EXPRESSION([ARG]) for each argument.  More efficient than
-# m4_foreach([var], [ARG...], [EXPRESSION(m4_defn([var]))])
-#
-# Please keep foreach.m4 in sync with any adjustments made here.
+#   m4_foreach([var], [ARG...], [EXPRESSION(m4_defn([var]))])
+# Shorthand for m4_map_args_sep([EXPRESSION(], [)], [], ARG...).
 m4_define([m4_map_args],
 [m4_if([$#], [0], [m4_fatal([$0: too few arguments: $#])],
        [$#], [1], [],
        [$#], [2], [$1([$2])[]],
-       [$1([$2])[]$0([$1], m4_shift2($@))])])
+       [_m4_foreach([$1(], [)], $@)])])
 
 
 # m4_map_args_pair(EXPRESSION, [END-EXPR = EXPRESSION], ARG...)
@@ -1183,6 +1172,41 @@ m4_define([m4_map_args_pair],
        [$1([$3], [$4])[]$0([$1], [$2], m4_shift(m4_shift3($@)))])])
 
 
+# m4_map_args_sep(PRE, POST, SEP, ARG...)
+# ---------------------------------------
+# Expand PRE[ARG]POST for each argument, with SEP between arguments.
+m4_define([m4_map_args_sep],
+[m4_if([$#], [0], [m4_fatal([$0: too few arguments: $#])],
+       [$#], [1], [],
+       [$#], [2], [],
+       [$#], [3], [],
+       [$#], [4], [$1[$4]$2[]],
+       [$1[$4]$2[]_m4_foreach([$3[]$1], [$2], m4_shift3($@))])])
+
+
+# m4_map_args_w(STRING, [PRE], [POST])
+# ------------------------------------
+# Perform the expansion of PRE[word]POST[] for each word in STRING
+# separated by whitespace.  More efficient than:
+#   m4_foreach_w([var], [STRING], [PRE[]m4_defn([var])POST])
+#
+# As long as we have to use m4_bpatsubst to split the string, we might
+# as well make it also apply PRE and POST; this avoids iteration
+# altogether.  But we must be careful of any \ in PRE or POST.
+# _m4_strip returns a quoted string, but that's okay, since it also
+# supplies an empty leading and trailing argument due to our
+# intentional whitespace around STRING.  We use m4_substr to strip the
+# empty elements and remove the extra layer of quoting.
+m4_define([m4_map_args_w],
+[_$0(_m4_split([ ]m4_flatten([$1])[ ], [[       ]+],
+              m4_if(m4_index([$2$3], [\]), [-1], [[$3[]$2]],
+                    [m4_bpatsubst([[$3[]$2]], [\\], [\\\\])])),
+     m4_len([[]$3]), m4_len([$2[]]))])
+
+m4_define([_m4_map_args_w],
+[m4_substr([$1], [$2], m4_eval(m4_len([$1]) - [$2] - [$3]))])
+
+
 # m4_stack_foreach(MACRO, FUNC)
 # m4_stack_foreach_lifo(MACRO, FUNC)
 # ----------------------------------
@@ -2026,7 +2050,6 @@ m4_define([m4_toupper],
 
 # m4_split(STRING, [REGEXP])
 # --------------------------
-#
 # Split STRING into an m4 list of quoted elements.  The elements are
 # quoted with [ and ].  Beginning spaces and end spaces *are kept*.
 # Use m4_strip to remove them.
@@ -2055,15 +2078,15 @@ m4_define([m4_toupper],
 # so avoid unnecessary dnl inside the definition.
 m4_define([m4_split],
 [m4_if([$1], [], [],
-       [$2], [ ], [m4_if(m4_index([$1], [ ]), [-1], [[[$1]]], [_$0($@)])],
-       [$2], [], [_$0([$1], [[  ]+])],
-       [_$0($@)])])
+       [$2], [ ], [m4_if(m4_index([$1], [ ]), [-1], [[[$1]]],
+                        [_$0([$1], [$2], [, ])])],
+       [$2], [], [_$0([$1], [[  ]+], [, ])],
+       [_$0([$1], [$2], [, ])])])
 
 m4_define([_m4_split],
 [m4_changequote([-=<{(],[)}>=-])]dnl
 [[m4_bpatsubst(-=<{(-=<{($1)}>=-)}>=-, -=<{($2)}>=-,
-              -=<{(], [)}>=-)]m4_changequote([, ])])
-
+              -=<{(]$3[)}>=-)]m4_changequote([, ])])
 
 
 # m4_flatten(STRING)
@@ -2173,20 +2196,14 @@ m4_define([_m4_joinall],
 #   m4_combine([, ], [[a], [b], [c]], [-], [1], [2], [3])
 #   => a-1, a-2, a-3, b-1, b-2, b-3, c-1, c-2, c-3
 #
-# In order to have the correct number of SEPARATORs, we use a temporary
-# variable that redefines itself after the first use.  We must use defn
-# rather than overquoting in case PREFIX or SUFFIX contains $1, but use
-# _m4_defn for speed.  Likewise, we compute the m4_shift3 only once,
-# rather than in each iteration of the outer m4_foreach.
+# This definition is a bit hairy; the thing to realize is that we want
+# to construct m4_map_args_sep([[prefix$3]], [], [[$1]], m4_shift3($@))
+# as the inner loop, using each prefix generated by the outer loop,
+# and without recalculating m4_shift3 every outer iteration.
 m4_define([m4_combine],
-[m4_if(m4_eval([$# > 3]), [1],
-       [m4_pushdef([m4_Separator], [m4_define([m4_Separator],
-                                   _m4_defn([m4_echo]))])]]dnl
-[[m4_foreach([m4_Prefix], [$2],
-   [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])])])
+[m4_if([$2], [], [], m4_eval([$# > 3]), [1],
+[m4_map_args_sep([m4_map_args_sep(m4_dquote(], [)[[$3]], [], [[$1]],]]]dnl
+[m4_dquote(m4_dquote(m4_shift3($@)))[[)], [[$1]], $2)])])
 
 
 # m4_append(MACRO-NAME, STRING, [SEPARATOR])
@@ -2275,8 +2292,7 @@ m4_define([_m4_append_uniq],
 #
 # Use _m4_defn for speed.
 m4_define([m4_append_uniq_w],
-[m4_foreach_w([m4_Word], [$2],
-             [_m4_append_uniq([$1], _m4_defn([m4_Word]), [ ])])])
+[m4_map_args_w([$2], [_m4_append_uniq([$1],], [, [ ])])])
 
 
 # m4_text_wrap(STRING, [PREFIX], [FIRST-PREFIX], [WIDTH])
@@ -2350,17 +2366,16 @@ dnl check if the cursor would exceed the wrap column
 dnl if so, reset cursor, and insert newline and prefix
 dnl if not, insert the separator (usually a space)
 dnl either way, insert the word
-[[m4_foreach_w([m4_Word], [$1],
-  [m4_define([m4_Cursor],
-            m4_eval(m4_Cursor + m4_qlen(_m4_defn([m4_Word]))
-                    + 1))m4_if(m4_eval(m4_Cursor > ([$4])),
-      [1], [m4_define([m4_Cursor],
-                     m4_eval(m4_Indent + m4_qlen(_m4_defn([m4_Word])) + 1))
-[$2]],
-      [m4_Separator[]])_m4_defn([m4_Word])])]],
+[[m4_map_args_w([$1], [$0_word(], [, [$2], [$4])])]],
 dnl finally, clean up the local variables
 [[_m4_popdef([m4_Separator], [m4_Cursor], [m4_Indent])]]))
 
+m4_define([_m4_text_wrap_word],
+[m4_define([m4_Cursor], m4_eval(m4_Cursor + m4_qlen([$1]) + 1))]dnl
+[m4_if(m4_eval(m4_Cursor > ([$3])),
+      [1], [m4_define([m4_Cursor], m4_eval(m4_Indent + m4_qlen([$1]) + 1))
+[$2]],
+      [m4_Separator[]])[$1]])
 
 # m4_text_box(MESSAGE, [FRAME-CHARACTER = `-'])
 # ---------------------------------------------
@@ -2696,8 +2711,7 @@ m4_define([m4_set_contains],
 # Use _m4_popdef for speed.  The existence of _m4_set_cleanup($1)
 # determines which version of _1 helper we use.
 m4_define([m4_set_contents],
-[m4_ifdef([_m4_set_cleanup($1)], [_$0_1c], [_$0_1])([$1])_$0_2([$1],
-  [], [], [[$2]])])
+[m4_set_map_sep([$1], [], [], [[$2]])])
 
 # _m4_set_contents_1(SET)
 # _m4_set_contents_1c(SET)
@@ -2753,12 +2767,12 @@ m4_define([m4_set_delete],
 # arguments, such as for m4_join, or wrapped inside quotes for use in
 # m4_foreach.  Order of the output is not guaranteed.
 #
-# Short-circuit the idempotence relation.  Use _m4_defn for speed.
+# Short-circuit the idempotence relation.
 m4_define([m4_set_difference],
-[m4_if([$1], [$2], [],
-       [m4_set_foreach([$1], [_m4_element],
-                      [m4_set_contains([$2], _m4_defn([_m4_element]), [],
-                                       [,_m4_defn([_m4_element])])])])])
+[m4_if([$1], [$2], [], [m4_set_map_sep([$1], [_$0([$2],], [)])])])
+
+m4_define([_m4_set_difference],
+[m4_set_contains([$1], [$2], [], [,[$2]])])
 
 # m4_set_dump(SET, [SEP])
 # -----------------------
@@ -2812,9 +2826,7 @@ m4_define([m4_set_empty],
 # guaranteed.  This is faster than the corresponding m4_foreach([VAR],
 #   m4_indir([m4_dquote]m4_set_listc([SET])), [ACTION])
 m4_define([m4_set_foreach],
-[m4_pushdef([$2])m4_ifdef([_m4_set_cleanup($1)],
-    [_m4_set_contents_1c], [_m4_set_contents_1])([$1])_m4_set_contents_2([$1],
-       [m4_define([$2],], [)$3[]])m4_popdef([$2])])
+[m4_pushdef([$2])m4_set_map_sep([$1], [m4_define([$2],], [)$3])])
 
 # m4_set_intersection(SET1, SET2)
 # -------------------------------
@@ -2825,13 +2837,14 @@ m4_define([m4_set_foreach],
 # m4_foreach.  Order of the output is not guaranteed.
 #
 # Iterate over the smaller set, and short-circuit the idempotence
-# relation.  Use _m4_defn for speed.
+# relation.
 m4_define([m4_set_intersection],
 [m4_if([$1], [$2], [m4_set_listc([$1])],
        m4_eval(m4_set_size([$2]) < m4_set_size([$1])), [1], [$0([$2], [$1])],
-       [m4_set_foreach([$1], [_m4_element],
-                      [m4_set_contains([$2], _m4_defn([_m4_element]),
-                                       [,_m4_defn([_m4_element])])])])])
+       [m4_set_map_sep([$1], [_$0([$2],], [)])])])
+
+m4_define([_m4_set_intersection],
+[m4_set_contains([$1], [$2], [,[$2]])])
 
 # m4_set_list(SET)
 # m4_set_listc(SET)
@@ -2843,12 +2856,10 @@ m4_define([m4_set_intersection],
 # containing only the empty string; with m4_set_listc, a leading comma
 # is output if there are any elements.
 m4_define([m4_set_list],
-[m4_ifdef([_m4_set_cleanup($1)], [_m4_set_contents_1c],
-         [_m4_set_contents_1])([$1])_m4_set_contents_2([$1], [], [], [,])])
+[m4_set_map_sep([$1], [], [], [,])])
 
 m4_define([m4_set_listc],
-[m4_ifdef([_m4_set_cleanup($1)], [_m4_set_contents_1c],
-         [_m4_set_contents_1])([$1])_m4_set_contents_2([$1], [,])])
+[m4_set_map_sep([$1], [,])])
 
 # m4_set_map(SET, ACTION)
 # -----------------------
@@ -2856,12 +2867,19 @@ m4_define([m4_set_listc],
 # current element.  ACTION should not recursively list SET's contents,
 # add elements to SET, nor delete any element from SET except the one
 # passed as an argument.  The order that the elements are visited in
-# is not guaranteed.  This is faster than the corresponding
+# is not guaranteed.  This is faster than either of the corresponding
 #   m4_map_args([ACTION]m4_set_listc([SET]))
+#   m4_set_foreach([SET], [VAR], [ACTION(m4_defn([VAR]))])
 m4_define([m4_set_map],
-[m4_ifdef([_m4_set_cleanup($1)],
-    [_m4_set_contents_1c], [_m4_set_contents_1])([$1])_m4_set_contents_2([$1],
-       [$2(], [)])])
+[m4_set_map_sep([$1], [$2(], [)])])
+
+# m4_set_map_sep(SET, PRE, POST, SEP)
+# -----------------------------------
+# For each element of SET, expand PRE[value]POST[], and expand SEP
+# between elements.
+m4_define([m4_set_map_sep],
+[m4_ifdef([_m4_set_cleanup($1)], [_m4_set_contents_1c],
+         [_m4_set_contents_1])([$1])_m4_set_contents_2($@)])
 
 # m4_set_remove(SET, VALUE, [IF-PRESENT], [IF-ABSENT])
 # ----------------------------------------------------
@@ -2907,12 +2925,14 @@ m4_define([_m4_set_size],
 # not guaranteed.
 #
 # We can rely on the fact that m4_set_listc prunes SET1, so we don't
-# need to check _m4_set([$1],element) for 0.  Use _m4_defn for speed.
-# Short-circuit the idempotence relation.
+# need to check _m4_set([$1],element) for 0.  Short-circuit the
+# idempotence relation.
 m4_define([m4_set_union],
-[m4_set_listc([$1])m4_if([$1], [$2], [], [m4_set_foreach([$2], [_m4_element],
-  [m4_ifdef([_m4_set([$1],]_m4_defn([_m4_element])[)], [],
-           [,_m4_defn([_m4_element])])])])])
+[m4_set_listc([$1])m4_if([$1], [$2], [],
+  [m4_set_map_sep([$2], [_$0([$1],], [)])])])
+
+m4_define([_m4_set_union],
+[m4_ifdef([_m4_set([$1],$2)], [], [,[$2]])])
 
 
 ## ------------------- ##
diff --git a/tests/m4sugar.at b/tests/m4sugar.at
index 70bb24b..5a90493 100644
--- a/tests/m4sugar.at
+++ b/tests/m4sugar.at
@@ -546,6 +546,7 @@ AT_CLEANUP
 ## ----------- ##
 
 AT_SETUP([m4@&address@hidden)
+AT_KEYWORDS([m4@&address@hidden m4@&address@hidden)
 
 AT_CHECK_M4SUGAR_TEXT(
 [[m4_define([active], [ACTIVE])dnl
@@ -876,7 +877,7 @@ AT_CLEANUP
 
 AT_SETUP([M4 loops])
 
-AT_KEYWORDS([m4@&address@hidden m4@&address@hidden m4@&address@hidden)
+AT_KEYWORDS([m4@&address@hidden m4@&address@hidden m4@&address@hidden 
m4@&address@hidden)
 
 AT_CHECK_M4SUGAR_TEXT([[dnl
 m4_define([myvar], [outer value])dnl
@@ -921,6 +922,10 @@ m4_foreach([myvar], [[a], [b, c], [d], [e
 m4_foreach_w([myvar], [a  b c, d,e f
 g], [ myvar|])
 myvar
+m4_map_args_w([a  b c, d,e f
+g], [ ], [|])
+m4_map_args_w([a b], [\1], [/])
+m4_map_args_w([a b], [/], [\1])
 dnl only one side effect expansion, prior to visiting list elements
 m4_foreach([i], [[1], [2], [3]m4_errprintn([hi])], [m4_errprintn(i)])dnl
 dnl shifting forms an important part of loops
@@ -959,6 +964,9 @@ m4_shiftn(3,1,2,3):m4_shiftn(3,1,2,3,4)
 | f|
  a| b| c,| d,e| f| g|
 outer value
+ a| b| c,| d,e| f| g|
+\1a/\1b/
+/a\1/b\1
 ::4
 :4
 ]], [[hi
@@ -1091,12 +1099,13 @@ hi
 AT_CLEANUP
 
 
-## ---------------------------------- ##
-## m4_map_args{,_pair} and m4_curry.  ##
-## ---------------------------------- ##
+## --------------------------------------- ##
+## m4_map_args{,_sep,_pair} and m4_curry.  ##
+## --------------------------------------- ##
 
 AT_SETUP([m4@&address@hidden and m4@&address@hidden)
-AT_KEYWORDS([m4@&address@hidden m4@&address@hidden)
+AT_KEYWORDS([m4@&address@hidden m4@&address@hidden m4@&address@hidden
+m4@&address@hidden)
 
 dnl First, make sure we can curry in isolation.
 AT_CHECK_M4SUGAR_TEXT(
@@ -1125,6 +1134,8 @@ m4_map_args_pair([, m4_reverse], [, m4_dquote], [1])
 m4_map_args_pair([, m4_reverse], [, m4_dquote], [1], [2])
 m4_map_args_pair([, m4_reverse], [, m4_dquote], [1], [2], [3])
 m4_map_args_pair([, m4_reverse], [, m4_dquote], [1], [2], [3], [4])
+m4_map_args_sep([<], [>], [:], [1], [2], [3])
+m4_map_args_sep([m4_echo(], [)], [ ], [plain], [active])
 ]],
 [[
  plain active
@@ -1138,6 +1149,8 @@ plainACTIVE
 , 2, 1
 , 2, 1, [3]
 , 2, 1, 4, 3
+<1>:<2>:<3>
+plain active
 ]])
 
 dnl Finally, put the two concepts together, to show the real power of the API.


hooks/post-receive
--
GNU Autoconf source repository




reply via email to

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