]> git.ipfire.org Git - thirdparty/autoconf.git/commitdiff
Add linear m4_cond for m4 1.4.x.
authorEric Blake <ebb9@byu.net>
Wed, 30 Jul 2008 22:44:03 +0000 (16:44 -0600)
committerEric Blake <ebb9@byu.net>
Wed, 6 Aug 2008 15:57:08 +0000 (09:57 -0600)
* lib/m4sugar/m4sugar.m4 (m4_cond): Split into...
(_m4_cond): ...this, for fewer macros per iteration.
* lib/m4sugar/foreach.m4 (_m4_cond): New implementation.
* tests/m4sugar.at (recursion): Test it.
* NEWS: Document the linear guarantee.

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

index a00502b05b3b5fafa99c9dfdacda066d6bee1503..60b3ee548f5aac9a6ff1c1012652e7260b0779ba 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2008-08-06  Eric Blake  <ebb9@byu.net>
 
+       Add linear m4_cond for m4 1.4.x.
+       * lib/m4sugar/m4sugar.m4 (m4_cond): Split into...
+       (_m4_cond): ...this, for fewer macros per iteration.
+       * lib/m4sugar/foreach.m4 (_m4_cond): New implementation.
+       * tests/m4sugar.at (recursion): Test it.
+       * NEWS: Document the linear guarantee.
+
        Speed up diversion handling.
        * lib/m4sugar/m4sugar.m4 (m4_divert, m4_divert_push)
        (m4_divert_pop, m4_divert_text): Avoid dnl for fewer macro
diff --git a/NEWS b/NEWS
index 30f0f4ea032e333bf24fbecae2d80a874a502666..efd7f46ecb64d16633d06237137a997b20793d10 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_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
+   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 3109a8f87a8fe3459c7226d09db5c9983b8ba782..78779c4040984534c515b5ade88528dce52a603a 100644 (file)
@@ -121,6 +121,29 @@ m4_define([m4_case],
 m4_define([_m4_case_],
 [[[$$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.
+# If the expansion of TESTn matches the string VALn, the result is IF-VALn.
+# The result is DEFAULT if no tests passed.  This macro allows
+# short-circuiting of expensive tests, where it pays to arrange quick
+# filter tests to run first.
+#
+# m4_cond already guarantees either 3*n or 3*n + 1 arguments, 1 <= n.
+# We only have to speed up _m4_cond, by building the temporary _m4_c:
+#   m4_define([_m4_c], _m4_defn([m4_unquote]))_m4_c([m4_if(($1), [($2)],
+#   [$3[]m4_define([_m4_c])])])_m4_c([m4_if(($4), [($5)],
+#   [$6[]m4_define([_m4_c])])])..._m4_c([m4_if(($m-2), [($m-1)],
+#   [$m[]m4_define([_m4_c])])])_m4_c([$m+1]_m4_popdef([_m4_c]))
+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_eval([$# / 3 * 3 + 1]))[_m4_popdef([_m4_c]))])_m4_c($@)])
+
+m4_define([_m4_cond_],
+[[_m4_c([m4_if(($$1), [($$2)], [$$3[]m4_define([_m4_c])])])]])
+
 # m4_bpatsubsts(STRING, RE1, SUBST1, RE2, SUBST2, ...)
 # ----------------------------------------------------
 # m4 equivalent of
@@ -147,7 +170,6 @@ 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 450d7a914d0c0bab105ad66e04957cff15eddb18..22af6efb0402961abeb5d009f4cac2f998b3691a 100644 (file)
@@ -449,8 +449,14 @@ m4_define([_m4_cdr],
 m4_define([m4_cond],
 [m4_if([$#], [0], [m4_fatal([$0: cannot be called without arguments])],
        [$#], [1], [$1],
-       [$#], [2], [m4_fatal([$0: missing an argument])],
-       [m4_if($1, [$2], [$3], [$0(m4_shift3($@))])])])
+       m4_eval([$# % 3]), [2], [m4_fatal([$0: missing an argument])],
+       [_$0($@)])])
+
+m4_define([_m4_cond],
+[m4_if(($1), [($2)], [$3],
+       [$#], [3], [],
+       [$#], [4], [$4],
+       [$0(m4_shift3($@))])])
 
 
 ## ---------------------------------------- ##
index 516881e9f15d79d9305055e1362f1487a0cdf59b..60910de899b8ac35c05aba190144bd2a0c642c55 100644 (file)
@@ -816,9 +816,9 @@ AT_CLEANUP
 
 AT_SETUP([recursion])
 
-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])
+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])
 
 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,
@@ -843,6 +843,8 @@ 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_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)
 ]])
 
@@ -856,6 +858,7 @@ end
 0
 0
 A
+9990 9990
 ]])
 
 AT_DATA_M4SUGAR([script.4s],
@@ -871,6 +874,7 @@ end
 0
 0
 A
+9990 9990
 m4_exit([0])])
 m4_init
 m4_divert_push(0)[]dnl
@@ -889,6 +893,8 @@ 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_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)
 ]])
 
@@ -902,6 +908,7 @@ end
 0
 0
 A
+9990 9990
 ]])
 
 AT_CLEANUP