]> git.ipfire.org Git - thirdparty/autoconf.git/commitdiff
Simplify diversion stack handling.
authorEric Blake <ebb9@byu.net>
Thu, 30 Oct 2008 21:32:56 +0000 (15:32 -0600)
committerEric Blake <ebb9@byu.net>
Fri, 31 Oct 2008 16:25:24 +0000 (10:25 -0600)
* lib/m4sugar/m4sugar.m4 (m4_divert_stack): Use fewer macros, and
avoid extra newlines.
(m4_divert_stack_push): Compute location here, rather than caller.
(m4_divert_push): Update caller.
(m4_divert): Likewise, and also adjust current diversion name.
(m4_divert_pop): Simplify rule that diversion stack must never go
empty.
(_m4_require_call): Bypass diversion stack when collecting
required macro text.
(m4_init): Set current diversion without requiring m4_init.
* lib/m4sugar/m4sh.m4 (AS_INIT): Avoid too many pops.
* lib/autotest/general.m4 (AT_INIT): Likewise.
* lib/autoconf/general.m4 (_AC_INIT_DEFAULTS): Schedule wrapped
text to run prior to m4sugar cleanup.
* doc/autoconf.texi (Text processing Macros) <m4_newline>: Mention
optional argument.
(Conditional constructs) <m4_ifvaln, m4_n>: Mention use of dnl.
* NEWS: Undo blurb about m4_divert.
* tests/m4sugar.at (m4@&t@_divert_stack): New test.

Signed-off-by: Eric Blake <ebb9@byu.net>
ChangeLog
NEWS
doc/autoconf.texi
lib/autoconf/general.m4
lib/autotest/general.m4
lib/m4sugar/m4sh.m4
lib/m4sugar/m4sugar.m4
tests/m4sugar.at

index 18c2919529e8586943736032397ec23799162570..ef29a6e446b6f45aa3ab2d6bd19b1f02ebea8744 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,26 @@
 2008-10-31  Eric Blake  <ebb9@byu.net>
 
+       Simplify diversion stack handling.
+       * lib/m4sugar/m4sugar.m4 (m4_divert_stack): Use fewer macros, and
+       avoid extra newlines.
+       (m4_divert_stack_push): Compute location here, rather than caller.
+       (m4_divert_push): Update caller.
+       (m4_divert): Likewise, and also adjust current diversion name.
+       (m4_divert_pop): Simplify rule that diversion stack must never go
+       empty.
+       (_m4_require_call): Bypass diversion stack when collecting
+       required macro text.
+       (m4_init): Set current diversion without requiring m4_init.
+       * lib/m4sugar/m4sh.m4 (AS_INIT): Avoid too many pops.
+       * lib/autotest/general.m4 (AT_INIT): Likewise.
+       * lib/autoconf/general.m4 (_AC_INIT_DEFAULTS): Schedule wrapped
+       text to run prior to m4sugar cleanup.
+       * doc/autoconf.texi (Text processing Macros) <m4_newline>: Mention
+       optional argument.
+       (Conditional constructs) <m4_ifvaln, m4_n>: Mention use of dnl.
+       * NEWS: Undo blurb about m4_divert.
+       * tests/m4sugar.at (m4@&t@_divert_stack): New test.
+
        Simplify expansion stack handling.
        * lib/m4sugar/m4sugar.m4 (m4_expansion_stack): Use fewer macros;
        always output 'top level'.
diff --git a/NEWS b/NEWS
index d07c14364fc6069f1a8f1ad15d0977891791db79..e22559ff288f433bac0d436a1fce0f713dc516c6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -12,8 +12,6 @@ GNU Autoconf NEWS - User visible changes.
 
 ** Configure scripts now use shell functions.
 
-** m4sugar requires m4_init in order to use m4_divert.
-
 ** The following documented m4sugar macros are new:
    m4_curry  m4_default_quoted  m4_map_args  m4_map_args_pair
    m4_set_map
index 35c9bfa9cbbd6112f4806a83c8f8959ea1daf050..c50cee47d2da9bca04772822272e35f668f2615f 100644 (file)
@@ -10824,12 +10824,13 @@ m4_if([@var{cond}], [], [@var{if-true}], [@var{if-false}])
 @defmac m4_ifvaln (@var{cond}, @ovar{if-true}, @ovar{if-false})
 @msindex{ifvaln}
 Similar to @code{m4_ifval}, except guarantee that a newline is present
-after any non-empty expansion.
+after any non-empty expansion.  Often followed by @code{dnl}.
 @end defmac
 
 @defmac m4_n (@var{text})
 @msindex{n}
 Expand to @var{text}, and add a newline if @var{text} is not empty.
+Often followed by @code{dnl}.
 @end defmac
 
 
@@ -11432,9 +11433,10 @@ them, to form a quoted list suitable for @code{m4_foreach}, it is more
 efficient to use @code{m4_dquote}.
 @end defmac
 
-@defmac m4_newline
+@defmac m4_newline (@ovar{text})
 @msindex{newline}
-This macro was introduced in Autoconf 2.62, and expands to a newline.
+This macro was introduced in Autoconf 2.62, and expands to a newline,
+followed by any @var{text}.
 It is primarily useful for maintaining macro formatting, and ensuring
 that M4 does not discard leading whitespace during argument collection.
 @end defmac
index ccaf3400e8a6fffe2887cb10dc7a15ad0ee42e44..c990c0558eed9201cff14262f53aeec65bdbbbcb 100644 (file)
@@ -433,7 +433,7 @@ AC_SUBST([PACKAGE_BUGREPORT],
         [m4_ifdef([AC_PACKAGE_BUGREPORT], ['AC_PACKAGE_BUGREPORT'])])dnl
 
 m4_divert_pop([DEFAULTS])dnl
-m4_wrap([m4_divert_text([DEFAULTS],
+m4_wrap_lifo([m4_divert_text([DEFAULTS],
 [ac_subst_vars='m4_set_dump([_AC_SUBST_VARS], m4_newline)'
 ac_subst_files='m4_ifdef([_AC_SUBST_FILES], [m4_defn([_AC_SUBST_FILES])])'
 ac_user_opts='
index 03d39024e6fa269a5d709609e45962beed1a675f..68f75d879b866f7a8900facbd00ea1e5145ac417 100644 (file)
@@ -1423,8 +1423,7 @@ m4_divert_pop([TESTS])dnl
 dnl End of AT_INIT: divert to KILL, only test groups are to be
 dnl output, the rest is ignored.  Current diversion is BODY, inherited
 dnl from M4sh.
-m4_divert_pop([BODY])
-m4_divert_push([KILL])
+m4_divert([KILL])
 ])# AT_INIT
 
 
index 1a61729896cdec1c600eb6fd0ff95a1fd43956ae..a506ef06dcb3747050eb9347d73c773f255eab7d 100644 (file)
@@ -235,8 +235,8 @@ dnl Remove any tests from suggested that are also required
             as_shell=$as_dir/$as_base
             AS_IF([{ test -f "$as_shell" || test -f "$as_shell.exe"; } &&
                    _AS_RUN(["$as_required"], ["$as_shell"])],
-                  [CONFIG_SHELL=$as_shell as_have_required=yes
-                  m4_set_empty([_AS_DETECT_SUGGESTED_BODY], [break 2],
+                  [CONFIG_SHELL=$as_shell as_have_required=yes
+                  m4_set_empty([_AS_DETECT_SUGGESTED_BODY], [break 2],
                     [AS_IF([_AS_RUN(["$as_suggested"], ["$as_shell"])],
                            [break 2])])])
           done;;
@@ -1906,8 +1906,7 @@ m4_divert_text([M4SH-SANITIZE], [_AS_SHELL_SANITIZE])
 m4_divert_text([M4SH-INIT-FN], [m4_text_box([M4sh Shell Functions.])])
 
 # Let's go!
-m4_divert_pop([KILL])[]dnl
-m4_divert_push([BODY])
+m4_divert([BODY])dnl
 m4_text_box([Main body of script.])
 _AS_DETECT_REQUIRED([_AS_SHELL_FN_WORK])dnl
 AS_REQUIRE([_AS_UNSET_PREPARE], [], [M4SH-INIT-FN])dnl
index 9a0d184b302d4bd040ccc496a2735b9069cc9ffa..fc912e24a3e085898e1018854ef0a11ea66474f4 100644 (file)
@@ -1258,16 +1258,19 @@ m4_define([_m4_divert()],                0)
 
 # m4_divert_stack
 # ------------------
-# Print m4_divert_stack with newline prepended, if it's nonempty.
+# Print the diversion stack, if it's nonempty.  The caller is
+# responsible for any leading or trailing newline.
 m4_define([m4_divert_stack],
-[m4_stack_foreach_lifo([_m4_divert_stack], [m4_newline])])
+[m4_stack_foreach_sep_lifo([_m4_divert_stack], [], [], [
+])])
 
 
-# m4_divert_stack_push(LOCATION, MACRO-NAME, DIVERSION-NAME)
-# -----------------------------------------------------------
-# Form an entry of the diversion stack and push it.
+# m4_divert_stack_push(MACRO-NAME, DIVERSION-NAME)
+# ------------------------------------------------
+# Form an entry of the diversion stack from caller MACRO-NAME and
+# entering DIVERSION-NAME and push it.
 m4_define([m4_divert_stack_push],
-[m4_pushdef([_m4_divert_stack], [[$1: $2: $3]])])
+[m4_pushdef([_m4_divert_stack], m4_location[: $1: $2])])
 
 
 # m4_divert(DIVERSION-NAME)
@@ -1275,7 +1278,8 @@ m4_define([m4_divert_stack_push],
 # Change the diversion stream to DIVERSION-NAME.
 m4_define([m4_divert],
 [m4_popdef([_m4_divert_stack])]dnl
-[m4_divert_stack_push(m4_location, [$0], [$1])]dnl
+[m4_define([_m4_divert_diversion], [$1])]dnl
+[m4_divert_stack_push([$0], [$1])]dnl
 [m4_builtin([divert], _m4_divert([$1]))])
 
 
@@ -1283,7 +1287,7 @@ m4_define([m4_divert],
 # ------------------------------
 # Change the diversion stream to DIVERSION-NAME, while stacking old values.
 m4_define([m4_divert_push],
-[m4_divert_stack_push(m4_location, [$0], [$1])]dnl
+[m4_divert_stack_push([$0], [$1])]dnl
 [m4_pushdef([_m4_divert_diversion], [$1])]dnl
 [m4_builtin([divert], _m4_divert([$1]))])
 
@@ -1294,16 +1298,14 @@ m4_define([m4_divert_push],
 # If specified, verify we left DIVERSION-NAME.
 # When we pop the last value from the stack, we divert to -1.
 m4_define([m4_divert_pop],
-[m4_ifndef([_m4_divert_diversion],
-          [m4_fatal([too many m4_divert_pop])])]dnl
 [m4_if([$1], [], [],
        [$1], _m4_defn([_m4_divert_diversion]), [],
-       [m4_fatal([$0($1): diversion mismatch: ]m4_divert_stack)])]dnl
+       [m4_fatal([$0($1): diversion mismatch:
+]m4_divert_stack)])]dnl
 [_m4_popdef([_m4_divert_stack], [_m4_divert_diversion])]dnl
-[m4_builtin([divert],
-           m4_ifdef([_m4_divert_diversion],
-                    [_m4_divert(_m4_defn([_m4_divert_diversion]))],
-                    -1))])
+[m4_ifdef([_m4_divert_diversion], [],
+          [m4_fatal([too many m4_divert_pop])])]dnl
+[m4_builtin([divert], _m4_divert(_m4_defn([_m4_divert_diversion])))])
 
 
 # m4_divert_text(DIVERSION-NAME, CONTENT)
@@ -1839,8 +1841,8 @@ m4_provide_if([$1],
              [],
              [m4_warn([syntax],
                       [$1 is m4_require'd but not m4_defun'd])])]],
-      [[m4_divert($3)]],
-      [[m4_undivert(_m4_divert_grow)]],
+      [[m4_builtin([divert], _m4_divert($3))]],
+      [[m4_builtin([undivert], _m4_divert_grow)]],
       [[m4_divert_pop(_m4_divert_grow)]],
       [[m4_define([_m4_divert_grow], m4_incr(_m4_divert_grow))]]))
 
@@ -2933,6 +2935,8 @@ m4_if(m4_sysval, [0], [],
 ## 17. Setting M4sugar up.  ##
 ## ------------------------ ##
 
+# _m4_divert_diversion should be defined.
+m4_divert_push([KILL])
 
 # m4_init
 # -------
@@ -2958,11 +2962,14 @@ m4_define([m4_popdef], _m4_defn([m4_popdef]))
 m4_define([m4_undefine], _m4_defn([m4_undefine]))],
 [m4_builtin([include], [m4sugar/foreach.m4])])
 
-# _m4_divert_diversion should be defined:
-m4_divert_push([KILL])
+# Rewrite the first entry of the diversion stack.
+m4_divert([KILL])
 
 # Check the divert push/pop perfect balance.
-m4_wrap([m4_divert_pop([])
-        m4_ifdef([_m4_divert_diversion],
-          [m4_fatal([$0: unbalanced m4_divert_push:]m4_divert_stack)])[]])
+# Some users are prone to also use m4_wrap to register last-minute
+# m4_divert_text; so after our diversion cleanups, we restore
+# KILL as the bottom of the diversion stack.
+m4_wrap([m4_popdef([_m4_divert_diversion])m4_ifdef(
+  [_m4_divert_diversion], [m4_fatal([$0: unbalanced m4_divert_push:
+]m4_divert_stack)])_m4_popdef([_m4_divert_stack])m4_divert_push([KILL])])
 ])
index d8554b5625d91956a15d4984afd65488590909bf..8034ced43dc79cd7b48bd70341b36d8fa168b8ef 100644 (file)
@@ -243,6 +243,74 @@ script.4s:6: the top level
 AT_CLEANUP
 
 
+## ----------------- ##
+## m4_divert_stack.  ##
+## ----------------- ##
+
+AT_SETUP([m4@&t@_divert_stack])
+
+AT_CHECK_M4SUGAR_TEXT([[1.m4_divert_stack
+m4_divert_push([10])2.m4_divert_stack
+m4_divert_text([20], [3.m4_divert_stack])dnl
+m4_divert([30])4.m4_divert_stack
+m4_divert_pop([30])dnl
+5.m4_undivert([20])
+6.m4_undivert([30])
+m4_pattern_allow([^m4_divert])dnl
+]], [[1.script.4s:2: m4@&t@_divert_push: 0
+script.4s:1: m4@&t@_divert: KILL
+5.3.script.4s:5: m4@&t@_divert_push: 20
+script.4s:4: m4@&t@_divert_push: 10
+script.4s:2: m4@&t@_divert_push: 0
+script.4s:1: m4@&t@_divert: KILL
+
+6.4.script.4s:6: m4@&t@_divert: 30
+script.4s:2: m4@&t@_divert_push: 0
+script.4s:1: m4@&t@_divert: KILL
+
+2.script.4s:4: m4@&t@_divert_push: 10
+script.4s:2: m4@&t@_divert_push: 0
+script.4s:1: m4@&t@_divert: KILL
+]])
+
+AT_DATA_M4SUGAR([script.4s],
+[[m4_divert_pop
+]])
+AT_CHECK_M4SUGAR([-o-], [1], [],
+[[script.4s:1: error: too many m4@&t@_divert_pop
+script.4s:1: the top level
+autom4te: m4 failed with exit status: 1
+]])
+
+AT_DATA_M4SUGAR([script.4s],
+[[m4_init
+m4_divert_push([1])
+m4_divert_pop([2])
+]])
+AT_CHECK_M4SUGAR([-o-], [1], [],
+[[script.4s:3: error: m4@&t@_divert_pop(2): diversion mismatch:
+script.4s:2: m4@&t@_divert_push: 1
+script.4s:1: m4@&t@_divert: KILL
+script.4s:3: the top level
+autom4te: m4 failed with exit status: 1
+]])
+
+AT_DATA_M4SUGAR([script.4s],
+[[m4_divert([1])
+m4_init
+m4_divert_push([2])
+]])
+AT_CHECK_M4SUGAR([-o-], [1], [],
+[[script.4s:2: error: m4@&t@_init: unbalanced m4@&t@_divert_push:
+script.4s:3: m4@&t@_divert_push: 2
+script.4s:2: m4@&t@_divert: KILL
+script.4s:2: the top level
+autom4te: m4 failed with exit status: 1
+]])
+
+AT_CLEANUP
+
+
 ## -------------------- ##
 ## m4_expansion_stack.  ##
 ## -------------------- ##