autoconf-patches
[Top][All Lists]
Advanced

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

[PATCH] AC_CONFIG_COMMANDS_PRE/POST: fix nested command registrations.


From: Nick Bowler
Subject: [PATCH] AC_CONFIG_COMMANDS_PRE/POST: fix nested command registrations.
Date: Sun, 17 Feb 2013 12:22:58 -0500

Currently, if a command registered with AC_CONFIG_COMMANDS_PRE itself
calls AC_CONFIG_COMMANDS_PRE, such commands will never be executed.
This occurs because each invocation of AC_CONFIG_COMMANDS_PRE appends
the argument to one big macro (AC_OUTPUT_COMMANDS_PRE) which is then
expanded once near the end of the configure output.

To solve this, we can keep track of the command registrations that occur
during expansion of AC_OUTPUT_COMMANDS_PRE, then after the original
registrations have been handled, output *those* commands, and so on
until there are no more commands.  This is similar to how atexit
works in the C library (although atexit uses a last-in first-out
ordering, whereas this implementation is first-in first-out).

* lib/m4sugar/m4sugar.m4 (m4_output_rec): New macro to help perform
this command expansion loop.
* lib/autoconf/status.m4 (AC_OUTPUT): Use m4_output_rec to expand
AC_OUTPUT_COMMANDS_PRE and AC_OUTPUT_COMMANDS_POST
* tests/base.at (AC_CONFIG_COMMANDS_PRE/POST: nested invocation): New
test.
---
 lib/autoconf/status.m4 |    4 ++--
 lib/m4sugar/m4sugar.m4 |   21 +++++++++++++++++++++
 tests/base.at          |   21 +++++++++++++++++++++
 3 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/lib/autoconf/status.m4 b/lib/autoconf/status.m4
index d125843..9b6e13c 100644
--- a/lib/autoconf/status.m4
+++ b/lib/autoconf/status.m4
@@ -1268,7 +1268,7 @@ test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
 m4_ifdef([_AC_SEEN_CONFIG(HEADERS)], [DEFS=-DHAVE_CONFIG_H], 
[AC_OUTPUT_MAKE_DEFS()])
 
 dnl Commands to run before creating config.status.
-AC_OUTPUT_COMMANDS_PRE()dnl
+m4_output_rec([AC_OUTPUT_COMMANDS_PRE])dnl
 
 : "${CONFIG_STATUS=./config.status}"
 ac_write_fail=0
@@ -1281,7 +1281,7 @@ test $ac_write_fail = 0 ||
   AC_MSG_ERROR([write failure creating $CONFIG_STATUS])
 
 dnl Commands to run after config.status was created
-AC_OUTPUT_COMMANDS_POST()dnl
+m4_output_rec([AC_OUTPUT_COMMANDS_POST])dnl
 
 # configure is writing to config.log, and then calls config.status.
 # config.status does its own redirection, appending to config.log.
diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4
index b732abc..f2e04c3 100644
--- a/lib/m4sugar/m4sugar.m4
+++ b/lib/m4sugar/m4sugar.m4
@@ -1305,6 +1305,27 @@ m4_define([_m4_map_args_w],
 [m4_substr([$1], [$2], m4_eval(m4_len([$1]) - [$2] - [$3]))])
 
 
+# _m4_output_rec(MACRO)
+# ---------------------
+# Internal recursive part of m4_output_rec.  This clobbers the definition of
+# MACRO so it should not be called directly.
+m4_define([_m4_output_rec], [m4_ifnblank(m4_defn([$1]),
+[m4_define([$1], [m4_define([$1])]m4_defn([$1]))dnl
+m4_indir([$1])dnl
+_m4_output_rec([$1])])])
+
+
+# m4_output_rec(MACRO)
+# --------------------
+# Until the definition of MACRO is empty, repeatedly expand MACRO in a
+# context where it has been redefined to the empty string.  The original
+# definition of MACRO is restored after all expansion is complete.
+m4_define([m4_output_rec],
+[m4_pushdef([$1], m4_defn([$1]))dnl
+_m4_output_rec([$1])dnl
+m4_popdef([$1])])
+
+
 # m4_stack_foreach(MACRO, FUNC)
 # m4_stack_foreach_lifo(MACRO, FUNC)
 # ----------------------------------
diff --git a/tests/base.at b/tests/base.at
index 87a0417..35bfd48 100644
--- a/tests/base.at
+++ b/tests/base.at
@@ -767,3 +767,24 @@ FOO
 ]])
 
 AT_CLEANUP
+
+
+# -------------------------------------- #
+# Nested AC_CONFIG_COMMANDS_{PRE,POST}.  #
+# -------------------------------------- #
+
+AT_SETUP([AC_CONFIG_COMMANDS_PRE/POST: nested invocation])
+AT_KEYWORDS([AC@&address@hidden AC@&address@hidden
+AC@&address@hidden m4@&address@hidden)
+
+AT_DATA([configure.ac],
+[[AC_INIT([test], [1])
+AC_CONFIG_COMMANDS_PRE([AC_CONFIG_COMMANDS_PRE([m4_define([okpre])])])
+AC_CONFIG_COMMANDS_POST([AC_CONFIG_COMMANDS_POST([m4_define([okpost])])])
+AC_OUTPUT
+m4@&address@hidden([okpre], [m4][_fatal([dropped nested 
AC_CONFIG_COMMANDS_PRE])])
+m4@&address@hidden([okpost], [m4][_fatal([dropped nested 
AC_CONFIG_COMMANDS_POST])])
+]])
+AT_CHECK_AUTOCONF([], [], [], [stderr])
+
+AT_CLEANUP
-- 
1.7.8.6




reply via email to

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