]> git.ipfire.org Git - thirdparty/autoconf.git/commitdiff
Add linear m4_bpatsubsts for m4 1.4.x.
authorEric Blake <ebb9@byu.net>
Wed, 30 Jul 2008 02:34:06 +0000 (20:34 -0600)
committerEric Blake <ebb9@byu.net>
Wed, 30 Jul 2008 02:37:30 +0000 (20:37 -0600)
* lib/m4sugar/m4sugar.m4 (m4_bpatsubsts): Match documentation
about anchors, even for only one substitution.
* lib/m4sugar/foreach.m4 (_m4_bpatsubsts): New implementation.
* doc/autoconf.texi (Conditional constructs) <m4_bpatsubsts>:
Clarify behavior with regard to quoting.
* tests/m4sugar.at (recursion): Test scaling of m4_bpatsubsts.
(m4@&t@_bpatsubsts): New test.
* NEWS: Document the linear guarantee.

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

index 93c8f78e80f2016e996645c916caee1adbb3f0f6..5f348b3458dfed347946c6fc5dd06096bee8a517 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2008-07-29  Eric Blake  <ebb9@byu.net>
 
+       Add linear m4_bpatsubsts for m4 1.4.x.
+       * lib/m4sugar/m4sugar.m4 (m4_bpatsubsts): Match documentation
+       about anchors, even for only one substitution.
+       * lib/m4sugar/foreach.m4 (_m4_bpatsubsts): New implementation.
+       * doc/autoconf.texi (Conditional constructs) <m4_bpatsubsts>:
+       Clarify behavior with regard to quoting.
+       * tests/m4sugar.at (recursion): Test scaling of m4_bpatsubsts.
+       (m4@&t@_bpatsubsts): New test.
+       * NEWS: Document the linear guarantee.
+
        Tweak m4_do semantics.
        * lib/m4sugar/m4sugar.m4 (m4_do): Don't concat final argument with
        subsequent text.
diff --git a/NEWS b/NEWS
index 9737c34894411bca5ae76c4c17c5e9f017d57ef7..30f0f4ea032e333bf24fbecae2d80a874a502666 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -33,8 +33,8 @@ GNU Autoconf NEWS - User visible changes.
    previously had linear scaling with m4 1.6 but quadratic scaling
    when using m4 1.4.x.  All macros built on top of these also gain
    the scaling improvements.
-   m4_case  m4_do  m4_dquote_elt  m4_foreach  m4_join  m4_list_cmp
-   m4_map  m4_map_sep  m4_max  m4_min  m4_shiftn
+   m4_bpatsubsts  m4_case  m4_do  m4_dquote_elt  m4_foreach  m4_join
+   m4_list_cmp  m4_map  m4_map_sep  m4_max  m4_min  m4_shiftn
 
 ** AT_KEYWORDS once again performs expansion on its argument, such that
    AT_KEYWORDS([m4_if([$1], [], [default])]) no longer complains about
index d27aeb283942c009cbb8fd8f1a0ec2da04b0cdf0..b1b2a24aa0bbd13cfecba4854dcfc568508f4898 100644 (file)
@@ -10635,7 +10635,8 @@ macro over-quotes @var{string}; this behavior is intentional, so that
 the result of each step of the recursion remains as a quoted string.
 However, it means that anchors (@samp{^} and @samp{$} in the @var{regex}
 will line up with the extra quotations, and not the characters of the
-original string.
+original string.  The overquoting is removed after the final
+substitution.
 @end defmac
 
 @defmac m4_case (@var{string}, @var{value-1}, @var{if-value-1}, @
index 3997ff27a8f285f806eabdb3838e54a2b85d0eb6..015e0beec0da2245f5edb7ca6edf48dd0ebbc271 100644 (file)
@@ -121,6 +121,33 @@ m4_define([m4_case],
 m4_define([_m4_case_],
 [[[$$1],[$$2],[$$3],]])
 
+# m4_bpatsubsts(STRING, RE1, SUBST1, RE2, SUBST2, ...)
+# ----------------------------------------------------
+# m4 equivalent of
+#
+#   $_ = STRING;
+#   s/RE1/SUBST1/g;
+#   s/RE2/SUBST2/g;
+#   ...
+#
+# m4_bpatsubsts already validated an odd number of arguments; we only
+# need to speed up _m4_bpatsubsts.  To avoid nesting, we build the
+# temporary _m4_p:
+#   m4_define([_m4_p], [$1])m4_define([_m4_p],
+#   m4_bpatsubst(m4_dquote(_m4_defn([_m4_p])), [$2], [$3]))m4_define([_m4_p],
+#   m4_bpatsubst(m4_dquote(_m4_defn([_m4_p])), [$4], [$5]))m4_define([_m4_p],...
+#   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],
+  [$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_define([_m4_bpatsubsts_],
+[[m4_define([_m4_p],
+m4_bpatsubst(m4_dquote(_m4_defn([_m4_p])), [$$1], [$$2]))]])
+
+
 # m4_shiftn(N, ...)
 # -----------------
 # Returns ... shifted N times.  Useful for recursive "varargs" constructs.
index b67b1adee4f3d05d0337b55844741faf889f0ac6..d864f18b70a29ec036ce5ecc193a1cdf998c93ae 100644 (file)
@@ -478,7 +478,8 @@ m4_define([m4_cond],
 m4_define([m4_bpatsubsts],
 [m4_if([$#], 0, [m4_fatal([$0: too few arguments: $#])],
        [$#], 1, [m4_fatal([$0: too few arguments: $#: $1])],
-       [$#], 2, [m4_builtin([patsubst], [$1], [$2])],
+       [$#], 2, [m4_unquote(m4_builtin([patsubst], [[$1]], [$2]))],
+       [$#], 3, [m4_unquote(m4_builtin([patsubst], [[$1]], [$2], [$3]))],
        [_$0($@m4_if(m4_eval($# & 1), 0, [,]))])])
 m4_define([_m4_bpatsubsts],
 [m4_if([$#], 2, [$1],
index ce119e08d1b8319ab2b90c6fc5cbad9a35228d9f..a1c0bd0d4bca91a1ba0c729e1603006bcdbdb76a 100644 (file)
@@ -521,6 +521,30 @@ AT_CHECK_M4RE([m4_re_string], [9a@_c])
 
 AT_CLEANUP
 
+## --------------- ##
+## m4_bpatsubsts.  ##
+## --------------- ##
+
+AT_SETUP([m4@&t@_bpatsubsts])
+
+AT_CHECK_M4SUGAR_TEXT(
+[[m4_bpatsubsts([11], [^..$])
+m4_bpatsubsts([11], [\(.\)1], [\12])
+m4_bpatsubsts([11], [^..$], [], [1], [2])
+m4_bpatsubsts([11], [\(.\)1], [\12], [1], [3])
+m4_define([a], [oops])m4_define([AB], [good])dnl
+m4_bpatsubsts([abc], [a], [A], [b], [B], [c])
+m4_bpatsubsts([$1$*$@], [\$\*], [$#])
+]], [[11
+21
+22
+23
+good
+$1$#$@
+]])
+
+AT_CLEANUP
+
 ## ---------- ##
 ## M4 Loops.  ##
 ## ---------- ##
@@ -787,9 +811,9 @@ AT_CLEANUP
 
 AT_SETUP([recursion])
 
-AT_KEYWORDS([m4@&t@_foreach m4@&t@_foreach_w m4@&t@_shiftn m4@&t@_dquote_elt
-m4@&t@_join m4@&t@_joinall m4@&t@_list_cmp m4@&t@_max m4@&t@_min
-m4@&t@_reverse])
+AT_KEYWORDS([m4@&t@_foreach m4@&t@_foreach_w m4@&t@_case m4@&t@_bpatsubsts
+m4@&t@_shiftn m4@&t@_do m4@&t@_dquote_elt m4@&t@_reverse m4@&t@_map
+m4@&t@_join m4@&t@_joinall m4@&t@_list_cmp m4@&t@_max m4@&t@_min])
 
 dnl This test completes in a reasonable time if m4_foreach is linear,
 dnl but thrashes if it is quadratic.  If we are testing with m4 1.4.x,
@@ -813,6 +837,7 @@ m4_list_cmp([0], [0m4_for([i], [1], [10000], [], [,0])])
 m4_list_cmp([0m4_for([i], [1], [10000], [], [,0])], [0])
 m4_for([i], [1], [10000], [], [m4_define(i)])dnl
 m4_undefine(1m4_for([i], [2], [10000], [], [,i]))dnl
+m4_bpatsubsts([a1]m4_for([i], [1], [10000], [], [,i]), [a2], [A])
 m4_divert_pop(0)
 ]])
 
@@ -825,6 +850,7 @@ end
 0
 0
 0
+A
 ]])
 
 AT_DATA_M4SUGAR([script.4s],
@@ -839,6 +865,7 @@ end
 0
 0
 0
+A
 m4_exit([0])])
 m4_init
 m4_divert_push(0)[]dnl
@@ -856,6 +883,7 @@ m4_list_cmp([0], [0m4_for([i], [1], [10000], [], [,0])])
 m4_list_cmp([0m4_for([i], [1], [10000], [], [,0])], [0])
 m4_for([i], [1], [10000], [], [m4_define(i)])dnl
 m4_undefine(1m4_for([i], [2], [10000], [], [,i]))dnl
+m4_bpatsubsts([a1]m4_for([i], [1], [10000], [], [,i]), [a2], [A])
 m4_divert_pop(0)
 ]])
 
@@ -868,6 +896,7 @@ end
 0
 0
 0
+A
 ]])
 
 AT_CLEANUP