Speed up m4_require.

* lib/m4sugar/m4sugar.m4 (_m4_divert_dump): Change semantics to
always be defined, as either empty or a number.
(_m4_defun_pro_outer, _m4_defun_epi_outer): Treat _m4_divert_dump
as a stack, rather than a one-shot macro.
(_m4_require_call): Expect third argument to be pre-expanded.
(m4_divert_require, m4_require): Adjust clients accordingly.
* lib/m4sugar/m4sh.m4 (AS_REQUIRE): Likewise.

Signed-off-by: Eric Blake <ebb9@byu.net>
This commit is contained in:
Eric Blake 2009-01-17 08:38:11 -07:00
parent ea20cd4c87
commit 91d1870bb4
3 changed files with 41 additions and 28 deletions

View File

@ -1,3 +1,14 @@
2009-01-19 Eric Blake <ebb9@byu.net>
Speed up m4_require.
* lib/m4sugar/m4sugar.m4 (_m4_divert_dump): Change semantics to
always be defined, as either empty or a number.
(_m4_defun_pro_outer, _m4_defun_epi_outer): Treat _m4_divert_dump
as a stack, rather than a one-shot macro.
(_m4_require_call): Expect third argument to be pre-expanded.
(m4_divert_require, m4_require): Adjust clients accordingly.
* lib/m4sugar/m4sh.m4 (AS_REQUIRE): Likewise.
2009-01-17 Eric Blake <ebb9@byu.net>
Avoid underfull hbox.

View File

@ -2,8 +2,8 @@
# M4 sugar for common shell constructs.
# Requires GNU M4 and M4sugar.
#
# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
# Free Software Foundation, Inc.
# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
# 2009 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -360,17 +360,13 @@ m4_divert_pop[]])
# given diversion when expanded (required or not). The expansion
# goes in the named diversion or an earlier one.
#
# Note: we expand _m4_divert_desired before passing it to m4_divert_require,
# otherwise we would need to use m4_pushdef and m4_popdef instead of
# simply m4_define.
#
# Since $2 can be quite large, this is factored for faster execution, giving
# either m4_require([$1], [$2]) or m4_divert_require(desired, [$1], [$2]).
m4_defun([AS_REQUIRE],
[m4_define([_m4_divert_desired], [m4_default_quoted([$3], [M4SH-INIT])])]dnl
[m4_if(m4_eval(_m4_divert(_m4_divert_dump) <= _m4_divert(_m4_divert_desired)),
[m4_if(m4_eval(_m4_divert_dump - 0 <= _m4_divert(_m4_divert_desired)),
1, [m4_require(],
[m4_divert_require(_m4_divert(_m4_divert_desired),]) [$1], [$2])])
[m4_divert_require(_m4_divert_desired,]) [$1], [$2])])
# _AS_REQUIRE_SHELL_FN(NAME-TO-CHECK, COMMENT, BODY-TO-EXPAND)
# ------------------------------------------------------------

View File

@ -4,7 +4,7 @@ divert(-1)# -*- Autoconf -*-
# Requires GNU M4.
#
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
# 2008 Free Software Foundation, Inc.
# 2008, 2009 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -1772,8 +1772,7 @@ m4_define([_m4_defun_pro],
[m4_expansion_stack_push([$1])m4_pushdef([_m4_expanding($1)])])
m4_define([_m4_defun_pro_outer],
[m4_define([_m4_divert_dump],
m4_defn([_m4_divert_diversion]))m4_divert_push([GROW])])
[m4_pushdef([_m4_divert_dump], m4_divnum)m4_divert_push([GROW])])
# _m4_defun_epi(MACRO-NAME)
# -------------------------
@ -1788,21 +1787,29 @@ m4_define([_m4_defun_epi],
[m4_provide([$1])])
m4_define([_m4_defun_epi_outer],
[_m4_undefine([_m4_divert_dump])m4_divert_pop([GROW])m4_undivert([GROW])])
[_m4_popdef([_m4_divert_dump])m4_divert_pop([GROW])m4_undivert([GROW])])
# _m4_divert_dump
# ---------------
# If blank, we are outside of any defun'd macro. Otherwise, expands
# to the diversion number (not name) where require'd macros should be
# moved once completed.
m4_define([_m4_divert_dump])
# m4_divert_require(DIVERSION, NAME-TO-CHECK, [BODY-TO-EXPAND])
# --------------------------------------------------------------
# Same as m4_require, but BODY-TO-EXPAND goes into the named diversion;
# Same as m4_require, but BODY-TO-EXPAND goes into the named DIVERSION;
# requirements still go in the current diversion though.
#
m4_define([m4_divert_require],
[m4_ifdef([_m4_expanding($2)],
[m4_fatal([$0: circular dependency of $2])])]dnl
[m4_ifdef([_m4_divert_dump], [],
[m4_if(_m4_divert_dump, [],
[m4_fatal([$0($2): cannot be used outside of an m4_defun'd macro])])]dnl
[m4_provide_if([$2], [],
[_m4_require_call([$2], [$3], [$1])])])
[_m4_require_call([$2], [$3], _m4_divert([$1]))])])
# m4_defun(NAME, EXPANSION, [MACRO = m4_define])
@ -1923,20 +1930,20 @@ m4_define([m4_before],
# This is called frequently, so minimize the number of macro invocations
# by avoiding dnl and other overhead on the common path.
m4_define([m4_require],
m4_do([[m4_ifdef([_m4_expanding($1)],
[m4_fatal([$0: circular dependency of $1])])]],
[[m4_ifdef([_m4_divert_dump], [],
[m4_fatal([$0($1): cannot be used outside of an ]dnl
m4_bmatch([$0], [^AC_], [[AC_DEFUN]], [[m4_defun]])['d macro])])]],
[[m4_provide_if([$1],
[],
[_m4_require_call([$1], [$2], [_m4_defn([_m4_divert_dump])])])]]))
[m4_ifdef([_m4_expanding($1)],
[m4_fatal([$0: circular dependency of $1])])]dnl
[m4_if(_m4_divert_dump, [],
[m4_fatal([$0($1): cannot be used outside of an ]dnl
m4_if([$0], [m4_require], [[m4_defun]], [[AC_DEFUN]])['d macro])])]dnl
[m4_provide_if([$1], [],
[_m4_require_call([$1], [$2], _m4_divert_dump)])])
# _m4_require_call(NAME-TO-CHECK, [BODY-TO-EXPAND = NAME-TO-CHECK], DIVERSION)
# ----------------------------------------------------------------------------
# _m4_require_call(NAME-TO-CHECK, [BODY-TO-EXPAND = NAME-TO-CHECK],
# DIVERSION-NUMBER)
# -----------------------------------------------------------------
# If m4_require decides to expand the body, it calls this macro. The
# expansion is placed in DIVERSION.
# expansion is placed in DIVERSION-NUMBER.
#
# This is called frequently, so minimize the number of macro invocations
# by avoiding dnl and other overhead on the common path.
@ -1946,8 +1953,7 @@ m4_define([_m4_require_call],
[m4_if([$2], [], [$1], [$2])
m4_provide_if([$1], [], [m4_warn([syntax],
[$1 is m4_require'd but not m4_defun'd])])]dnl
[_m4_divert_raw(_m4_divert($3))]dnl
[_m4_undivert(_m4_divert_grow)]dnl
[_m4_divert_raw($3)_m4_undivert(_m4_divert_grow)]dnl
[m4_divert_pop(_m4_divert_grow)_m4_popdef([_m4_divert_grow])])