2005-01-03 Stepan Kasal
A cleanup of the diversion support in m4sugar.
* lib/m4sugar/m4sugar.m4 (_m4_divert): A typo in description.
(_m4_divert_n_stack): New macro; the expansion is
m4_divert_stack, if m4_divert_stack is defined, and void
otherwise.
(m4_divert, m4_divert_push, m4_divert_pop, m4_init): Use it.
(m4_divert_push, m4_divert_pop, _m4_defun_epi): Don't expand the word
stored in _m4_divert_diversion or _m4_divert_dump.
(m4_divert_pop): When the parameter is given, compare the symbolic
name with the last diversion pushed on the stack. Previously, the
current diversion was compared with the numeric value of the
diversion given as the parameter.
(m4_require): If the macro hasn't been expanded yet, call ...
(_m4_require_call): this new macro.
--- lib/m4sugar/m4sugar.m4 2005-01-03 17:07:07.000000000 +0100
+++ lib/m4sugar/m4sugar.m4.new 2005-01-03 18:00:09.000000000 +0100
@@ -699,7 +699,7 @@ # m4_foreach(VARIABLE, LIST, EXPRESSION)
# _m4_divert(DIVERSION-NAME or NUMBER)
# ------------------------------------
# If DIVERSION-NAME is the name of a diversion, return its number,
-# otherwise if is a NUMBER return it.
+# otherwise if it is a NUMBER return it.
m4_define([_m4_divert],
[m4_ifdef([_m4_divert($1)],
[m4_indir([_m4_divert($1)])],
@@ -709,13 +709,19 @@ # _m4_divert(DIVERSION-NAME or NUMBER)
m4_define([_m4_divert(KILL)], -1)
+# _m4_divert_n_stack
+# ------------------
+# Print m4_divert_stack with newline prepended, if it's nonempty.
+m4_define([_m4_divert_n_stack],
+[m4_ifdef([m4_divert_stack], [
+m4_defn([m4_divert_stack])])])
+
+
# m4_divert(DIVERSION-NAME)
# -------------------------
# Change the diversion stream to DIVERSION-NAME.
m4_define([m4_divert],
-[m4_define([m4_divert_stack],
- m4_location[: $0: $1]m4_ifdef([m4_divert_stack], [
-m4_defn([m4_divert_stack])]))dnl
+[m4_define([m4_divert_stack], m4_location[: $0: $1]_m4_divert_n_stack)dnl
m4_builtin([divert], _m4_divert([$1]))dnl
])
@@ -724,11 +730,9 @@ # m4_divert_push(DIVERSION-NAME)
# ------------------------------
# Change the diversion stream to DIVERSION-NAME, while stacking old values.
m4_define([m4_divert_push],
-[m4_pushdef([m4_divert_stack],
- m4_location[: $0: $1]m4_ifdef([m4_divert_stack], [
-m4_defn([m4_divert_stack])]))dnl
+[m4_pushdef([m4_divert_stack], m4_location[: $0: $1]_m4_divert_n_stack)dnl
m4_pushdef([_m4_divert_diversion], [$1])dnl
-m4_builtin([divert], _m4_divert(_m4_divert_diversion))dnl
+m4_builtin([divert], _m4_divert([$1]))dnl
])
@@ -736,18 +740,19 @@ # m4_divert_pop([DIVERSION-NAME])
# -------------------------------
# Change the diversion stream to its previous value, unstacking it.
# 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_ifval([$1],
- [m4_if(_m4_divert([$1]), m4_divnum, [],
- [m4_fatal([$0($1): diversion mismatch: ]
-m4_defn([m4_divert_stack]))])])dnl
+[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_n_stack)])dnl
+m4_popdef([m4_divert_stack])dnl
m4_popdef([_m4_divert_diversion])dnl
-dnl m4_ifndef([_m4_divert_diversion],
-dnl [m4_fatal([too many m4_divert_pop])])dnl
m4_builtin([divert],
m4_ifdef([_m4_divert_diversion],
- [_m4_divert(_m4_divert_diversion)], -1))dnl
-m4_popdef([m4_divert_stack])dnl
+ [_m4_divert(m4_defn([_m4_divert_diversion]))],
+ -1))dnl
])
@@ -1172,7 +1177,7 @@ # _m4_defun_epi(MACRO-NAME)
# the PRO/EPI pairs.
m4_define([_m4_defun_epi],
[m4_divert_pop()dnl
-m4_if(_m4_divert_dump, _m4_divert_diversion,
+m4_if(m4_defn([_m4_divert_dump]), m4_defn([_m4_divert_diversion]),
[m4_undivert([GROW])dnl
m4_undefine([_m4_divert_dump])])dnl
m4_expansion_stack_pop()dnl
@@ -1275,16 +1280,24 @@ # m4_provide'd), expand BODY-TO-EXPAND *
[m4_fatal([$0: cannot be used outside of an m4_defun'd macro])])dnl
m4_provide_if([$1],
[],
- [m4_divert_push(m4_eval(m4_divnum - 1))dnl
+ [_m4_require_call([$1], [$2])])dnl
+m4_expansion_stack_pop()dnl
+])
+
+
+# _m4_require_call(BODY-TO-EXPAND)
+# --------------------------------
+# If m4_require decides to expand the body, it calls this macro.
+m4_define([_m4_require_call],
+[m4_divert_push(m4_eval(m4_divnum - 1))dnl
m4_default([$2], [$1])
-m4_divert(m4_defn([_m4_divert_dump]))dnl
-m4_undivert(m4_defn([_m4_divert_diversion]))dnl
-m4_divert_pop(m4_defn([_m4_divert_dump]))])dnl
m4_provide_if([$1],
[],
[m4_warn([syntax],
- [$1 is m4_require'd but is not m4_defun'd])])dnl
-m4_expansion_stack_pop()dnl
+ [$1 is m4_require'd but not m4_defun'd])])dnl
+m4_divert(m4_defn([_m4_divert_dump]))dnl
+m4_undivert(m4_defn([_m4_divert_diversion]))dnl
+m4_divert_pop()dnl
])
@@ -1774,8 +1787,7 @@ # m4_init
# Check the divert push/pop perfect balance.
m4_wrap([m4_ifdef([_m4_divert_diversion],
- [m4_fatal([$0: unbalanced m4_divert_push:]
-m4_defn([m4_divert_stack]))])[]])
+ [m4_fatal([$0: unbalanced m4_divert_push:]_m4_divert_n_stack)])[]])
m4_divert_push([KILL])
m4_wrap([m4_divert_pop([KILL])[]])