]> git.ipfire.org Git - thirdparty/autoconf.git/commitdiff
Optimize m4_bmatch.
authorEric Blake <ebb9@byu.net>
Tue, 12 Aug 2008 21:23:56 +0000 (15:23 -0600)
committerEric Blake <ebb9@byu.net>
Tue, 12 Aug 2008 21:29:39 +0000 (15:29 -0600)
* lib/m4sugar/foreach.m4 (m4_bmatch): Provide linear
implementation for m4 1.4.x.
* tests/m4sugar.at (m4@&t@_bmatch): New test.
(recursion): Test the linear nature.
* NEWS: Document the fix.

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

index d4600784cae5dae0dba3d7f61e1c7c9a74c8ac78..aa824655e0b67e18c7c365ae670ff38e27f9c636 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2008-08-12  Eric Blake  <ebb9@byu.net>
 
+       Optimize m4_bmatch.
+       * lib/m4sugar/foreach.m4 (m4_bmatch): Provide linear
+       implementation for m4 1.4.x.
+       * tests/m4sugar.at (m4@&t@_bmatch): New test.
+       (recursion): Test the linear nature.
+       * NEWS: Document the fix.
+
        Fix m4_cond corner case.
        * lib/m4sugar/foreach.m4 (_m4_cond): Ensure alternate
        implementation allows concatenation with subsequent text.
diff --git a/NEWS b/NEWS
index dbff114c5a13dee2bdbcee07be7fe4b880e434ce..2cf67471d4584e55151a800cc4b0134a229ba3c3 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -38,8 +38,9 @@ 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_bpatsubsts  m4_case  m4_cond  m4_do  m4_dquote_elt  m4_foreach
-   m4_join  m4_list_cmp  m4_map  m4_map_sep  m4_max  m4_min  m4_shiftn
+   m4_bmatch  m4_bpatsubsts  m4_case  m4_cond  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 b85fce2ffb060f55aed9121f5d53f917319a5c72..816ee608df073a4980a0df04318ff25860aa2ce7 100644 (file)
@@ -121,6 +121,39 @@ m4_define([m4_case],
 m4_define([_m4_case_],
 [[[$$1],[$$2],[$$3],]])
 
+# m4_bmatch(SWITCH, RE1, VAL1, RE2, VAL2, ..., DEFAULT)
+# -----------------------------------------------------
+# m4 equivalent of
+#
+# if (SWITCH =~ RE1)
+#   VAL1;
+# elif (SWITCH =~ RE2)
+#   VAL2;
+# elif ...
+#   ...
+# else
+#   DEFAULT
+#
+# We build the temporary macro _m4_b:
+#   m4_define([_m4_b], _m4_defn([_m4_bmatch]))_m4_b([$1], [$2], [$3])...
+#   _m4_b([$1], [$m-1], [$m])_m4_b([], [], [$m+1]_m4_popdef([_m4_b]))
+# then invoke m4_unquote(_m4_b($@)), for concatenation with later text.
+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_define([_m4_bmatch],
+[m4_if(m4_bregexp([$1], [$2]), [-1], [], [[$3]m4_define([$0])])])
+
+m4_define([_m4_bmatch_],
+[[_m4_b([$$1], [$$2], [$$3])]])
+
+
 # m4_cond(TEST1, VAL1, IF-VAL1, TEST2, VAL2, IF-VAL2, ..., [DEFAULT])
 # -------------------------------------------------------------------
 # Similar to m4_if, except that each TEST is expanded when encountered.
index 8e5fd012db45b8926d80ff1714e8d3d955ab1765..8e9885ae472e44f69c4f211356bded9eb0f69839 100644 (file)
@@ -573,6 +573,38 @@ AT_CHECK_M4RE([m4_re_string], [9a@_c])
 
 AT_CLEANUP
 
+## ----------- ##
+## m4_bmatch.  ##
+## ----------- ##
+
+AT_SETUP([m4@&t@_bmatch])
+
+AT_CHECK_M4SUGAR_TEXT(
+[[m4_bmatch([abc], [default\])
+m4_bmatch([abc], [^a], [yes])
+m4_bmatch([abc], [^a], [yes], [no])
+m4_bmatch([abc], [^.a], [yes])
+m4_bmatch([abc], [^.a], [yes], [no\])
+m4_bmatch([abc], [a], [1], [b], [2])
+m4_bmatch([abc], [A], [1], [b], [2])
+m4_define([ab], [AB])dnl
+m4_bmatch([$*], [a])b
+m4_bmatch([$*], [\*], [a])b
+m4_bmatch([$*], [1], [2], [a])b
+]], [[default\
+yes
+yes
+
+no\
+1
+2
+AB
+AB
+AB
+]])
+
+AT_CLEANUP
+
 ## --------------- ##
 ## m4_bpatsubsts.  ##
 ## --------------- ##
@@ -870,7 +902,8 @@ AT_SETUP([recursion])
 
 AT_KEYWORDS([m4@&t@_foreach m4@&t@_foreach_w m4@&t@_case m4@&t@_cond
 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])
+m4@&t@_map m4@&t@_join m4@&t@_joinall m4@&t@_list_cmp m4@&t@_max m4@&t@_min
+m4@&t@_bmatch])
 
 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,
@@ -895,6 +928,7 @@ 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_bmatch([9997]m4_for([i], [1], [10000], [], [,^i$]))
 m4_define([up], [m4_define([$1], m4_incr($1))$1])m4_define([j], 0)dnl
 m4_cond(m4_for([i], [1], [10000], [], [[up([j])], [9990], i,]) [oops]) j
 m4_divert_pop(0)
@@ -910,6 +944,7 @@ end
 0
 0
 A
+^9998$
 9990 9990
 ]])
 
@@ -926,6 +961,7 @@ end
 0
 0
 A
+^9998$
 9990 9990
 m4_exit([0])])
 m4_init
@@ -945,6 +981,7 @@ 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_bmatch([9997]m4_for([i], [1], [10000], [], [,^i$]))
 m4_define([up], [m4_define([$1], m4_incr($1))$1])m4_define([j], 0)dnl
 m4_cond(m4_for([i], [1], [10000], [], [[up([j])], [9990], i,]) [oops])
 m4_divert_pop(0)
@@ -960,6 +997,7 @@ end
 0
 0
 A
+^9998$
 9990 9990
 ]])