2008-10-31 Eric Blake <ebb9@byu.net>
+ Support multiple undiverts and dumpdefs at once.
+ * lib/m4sugar/m4sugar.m4 (m4_dumpdefs, m4_undivert): Allow extra
+ arguments.
+ * doc/autoconf.texi (Redefined M4 Macros) <m4_dumpdef>,
+ <m4_undivert>: Document argument list change.
+ * tests/m4sugar.at (m4@&t@_divert_stack, m4@&t@_dumpdef): Test
+ them.
+
Simplify diversion stack handling.
* lib/m4sugar/m4sugar.m4 (m4_divert_stack): Use fewer macros, and
avoid extra newlines.
@end defmac
@defmac m4_dumpdef (@var{name}@dots{})
-@defmacx m4_dumpdefs (@var{name})
+@defmacx m4_dumpdefs (@var{name}@dots{})
@msindex{dumpdef}
@msindex{dumpdefs}
@code{m4_dumpdef} is like the M4 builtin, except that this version
requires at least one argument, output always goes to standard error
rather than the current debug file, and an error is issued if any
@var{name} is undefined. @code{m4_dumpdefs} is a convenience macro that
-takes exactly one @var{name}, and calls @code{m4_dumpdef} for all of the
+calls @code{m4_dumpdef} for all of the
@code{m4_pushdef} stack of definitions, starting with the current, and
silently does nothing if @var{name} is undefined.
@end defmac
if you are not sure whether @var{macro} is defined.
@end defmac
-@defmac m4_undivert (@var{diversion})
+@defmac m4_undivert (@var{diversion}@dots{})
@msindex{undivert}
-Unlike the M4 builtin, only one diversion can be undiverted per
-invocation. Also, since the M4sugar diversion stack prefers named
+Unlike the M4 builtin, at least one @var{diversion} must be specified.
+Also, since the M4sugar diversion stack prefers named
diversions, the use of @code{m4_undivert} to include files is risky.
@xref{Diversion support}, for more details about the use of the
diversion stack.
[m4_map_args([$0], $@)])])
-# m4_dumpdefs(NAME)
-# -----------------
+# m4_dumpdefs(NAME...)
+# --------------------
# Similar to `m4_dumpdef(NAME)', but if NAME was m4_pushdef'ed, display its
-# value stack (most recent displayed first).
+# value stack (most recent displayed first). Also, this version silently
+# ignores undefined macros, rather than erroring out.
#
# This macro cheats, because it relies on the current definition of NAME
# while the second argument of m4_stack_foreach_lifo is evaluated (which
# would be undefined according to the API).
m4_define([m4_dumpdefs],
-[m4_stack_foreach_lifo([$1], [m4_dumpdef([$1])m4_ignore])])
+[m4_if([$#], [0], [m4_fatal([$0: missing argument])],
+ [$#], [1], [m4_stack_foreach_lifo([$1], [m4_dumpdef([$1])m4_ignore])],
+ [m4_map_args([$0], $@)])])
# m4_popdef(NAME)
[m4_expand_once([m4_divert_text([$1], [$2])])])
-# m4_undivert(DIVERSION-NAME)
-# ---------------------------
-# Undivert DIVERSION-NAME. Unlike the M4 version, this only takes a single
-# diversion identifier, and should not be used to undivert files.
+# m4_undivert(DIVERSION-NAME...)
+# ------------------------------
+# Undivert DIVERSION-NAME. Unlike the M4 version, this requires at
+# least one DIVERSION-NAME; also, due to support for named diversions,
+# this should not be used to undivert files.
m4_define([m4_undivert],
-[m4_builtin([undivert], _m4_divert([$1]))])
+[m4_if([$#], [0], [m4_fatal([$0: missing argument])],
+ [$#], [1], [m4_builtin([undivert], _m4_divert([$1]))],
+ [m4_map_args([$0], $@)])])
## --------------------------------------------- ##
m4_pushdef([a], [1])
m4_pushdef([a], [2])
m4_dumpdef([a])
-m4_dumpdefs([a])
-m4_dumpdefs([oops])
+m4_dumpdefs([oops], [a])
m4_divert_pop([KILL])dnl
]], [],
[[a: [2]
## ----------------- ##
AT_SETUP([m4@&t@_divert_stack])
+AT_KEYWORDS([m4@&t@_divert m4@&t@_divert_push m4@&t@_divert_pop
+m4@&t@_undivert])
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])
+5.m4_undivert([20], [30])
m4_pattern_allow([^m4_divert])dnl
]], [[1.script.4s:2: m4@&t@_divert_push: 0
script.4s:1: m4@&t@_divert: KILL
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
+4.script.4s:6: m4@&t@_divert: 30
script.4s:2: m4@&t@_divert_push: 0
script.4s:1: m4@&t@_divert: KILL