]> git.ipfire.org Git - thirdparty/autoconf.git/commitdiff
Add m4_map_args_w.
authorEric Blake <ebb9@byu.net>
Thu, 6 Nov 2008 00:11:15 +0000 (17:11 -0700)
committerEric Blake <ebb9@byu.net>
Thu, 6 Nov 2008 03:04:49 +0000 (20:04 -0700)
* 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@&t@_append): Augment test keywords.
(M4 loops): Test new interface.

Signed-off-by: Eric Blake <ebb9@byu.net>
ChangeLog
lib/m4sugar/m4sugar.m4
tests/m4sugar.at

index 73e80955e589ddf1318156878fe6526af6bacbde..e6686fc5a1593a1130bd3b9db280531ed2be9f8d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2008-11-05  Eric Blake  <ebb9@byu.net>
 
+       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@&t@_append): 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.
index 5c2e1c80cf2640fd175d9513344f29fa995841bb..2a0d7ceed1d946c8997b95f5d4c528a238effc21 100644 (file)
@@ -1073,8 +1073,8 @@ m4_define([_m4_foreach],
 
 # 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
@@ -1082,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)
@@ -1181,6 +1184,29 @@ m4_define([m4_map_args_sep],
        [$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)
 # ----------------------------------
@@ -2024,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.
@@ -2053,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)
@@ -2267,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])
@@ -2342,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 = `-'])
 # ---------------------------------------------
index c8b22eb6823ff48f47c34834d5ab383dbdce6310..5a90493ae311b19a95f2804b985d73244bc98390 100644 (file)
@@ -546,6 +546,7 @@ AT_CLEANUP
 ## ----------- ##
 
 AT_SETUP([m4@&t@_append])
+AT_KEYWORDS([m4@&t@_append_uniq m4@&t@_append_uniq_w])
 
 AT_CHECK_M4SUGAR_TEXT(
 [[m4_define([active], [ACTIVE])dnl
@@ -876,7 +877,7 @@ AT_CLEANUP
 
 AT_SETUP([M4 loops])
 
-AT_KEYWORDS([m4@&t@_for m4@&t@_foreach m4@&t@_foreach_w])
+AT_KEYWORDS([m4@&t@_for m4@&t@_foreach m4@&t@_foreach_w m4@&t@_map_args_w])
 
 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