* lib/m4sugar/m4sugar.m4 (_m4_require_call): Accept a third argument.
(m4_require): Pass it.
(m4_divert_require): New.
* lib/m4sugar/m4sh.m4 (AS_REQUIRE): Rewrite using m4_divert_require.
Remove comment about differences with m4_require.
* tests/m4sh.at (AS_REQUIRE_SHELL_FN and m4_require): Update to test
the expected behavior.
(Nested AS_REQUIRE_SHELL_FN): New test.
+2008-10-14 Paolo Bonzini <bonzini@gnu.org>
+
+ Use m4_require to implement AS_REQUIRE.
+ * lib/m4sugar/m4sugar.m4 (_m4_require_call): Accept a third argument.
+ (m4_require): Pass it.
+ (m4_divert_require): New.
+ * lib/m4sugar/m4sh.m4 (AS_REQUIRE): Rewrite using m4_divert_require.
+ Remove comment about differences with m4_require.
+ * tests/m4sh.at (AS_REQUIRE_SHELL_FN and m4_require): Update to test
+ the expected behavior.
+ (Nested AS_REQUIRE_SHELL_FN): New test.
+
2008-10-13 Paolo Bonzini <bonzini@gnu.org>
Test AS_LINENO_PREPARE.
# [DIVERSION = M4SH-INIT])
# -----------------------------------------------------------
# BODY-TO-EXPAND is some initialization which must be expanded in the
-# given diversion when expanded (required or not). This is very
-# different from m4_require. For instance:
+# given diversion when expanded (required or not). The expansion
+# goes in the named diversion or an earlier one.
#
-# m4_defun([_FOO_PREPARE], [foo=foo])
-# m4_defun([FOO],
-# [m4_require([_FOO_PREPARE])dnl
-# echo $foo])
-#
-# m4_defun([_BAR_PREPARE], [bar=bar])
-# m4_defun([BAR],
-# [AS_REQUIRE([_BAR_PREPARE])dnl
-# echo $bar])
-#
-# AS_INIT
-# foo1=`FOO`
-# foo2=`FOO`
-# bar1=`BAR`
-# bar2=`BAR`
-#
-# gives
-#
-# #! /bin/sh
-# bar=bar
-#
-# foo1=`foo=foo
-# echo $foo`
-# foo2=`echo $foo`
-# bar1=`echo $bar`
-# bar2=`echo $bar`
-#
-# Due to the simple implementation, all the AS_REQUIRE calls have to be at
-# the very beginning of the macro body, or the AS_REQUIREs may not be nested.
-# More exactly, if a macro doesn't have all AS_REQUIREs at its beginning,
-# it may not be AS_REQUIREd.
-#
-m4_define([AS_REQUIRE],
-[m4_provide_if([$1], [],
- [m4_divert_text(m4_default_quoted([$3], [M4SH-INIT]),
- [m4_default([$2], [$1])])])])
+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)), 1,
+ [m4_require([$1], [$2])],
+ [m4_divert_require([_m4_divert_desired], [$1], [$2])])])
# AS_REQUIRE_SHELL_FN(NAME-TO-CHECK, BODY-TO-EXPAND,
[_m4_undefine([_m4_divert_dump])m4_divert_pop([GROW])m4_undivert([GROW])])
+# m4_divert_require(DIVERSION, NAME-TO-CHECK, [BODY-TO-EXPAND])
+# --------------------------------------------------------------
+# 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_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_defun(NAME, EXPANSION)
# -------------------------
# Define a macro which automatically provides itself. Add machinery
m4_bmatch([$0], [^AC_], [[AC_DEFUN]], [[m4_defun]])['d macro])])]],
[[m4_provide_if([$1],
[],
- [_m4_require_call([$1], [$2])])]]))
+ [_m4_require_call([$1], [$2], [_m4_defn([_m4_divert_dump])])])]]))
-# _m4_require_call(NAME-TO-CHECK, [BODY-TO-EXPAND = NAME-TO-CHECK])
-# -----------------------------------------------------------------
-# If m4_require decides to expand the body, it calls this macro.
+# _m4_require_call(NAME-TO-CHECK, [BODY-TO-EXPAND = NAME-TO-CHECK], DIVERSION)
+# ----------------------------------------------------------------------------
+# If m4_require decides to expand the body, it calls this macro. The
+# expansion is placed in DIVERSION.
#
# This is called frequently, so minimize the number of macro invocations
# by avoiding dnl and other overhead on the common path.
[],
[m4_warn([syntax],
[$1 is m4_require'd but not m4_defun'd])])]],
- [[m4_divert(_m4_defn([_m4_divert_dump]))]],
+ [[m4_divert($3)]],
[[m4_undivert(_m4_divert_grow)]],
[[m4_divert_pop(_m4_divert_grow)]],
[[m4_define([_m4_divert_grow], m4_incr(_m4_divert_grow))]]))
AT_CLEANUP
+## --------------------------- ##
+## Nested AS_REQUIRE_SHELL_FN ##
+## --------------------------- ##
+
+# Hypothesis: M4sh expands nested AS_REQUIRE_SHELL_FN
+# separately.
+
+AT_SETUP([Nested AS@&t@_REQUIRE_SHELL_FN])
+AT_KEYWORDS([m4sh])
+
+AT_DATA_M4SH([script.as], [[dnl
+m4_define([INIT], [oops])dnl
+AS_INIT
+
+m4_defun([TEST_FUNC2_BODY], [
+:
+])
+
+m4_defun([TEST_FUNC1_BODY], [
+AS_REQUIRE_SHELL_FN([test_func2], [TEST_FUNC2_BODY])
+:
+])
+
+AS_REQUIRE_SHELL_FN([test_func1], [TEST_FUNC1_BODY])
+test_func2
+]])
+
+AT_CHECK_M4SH
+AT_CHECK([./script])
+
+AT_CLEANUP
+
+
## ------------------------------------ ##
## AS_REQUIRE_SHELL_FN and m4_require. ##
## ------------------------------------ ##
# Hypothesis: M4sh expands the requirements of AS_REQUIRE_SHELL_FN
-# in the main diversion, and not in M4SH-INIT.
+# in M4SH-INIT-FN. This changed after Autoconf 2.63.
AT_SETUP([AS@&t@_REQUIRE_SHELL_FN and m4@&t@_require])
AT_KEYWORDS([m4sh])
m4_defun([test_init], [
-AS_REQUIRE([in_m4_sh_init])
+AS_REQUIRE([in_m4_sh_init], , [M4SH-INIT-FN])
AS_REQUIRE_SHELL_FN([test_func], [TEST_FUNC_BODY])
AS_REQUIRE([not_in_m4_sh_init])
])