mirror of
git://git.sv.gnu.org/autoconf
synced 2025-02-23 14:09:51 +08:00
Improve AC_DEFUN_ONCE semantics.
* lib/m4sugar/m4sugar.m4 (m4_defun_once): Rewrite to be no-op, rather than warning, on second use, and make sure first use never occurs out of order. * tests/m4sugar.at (m4@&t@_require: one-shot initialization): Enhance test. * tests/base.at (AC_REQUIRE & AC_DEFUN_ONCE: [Require, expand], (AC_REQUIRE & AC_DEFUN_ONCE: [Expand, require]): Adjust tests. * NEWS: Document this. * doc/autoconf.texi (Macro Definitions) <AC_DEFUN>: Mention AC_DEFUN_ONCE. (Prerequisite Macros) <AC_REQUIRE>: Likewise. (Expanded Before Required): Likewise. (One-Shot Macros) <AC_DEFUN_ONCE>: Document new semantics. Reported by Bruno Haible, with suggestion by Paolo Bonzini. Signed-off-by: Eric Blake <ebb9@byu.net>
This commit is contained in:
parent
2cc17c497c
commit
9f32bcf860
18
ChangeLog
18
ChangeLog
@ -1,3 +1,21 @@
|
||||
2009-01-26 Eric Blake <ebb9@byu.net>
|
||||
|
||||
Improve AC_DEFUN_ONCE semantics.
|
||||
* lib/m4sugar/m4sugar.m4 (m4_defun_once): Rewrite to be no-op,
|
||||
rather than warning, on second use, and make sure first use never
|
||||
occurs out of order.
|
||||
* tests/m4sugar.at (m4@&t@_require: one-shot initialization):
|
||||
Enhance test.
|
||||
* tests/base.at (AC_REQUIRE & AC_DEFUN_ONCE: [Require, expand],
|
||||
(AC_REQUIRE & AC_DEFUN_ONCE: [Expand, require]): Adjust tests.
|
||||
* NEWS: Document this.
|
||||
* doc/autoconf.texi (Macro Definitions) <AC_DEFUN>: Mention
|
||||
AC_DEFUN_ONCE.
|
||||
(Prerequisite Macros) <AC_REQUIRE>: Likewise.
|
||||
(Expanded Before Required): Likewise.
|
||||
(One-Shot Macros) <AC_DEFUN_ONCE>: Document new semantics.
|
||||
Reported by Bruno Haible, with suggestion by Paolo Bonzini.
|
||||
|
||||
2009-01-24 Eric Blake <ebb9@byu.net>
|
||||
|
||||
Fix typos in recent patches.
|
||||
|
6
NEWS
6
NEWS
@ -14,6 +14,12 @@ GNU Autoconf NEWS - User visible changes.
|
||||
the bug in earlier autoconf versions and avoid increased script
|
||||
size in the current version.
|
||||
|
||||
** AC_DEFUN_ONCE has improved semantics. Previously, a macro declared
|
||||
with AC_DEFUN_ONCE warned on a second invocation; and out-of-order
|
||||
expansion was still possible. Now, dependencies are guaranteed,
|
||||
and subsequent invocations are a silent no-op. This makes
|
||||
AC_DEFUN_ONCE an ideal macro for silencing AC_REQUIRE warnings.
|
||||
|
||||
** AC_LANG_ERLANG works once again (regression introduced in 2.61a).
|
||||
|
||||
** AC_HEADER_ASSERT is fixed so that './configure --enable-assert' no
|
||||
|
@ -12830,7 +12830,8 @@ the argument to @code{AC_REQUIRE}. The other category includes macros
|
||||
which are shorthand for a fixed block of text, and therefore do not take
|
||||
arguments. For this category of macros, directly expanding the macro
|
||||
multiple times results in redundant output, so it is more common to use
|
||||
the macro as the argument to @code{AC_REQUIRE}.
|
||||
the macro as the argument to @code{AC_REQUIRE}, or to declare the macro
|
||||
with @code{AC_DEFUN_ONCE} (@pxref{One-Shot Macros}).
|
||||
|
||||
Be sure to properly quote both the @var{macro-body} @emph{and} the
|
||||
@var{macro-name} to avoid any problems if the macro happens to have
|
||||
@ -13171,7 +13172,9 @@ in C
|
||||
|
||||
The bug is not in Autoconf, but in the macro definitions. If you ever
|
||||
pass a particular macro name to @code{AC_REQUIRE}, then you are implying
|
||||
that the macro only needs to be expanded once. But to enforce this, all
|
||||
that the macro only needs to be expanded once. But to enforce this,
|
||||
either the macro must be declared with @code{AC_DEFUN_ONCE} (although
|
||||
this only helps in Autoconf 2.64 or newer), or all
|
||||
uses of that macro should be through @code{AC_REQUIRE}; directly
|
||||
expanding the macro defeats the point of using @code{AC_REQUIRE} to
|
||||
eliminate redundant expansion. In the example, this rule of thumb was
|
||||
@ -13271,16 +13274,21 @@ macros can be defined using @code{AC_DEFUN_ONCE}.
|
||||
|
||||
@defmac AC_DEFUN_ONCE (@var{macro-name}, @var{macro-body})
|
||||
@acindex{DEFUN_ONCE}
|
||||
|
||||
Declare macro @var{macro-name} like @code{AC_DEFUN} would (@pxref{Macro
|
||||
Definitions}), and emit a warning any time the macro is called more than
|
||||
once.
|
||||
Definitions}), but add additional logic that guarantees that only the
|
||||
first use of the macro (whether by direct expansion or
|
||||
@code{AC_REQUIRE}) causes an expansion of @var{macro-body}; the
|
||||
expansion will occur before the start of any enclosing macro defined by
|
||||
@code{AC_DEFUN}. Subsequent expansions are silently ignored.
|
||||
Generally, it does not make sense for @var{macro-body} to use parameters
|
||||
such as @code{$1}.
|
||||
@end defmac
|
||||
|
||||
Obviously it is not sensible to evaluate a macro defined by
|
||||
@code{AC_DEFUN_ONCE} in a macro defined by @code{AC_DEFUN}.
|
||||
Most of the time you want to use @code{AC_REQUIRE} (@pxref{Prerequisite
|
||||
Macros}).
|
||||
Prior to Autoconf 2.64, a macro defined by @code{AC_DEFUN_ONCE} would
|
||||
emit a warning if it was directly expanded a second time, so for
|
||||
portability, it is better to use @code{AC_REQUIRE} than direct
|
||||
invocation of @var{macro-name} inside a macro defined by @code{AC_DEFUN}
|
||||
(@pxref{Prerequisite Macros}).
|
||||
|
||||
@node Obsoleting Macros
|
||||
@section Obsoleting Macros
|
||||
@ -22867,7 +22875,10 @@ $ @kbd{autoconf}
|
||||
@noindent
|
||||
To avoid this warning, decide what purpose the macro in question serves.
|
||||
If it only needs to be expanded once (for example, if it provides
|
||||
initialization text used by later macros), then the fix is to change all
|
||||
initialization text used by later macros), then the simplest fix is to
|
||||
change the macro to be declared with @code{AC_DEFUN_ONCE}
|
||||
(@pxref{One-Shot Macros}), although this only works in Autoconf 2.64 and
|
||||
newer. A more portable fix is to change all
|
||||
instances of direct calls to instead go through @code{AC_REQUIRE}
|
||||
(@pxref{Prerequisite Macros}). If, instead, the macro is parameterized
|
||||
by arguments or by the current definition of other macros in the m4
|
||||
|
@ -1914,14 +1914,17 @@ m4_define([m4_defun_init],
|
||||
|
||||
# m4_defun_once(NAME, EXPANSION)
|
||||
# ------------------------------
|
||||
# Like m4_defun, but issues the EXPANSION only once, and warns if used
|
||||
# several times.
|
||||
# Like m4_defun, but guarantee that EXPANSION only happens once
|
||||
# (thereafter, using NAME is a no-op).
|
||||
#
|
||||
# If _m4_divert_dump is empty, we are called at the top level;
|
||||
# otherwise, we must ensure that we are required in front of the
|
||||
# current defun'd macro.
|
||||
m4_define([m4_defun_once],
|
||||
[m4_define([m4_location($1)], m4_location)dnl
|
||||
m4_define([$1],
|
||||
[m4_provide_if([$1],
|
||||
[m4_warn([syntax], [$1 invoked multiple times])],
|
||||
[_m4_defun_pro([$1])$2[]_m4_defun_epi([$1])])])])
|
||||
[m4_define([m4_location($1)], m4_location)]dnl
|
||||
[m4_define([$1], [m4_pushdef([$1])m4_if(_m4_divert_dump, [],
|
||||
[_m4_defun_pro([$1])$2[]_m4_defun_epi([$1])],
|
||||
[_m4_require_call([$1], [$2[]m4_provide([$1])], _m4_divert_dump)])])])
|
||||
|
||||
|
||||
# m4_pattern_forbid(ERE, [WHY])
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
AT_BANNER([Autoconf base layer.])
|
||||
|
||||
# Copyright (C) 2000, 2001, 2003, 2005, 2006, 2007, 2008 Free Software
|
||||
# Foundation, Inc.
|
||||
# Copyright (C) 2000, 2001, 2003, 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
|
||||
@ -28,6 +28,7 @@ AT_BANNER([Autoconf base layer.])
|
||||
# Check that dependencies are always properly honored.
|
||||
|
||||
AT_SETUP([AC_REQUIRE: topological sort])
|
||||
AT_KEYWORDS([m4@&t@_require])
|
||||
|
||||
AT_DATA([configure.ac],
|
||||
[[define([REQUIRE_AND_CHECK],
|
||||
@ -71,6 +72,7 @@ AT_CLEANUP
|
||||
# Check that the message mentions AC_DEFUN, not m4_defun.
|
||||
|
||||
AT_SETUP([AC_REQUIRE: error message])
|
||||
AT_KEYWORDS([m4@&t@_require])
|
||||
AT_DATA([configure.ac],
|
||||
[[AC_REQUIRE([AC_PROG_CC])
|
||||
]])
|
||||
@ -88,6 +90,7 @@ AT_CLEANUP
|
||||
## ----------------------------------------------- ##
|
||||
|
||||
AT_SETUP([AC_REQUIRE & AC_DEFUN_ONCE: [Require, expand]])
|
||||
AT_KEYWORDS([m4@&t@_require m4@&t@_require_once])
|
||||
|
||||
AT_DATA([configure.ac],
|
||||
[[AC_DEFUN([TEST],
|
||||
@ -116,10 +119,7 @@ case $multi_test:$single_test in
|
||||
esac
|
||||
]])
|
||||
|
||||
AT_CHECK_AUTOCONF([], 0, [],
|
||||
[configure.ac:17: warning: SINGLE_TEST invoked multiple times
|
||||
configure.ac:18: warning: SINGLE_TEST invoked multiple times
|
||||
])
|
||||
AT_CHECK_AUTOCONF([], 0, [])
|
||||
|
||||
AT_CHECK_CONFIGURE
|
||||
|
||||
@ -132,6 +132,7 @@ AT_CLEANUP
|
||||
## ----------------------------------------------- ##
|
||||
|
||||
AT_SETUP([AC_REQUIRE & AC_DEFUN_ONCE: [Expand, require]])
|
||||
AT_KEYWORDS([m4@&t@_require m4@&t@_require_once])
|
||||
|
||||
AT_DATA([configure.ac],
|
||||
[[AC_DEFUN([TEST],
|
||||
@ -161,9 +162,7 @@ case $multi_test:$single_test in
|
||||
esac
|
||||
]])
|
||||
|
||||
AT_CHECK_AUTOCONF([], 0, [],
|
||||
[configure.ac:16: warning: SINGLE_TEST invoked multiple times
|
||||
])
|
||||
AT_CHECK_AUTOCONF([], 0, [])
|
||||
AT_CHECK_CONFIGURE
|
||||
|
||||
AT_CLEANUP
|
||||
@ -175,6 +174,7 @@ AT_CLEANUP
|
||||
## ------------------------- ##
|
||||
|
||||
AT_SETUP([AC_REQUIRE & AC_PROVIDE])
|
||||
AT_KEYWORDS([m4@&t@_require])
|
||||
|
||||
AT_DATA([configure.ac],
|
||||
[[AC_DEFUN([TEST],
|
||||
|
@ -430,8 +430,9 @@ AT_CLEANUP
|
||||
|
||||
AT_SETUP([m4@&t@_require: one-shot initialization])
|
||||
AT_KEYWORDS([m4@&t@_require])
|
||||
AT_KEYWORDS([m4@&t@_defun_init m4@&t@_copy])
|
||||
AT_KEYWORDS([m4@&t@_defun_init m4@&t@_copy m4@&t@_defun_once])
|
||||
|
||||
dnl check out m4_defun_init, m4_copy, and odd macro names
|
||||
AT_CHECK_M4SUGAR_TEXT([[
|
||||
m4_defun_init([a], [[init a
|
||||
]], [[common a]])dnl
|
||||
@ -455,6 +456,33 @@ hello, world
|
||||
goodbye
|
||||
hello, again
|
||||
]])
|
||||
|
||||
dnl Check m4_defun_once behavior
|
||||
AT_CHECK_M4SUGAR_TEXT([[
|
||||
m4_defun_once([a], [[a]])dnl
|
||||
m4_defun([b], [[b]m4_require([a])])dnl
|
||||
m4_defun([c], [[c]
|
||||
a[]m4_require([b])])dnl
|
||||
c
|
||||
a
|
||||
m4_defun_once([d], [[d]m4_require([a])])dnl
|
||||
d
|
||||
m4_defun_once([e], [[e]])dnl
|
||||
m4_defun([f], [[f]m4_require([e])e])dnl
|
||||
f
|
||||
]], [[
|
||||
a
|
||||
b
|
||||
c
|
||||
|
||||
|
||||
d
|
||||
e
|
||||
|
||||
f
|
||||
]])
|
||||
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user