]> git.ipfire.org Git - thirdparty/autoconf.git/commitdiff
Implement m4_transform_pair, to speed up AS_IF.
authorEric Blake <ebb9@byu.net>
Wed, 13 Aug 2008 15:12:28 +0000 (09:12 -0600)
committerEric Blake <ebb9@byu.net>
Fri, 15 Aug 2008 03:51:40 +0000 (21:51 -0600)
* lib/m4sugar/m4sugar.m4 (m4_transform, m4_transform_pair): New
macros, undocumented for now.
* lib/m4sugar/foreach.m4 (m4_transform, m4_transform_pair): Also
the m4 1.4.x counterparts.
* lib/m4sugar/m4sh.m4 (AS_IF, AS_CASE): Use it.
* tests/m4sh.at (AS@&t@_IF and AS@&t@_CASE): Test it.

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

index a2e209f5a0220241a36cca7aae7cad28ee76d49c..9df0fa666adffec096c606ffd3f845dbae6fc64f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2008-08-14  Eric Blake  <ebb9@byu.net>
+
+       Implement m4_transform_pair, to speed up AS_IF.
+       * lib/m4sugar/m4sugar.m4 (m4_transform, m4_transform_pair): New
+       macros, undocumented for now.
+       * lib/m4sugar/foreach.m4 (m4_transform, m4_transform_pair): Also
+       the m4 1.4.x counterparts.
+       * lib/m4sugar/m4sh.m4 (AS_IF, AS_CASE): Use it.
+       * tests/m4sh.at (AS@&t@_IF and AS@&t@_CASE): Test it.
+
 2008-08-14  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
 
        * lib/autoconf/programs.m4 (AC_PATH_TARGET_TOOL)
index 816ee608df073a4980a0df04318ff25860aa2ce7..53a2c7e24a0a1107306b23a331059ff957a21128 100644 (file)
@@ -263,6 +263,47 @@ m4_define([_m4_map],
        [m4_foreach([_m4_elt], [m4_shift2($@)],
                   [m4_apply([$1], m4_defn([_m4_elt]))])])])
 
+# m4_transform(EXPRESSION, ARG...)
+# --------------------------------
+# Expand EXPRESSION([ARG]) for each argument.  More efficient than
+# m4_foreach([var], [ARG...], [EXPRESSION(m4_defn([var]))])
+#
+# Invoke the temporary macro _m4_transform, defined as:
+#   $1([$2])[]$1([$3])[]...$1([$m])[]_m4_popdef([_m4_transform])
+m4_define([m4_transform],
+[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_transform_],
+[[$$1([$$2])[]]])
+
+# m4_transform_pair(EXPRESSION, [END-EXPR = EXPRESSION], ARG...)
+# --------------------------------------------------------------
+# Perform a pairwise grouping of consecutive ARGs, by expanding
+# EXPRESSION([ARG1], [ARG2]).  If there are an odd number of ARGs, the
+# final argument is expanded with END-EXPR([ARGn]).
+#
+# Build the temporary macro _m4_transform_pair, with the $2([$m+1])
+# only output if $# is odd:
+#   $1([$3], [$4])[]$1([$5], [$6])[]...$1([$m-1],
+#   [$m])[]m4_default([$2], [$1])([$m+1])[]_m4_popdef([_m4_transform_pair])
+m4_define([m4_transform_pair],
+[m4_if([$#], [0], [m4_fatal([$0: too few arguments: $#])],
+       [$#], [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(
+   [1], [2], [$#])[_m4_popdef([_$0])])_$0($@)])])
+
+m4_define([_m4_transform_pair_],
+[[$$1([$$2], [$$3])[]]])
+
+m4_define([_m4_transform_pair_end],
+[m4_if(m4_eval([$3 & 1]), [1], [[m4_default([$$2], [$$1])([$$3])[]]])])
+
 # m4_join(SEP, ARG1, ARG2...)
 # ---------------------------
 # Produce ARG1SEPARG2...SEPARGn.  Avoid back-to-back SEP when a given ARG
index 74d83778de98e1b7e2751da6b1d6b982bf72b8a6..1517630986c001d3428d33cad1ca8edb6c671d6b 100644 (file)
@@ -453,16 +453,15 @@ m4_defun([AS_PREPARE],
 # | *) DEFAULT ;;
 # | esac
 m4_define([_AS_CASE],
-[m4_if([$#], 0, [m4_fatal([$0: too few arguments: $#])],
-       [$#], 1, [  *) $1 ;;],
-       [$#], 2, [  $1) m4_default([$2], [:]) ;;],
-       [  $1) m4_default([$2], [:]) ;;
-$0(m4_shift2($@))])dnl
+[  $1[)] m4_default([$2], [:]) ;;
+])
+m4_define([_AS_CASE_DEFAULT],
+[  *[)] $1 ;;
 ])
 m4_defun([AS_CASE],
 [m4_ifval([$2$3],
 [case $1 in
-_AS_CASE(m4_shift($@))
+m4_transform_pair([_$0], [_$0_DEFAULT], m4_shift($@))dnl
 esac
 ])dnl
 ])# AS_CASE
@@ -496,20 +495,18 @@ m4_define([AS_EXIT],
 # with simplifications if IF-TRUE1 and/or IF-FALSE is empty.
 #
 m4_define([_AS_IF],
-[m4_ifval([$2$3],
 [elif $1; then
   m4_default([$2], [:])
-m4_ifval([$3], [$0(m4_shift2($@))])],
+])
+m4_define([_AS_IF_ELSE],
 [m4_ifvaln([$1],
 [else
-  $1])dnl
-])dnl
-])# _AS_IF
+  $1])])
 m4_defun([AS_IF],
 [m4_ifval([$2$3],
 [if $1; then
   m4_default([$2], [:])
-m4_ifval([$3], [_$0(m4_shift2($@))])[]dnl
+m4_transform_pair([_$0], [_$0_ELSE], m4_shift2($@))dnl
 fi
 ])dnl
 ])# AS_IF
index 22af6efb0402961abeb5d009f4cac2f998b3691a..a5a07b9616e1cbaa5c8323bf7d30b040e9bd4480 100644 (file)
@@ -1028,6 +1028,38 @@ m4_define([m4_map_sep],
        [m4_apply([$1], m4_car($3))_m4_map([[$2]$1], $3)])])
 
 
+# m4_transform(EXPRESSION, ARG...)
+# --------------------------------
+# Expand EXPRESSION([ARG]) for each argument.  More efficient than
+# m4_foreach([var], [ARG...], [EXPRESSION(m4_defn([var]))])
+m4_define([m4_transform],
+[m4_if([$#], [0], [m4_fatal([$0: too few arguments: $#])],
+       [$#], [1], [],
+       [$#], [2], [$1([$2])[]],
+       [$1([$2])[]$0([$1], m4_shift2($@))])])
+
+
+# m4_transform_pair(EXPRESSION, [END-EXPR = EXPRESSION], ARG...)
+# --------------------------------------------------------------
+# Perform a pairwise grouping of consecutive ARGs, by expanding
+# EXPRESSION([ARG1], [ARG2]).  If there are an odd number of ARGs, the
+# final argument is expanded with END-EXPR([ARGn]).
+#
+# For example:
+#   m4_define([show], [($*)m4_newline])dnl
+#   m4_transform_pair([show], [], [a], [b], [c], [d], [e])dnl
+#   => (a,b)
+#   => (c,d)
+#   => (e)
+m4_define([m4_transform_pair],
+[m4_if([$#], [0], [m4_fatal([$0: too few arguments: $#])],
+       [$#], [1], [m4_fatal([$0: too few arguments: $#: $1])],
+       [$#], [2], [],
+       [$#], [3], [m4_default([$2], [$1])([$3])[]],
+       [$#], [4], [$1([$3], [$4])[]],
+       [$1([$3], [$4])[]$0([$1], [$2], m4_shift(m4_shift3($@)))])])
+
+
 ## --------------------------- ##
 ## 9. More diversion support.  ##
 ## --------------------------- ##
index e01f769fa4263b6f1c25254e8b22d8e14adc784f..ac5f8ba8603e8e4e52a4d366242bd485ade31c71 100644 (file)
@@ -634,6 +634,8 @@ AT_CLEANUP
 
 AT_SETUP([AS@&t@_IF and AS@&t@_CASE])
 
+AT_KEYWORDS([m4@&t@_foreach_pair])
+
 AT_DATA_M4SH([script.as], [[dnl
 AS_INIT
 # Syntax checks: cope with empty arguments.
@@ -725,6 +727,31 @@ foo8=8 bar8=8
 foo9=9 bar9=9
 ]])
 
+dnl stress test for large number of conditionals
+AT_DATA_M4SH([script.as], [[dnl
+AS_INIT
+AS_IF(m4_shift(m4_for([i], [1], [1000], [], [, test $[1] = i, echo i])))
+AS_IF(m4_shift(m4_for([i], [1], [1000], [], [, test $[1] = i, echo i])),
+      [echo default])
+AS_CASE([$[1]]m4_for([i], [1], [1000], [], [, i, echo i]))
+AS_CASE([$[1]]m4_for([i], [1], [1000], [], [, i, echo i]), [echo default])
+]])
+
+AT_CHECK_M4SH
+AT_CHECK([./script 1], [0], [[1
+1
+1
+1
+]])
+AT_CHECK([./script 1000], [0], [[1000
+1000
+1000
+1000
+]])
+AT_CHECK([./script default], [0], [[default
+default
+]])
+
 AT_CLEANUP