autoconf-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 3/3] Consistently expand macros in whitespace-separated lists.


From: Zack Weinberg
Subject: [PATCH 3/3] Consistently expand macros in whitespace-separated lists.
Date: Wed, 25 Mar 2020 15:15:21 -0400

Several of the most commonly used Autoconf macros (starting with
AC_CHECK_FUNCS and AC_CHECK_HEADERS) take a whitespace-separated list
of symbols as their primary argument.  It would abstractly be best if
this list were _not_ subject to M4 macro expansion, in case there’s a
collision between a M4 macro name and something to be looked for.
However, we have historically not been careful about this, and there’s
been reports of configure scripts using ‘dnl’ to write comments inside
the list.  The AS_LITERAL_IF optimizations added to AC_CHECK_FUNCS and
AC_CHECK_HEADERS since 2.69 broke some of those scripts with bizarre
shell syntax errors.

Also, the macro expansion behavior is not consistent among all of the
macros that take whitespace-separated lists, nor is it consistent
between autoconf and autoheader.

Address this by introducing a new m4sugar macro, currently called
‘m4_validate_w’ (I’m open to suggestions for better names).  Here’s
its documentation comment:

| m4_validate_w(STRING): Expands into m4_normalize(m4_expand([STRING])),
| but if that is not the same as just m4_normalize([STRING]),
| issue a warning.

The text of the warning is

| configure.ac:N: warning: whitespace-separated-list contains macros;
| configure.ac:N: in a future version of Autoconf they will not be expanded

If the unexpanded form of the string contains the token ‘dnl’ then
there’s an additional line:

| configure.ac:N: note: ‘dnl’ is a macro

All of the public macros that take a whitespace-separated list of
symbols are changed to pass that argument through m4_validate_w before
doing anything else with it, and the test suite is updated to verify
consistent behavior for every last one of them.

This addresses Savannah issues #110210 and #110211, and the harmless
but annoying autoheader behavior described at
https://lists.gnu.org/archive/html/bug-autoconf/2018-02/msg00005.html .

In order to avoid expanding relatively expensive m4sugar macros
multiple times per top-level macro invocation, several of the affected
Autoconf macros are restructured along the same lines as I did for
AC_REPLACE_FUNCS in the previous patch.

* lib/m4sugar/m4sugar.m4 (m4_validate_w): New macro.
* lib/autoconf/functions.m4 (AC_CHECK_FUNCS, AC_CHECK_FUNCS_ONCE)
  (AC_REPLACE_FUNCS)
* lib/autoconf/general.m4 (AC_CONFIG_MACRO_DIRS, AC_CHECK_FILES)
* lib/autoconf/headers.m4 (AC_CHECK_HEADERS, AC_CHECK_HEADERS_ONCE)
* lib/autoconf/status.m4 (AC_CONFIG_SUBDIRS): Pass $1 through
  m4_validate_w before use.

* lib/autoconf/headers.m4 (AC_CHECK_HEADERS): Refactor with helpers
  _AC_CHECK_HEADERS_ONE_U, _AC_CHECK_HEADERS_ONE_S, _AC_CHECK_HEADERS_ONE_C.
  (AC_CHECK_HEADERS_ONCE): Eliminate _AC_CHECK_HEADERS_ONCE.
  (AC_CHECK_INCLUDES_DEFAULT): Don’t use _AC_CHECK_HEADERS_ONCE.

* lib/autoconf/functions.m4 (AC_CHECK_FUNCS): Refactor with helpers
  _AC_CHECK_FUNCS_ONE_U, _AC_CHECK_FUNCS_ONE_S, _AC_CHECK_FUNCS_ONE_C.

* lib/autoconf/status.m4 (_AC_CONFIG_SUBDIRS): No need to use m4_normalize.

* tests/semantics.at: Add tests for expansion of M4 macros in
  whitespace-separated list arguments to all of the above.
---
 NEWS                      |  16 +++
 lib/autoconf/functions.m4 |  47 +++++--
 lib/autoconf/general.m4   |   6 +-
 lib/autoconf/headers.m4   |  55 +++++---
 lib/autoconf/status.m4    |   9 +-
 lib/m4sugar/m4sugar.m4    |  21 ++++
 tests/semantics.at        | 259 +++++++++++++++++++++++++++++++++++++-
 7 files changed, 378 insertions(+), 35 deletions(-)

diff --git a/NEWS b/NEWS
index 3cb2876d..fc0fef80 100644
--- a/NEWS
+++ b/NEWS
@@ -39,6 +39,22 @@ GNU Autoconf NEWS - User visible changes.
    account.  This makes it possible to use AC_DEFINE for secondary
    headers without duplicating the template in the main config header.
 
+** Macros that take whitespace-separated lists as arguments
+   now always expand macros within those arguments.  (Formerly, these
+   macros would *usually* expand those arguments, but the behavior was
+   not reliable nor was it consistent between autoconf and autoheader.)
+
+   Macro expansion within these arguments is deprecated; if expansion
+   changes the list, a warning in the 'obsolete' category will be
+   emitted.  Note that 'dnl' is a macro.  Putting 'dnl' comments
+   inside any argument to an Autoconf macro is, in general, only
+   supported when that argument takes more Autoconf code (e.g. the
+   ACTION-IF-TRUE argument to AC_COMPILE_IFELSE).
+
+   The affected macros are AC_CHECK_FILES, AC_CHECK_FUNCS,
+   AC_CHECK_FUNCS_ONCE, AC_CHECK_HEADERS, AC_CHECK_HEADERS_ONCE,
+   AC_CONFIG_MACRO_DIRS, AC_CONFIG_SUBDIRS, and AC_REPLACE_FUNCS.
+
 ** Macros
 
 - New macro AC_C__GENERIC.
diff --git a/lib/autoconf/functions.m4 b/lib/autoconf/functions.m4
index 44730096..645a7c60 100644
--- a/lib/autoconf/functions.m4
+++ b/lib/autoconf/functions.m4
@@ -78,6 +78,34 @@ m4_define([_AH_CHECK_FUNC],
 [AH_TEMPLATE(AS_TR_CPP([HAVE_$1]),
   [Define to 1 if you have the `$1' function.])])
 
+# _AC_CHECK_FUNCS_ONE_U(FUNCTION)
+# -------------------------------
+# Perform the actions that need to be performed unconditionally
+# for every FUNCTION that *could* be checked for by AC_CHECK_FUNCS.
+m4_define([_AC_CHECK_FUNCS_ONE_U],
+[AS_LITERAL_WORD_IF([$1],
+  [_AH_CHECK_FUNC([$1])],
+  [AC_DIAGNOSE([syntax], [AC_CHECK_FUNCS($1): you should use literals])])])
+
+# _AC_CHECK_FUNCS_ONE_S(FUNCTION)
+# -------------------------------
+# If FUNCTION exists, define HAVE_FUNCTION.  FUNCTION must be literal.
+# Used by AC_CHECK_FUNCS for its simplest case, when its FUNCTION list
+# is fully literal and no optional actions were supplied.
+m4_define([_AC_CHECK_FUNCS_ONE_S],
+[_AH_CHECK_FUNC([$1])]dnl
+[AC_CHECK_FUNC([$1],
+  [AC_DEFINE(AS_TR_CPP([HAVE_$1]))])])
+
+# _AC_CHECK_FUNCS_ONE_C(FUNCTION, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+# -------------------------------------------------------------------------
+# If FUNCTION exists, define HAVE_FUNCTION and execute ACTION-IF-FOUND.
+# Otherwise execute ACTION-IF-NOT-FOUND.  FUNCTION can be a shell variable.
+# Used by AC_CHECK_FUNCS for complex cases.
+m4_define([_AC_CHECK_FUNCS_ONE_C],
+[AC_CHECK_FUNC([$1],
+  [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_]$1)) $2],
+  [$3])])
 
 # AC_CHECK_FUNCS(FUNCTION..., [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
 # ---------------------------------------------------------------------
@@ -87,17 +115,14 @@ m4_define([_AH_CHECK_FUNC],
 # available for each found function.  Either ACTION may include
 # `break' to stop the search.
 AC_DEFUN([AC_CHECK_FUNCS],
-[m4_map_args_w([$1], [_AH_CHECK_FUNC(], [)])]dnl
-[m4_if([$2$3]AS_LITERAL_IF([$1], [[yes]], [[no]]), [yes],
-       [m4_map_args_w([$1], [_$0(], [)])],
-       [AS_FOR([AC_func], [ac_func], [$1], [_$0(AC_func, [$2], [$3])])])dnl
-])# AC_CHECK_FUNCS
+[_$0(m4_validate_w([$1]), [$2], [$3])])
 
 m4_define([_AC_CHECK_FUNCS],
-[AC_CHECK_FUNC([$1],
-              [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_]$1)) $2],
-              [$3])dnl
-])
+[m4_if([$2$3]AS_LITERAL_IF([$1], [[yes]], [[no]]), [yes],
+  [m4_map_args_w([$1], [_AC_CHECK_FUNCS_ONE_S(], [)])],
+  [m4_map_args_w([$1], [_AC_CHECK_FUNCS_ONE_U(], [)])]
+  [AS_FOR([AC_func], [ac_func], [$1],
+    [_AC_CHECK_FUNCS_ONE_C(AC_func, [$2], [$3])])])])
 
 
 # _AC_CHECK_FUNC_ONCE(FUNCTION)
@@ -114,7 +139,7 @@ m4_define([_AC_CHECK_FUNC_ONCE],
 # Add each whitespace-separated name in FUNCTION to the list of functions
 # to check once.
 AC_DEFUN([AC_CHECK_FUNCS_ONCE],
-[m4_map_args_w([$1], [_AC_CHECK_FUNC_ONCE(], [)])])
+[m4_map_args_w(m4_validate_w([$1]), [_AC_CHECK_FUNC_ONCE(], [)])])
 
 # _AC_FUNCS_EXPANSION(LANG)
 # -------------------------
@@ -177,7 +202,7 @@ m4_define([_AC_REPLACE_FUNC_NL],
 # equivalent of AC_CHECK_FUNC, then call AC_LIBOBJ if the function
 # was not found.
 AC_DEFUN([AC_REPLACE_FUNCS],
-[_$0(m4_flatten([$1]))])
+[_$0(m4_validate_w([$1]))])
 
 m4_define([_AC_REPLACE_FUNCS],
 [AS_LITERAL_IF([$1],
diff --git a/lib/autoconf/general.m4 b/lib/autoconf/general.m4
index e80f7eb0..e725d88c 100644
--- a/lib/autoconf/general.m4
+++ b/lib/autoconf/general.m4
@@ -1791,7 +1791,8 @@ m4_define([_AC_CONFIG_MACRO_DIRS],
 # If no directory has been traced yet, then this macro also triggers
 # a trace of AC_CONFIG_MACRO_DIR on the first directory.
 AC_DEFUN([AC_CONFIG_MACRO_DIRS],
-[m4_map_args_w([$1], [_$0(_$0_USED()[$0], ], [)])])
+[m4_map_args_w(m4_validate_w([$1]),
+  [_$0(_$0_USED()[$0], ], [)])])
 
 # AC_CONFIG_MACRO_DIR(DIR)
 # ------------------------
@@ -2879,7 +2880,8 @@ m4_define([_AC_CHECK_FILES],
 # ACTION-IF-FOUND or ACTION-IF-NOT-FOUND.  For files that exist, also
 # provide the preprocessor variable HAVE_FILE.
 AC_DEFUN([AC_CHECK_FILES],
-[m4_map_args_w([$1], [AC_CHECK_FILE(_$0(], [)[$2], [$3])])])
+[m4_map_args_w(m4_validate_w([$1]),
+  [AC_CHECK_FILE(_$0(], [)[$2], [$3])])])
 
 
 ## ------------------------------- ##
diff --git a/lib/autoconf/headers.m4 b/lib/autoconf/headers.m4
index be528261..ae8bf28f 100644
--- a/lib/autoconf/headers.m4
+++ b/lib/autoconf/headers.m4
@@ -173,6 +173,37 @@ m4_define([_AH_CHECK_HEADER],
 m4_define([AH_CHECK_HEADERS],
 [m4_foreach_w([AC_Header], [$1], [_AH_CHECK_HEADER(m4_defn([AC_Header]))])])
 
+# _AC_CHECK_HEADERS_ONE_U(HEADER-FILE)
+# -------------------------------
+# Perform the actions that need to be performed unconditionally
+# for every HEADER-FILE that *could* be checked for by AC_CHECK_HEADERS.
+m4_define([_AC_CHECK_HEADERS_ONE_U],
+[AS_LITERAL_WORD_IF([$1],
+  [_AH_CHECK_HEADER([$1])],
+  [AC_DIAGNOSE([syntax], [AC_CHECK_HEADERS($1): you should use literals])])])
+
+# _AC_CHECK_HEADERS_ONE_S(HEADER-FILE, [INCLUDES])
+# -------------------------------
+# If HEADER-FILE exists, define HAVE_HEADER_FILE.  HEADER-FILE must be literal.
+# Used by AC_CHECK_HEADERS for its simplest case, when its HEADER-FILE list
+# is fully literal and no optional actions were supplied.
+# INCLUDES is as for AC_CHECK_HEADER.
+m4_define([_AC_CHECK_HEADERS_ONE_S],
+[_AH_CHECK_HEADER([$1])]dnl
+[AC_CHECK_HEADER([$1],
+  [AC_DEFINE(AS_TR_CPP([HAVE_$1]))], [], [$2])])
+
+# _AC_CHECK_HEADERS_ONE_C(HEADER-FILE, [ACTION-IF-FOUND],
+#    [ACTION-IF-NOT-FOUND], [INCLUDES])
+# -------------------------------------------------------------------------
+# If HEADER-FILE exists, define HAVE_HEADER-FILE and execute ACTION-IF-FOUND.
+# Otherwise execute ACTION-IF-NOT-FOUND.  HEADER-FILE can be a shell variable.
+# Used by AC_CHECK_HEADERS for complex cases.
+# INCLUDES is as for AC_CHECK_HEADER.
+m4_define([_AC_CHECK_HEADERS_ONE_C],
+[AC_CHECK_HEADER([$1],
+  [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_]$1)) $2],
+  [$3], [$4])])
 
 # AC_CHECK_HEADERS(HEADER-FILE...,
 #                 [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND],
@@ -184,17 +215,14 @@ m4_define([AH_CHECK_HEADERS],
 # preprocessor definition HAVE_HEADER_FILE available for each found
 # header.  Either ACTION may include `break' to stop the search.
 AC_DEFUN([AC_CHECK_HEADERS],
-[m4_map_args_w([$1], [_AH_CHECK_HEADER(], [)])]dnl
-[m4_if([$2$3]AS_LITERAL_IF([$1], [[yes]], [[no]]), [yes],
-       [m4_map_args_w([$1], [_$0(], [, [], [], [$4])])],
-       [AS_FOR([AC_header], [ac_header], [$1], [_$0(AC_header, [$2], [$3], 
[$4])])])dnl
-])# AC_CHECK_HEADERS
+[_$0(m4_validate_w([$1]), [$2], [$3], [$4])])
 
 m4_define([_AC_CHECK_HEADERS],
-[AC_CHECK_HEADER([$1],
-                [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_]$1)) $2],
-                [$3], [$4])dnl
-])
+[m4_if([$2$3]AS_LITERAL_IF([$1], [[yes]], [[no]]), [yes],
+       [m4_map_args_w([$1], [_AC_CHECK_HEADERS_ONE_S(], [, [$4])])],
+       [m4_map_args_w([$1], [_AC_CHECK_HEADERS_ONE_U(], [)])]dnl
+       [AS_FOR([AC_header], [ac_header], [$1],
+               [_AC_CHECK_HEADERS_ONE_C(AC_header, [$2], [$3], [$4])])])])
 
 
 # _AC_CHECK_HEADER_ONCE(HEADER-FILE)
@@ -217,10 +245,8 @@ m4_define([_AC_CHECK_HEADER_ONCE],
 # and vice versa.
 AC_DEFUN([AC_CHECK_HEADERS_ONCE],
   [AC_REQUIRE([AC_CHECK_INCLUDES_DEFAULT])]dnl
-  [_AC_CHECK_HEADERS_ONCE([$1])])
+  [m4_map_args_w(m4_validate_w([$1]), [_AC_CHECK_HEADER_ONCE(], [)])])
 
-AC_DEFUN([_AC_CHECK_HEADERS_ONCE],
-  [m4_map_args_w([$1], [_AC_CHECK_HEADER_ONCE(], [)])])
 
 # _AC_HEADERS_EXPANSION(LANG)
 # ---------------------------
@@ -289,8 +315,9 @@ ac_includes_default="\
 # include <unistd.h>
 #endif"
 ])]dnl
-[_AC_CHECK_HEADERS_ONCE(
-  [sys/types.h sys/stat.h strings.h inttypes.h stdint.h unistd.h])]dnl
+[m4_map_args([_AC_CHECK_HEADER_ONCE],
+  [sys/types.h], [sys/stat.h], [strings.h],
+  [inttypes.h], [stdint.h], [unistd.h])]dnl
 dnl For backward compatibility, provide unconditional AC_DEFINEs of
 dnl HAVE_STDLIB_H, HAVE_STRING_H, and STDC_HEADERS.
 [AC_DEFINE([HAVE_STDLIB_H], [1],
diff --git a/lib/autoconf/status.m4 b/lib/autoconf/status.m4
index 5c0a6456..cb337d74 100644
--- a/lib/autoconf/status.m4
+++ b/lib/autoconf/status.m4
@@ -1096,15 +1096,18 @@ m4_define([AC_OUTPUT_COMMANDS_POST])
 #   included, if for instance the user refused a part of the tree.
 #   This is used in _AC_OUTPUT_SUBDIRS.
 AC_DEFUN([AC_CONFIG_SUBDIRS],
+[_$0(m4_validate_w([$1]))])
+
+m4_define([_AC_CONFIG_SUBDIRS],
 [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])]dnl
 [AC_REQUIRE([AC_DISABLE_OPTION_CHECKING])]dnl
+[AS_LITERAL_IF([$1], [],
+              [AC_DIAGNOSE([syntax], [$0: you should use literals])])]dnl
 [m4_map_args_w([$1], [_AC_CONFIG_UNIQUE([SUBDIRS],
   _AC_CONFIG_COMPUTE_DEST(], [))])]dnl
 [m4_append([_AC_LIST_SUBDIRS], [$1], [
 ])]dnl
-[AS_LITERAL_IF([$1], [],
-              [AC_DIAGNOSE([syntax], [$0: you should use literals])])]dnl
-[AC_SUBST([subdirs], ["$subdirs m4_normalize([$1])"])])
+[AC_SUBST([subdirs], ["$subdirs $1"])])
 
 
 # _AC_OUTPUT_SUBDIRS
diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4
index 6a191345..b42fc1a6 100644
--- a/lib/m4sugar/m4sugar.m4
+++ b/lib/m4sugar/m4sugar.m4
@@ -2412,6 +2412,27 @@ m4_define([m4_normalize],
 [m4_strip(m4_flatten([$1]))])
 
 
+# m4_validate_w(STRING)
+# ---------------------
+# Expands into m4_normalize(m4_expand([STRING])), but if that is not
+# the same as just m4_normalize([STRING]), issue a warning.
+#
+# This is used in several Autoconf macros that take a
+# whitespace-separated list of symbols as an argument.  Ideally that
+# list would not be expanded before use, but several packages used
+# `dnl' to put comments inside those lists, so they must be expanded
+# for compatibility's sake.
+m4_define([m4_validate_w],
+[_m4_validate_w(m4_normalize([$1]), m4_normalize(m4_expand([$1])))])
+
+m4_define([_m4_validate_w],
+[m4_if([$1], [$2], [],
+  [m4_warn([obsolete], [whitespace-separated list contains macros;
+in a future version of Autoconf they will not be expanded]dnl
+m4_if(m4_bregexp([$1], [\bdn[l]\b]), -1, [], [
+note: `dn@&t@l' is a macro]))])dnl
+[$2]])
+
 
 # m4_join(SEP, ARG1, ARG2...)
 # ---------------------------
diff --git a/tests/semantics.at b/tests/semantics.at
index 29c1f749..b0b42070 100644
--- a/tests/semantics.at
+++ b/tests/semantics.at
@@ -285,18 +285,20 @@ AT_DATA([header2.h],
 [typedef foo bar;
 ])
 
-AT_CONFIGURE_AC([AC_CHECK_HEADERS(header2.h, [], [], -)])
+AT_CONFIGURE_AC([[AC_CHECK_HEADERS([header2.h], [], [], [-])]])
 
-AT_CHECK_AUTOCONF([-W obsolete], [], [], [stderr])
-AT_CHECK([[grep '^configure\.ac' stderr]], [0],
-[configure.ac:4: warning: Checking for headers with the preprocessor is
+AT_CHECK_AUTOCONF([-W obsolete], [], [],
+[[configure.ac:4: warning: Checking for headers with the preprocessor is
 configure.ac:4: deprecated. Specify prerequisite code to AC_CHECK_HEADER
 configure.ac:4: instead of using fourth argument `-'. (Many headers need
 configure.ac:4: no prerequisites. If you truly need to test whether
 configure.ac:4: something passes the preprocessor but not the compiler,
 configure.ac:4: use AC_PREPROC_IFELSE.)
+headers.m4: _AC_CHECK_HEADER_PREPROC is expanded from...
+headers.m4: AC_CHECK_HEADER is expanded from...
+headers.m4: AC_CHECK_HEADERS is expanded from...
 configure.ac:4: the top level
-])
+]])
 AT_CHECK_AUTOHEADER([], [HAVE_HEADER2_H])
 AT_CHECK_CONFIGURE([CPPFLAGS=-I.])
 AT_CHECK_ENV
@@ -804,3 +806,250 @@ AT_CLEANUP
 AT_CHECK_MACRO([AC_SYS_RESTARTABLE_SYSCALLS], , ,[-W no-obsolete])
 AT_CHECK_MACRO([AC_FUNC_SETVBUF_REVERSED], , ,[-W no-obsolete])
 AT_CHECK_MACRO([AC_FUNC_WAIT3], , ,[-W no-obsolete])
+
+
+## ----------------------------------------- ##
+## Expansion of whitespace-separated lists.  ##
+## ----------------------------------------- ##
+
+
+m4_define([AT_CHECK_EXPANSION_IN_FUNCS],
+[AT_SETUP([Macro expansion in $1]m4_if([$2],[literal],[],[ (literal)]))
+
+AT_CONFIGURE_AC([[
+m4@&t@_define([fn_bar],[fn_quux])
+$1([dn@&t@l
+    fn_foo dn@&t@l
+    fn_nocomment
+    fn_bar dn@&t@l Ordinary comment
+    fn_blurf dn@&t@l Apos'trophed comment
+])
+]])
+AT_CHECK_AUTOCONF([-W obsolete], [0], [],
+[configure.ac:6: warning: whitespace-separated list contains macros;
+configure.ac:6: in a future version of Autoconf they will not be expanded
+configure.ac:6: note: `dn@&t@l' is a macro
+functions.m4: $1 is expanded from...
+configure.ac:6: the top level
+])
+AT_CHECK_AUTOHEADER([], [
+  HAVE_FN_BLURF
+  HAVE_FN_FOO
+  HAVE_FN_NOCOMMENT
+  HAVE_FN_QUUX
+])
+AT_CHECK_CONFIGURE
+AT_CLEANUP
+
+m4_if([$2], [literal], [], [
+AT_SETUP([Macro expansion in $1 (variable)])
+
+AT_CONFIGURE_AC([[
+m4@&t@_define([fn_bar],[fn_quux])
+fns="fn_foo" _AH_CHECK_FUNC([fn_foo])
+fns="$fns fn_nocomment" _AH_CHECK_FUNC([fn_nocomment])
+$1([dn@&t@l
+    $[]fns
+    fn_bar dn@&t@l Ordinary comment
+    fn_blurf dn@&t@l Apos'trophed comment
+])
+]])
+AT_CHECK_AUTOCONF([-W obsolete], [0], [],
+[configure.ac:8: warning: whitespace-separated list contains macros;
+configure.ac:8: in a future version of Autoconf they will not be expanded
+configure.ac:8: note: `dn@&t@l' is a macro
+functions.m4: $1 is expanded from...
+configure.ac:8: the top level
+configure.ac:8: warning: $1($fns): you should use literals
+functions.m4: $1 is expanded from...
+configure.ac:8: the top level
+])
+AT_CHECK_AUTOHEADER([], [
+  HAVE_FN_BLURF
+  HAVE_FN_FOO
+  HAVE_FN_NOCOMMENT
+  HAVE_FN_QUUX
+], [], [],
+[configure.ac:8: warning: $1($fns): you should use literals
+functions.m4: $1 is expanded from...
+configure.ac:8: the top level
+])
+AT_CHECK_CONFIGURE
+AT_CLEANUP
+])])
+
+m4_define([AT_CHECK_EXPANSION_IN_HEADERS],
+[AT_SETUP([Macro expansion in $1]m4_if([$2],[literal],[],[ (literal)]))
+
+AT_CONFIGURE_AC([[
+m4@&t@_define([bar],[quux])
+$1([dn@&t@l
+    foo.h dn@&t@l
+    nocomment.h
+    bar.h dn@&t@l Ordinary comment
+    blurf.h dn@&t@l Apos'trophed comment
+])
+]])
+AT_CHECK_AUTOCONF([-W obsolete], [0], [],
+[configure.ac:6: warning: whitespace-separated list contains macros;
+configure.ac:6: in a future version of Autoconf they will not be expanded
+configure.ac:6: note: `dn@&t@l' is a macro
+headers.m4: $1 is expanded from...
+configure.ac:6: the top level
+])
+AT_CHECK_AUTOHEADER([], [
+  HAVE_BLURF_H
+  HAVE_FOO_H
+  HAVE_INTTYPES_H
+  HAVE_NOCOMMENT_H
+  HAVE_QUUX_H
+  HAVE_STDINT_H
+  HAVE_STDLIB_H
+  HAVE_STRINGS_H
+  HAVE_STRING_H
+  HAVE_SYS_STAT_H
+  HAVE_SYS_TYPES_H
+  HAVE_UNISTD_H
+  STDC_HEADERS
+])
+AT_CHECK_CONFIGURE
+AT_CLEANUP
+
+m4_if([$2], [literal], [], [
+AT_SETUP([Macro expansion in $1 (variable)])
+
+AT_CONFIGURE_AC([[
+m4@&t@_define([bar],[quux])
+hs="foo.h" _AH_CHECK_HEADER([foo.h])
+hs="$hs nocomment.h" _AH_CHECK_HEADER([nocomment.h])
+$1([dn@&t@l
+    $[]hs
+    bar.h dn@&t@l Ordinary comment
+    blurf.h dn@&t@l Apos'trophed comment
+])
+]])
+AT_CHECK_AUTOCONF([-W obsolete], [0], [],
+[configure.ac:8: warning: whitespace-separated list contains macros;
+configure.ac:8: in a future version of Autoconf they will not be expanded
+configure.ac:8: note: `dn@&t@l' is a macro
+headers.m4: $1 is expanded from...
+configure.ac:8: the top level
+configure.ac:8: warning: $1($hs): you should use literals
+headers.m4: $1 is expanded from...
+configure.ac:8: the top level
+])
+AT_CHECK_AUTOHEADER([], [
+  HAVE_BLURF_H
+  HAVE_FOO_H
+  HAVE_INTTYPES_H
+  HAVE_NOCOMMENT_H
+  HAVE_QUUX_H
+  HAVE_STDINT_H
+  HAVE_STDLIB_H
+  HAVE_STRINGS_H
+  HAVE_STRING_H
+  HAVE_SYS_STAT_H
+  HAVE_SYS_TYPES_H
+  HAVE_UNISTD_H
+  STDC_HEADERS
+], [], [],
+[configure.ac:8: warning: $1($hs): you should use literals
+headers.m4: $1 is expanded from...
+configure.ac:8: the top level
+])
+AT_CHECK_CONFIGURE
+AT_CLEANUP
+])])
+
+AT_CHECK_EXPANSION_IN_FUNCS([AC_CHECK_FUNCS])
+AT_CHECK_EXPANSION_IN_FUNCS([AC_CHECK_FUNCS_ONCE], [literal])
+AT_CHECK_EXPANSION_IN_FUNCS([AC_REPLACE_FUNCS])
+
+AT_CHECK_EXPANSION_IN_HEADERS([AC_CHECK_HEADERS])
+AT_CHECK_EXPANSION_IN_HEADERS([AC_CHECK_HEADERS_ONCE], [literal])
+
+AT_SETUP([Macro expansion in AC_CHECK_FILES])
+
+AT_CONFIGURE_AC([[
+m4@&t@_define([f_bar], [f_quux])
+AC_CHECK_FILES([dn@&t@l
+  /nonex/f_foo
+  /nonex/f_bar dn@&t@l Ordinary comment
+  /nonex/f_blurf dn@&t@l Apos'trophed comment
+])
+]])
+AT_CHECK_AUTOCONF([-W obsolete], [0], [],
+[configure.ac:6: warning: whitespace-separated list contains macros;
+configure.ac:6: in a future version of Autoconf they will not be expanded
+configure.ac:6: note: `dn@&t@l' is a macro
+general.m4: AC_CHECK_FILES is expanded from...
+configure.ac:6: the top level
+])
+AT_CHECK_AUTOHEADER([], [
+  HAVE__NONEX_F_BLURF
+  HAVE__NONEX_F_FOO
+  HAVE__NONEX_F_QUUX
+])
+
+AT_CHECK_CONFIGURE
+AT_CLEANUP
+
+AT_SETUP([Macro expansion in AC_CONFIG_MACRO_DIRS])
+
+AT_CONFIGURE_AC([[
+m4@&t@_define([d_bar], [d_quux])
+AC_CONFIG_MACRO_DIRS([dn@&t@l
+  d_foo
+  d_bar dn@&t@l Ordinary comment
+  d_blurf dn@&t@l Apos'trophed comment
+])
+]])
+AT_CHECK_AUTOCONF([-W obsolete -t AC_CONFIG_MACRO_DIR_TRACE], [0],
+[configure.ac:6:AC_CONFIG_MACRO_DIR_TRACE:d_foo
+configure.ac:6:AC_CONFIG_MACRO_DIR_TRACE:d_quux
+configure.ac:6:AC_CONFIG_MACRO_DIR_TRACE:d_blurf
+],
+[configure.ac:6: warning: whitespace-separated list contains macros;
+configure.ac:6: in a future version of Autoconf they will not be expanded
+configure.ac:6: note: `dn@&t@l' is a macro
+general.m4: AC_CONFIG_MACRO_DIRS is expanded from...
+configure.ac:6: the top level
+])
+
+AT_CLEANUP
+
+AT_SETUP([Macro expansion in AC_CONFIG_SUBDIRS])
+
+(set -ex
+for d in d_foo d_bar d_blurf d_quux; do
+  mkdir $d
+  printf '%s\n%s\n' '#! /bin/sh' "echo entered $d/configure" \
+    > $d/configure
+  chmod +x $d/configure
+done)
+
+AT_CONFIGURE_AC([[
+m4@&t@_define([d_bar], [d_quux])
+AC_CONFIG_SUBDIRS([dn@&t@l
+  d_foo
+  d_bar dn@&t@l Ordinary comment
+  d_blurf dn@&t@l Apos'trophed comment
+])
+]])
+AT_CHECK_AUTOCONF([-W obsolete], [0], [],
+[configure.ac:6: warning: whitespace-separated list contains macros;
+configure.ac:6: in a future version of Autoconf they will not be expanded
+configure.ac:6: note: `dn@&t@l' is a macro
+status.m4: AC_CONFIG_SUBDIRS is expanded from...
+configure.ac:6: the top level
+])
+AT_CHECK_AUTOHEADER
+AT_CHECK_CONFIGURE([], [0], [stdout])
+AT_CHECK([grep '^entered' stdout], [0],
+[[entered d_foo/configure
+entered d_quux/configure
+entered d_blurf/configure
+]])
+
+AT_CLEANUP
+
-- 
2.26.0.rc2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]