# }.
# All the values are optional, and the macro is robust to active
# symbols properly quoted.
+#
+# Please keep foreach.m4 in sync with any adjustments made here.
m4_define([m4_case],
[m4_if([$#], 0, [],
[$#], 1, [],
#
# All the values are optional, and the macro is robust to active symbols
# properly quoted.
+#
+# Please keep foreach.m4 in sync with any adjustments made here.
m4_define([m4_bmatch],
[m4_if([$#], 0, [m4_fatal([$0: too few arguments: $#])],
[$#], 1, [m4_fatal([$0: too few arguments: $#: $1])],
#
# In the common case of $1 with no backslash, only one m4_index expansion
# occurs, and m4_eval is avoided altogether.
+#
+# Please keep foreach.m4 in sync with any adjustments made here.
m4_define([m4_cond],
[m4_if([$#], [0], [m4_fatal([$0: cannot be called without arguments])],
[$#], [1], [$1],
#
# Recall that m4_shift3 always results in an argument. Hence, we need
# to distinguish between a final deletion vs. ending recursion.
+#
+# Please keep foreach.m4 in sync with any adjustments made here.
m4_define([m4_bpatsubsts],
[m4_if([$#], 0, [m4_fatal([$0: too few arguments: $#])],
[$#], 1, [m4_fatal([$0: too few arguments: $#: $1])],
#
# This macro is called frequently, so minimize the amount of additional
# expansions by skipping m4_ifndef. Better yet, if __m4_version__ exists,
-# (added in M4 1.6), then let m4 do the job for us.
+# (added in M4 1.6), then let m4 do the job for us (see m4_init).
#
# _m4_defn is for internal use only - it bypasses the wrapper, so it
# must only be used on one argument at a time, and only on macros
# known to be defined. Make sure this still works if the user renames
# m4_defn but not _m4_defn.
m4_copy([m4_defn], [_m4_defn])
-m4_ifdef([__m4_version__], [],
-[m4_define([m4_defn],
+m4_define([m4_defn],
[m4_if([$#], [0], [[$0]],
[$#], [1], [m4_ifdef([$1], [_m4_defn([$1])],
[m4_fatal([$0: undefined macro: $1])])],
- [m4_foreach([_m4_macro], [$@], [$0(_m4_defn([_m4_macro]))])])])])
+ [m4_foreach([_m4_macro], [$@], [$0(_m4_defn([_m4_macro]))])])])
# _m4_dumpdefs_up(NAME)
#
# This macro is called frequently, so minimize the amount of additional
# expansions by skipping m4_ifndef. Better yet, if __m4_version__ exists,
-# (added in M4 1.6), then let m4 do the job for us.
+# (added in M4 1.6), then let m4 do the job for us (see m4_init).
#
# _m4_popdef is for internal use only - it bypasses the wrapper, so it
# must only be used on macros known to be defined. Make sure this
# still works if the user renames m4_popdef but not _m4_popdef.
m4_copy([m4_popdef], [_m4_popdef])
-m4_ifdef([__m4_version__], [],
-[m4_define([m4_popdef],
+m4_define([m4_popdef],
[m4_if([$#], [0], [[$0]],
[$#], [1], [m4_ifdef([$1], [_m4_popdef([$1])],
[m4_fatal([$0: undefined macro: $1])])],
- [m4_foreach([_m4_macro], [$@], [$0(_m4_defn([_m4_macro]))])])])])
+ [m4_foreach([_m4_macro], [$@], [$0(_m4_defn([_m4_macro]))])])])
# m4_shiftn(N, ...)
# [_m4_shiftn(m4_decr([$1]), m4_shift(m4_shift($@)))])
# but with the final `m4_shift(m4_shift($@)))' shared between the two
# paths. The first leg uses a no-op m4_shift(,$@) to balance out the ().
+#
+# Please keep foreach.m4 in sync with any adjustments made here.
m4_define([m4_shiftn],
[m4_assert(0 < $1 && $1 < $#)_$0($@)])
#
# This macro is called frequently, so minimize the amount of additional
# expansions by skipping m4_ifndef. Better yet, if __m4_version__ exists,
-# (added in M4 1.6), then let m4 do the job for us.
+# (added in M4 1.6), then let m4 do the job for us (see m4_init).
#
# _m4_undefine is for internal use only - it bypasses the wrapper, so
# it must only be used on macros known to be defined. Make sure this
# still works if the user renames m4_undefine but not _m4_undefine.
m4_copy([m4_undefine], [_m4_undefine])
-m4_ifdef([__m4_version__], [],
-[m4_define([m4_undefine],
+m4_define([m4_undefine],
[m4_if([$#], [0], [[$0]],
[$#], [1], [m4_ifdef([$1], [_m4_undefine([$1])],
[m4_fatal([$0: undefined macro: $1])])],
- [m4_foreach([_m4_macro], [$@], [$0(_m4_defn([_m4_macro]))])])])])
+ [m4_foreach([_m4_macro], [$@], [$0(_m4_defn([_m4_macro]))])])])
# _m4_wrap(PRE, POST)
# -------------------
# useful for making your macros more structured and readable by dropping
# unnecessary dnl's and have the macros indented properly. No concatenation
# occurs after a STRING; use m4_unquote(m4_join(,STRING)) for that.
+#
+# Please keep foreach.m4 in sync with any adjustments made here.
m4_define([m4_do],
[m4_if([$#], 0, [],
[$#], 1, [$1[]],
# m4_dquote_elt(ARGS)
# -------------------
# Return ARGS as an unquoted list of double-quoted arguments.
+#
+# Please keep foreach.m4 in sync with any adjustments made here.
m4_define([m4_dquote_elt],
[m4_if([$#], [0], [],
[$#], [1], [[[$1]]],
# m4_reverse(ARGS)
# ----------------
# Output ARGS in reverse order.
+#
+# Please keep foreach.m4 in sync with any adjustments made here.
m4_define([m4_reverse],
[m4_if([$#], [0], [], [$#], [1], [[$1]],
[$0(m4_shift($@)), [$1]])])
# [] and use m4_car/m4_cdr for recursion, we instead unbox the list (which
# requires swapping the argument order in the helper), insert an ignored
# third argument, and use m4_shift3 to detect when recursion is complete.
+#
+# Please keep foreach.m4 in sync with any adjustments made here.
m4_define([m4_foreach],
[m4_if([$2], [], [],
[m4_pushdef([$1])_$0([$1], [$3], [], $2)m4_popdef([$1])])])
# _m4_map. For m4_map, an empty list behaves like an empty sublist
# and gets ignored; for m4_mapall, we must special-case the empty
# list.
+#
+# Please keep foreach.m4 in sync with any adjustments made here.
m4_define([m4_map],
[_m4_map([_m4_apply([$1]], [], $2)])
# arguments.
#
# For m4_mapall_sep, merely expand the first iteration without the
-# separator, then include separator as part of subsequent recursion.
+# separator, then include separator as part of subsequent recursion;
+# but avoid extra expansion of LIST's side-effects via a helper macro.
# For m4_map_sep, things are trickier - we don't know if the first
# list element is an empty sublist, so we must define a self-modifying
# helper macro and use that as the separator instead.
[_m4_map([_m4_apply([m4_Sep([$2])[]$1]], [], $3)m4_popdef([m4_Sep])])
m4_define([m4_mapall_sep],
-[m4_if([$3], [], [],
- [m4_apply([$1], m4_car($3))_m4_map([m4_apply([$2[]$1]], $3)])])
+[m4_if([$3], [], [], [_$0([$1], [$2], $3)])])
+
+m4_define([_m4_mapall_sep],
+[m4_apply([$1], [$3])_m4_map([m4_apply([$2[]$1]], m4_shift2($@))])
# _m4_map(PREFIX, IGNORED, SUBLIST, ...)
# --------------------------------------
# then appends `,', the current SUBLIST and the closing `)', then
# recurses to the next SUBLIST. IGNORED is an aid to ending recursion
# efficiently.
+#
+# Please keep foreach.m4 in sync with any adjustments made here.
m4_define([_m4_map],
[m4_if([$#], [2], [],
[$1, [$3])$0([$1], m4_shift2($@))])])
# --------------------------------
# Expand EXPRESSION([ARG]) for each argument. More efficient than
# m4_foreach([var], [ARG...], [EXPRESSION(m4_defn([var]))])
+#
+# Please keep foreach.m4 in sync with any adjustments made here.
m4_define([m4_transform],
[m4_if([$#], [0], [m4_fatal([$0: too few arguments: $#])],
[$#], [1], [],
# => (a,b)
# => (c,d)
# => (e)
+#
+# Please keep foreach.m4 in sync with any adjustments made here.
m4_define([m4_transform_pair],
[m4_if([$#], [0], [m4_fatal([$0: too few arguments: $#])],
[$#], [1], [m4_fatal([$0: too few arguments: $#: $1])],
# elements, and outputs them following a separator. The final trick to
# note is that we decide between recursing with $0 or _$0 based on the
# nested m4_if ending with `_'.
+#
+# Please keep foreach.m4 in sync with any adjustments made here.
m4_define([m4_join],
[m4_if([$#], [1], [],
[$#], [2], [[$2]],
# ------------------------------
# Produce ARG1SEPARG2...SEPARGn. An empty ARG results in back-to-back SEP.
# No expansion is performed on SEP or ARGs.
+#
+# Please keep foreach.m4 in sync with any adjustments made here.
m4_define([m4_joinall], [[$2]_$0([$1], m4_shift($@))])
m4_define([_m4_joinall],
[m4_if([$#], [2], [], [[$1$3]$0([$1], m4_shift2($@))])])
# long lists, since less text is being expanded for deciding when to end
# recursion. The recursion is between a pair of macros that alternate
# which list is trimmed by one element; this is more efficient than
-# calling m4_cdr on both lists from a single macro.
+# calling m4_cdr on both lists from a single macro. Guarantee exactly
+# one expansion of both lists' side effects.
+#
+# Please keep foreach.m4 in sync with any adjustments made here.
m4_define([m4_list_cmp],
+[_$0_raw(m4_dquote($1), m4_dquote($2))])
+
+m4_define([_m4_list_cmp_raw],
[m4_if([$1], [$2], [0], [_m4_list_cmp_1([$1], $2)])])
m4_define([_m4_list_cmp],
[m4_if([$1], [], [0m4_ignore], [$2], [0], [m4_unquote], [$2m4_ignore])])
m4_define([_m4_list_cmp_1],
-[_m4_list_cmp_2([$2], m4_dquote(m4_shift2($@)), $1)])
+[_m4_list_cmp_2([$2], [m4_shift2($@)], $1)])
m4_define([_m4_list_cmp_2],
[_m4_list_cmp([$1$3], m4_cmp([$3+0], [$1+0]))(
# M4 1.4.x doesn't provide ?:. Hence this huge m4_eval. Avoid m4_eval
# if both arguments are identical, but be aware of m4_max(0xa, 10) (hence
# the use of <=, not just <, in the second multiply).
+#
+# Please keep foreach.m4 in sync with any adjustments made here.
m4_define([m4_max],
[m4_if([$#], [0], [m4_fatal([too few arguments to $0])],
[$#], [1], [m4_eval([$1])],
# ---------------------------------
# Common recursion code for m4_max and m4_min. METHOD must be _m4_max
# or _m4_min, and there must be at least two arguments to combine.
+#
+# Please keep foreach.m4 in sync with any adjustments made here.
m4_define([_m4_minmax],
[m4_if([$#], [3], [$1([$2], [$3])],
[$0([$1], $1([$2], [$3]), m4_shift3($@))])])
# -1 if VERSION-1 < VERSION-2
# 0 if =
# 1 if >
+#
+# Since _m4_version_unletter does not output side effects, we can
+# safely bypass the overhead of m4_version_cmp.
m4_define([m4_version_compare],
-[m4_list_cmp(_m4_version_unletter([$1]), _m4_version_unletter([$2]))])
+[_m4_list_cmp_raw(_m4_version_unletter([$1]), _m4_version_unletter([$2]))])
# m4_PACKAGE_NAME
# not pruned. The recursion helpers ignore their second argument, so
# that we can use the faster m4_shift2 and 2 arguments, rather than
# _m4_shift2 and one argument, as the signal to end recursion.
+#
+# Please keep foreach.m4 in sync with any adjustments made here.
m4_define([m4_set_add_all],
[m4_define([_m4_set_size($1)], m4_eval(m4_set_size([$1])
+ m4_len(m4_ifdef([_m4_set_cleanup($1)], [_$0_check], [_$0])([$1], $@))))])
m4_pattern_forbid([^dnl$])
# If __m4_version__ is defined, we assume that we are being run by M4
-# 1.6 or newer, and thus that $@ recursion is linear; nothing further
-# needs to be done. But if it is missing, we assume we are being run
-# by M4 1.4.x, that $@ recursion is quadratic, and that we need
-# foreach-based replacement macros. Use the raw builtin to avoid
-# tripping up include tracing.
-m4_ifndef([__m4_version__], [m4_builtin([include], [m4sugar/foreach.m4])])
+# 1.6 or newer, and thus that $@ recursion is linear and debugmode(d)
+# is available for faster checks of dereferencing undefined macros.
+# But if it is missing, we assume we are being run by M4 1.4.x, that
+# $@ recursion is quadratic, and that we need foreach-based
+# replacement macros. Use the raw builtin to avoid tripping up
+# include tracing.
+m4_ifdef([__m4_version__],
+[m4_debugmode([+d])
+m4_copy([_m4_defn], [m4_defn])
+m4_copy([_m4_popdef], [m4_popdef])
+m4_copy([_m4_undefine], [m4_undefine])],
+[m4_builtin([include], [m4sugar/foreach.m4])])
# _m4_divert_diversion should be defined:
m4_divert_push([KILL])