diff --git a/NEWS b/NEWS index 5994d6be..4cad963b 100644 --- a/NEWS +++ b/NEWS @@ -387,6 +387,12 @@ GNU Autoconf NEWS - User visible changes. This means configure scripts will no longer check repeatedly for the C compiler under some combinations of macro use. +*** AS_IF’s if-false argument may be empty after macro expansion. + + This long-standing limitation broke configure scripts that used + macros in this position that emitted shell code in 2.69 but no + longer do, so we have lifted it. + *** AC_HEADER_MAJOR detects the location of the major, minor, and makedev macros correctly under glibc 2.25 and later. diff --git a/doc/autoconf.texi b/doc/autoconf.texi index da050b47..f78e5fc5 100644 --- a/doc/autoconf.texi +++ b/doc/autoconf.texi @@ -13972,13 +13972,6 @@ AS_IF([test "x$foo" = xyes], [HANDLE_FOO([yes])], ensures any required macros of @code{HANDLE_FOO} are expanded before the first test. -The @var{run-if-false} argument should either consist entirely of -blanks, or expand to a nonempty shell command. For example, -@code{AS_IF([:], [:], [[]])} is invalid because its @var{run-if-false} -argument contains the nonblank characters @code{[]} which expand to -nothing. This restriction on @var{run-if-false} also applies to other -macros with ``if-false'' arguments denoting shell commands. - This macro should be used instead of plain @samp{if} in code outside of an @code{AC_DEFUN} macro, when the contents of the @samp{if} use @code{AC_REQUIRE} directly or indirectly (@pxref{Prerequisite Macros}). diff --git a/lib/m4sugar/m4sh.m4 b/lib/m4sugar/m4sh.m4 index 8f96eb7b..81b3f82e 100644 --- a/lib/m4sugar/m4sh.m4 +++ b/lib/m4sugar/m4sh.m4 @@ -98,9 +98,10 @@ _$0 # _AS_BOURNE_COMPATIBLE # --------------------- # This is the part of AS_BOURNE_COMPATIBLE which has to be repeated inside -# each instance. +# each instance. See _AS_EMPTY_ELSE_PREPARE for explanation of as_nop. m4_define([_AS_BOURNE_COMPATIBLE], -[AS_IF([test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1], +[as_nop=: +AS_IF([test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1], [emulate sh NULLCMD=: [#] Pre-4.2 versions of Zsh do word splitting on ${1+"$[@]"}, which @@ -351,7 +352,8 @@ m4_defun([_AS_PREPARE], [m4_pushdef([AS_MESSAGE_LOG_FD], [-1])]dnl [_AS_ERROR_PREPARE _m4_popdef([AS_MESSAGE_LOG_FD])]dnl -[_AS_EXIT_PREPARE +[_AS_EMPTY_ELSE_PREPARE +_AS_EXIT_PREPARE _AS_UNSET_PREPARE _AS_VAR_APPEND_PREPARE _AS_VAR_ARITH_PREPARE @@ -387,6 +389,7 @@ AS_REQUIRE([_AS_CR_PREPARE]) AS_REQUIRE([_AS_LINENO_PREPARE]) AS_REQUIRE([_AS_ECHO_N_PREPARE]) AS_REQUIRE([_AS_EXIT_PREPARE]) +AS_REQUIRE([_AS_EMPTY_ELSE_PREPARE]) AS_REQUIRE([_AS_LN_S_PREPARE]) AS_REQUIRE([_AS_MKDIR_P_PREPARE]) AS_REQUIRE([_AS_TEST_PREPARE]) @@ -669,14 +672,27 @@ done[]_m4_popdef([$1])]) # | fi # with simplifications when IF-TRUE1 and/or IF-FALSE are empty. # +# Note: IF-TRUEn and IF_FALSE may be nonempty but, after further macro +# expansion, leave no actual shell code. We can't detect this, so we +# include a no-op statement in each clause to prevent it becoming a shell +# syntax error. For the IF-TRUEn this can simply be `:' at the beginning of +# the clause. IF-FALSE is harder because it must preserve the value of $? +# from the conditional expression. The most practical way to do this is +# with a shell function whose body is `return $?' but AS_IF is used before +# it's safe to use shell functions. To deal with *that*, there is a shell +# variable $as_fn_nop that expands to `:' before the nop shell function is +# defined, and invokes the nop shell function afterward. Early uses of +# AS_IF (which are all under our control) must not use the value of $? from +# the conditional expression in an else clause. m4_define([_AS_IF], [elif $1 then : $2 ]) -m4_define([_AS_IF_ELSE], +m4_defun([_AS_IF_ELSE], [m4_ifnblank([$1], -[else +[m4_append_uniq([_AS_CLEANUP], [AS_REQUIRE([_AS_EMPTY_ELSE_PREPARE])])]dnl +[else $as_nop $1 ])]) @@ -687,6 +703,16 @@ then : m4_map_args_pair([_$0], [_$0_ELSE], m4_shift2($@))]dnl [fi[]])# AS_IF +m4_defun([_AS_EMPTY_ELSE_PREPARE], +[m4_divert_text([M4SH-INIT-FN], +[AS_FUNCTION_DESCRIBE([as_fn_nop], [], + [Do nothing but, unlike ":", preserve the value of $][?.]) +as_fn_nop () +{ + return $[]? +} +as_nop=as_fn_nop])]) + # AS_SET_STATUS(STATUS) # --------------------- @@ -705,7 +731,8 @@ as_fn_unset () { AS_UNSET([$[1]]) } -as_unset=as_fn_unset]) +as_unset=as_fn_unset +]) # AS_UNSET(VAR) diff --git a/tests/m4sh.at b/tests/m4sh.at index 633becdd..21c61237 100644 --- a/tests/m4sh.at +++ b/tests/m4sh.at @@ -1320,13 +1320,11 @@ dnl Handle blank arguments. AS_IF([false], [:], [ ]) && AS_CASE([foo], [foo], [] ) && echo seventeen m4_define([empty])AS_IF([:], [empty] -) && AS_CASE([foo], [foo], [empty]) && echo eighteen +) && AS_IF([false], [], [empty] +) || AS_CASE([foo], [foo], [empty]) && echo eighteen dnl Allow for users that don't know to avoid trailing whitespace AS_IF([: ], [echo nineteen]) -dnl We can't handle AS_IF([false], [:], [empty]) unless m4_expand is -dnl taught how to handle m4_require. The user is responsible for -dnl avoiding the syntax error in that case. # check that require works correctly m4_for([n], 1, 9, [],