]> git.ipfire.org Git - thirdparty/autoconf.git/commitdiff
One more round of m4_foreach_w speedups.
authorEric Blake <ebb9@byu.net>
Thu, 4 Oct 2007 15:43:59 +0000 (09:43 -0600)
committerEric Blake <ebb9@byu.net>
Thu, 4 Oct 2007 16:09:38 +0000 (10:09 -0600)
* lib/m4sugar/m4sugar.m4 (m4_flatten): Only use regex if newline
is present.
(_m4_split): Avoid useless expansions inside definition.  Move
argument defaulting...
(m4_split): ...here.  Change alternate quote to something less
likely to appear in $1.  Also, special case space as regexp...
(m4_foreach_w): ...to avoid regexp on single-term list.
(m4_default, m4_defn, m4_popdef, m4_undefine, _m4_foreach): Avoid
useless expansions inside definition.
* tests/m4sugar.at (m4@&t@_split): Add tests.

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

index a2669a8b1347f6165bbf76f704dee81a986e8b78..5a37f4cb12648b58c710ec8cec171a02e7c66a45 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2007-10-04  Eric Blake  <ebb9@byu.net>
+
+       One more round of m4_foreach_w speedups.
+       * lib/m4sugar/m4sugar.m4 (m4_flatten): Only use regex if newline
+       is present.
+       (_m4_split): Avoid useless expansions inside definition.  Move
+       argument defaulting...
+       (m4_split): ...here.  Change alternate quote to something less
+       likely to appear in $1.  Also, special case space as regexp...
+       (m4_foreach_w): ...to avoid regexp on single-term list.
+       (m4_default, m4_defn, m4_popdef, m4_undefine, _m4_foreach): Avoid
+       useless expansions inside definition.
+       * tests/m4sugar.at (m4@&t@_split): Add tests.
+
 2007-10-04  Paolo Bonzini  <bonzini@gnu.org>
 
        Fix previous commit.
index 5317617c846927fb481045b36a099e430f07f2c5..d9cf142a1441839dbf3ccc15979ceb0288c4edda 100644 (file)
@@ -477,18 +477,24 @@ m4_define([m4_define_default],
 # m4_default(EXP1, EXP2)
 # ----------------------
 # Returns EXP1 if non empty, otherwise EXP2.
+#
+# This macro is called on hot paths, so inline the contents of m4_ifval,
+# for one less round of expansion.
 m4_define([m4_default],
-[m4_ifval([$1], [$1], [$2])])
+[m4_if([$1], [], [$2], [$1])])
 
 
 # m4_defn(NAME)
 # -------------
 # Like the original, except don't tolerate popping something which is
-# undefined.
+# undefined, and only support one argument.
+#
+# This macro is called frequently, so minimize the amount of additional
+# expansions by skipping m4_ifndef.
 m4_define([m4_defn],
-[m4_ifndef([$1],
-          [m4_fatal([$0: undefined macro: $1])])dnl
-m4_builtin([defn], $@)])
+[m4_ifdef([$1], [],
+         [m4_fatal([$0: undefined macro: $1])])]dnl
+[m4_builtin([defn], $@)])
 
 
 # _m4_dumpdefs_up(NAME)
@@ -522,11 +528,14 @@ _m4_dumpdefs_down([$1])])
 # m4_popdef(NAME)
 # ---------------
 # Like the original, except don't tolerate popping something which is
-# undefined.
+# undefined, and only support one argument.
+#
+# This macro is called frequently, so minimize the amount of additional
+# expansions by skipping m4_ifndef.
 m4_define([m4_popdef],
-[m4_ifndef([$1],
-          [m4_fatal([$0: undefined macro: $1])])dnl
-m4_builtin([popdef], $@)])
+[m4_ifdef([$1], [],
+         [m4_fatal([$0: undefined macro: $1])])]dnl
+[m4_builtin([popdef], $@)])
 
 
 # m4_quote(ARGS)
@@ -579,11 +588,14 @@ m4_define([m4_shift3], [m4_shift(m4_shift(m4_shift($@)))])
 # m4_undefine(NAME)
 # -----------------
 # Like the original, except don't tolerate undefining something which is
-# undefined.
+# undefined, and only support one argument.
+#
+# This macro is called frequently, so minimize the amount of additional
+# expansions by skipping m4_ifndef.
 m4_define([m4_undefine],
-[m4_ifndef([$1],
-          [m4_fatal([$0: undefined macro: $1])])dnl
-m4_builtin([undefine], $@)])
+[m4_ifdef([$1], [],
+         [m4_fatal([$0: undefined macro: $1])])]dnl
+[m4_builtin([undefine], $@)])
 
 
 ## -------------------------- ##
@@ -724,13 +736,15 @@ m4_if(m4_defn([$1]), [$2], [],
 #
 #      | m4_foreach(Var, [[[active]], [[active]]], [-Var-])
 #     => -active--active-
+#
+# This macro is called frequently, so avoid extra expansions such as
+# m4_ifval and dnl.
 m4_define([m4_foreach],
-[m4_pushdef([$1])_m4_foreach($@)m4_popdef([$1])])
+[m4_pushdef([$1])_$0($@)m4_popdef([$1])])
 
 m4_define([_m4_foreach],
-[m4_ifval([$2],
-         [m4_define([$1], m4_car($2))$3[]dnl
-_m4_foreach([$1], m4_cdr($2), [$3])])])
+[m4_if([$2], [], [],
+       [m4_define([$1], m4_car($2))$3[]$0([$1], m4_cdr($2), [$3])])])
 
 
 # m4_foreach_w(VARIABLE, LIST, EXPRESSION)
@@ -745,7 +759,7 @@ _m4_foreach([$1], m4_cdr($2), [$3])])])
 #    => -active--b--active-end
 #
 m4_define([m4_foreach_w],
-[m4_foreach([$1], m4_split(m4_normalize([$2])), [$3])])
+[m4_foreach([$1], m4_split(m4_normalize([$2]), [ ]), [$3])])
 
 
 
@@ -1488,28 +1502,32 @@ m4_define([m4_toupper],
 #
 # Pay attention to the m4_changequotes.  When m4 reads the definition of
 # m4_split, it still has quotes set to [ and ].  Luckily, these are matched
-# in the macro body, so the definition is stored correctly.
+# in the macro body, so the definition is stored correctly.  Use the same
+# alternate quotes as m4_noquote; it must be unlikely to appear in $1.
 #
 # Also, notice that $1 is quoted twice, since we want the result to
 # be quoted.  Then you should understand that the argument of
-# patsubst is ``STRING'' (i.e., with additional `` and '').
+# patsubst is -=<{STRING}>=- (i.e., with additional -=<{ and }>=-).
 #
 # This macro is safe on active symbols, i.e.:
 #   m4_define(active, ACTIVE)
 #   m4_split([active active ])end
 #   => [active], [active], []end
-
+#
+# Optimize on regex of ` ' (space), since m4_foreach_w already guarantees
+# that the list contains single space separators, and a common case is
+# splitting a single-element list.  This macro is called frequently,
+# so avoid unnecessary dnl inside the definition.
 m4_define([m4_split],
-[m4_ifval([$1], [_m4_split($@)])])
+[m4_if([$1], [], [],
+       [$2], [ ], [m4_if(m4_index([$1], [ ]), [-1], [[[$1]]], [_$0($@)])],
+       [$2], [], [_$0([$1], [[  ]+])],
+       [_$0($@)])])
 
 m4_define([_m4_split],
-[m4_changequote(``, '')dnl
-[dnl Can't use m4_default here instead of m4_if, because m4_default uses
-dnl [ and ] as quotes.
-m4_bpatsubst(````$1'''',
-            m4_if(``$2'',, ``[  ]+'', ``$2''),
-            ``], ['')]dnl
-m4_changequote([, ])])
+[m4_changequote(-=<{,}>=-)]dnl
+[[m4_bpatsubst(-=<{-=<{$1}>=-}>=-, -=<{$2}>=-,
+              -=<{], [}>=-)]m4_changequote([, ])])
 
 
 
@@ -1523,10 +1541,14 @@ m4_changequote([, ])])
 #    act\
 #    ive])end
 #    => active activeend
+#
+# In m4, m4_bpatsubst is expensive, so first check for a newline.
 m4_define([m4_flatten],
-[m4_translit(m4_bpatsubst([[[$1]]], [\\
+[m4_if(m4_index([$1], [
+]), [-1], [[$1]],
+       [m4_translit(m4_bpatsubst([[[$1]]], [\\
 ]), [
-], [ ])])
+], [ ])])])
 
 
 # m4_strip(STRING)
index 5aff0c9dbee69146629742c3ef9518b6e697e223..81e7919e356bccb25f250cfcbac36184f2be23fb 100644 (file)
@@ -40,7 +40,10 @@ AT_CHECK_M4SUGAR([-o-],, [$2], [$3])
 # - m4_require
 # uses warn/error code.
 #
+# - m4_split
+#
 # - m4_text_wrap
+# uses m4_split code.
 
 ## --------- ##
 ## m4_warn.  ##
@@ -140,6 +143,45 @@ autom4te: m4 failed with exit status: 1
 AT_CLEANUP
 
 
+## ---------- ##
+## m4_split.  ##
+## ---------- ##
+
+AT_SETUP([m4@&t@_split])
+
+AT_CHECK_M4SUGAR_TEXT(
+[[m4_define([active], [ACT, IVE])m4_define([bd], [oops])
+m4_split
+m4_split([[]])
+m4_split([ ])
+m4_split([active])
+m4_split([ active      active ])end
+m4_split([ ], [ ])
+m4_split([active], [ ])
+m4_split([ active      active ], [ ])end
+m4_split([abcde], [bd])
+m4_split([abcde], [[bd]])
+m4_split([foo=`` bar=''])
+m4_split([foo='' bar=``])
+]],
+[[
+
+[[]]
+[], []
+[active]
+[], [active], [active], []end
+[], []
+[active]
+[], [active    active], []end
+[abcde]
+[a], [c], [e]
+[foo=``], [bar='']
+[foo=''], [bar=``]
+]])
+
+AT_CLEANUP
+
+
 ## -------------- ##
 ## m4_text_wrap.  ##
 ## -------------- ##