| divert(-1)# -*- Autoconf -*- |
| # This file is part of Autoconf. |
| # Base M4 layer. |
| # Requires GNU M4. |
| # |
| # Copyright (C) 1999-2012 Free Software Foundation, Inc. |
| |
| # This file is part of Autoconf. This program is free |
| # software; you can redistribute it and/or modify it under the |
| # terms of the GNU General Public License as published by the |
| # Free Software Foundation, either version 3 of the License, or |
| # (at your option) any later version. |
| # |
| # This program is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| # |
| # Under Section 7 of GPL version 3, you are granted additional |
| # permissions described in the Autoconf Configure Script Exception, |
| # version 3.0, as published by the Free Software Foundation. |
| # |
| # You should have received a copy of the GNU General Public License |
| # and a copy of the Autoconf Configure Script Exception along with |
| # this program; see the files COPYINGv3 and COPYING.EXCEPTION |
| # respectively. If not, see <http://www.gnu.org/licenses/>. |
| |
| # Written by Akim Demaille. |
| |
| # Set the quotes, whatever the current quoting system. |
| changequote() |
| changequote([, ]) |
| |
| # Some old m4's don't support m4exit. But they provide |
| # equivalent functionality by core dumping because of the |
| # long macros we define. |
| ifdef([__gnu__], , |
| [errprint(M4sugar requires GNU M4. Install it before installing M4sugar or |
| set the M4 environment variable to its absolute file name.) |
| m4exit(2)]) |
| |
| |
| ## ------------------------------- ## |
| ## 1. Simulate --prefix-builtins. ## |
| ## ------------------------------- ## |
| |
| # m4_define |
| # m4_defn |
| # m4_undefine |
| define([m4_define], defn([define])) |
| define([m4_defn], defn([defn])) |
| define([m4_undefine], defn([undefine])) |
| |
| m4_undefine([define]) |
| m4_undefine([defn]) |
| m4_undefine([undefine]) |
| |
| |
| # m4_copy(SRC, DST) |
| # ----------------- |
| # Define DST as the definition of SRC. |
| # What's the difference between: |
| # 1. m4_copy([from], [to]) |
| # 2. m4_define([to], [from($@)]) |
| # Well, obviously 1 is more expensive in space. Maybe 2 is more expensive |
| # in time, but because of the space cost of 1, it's not that obvious. |
| # Nevertheless, one huge difference is the handling of `$0'. If `from' |
| # uses `$0', then with 1, `to''s `$0' is `to', while it is `from' in 2. |
| # The user would certainly prefer to see `to'. |
| # |
| # This definition is in effect during m4sugar initialization, when |
| # there are no pushdef stacks; later on, we redefine it to something |
| # more powerful for all other clients to use. |
| m4_define([m4_copy], |
| [m4_define([$2], m4_defn([$1]))]) |
| |
| |
| # m4_rename(SRC, DST) |
| # ------------------- |
| # Rename the macro SRC to DST. |
| m4_define([m4_rename], |
| [m4_copy([$1], [$2])m4_undefine([$1])]) |
| |
| |
| # m4_rename_m4(MACRO-NAME) |
| # ------------------------ |
| # Rename MACRO-NAME to m4_MACRO-NAME. |
| m4_define([m4_rename_m4], |
| [m4_rename([$1], [m4_$1])]) |
| |
| |
| # m4_copy_unm4(m4_MACRO-NAME) |
| # --------------------------- |
| # Copy m4_MACRO-NAME to MACRO-NAME. |
| m4_define([m4_copy_unm4], |
| [m4_copy([$1], m4_bpatsubst([$1], [^m4_\(.*\)], [[\1]]))]) |
| |
| |
| # Some m4 internals have names colliding with tokens we might use. |
| # Rename them a` la `m4 --prefix-builtins'. Conditionals first, since |
| # some subsequent renames are conditional. |
| m4_rename_m4([ifdef]) |
| m4_rename([ifelse], [m4_if]) |
| |
| m4_rename_m4([builtin]) |
| m4_rename_m4([changecom]) |
| m4_rename_m4([changequote]) |
| m4_ifdef([changeword],dnl conditionally available in 1.4.x |
| [m4_undefine([changeword])]) |
| m4_rename_m4([debugfile]) |
| m4_rename_m4([debugmode]) |
| m4_rename_m4([decr]) |
| m4_rename_m4([divnum]) |
| m4_rename_m4([dumpdef]) |
| m4_rename_m4([errprint]) |
| m4_rename_m4([esyscmd]) |
| m4_rename_m4([eval]) |
| m4_rename_m4([format]) |
| m4_undefine([include]) |
| m4_rename_m4([incr]) |
| m4_rename_m4([index]) |
| m4_rename_m4([indir]) |
| m4_rename_m4([len]) |
| m4_rename([m4exit], [m4_exit]) |
| m4_undefine([m4wrap]) |
| m4_ifdef([mkstemp],dnl added in M4 1.4.8 |
| [m4_rename_m4([mkstemp]) |
| m4_copy([m4_mkstemp], [m4_maketemp]) |
| m4_undefine([maketemp])], |
| [m4_rename_m4([maketemp]) |
| m4_copy([m4_maketemp], [m4_mkstemp])]) |
| m4_rename([patsubst], [m4_bpatsubst]) |
| m4_rename_m4([popdef]) |
| m4_rename_m4([pushdef]) |
| m4_rename([regexp], [m4_bregexp]) |
| m4_rename_m4([shift]) |
| m4_undefine([sinclude]) |
| m4_rename_m4([substr]) |
| m4_ifdef([symbols],dnl present only in alpha-quality 1.4o |
| [m4_rename_m4([symbols])]) |
| m4_rename_m4([syscmd]) |
| m4_rename_m4([sysval]) |
| m4_rename_m4([traceoff]) |
| m4_rename_m4([traceon]) |
| m4_rename_m4([translit]) |
| |
| # _m4_defn(ARG) |
| # ------------- |
| # _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_divert_raw(NUM) |
| # ------------------- |
| # _m4_divert_raw is for internal use only. Use this instead of |
| # m4_builtin([divert], NUM), so that tracing diversion flow is easier. |
| m4_rename([divert], [_m4_divert_raw]) |
| |
| # _m4_popdef(ARG...) |
| # ------------------ |
| # _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_undefine(ARG...) |
| # -------------------- |
| # _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_undivert(NUM...) |
| # -------------------- |
| # _m4_undivert is for internal use only, and should always be given |
| # arguments. Use this instead of m4_builtin([undivert], NUM...), so |
| # that tracing diversion flow is easier. |
| m4_rename([undivert], [_m4_undivert]) |
| |
| |
| ## ------------------- ## |
| ## 2. Error messages. ## |
| ## ------------------- ## |
| |
| |
| # m4_location |
| # ----------- |
| # Output the current file, colon, and the current line number. |
| m4_define([m4_location], |
| [__file__:__line__]) |
| |
| |
| # m4_errprintn(MSG) |
| # ----------------- |
| # Same as `errprint', but with the missing end of line. |
| m4_define([m4_errprintn], |
| [m4_errprint([$1 |
| ])]) |
| |
| |
| # m4_warning(MSG) |
| # --------------- |
| # Warn the user. |
| m4_define([m4_warning], |
| [m4_errprintn(m4_location[: warning: $1])]) |
| |
| |
| # m4_fatal(MSG, [EXIT-STATUS]) |
| # ---------------------------- |
| # Fatal the user. :) |
| m4_define([m4_fatal], |
| [m4_errprintn(m4_location[: error: $1] |
| m4_expansion_stack)m4_exit(m4_if([$2],, 1, [$2]))]) |
| |
| |
| # m4_assert(EXPRESSION, [EXIT-STATUS = 1]) |
| # ---------------------------------------- |
| # This macro ensures that EXPRESSION evaluates to true, and exits if |
| # EXPRESSION evaluates to false. |
| m4_define([m4_assert], |
| [m4_if(m4_eval([$1]), 0, |
| [m4_fatal([assert failed: $1], [$2])])]) |
| |
| |
| |
| ## ------------- ## |
| ## 3. Warnings. ## |
| ## ------------- ## |
| |
| |
| # _m4_warn(CATEGORY, MESSAGE, [STACK-TRACE]) |
| # ------------------------------------------ |
| # Report a MESSAGE to the user if the CATEGORY of warnings is enabled. |
| # This is for traces only. |
| # If present, STACK-TRACE is a \n-separated list of "LOCATION: MESSAGE", |
| # where the last line (and no other) ends with "the top level". |
| # |
| # Within m4, the macro is a no-op. This macro really matters |
| # when autom4te post-processes the trace output. |
| m4_define([_m4_warn], []) |
| |
| |
| # m4_warn(CATEGORY, MESSAGE) |
| # -------------------------- |
| # Report a MESSAGE to the user if the CATEGORY of warnings is enabled. |
| m4_define([m4_warn], |
| [_m4_warn([$1], [$2], |
| m4_ifdef([_m4_expansion_stack], [m4_expansion_stack]))]) |
| |
| |
| |
| ## ------------------- ## |
| ## 4. File inclusion. ## |
| ## ------------------- ## |
| |
| |
| # We also want to neutralize include (and sinclude for symmetry), |
| # but we want to extend them slightly: warn when a file is included |
| # several times. This is, in general, a dangerous operation, because |
| # too many people forget to quote the first argument of m4_define. |
| # |
| # For instance in the following case: |
| # m4_define(foo, [bar]) |
| # then a second reading will turn into |
| # m4_define(bar, [bar]) |
| # which is certainly not what was meant. |
| |
| # m4_include_unique(FILE) |
| # ----------------------- |
| # Declare that the FILE was loading; and warn if it has already |
| # been included. |
| m4_define([m4_include_unique], |
| [m4_ifdef([m4_include($1)], |
| [m4_warn([syntax], [file `$1' included several times])])dnl |
| m4_define([m4_include($1)])]) |
| |
| |
| # m4_include(FILE) |
| # ---------------- |
| # Like the builtin include, but warns against multiple inclusions. |
| m4_define([m4_include], |
| [m4_include_unique([$1])dnl |
| m4_builtin([include], [$1])]) |
| |
| |
| # m4_sinclude(FILE) |
| # ----------------- |
| # Like the builtin sinclude, but warns against multiple inclusions. |
| m4_define([m4_sinclude], |
| [m4_include_unique([$1])dnl |
| m4_builtin([sinclude], [$1])]) |
| |
| |
| |
| ## ------------------------------------ ## |
| ## 5. Additional branching constructs. ## |
| ## ------------------------------------ ## |
| |
| # Both `m4_ifval' and `m4_ifset' tests against the empty string. The |
| # difference is that `m4_ifset' is specialized on macros. |
| # |
| # In case of arguments of macros, eg. $1, it makes little difference. |
| # In the case of a macro `FOO', you don't want to check `m4_ifval(FOO, |
| # TRUE)', because if `FOO' expands with commas, there is a shifting of |
| # the arguments. So you want to run `m4_ifval([FOO])', but then you just |
| # compare the *string* `FOO' against `', which, of course fails. |
| # |
| # So you want the variation `m4_ifset' that expects a macro name as $1. |
| # If this macro is both defined and defined to a non empty value, then |
| # it runs TRUE, etc. |
| |
| |
| # m4_ifblank(COND, [IF-BLANK], [IF-TEXT]) |
| # m4_ifnblank(COND, [IF-TEXT], [IF-BLANK]) |
| # ---------------------------------------- |
| # If COND is empty, or consists only of blanks (space, tab, newline), |
| # then expand IF-BLANK, otherwise expand IF-TEXT. This differs from |
| # m4_ifval only if COND has just whitespace, but it helps optimize in |
| # spite of users who mistakenly leave trailing space after what they |
| # thought was an empty argument: |
| # macro( |
| # [] |
| # ) |
| # |
| # Writing one macro in terms of the other causes extra overhead, so |
| # we inline both definitions. |
| m4_define([m4_ifblank], |
| [m4_if(m4_translit([[$1]], [ ][ ][ |
| ]), [], [$2], [$3])]) |
| |
| m4_define([m4_ifnblank], |
| [m4_if(m4_translit([[$1]], [ ][ ][ |
| ]), [], [$3], [$2])]) |
| |
| |
| # m4_ifval(COND, [IF-TRUE], [IF-FALSE]) |
| # ------------------------------------- |
| # If COND is not the empty string, expand IF-TRUE, otherwise IF-FALSE. |
| # Comparable to m4_ifdef. |
| m4_define([m4_ifval], |
| [m4_if([$1], [], [$3], [$2])]) |
| |
| |
| # m4_n(TEXT) |
| # ---------- |
| # If TEXT is not empty, return TEXT and a new line, otherwise nothing. |
| m4_define([m4_n], |
| [m4_if([$1], |
| [], [], |
| [$1 |
| ])]) |
| |
| |
| # m4_ifvaln(COND, [IF-TRUE], [IF-FALSE]) |
| # -------------------------------------- |
| # Same as `m4_ifval', but add an extra newline to IF-TRUE or IF-FALSE |
| # unless that argument is empty. |
| m4_define([m4_ifvaln], |
| [m4_if([$1], |
| [], [m4_n([$3])], |
| [m4_n([$2])])]) |
| |
| |
| # m4_ifset(MACRO, [IF-TRUE], [IF-FALSE]) |
| # -------------------------------------- |
| # If MACRO has no definition, or of its definition is the empty string, |
| # expand IF-FALSE, otherwise IF-TRUE. |
| m4_define([m4_ifset], |
| [m4_ifdef([$1], |
| [m4_ifval(_m4_defn([$1]), [$2], [$3])], |
| [$3])]) |
| |
| |
| # m4_ifndef(NAME, [IF-NOT-DEFINED], [IF-DEFINED]) |
| # ----------------------------------------------- |
| m4_define([m4_ifndef], |
| [m4_ifdef([$1], [$3], [$2])]) |
| |
| |
| # m4_case(SWITCH, VAL1, IF-VAL1, VAL2, IF-VAL2, ..., DEFAULT) |
| # ----------------------------------------------------------- |
| # m4 equivalent of |
| # switch (SWITCH) |
| # { |
| # case VAL1: |
| # IF-VAL1; |
| # break; |
| # case VAL2: |
| # IF-VAL2; |
| # break; |
| # ... |
| # default: |
| # DEFAULT; |
| # break; |
| # }. |
| # 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, [], |
| [$#], 2, [$2], |
| [$1], [$2], [$3], |
| [$0([$1], m4_shift3($@))])]) |
| |
| |
| # m4_bmatch(SWITCH, RE1, VAL1, RE2, VAL2, ..., DEFAULT) |
| # ----------------------------------------------------- |
| # m4 equivalent of |
| # |
| # if (SWITCH =~ RE1) |
| # VAL1; |
| # elif (SWITCH =~ RE2) |
| # VAL2; |
| # elif ... |
| # ... |
| # else |
| # DEFAULT |
| # |
| # 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])], |
| [$#], 2, [$2], |
| [m4_if(m4_bregexp([$1], [$2]), -1, [$0([$1], m4_shift3($@))], |
| [$3])])]) |
| |
| # m4_argn(N, ARGS...) |
| # ------------------- |
| # Extract argument N (greater than 0) from ARGS. Example: |
| # m4_define([b], [B]) |
| # m4_argn([2], [a], [b], [c]) => b |
| # |
| # Rather than using m4_car(m4_shiftn([$1], $@)), we exploit the fact that |
| # GNU m4 can directly reference any argument, through an indirect macro. |
| m4_define([m4_argn], |
| [m4_assert([0 < $1])]dnl |
| [m4_pushdef([_$0], [_m4_popdef([_$0])]m4_dquote([$]m4_incr([$1])))_$0($@)]) |
| |
| |
| # m4_car(ARGS...) |
| # m4_cdr(ARGS...) |
| # --------------- |
| # Manipulate m4 lists. m4_car returns the first argument. m4_cdr |
| # bundles all but the first argument into a quoted list. These two |
| # macros are generally used with list arguments, with quoting removed |
| # to break the list into multiple m4 ARGS. |
| m4_define([m4_car], [[$1]]) |
| m4_define([m4_cdr], |
| [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], |
| [$#], 1, [], |
| [m4_dquote(m4_shift($@))])]) |
| |
| # _m4_cdr(ARGS...) |
| # ---------------- |
| # Like m4_cdr, except include a leading comma unless only one argument |
| # remains. Why? Because comparing a large list against [] is more |
| # expensive in expansion time than comparing the number of arguments; so |
| # _m4_cdr can be used to reduce the number of arguments when it is time |
| # to end recursion. |
| m4_define([_m4_cdr], |
| [m4_if([$#], 1, [], |
| [, m4_dquote(m4_shift($@))])]) |
| |
| |
| |
| # m4_cond(TEST1, VAL1, IF-VAL1, TEST2, VAL2, IF-VAL2, ..., [DEFAULT]) |
| # ------------------------------------------------------------------- |
| # Similar to m4_if, except that each TEST is expanded when encountered. |
| # If the expansion of TESTn matches the string VALn, the result is IF-VALn. |
| # The result is DEFAULT if no tests passed. This macro allows |
| # short-circuiting of expensive tests, where it pays to arrange quick |
| # filter tests to run first. |
| # |
| # For an example, consider a previous implementation of _AS_QUOTE_IFELSE: |
| # |
| # m4_if(m4_index([$1], [\]), [-1], [$2], |
| # m4_eval(m4_index([$1], [\\]) >= 0), [1], [$2], |
| # m4_eval(m4_index([$1], [\$]) >= 0), [1], [$2], |
| # m4_eval(m4_index([$1], [\`]) >= 0), [1], [$3], |
| # m4_eval(m4_index([$1], [\"]) >= 0), [1], [$3], |
| # [$2]) |
| # |
| # Here, m4_index is computed 5 times, and m4_eval 4, even if $1 contains |
| # no backslash. It is more efficient to do: |
| # |
| # m4_cond([m4_index([$1], [\])], [-1], [$2], |
| # [m4_eval(m4_index([$1], [\\]) >= 0)], [1], [$2], |
| # [m4_eval(m4_index([$1], [\$]) >= 0)], [1], [$2], |
| # [m4_eval(m4_index([$1], [\`]) >= 0)], [1], [$3], |
| # [m4_eval(m4_index([$1], [\"]) >= 0)], [1], [$3], |
| # [$2]) |
| # |
| # 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], |
| m4_eval([$# % 3]), [2], [m4_fatal([$0: missing an argument])], |
| [_$0($@)])]) |
| |
| m4_define([_m4_cond], |
| [m4_if(($1), [($2)], [$3], |
| [$#], [3], [], |
| [$#], [4], [$4], |
| [$0(m4_shift3($@))])]) |
| |
| |
| ## ---------------------------------------- ## |
| ## 6. Enhanced version of some primitives. ## |
| ## ---------------------------------------- ## |
| |
| # m4_bpatsubsts(STRING, RE1, SUBST1, RE2, SUBST2, ...) |
| # ---------------------------------------------------- |
| # m4 equivalent of |
| # |
| # $_ = STRING; |
| # s/RE1/SUBST1/g; |
| # s/RE2/SUBST2/g; |
| # ... |
| # |
| # All the values are optional, and the macro is robust to active symbols |
| # properly quoted. |
| # |
| # I would have liked to name this macro `m4_bpatsubst', unfortunately, |
| # due to quotation problems, I need to double quote $1 below, therefore |
| # the anchors are broken :( I can't let users be trapped by that. |
| # |
| # 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])], |
| [$#], 2, [m4_unquote(m4_builtin([patsubst], [[$1]], [$2]))], |
| [$#], 3, [m4_unquote(m4_builtin([patsubst], [[$1]], [$2], [$3]))], |
| [_$0($@m4_if(m4_eval($# & 1), 0, [,]))])]) |
| m4_define([_m4_bpatsubsts], |
| [m4_if([$#], 2, [$1], |
| [$0(m4_builtin([patsubst], [[$1]], [$2], [$3]), |
| m4_shift3($@))])]) |
| |
| |
| # m4_copy(SRC, DST) |
| # ----------------- |
| # Define the pushdef stack DST as a copy of the pushdef stack SRC; |
| # give an error if DST is already defined. This is particularly nice |
| # for copying self-modifying pushdef stacks, where the top definition |
| # includes one-shot initialization that is later popped to the normal |
| # definition. This version intentionally does nothing if SRC is |
| # undefined. |
| # |
| # Some macros simply can't be renamed with this method: namely, anything |
| # involved in the implementation of m4_stack_foreach_sep. |
| m4_define([m4_copy], |
| [m4_ifdef([$2], [m4_fatal([$0: won't overwrite defined macro: $2])], |
| [m4_stack_foreach_sep([$1], [m4_pushdef([$2],], [)])])]dnl |
| [m4_ifdef([m4_location($1)], [m4_define([m4_location($2)], m4_location)])]) |
| |
| |
| # m4_copy_force(SRC, DST) |
| # m4_rename_force(SRC, DST) |
| # ------------------------- |
| # Like m4_copy/m4_rename, except blindly overwrite any existing DST. |
| # Note that m4_copy_force tolerates undefined SRC, while m4_rename_force |
| # does not. |
| m4_define([m4_copy_force], |
| [m4_ifdef([$2], [_m4_undefine([$2])])m4_copy($@)]) |
| |
| m4_define([m4_rename_force], |
| [m4_ifdef([$2], [_m4_undefine([$2])])m4_rename($@)]) |
| |
| |
| # m4_define_default(MACRO, VALUE) |
| # ------------------------------- |
| # If MACRO is undefined, set it to VALUE. |
| m4_define([m4_define_default], |
| [m4_ifndef([$1], [m4_define($@)])]) |
| |
| |
| # m4_default(EXP1, EXP2) |
| # m4_default_nblank(EXP1, EXP2) |
| # ----------------------------- |
| # Returns EXP1 if not empty/blank, otherwise EXP2. Expand the result. |
| # |
| # m4_default is called on hot paths, so inline the contents of m4_ifval, |
| # for one less round of expansion. |
| m4_define([m4_default], |
| [m4_if([$1], [], [$2], [$1])]) |
| |
| m4_define([m4_default_nblank], |
| [m4_ifblank([$1], [$2], [$1])]) |
| |
| |
| # m4_default_quoted(EXP1, EXP2) |
| # m4_default_nblank_quoted(EXP1, EXP2) |
| # ------------------------------------ |
| # Returns EXP1 if non empty/blank, otherwise EXP2. Leave the result quoted. |
| # |
| # For comparison: |
| # m4_define([active], [ACTIVE]) |
| # m4_default([active], [default]) => ACTIVE |
| # m4_default([], [active]) => ACTIVE |
| # -m4_default([ ], [active])- => - - |
| # -m4_default_nblank([ ], [active])- => -ACTIVE- |
| # m4_default_quoted([active], [default]) => active |
| # m4_default_quoted([], [active]) => active |
| # -m4_default_quoted([ ], [active])- => - - |
| # -m4_default_nblank_quoted([ ], [active])- => -active- |
| # |
| # m4_default macro is called on hot paths, so inline the contents of m4_ifval, |
| # for one less round of expansion. |
| m4_define([m4_default_quoted], |
| [m4_if([$1], [], [[$2]], [[$1]])]) |
| |
| m4_define([m4_default_nblank_quoted], |
| [m4_ifblank([$1], [[$2]], [[$1]])]) |
| |
| |
| # m4_defn(NAME) |
| # ------------- |
| # Like the original, except guarantee a warning when using something which is |
| # undefined (unlike M4 1.4.x). This replacement is not a full-featured |
| # replacement: if any of the defined macros contain unbalanced quoting, but |
| # when pasted together result in a well-quoted string, then only native m4 |
| # support is able to get it correct. But that's where quadrigraphs come in |
| # handy, if you really need unbalanced quotes inside your macros. |
| # |
| # 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 (see m4_init). |
| m4_define([m4_defn], |
| [m4_if([$#], [0], [[$0]], |
| [$#], [1], [m4_ifdef([$1], [_m4_defn([$1])], |
| [m4_fatal([$0: undefined macro: $1])])], |
| [m4_map_args([$0], $@)])]) |
| |
| |
| # m4_dumpdef(NAME...) |
| # ------------------- |
| # In m4 1.4.x, dumpdef writes to the current debugfile, rather than |
| # stderr. This in turn royally confuses autom4te; so we follow the |
| # lead of newer m4 and always dump to stderr. Unlike the original, |
| # this version requires an argument, since there is no convenient way |
| # in m4 1.4.x to grab the names of all defined macros. Newer m4 |
| # always dumps to stderr, regardless of the current debugfile; it also |
| # provides m4symbols as a way to grab all current macro names. But |
| # dumpdefs is not frequently called, so we don't need to worry about |
| # conditionally using these newer features. Also, this version |
| # doesn't sort multiple arguments. |
| # |
| # If we detect m4 1.6 or newer, then provide an alternate definition, |
| # installed during m4_init, that allows builtins through. |
| # Unfortunately, there is no nice way in m4 1.4.x to dump builtins. |
| m4_define([m4_dumpdef], |
| [m4_if([$#], [0], [m4_fatal([$0: missing argument])], |
| [$#], [1], [m4_ifdef([$1], [m4_errprintn( |
| [$1: ]m4_dquote(_m4_defn([$1])))], [m4_fatal([$0: undefined macro: $1])])], |
| [m4_map_args([$0], $@)])]) |
| |
| m4_define([_m4_dumpdef], |
| [m4_if([$#], [0], [m4_fatal([$0: missing argument])], |
| [$#], [1], [m4_builtin([dumpdef], [$1])], |
| [m4_map_args_sep([m4_builtin([dumpdef],], [)], [], $@)])]) |
| |
| |
| # m4_dumpdefs(NAME...) |
| # -------------------- |
| # Similar to `m4_dumpdef(NAME)', but if NAME was m4_pushdef'ed, display its |
| # 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_if([$#], [0], [m4_fatal([$0: missing argument])], |
| [$#], [1], [m4_stack_foreach_lifo([$1], [m4_dumpdef([$1])m4_ignore])], |
| [m4_map_args([$0], $@)])]) |
| |
| # m4_esyscmd_s(COMMAND) |
| # --------------------- |
| # Like m4_esyscmd, except strip any trailing newlines, thus behaving |
| # more like shell command substitution. |
| m4_define([m4_esyscmd_s], |
| [m4_chomp_all(m4_esyscmd([$1]))]) |
| |
| |
| # m4_popdef(NAME) |
| # --------------- |
| # Like the original, except guarantee a warning when using something which is |
| # undefined (unlike M4 1.4.x). |
| # |
| # 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 (see m4_init). |
| m4_define([m4_popdef], |
| [m4_if([$#], [0], [[$0]], |
| [$#], [1], [m4_ifdef([$1], [_m4_popdef([$1])], |
| [m4_fatal([$0: undefined macro: $1])])], |
| [m4_map_args([$0], $@)])]) |
| |
| |
| # m4_shiftn(N, ...) |
| # ----------------- |
| # Returns ... shifted N times. Useful for recursive "varargs" constructs. |
| # |
| # Autoconf does not use this macro, because it is inherently slower than |
| # calling the common cases of m4_shift2 or m4_shift3 directly. But it |
| # might as well be fast for other clients, such as Libtool. One way to |
| # do this is to expand $@ only once in _m4_shiftn (otherwise, for long |
| # lists, the expansion of m4_if takes twice as much memory as what the |
| # list itself occupies, only to throw away the unused branch). The end |
| # result is strictly equivalent to |
| # m4_if([$1], 1, [m4_shift(,m4_shift(m4_shift($@)))], |
| # [_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($@)]) |
| |
| m4_define([_m4_shiftn], |
| [m4_if([$1], 1, [m4_shift(], |
| [$0(m4_decr([$1])]), m4_shift(m4_shift($@)))]) |
| |
| # m4_shift2(...) |
| # m4_shift3(...) |
| # -------------- |
| # Returns ... shifted twice, and three times. Faster than m4_shiftn. |
| m4_define([m4_shift2], [m4_shift(m4_shift($@))]) |
| m4_define([m4_shift3], [m4_shift(m4_shift(m4_shift($@)))]) |
| |
| # _m4_shift2(...) |
| # _m4_shift3(...) |
| # --------------- |
| # Like m4_shift2 or m4_shift3, except include a leading comma unless shifting |
| # consumes all arguments. Why? Because in recursion, it is nice to |
| # distinguish between 1 element left and 0 elements left, based on how many |
| # arguments this shift expands to. |
| m4_define([_m4_shift2], |
| [m4_if([$#], [2], [], |
| [, m4_shift(m4_shift($@))])]) |
| m4_define([_m4_shift3], |
| [m4_if([$#], [3], [], |
| [, m4_shift(m4_shift(m4_shift($@)))])]) |
| |
| |
| # m4_undefine(NAME) |
| # ----------------- |
| # Like the original, except guarantee a warning when using something which is |
| # undefined (unlike M4 1.4.x). |
| # |
| # 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 (see m4_init). |
| m4_define([m4_undefine], |
| [m4_if([$#], [0], [[$0]], |
| [$#], [1], [m4_ifdef([$1], [_m4_undefine([$1])], |
| [m4_fatal([$0: undefined macro: $1])])], |
| [m4_map_args([$0], $@)])]) |
| |
| # _m4_wrap(PRE, POST) |
| # ------------------- |
| # Helper macro for m4_wrap and m4_wrap_lifo. Allows nested calls to |
| # m4_wrap within wrapped text. Use _m4_defn and _m4_popdef for speed. |
| m4_define([_m4_wrap], |
| [m4_ifdef([$0_text], |
| [m4_define([$0_text], [$1]_m4_defn([$0_text])[$2])], |
| [m4_builtin([m4wrap], [m4_unquote( |
| _m4_defn([$0_text])_m4_popdef([$0_text]))])m4_define([$0_text], [$1$2])])]) |
| |
| # m4_wrap(TEXT) |
| # ------------- |
| # Append TEXT to the list of hooks to be executed at the end of input. |
| # Whereas the order of the original may be LIFO in the underlying m4, |
| # this version is always FIFO. |
| m4_define([m4_wrap], |
| [_m4_wrap([], [$1[]])]) |
| |
| # m4_wrap_lifo(TEXT) |
| # ------------------ |
| # Prepend TEXT to the list of hooks to be executed at the end of input. |
| # Whereas the order of m4_wrap may be FIFO in the underlying m4, this |
| # version is always LIFO. |
| m4_define([m4_wrap_lifo], |
| [_m4_wrap([$1[]])]) |
| |
| ## ------------------------- ## |
| ## 7. Quoting manipulation. ## |
| ## ------------------------- ## |
| |
| |
| # m4_apply(MACRO, LIST) |
| # --------------------- |
| # Invoke MACRO, with arguments provided from the quoted list of |
| # comma-separated quoted arguments. If LIST is empty, invoke MACRO |
| # without arguments. The expansion will not be concatenated with |
| # subsequent text. |
| m4_define([m4_apply], |
| [m4_if([$2], [], [$1], [$1($2)])[]]) |
| |
| # _m4_apply(MACRO, LIST) |
| # ---------------------- |
| # Like m4_apply, except do nothing if LIST is empty. |
| m4_define([_m4_apply], |
| [m4_if([$2], [], [], [$1($2)[]])]) |
| |
| |
| # m4_count(ARGS) |
| # -------------- |
| # Return a count of how many ARGS are present. |
| m4_define([m4_count], [$#]) |
| |
| |
| # m4_curry(MACRO, ARG...) |
| # ----------------------- |
| # Perform argument currying. The expansion of this macro is another |
| # macro that takes exactly one argument, appends it to the end of the |
| # original ARG list, then invokes MACRO. For example: |
| # m4_curry([m4_curry], [m4_reverse], [1])([2])([3]) => 3, 2, 1 |
| # Not quite as practical as m4_incr, but you could also do: |
| # m4_define([add], [m4_eval(([$1]) + ([$2]))]) |
| # m4_define([add_one], [m4_curry([add], [1])]) |
| # add_one()([2]) => 3 |
| m4_define([m4_curry], [$1(m4_shift($@,)_$0]) |
| m4_define([_m4_curry], [[$1])]) |
| |
| |
| # m4_do(STRING, ...) |
| # ------------------ |
| # This macro invokes all its arguments (in sequence, of course). It is |
| # 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[]], |
| [$1[]$0(m4_shift($@))])]) |
| |
| |
| # m4_dquote(ARGS) |
| # --------------- |
| # Return ARGS as a quoted list of quoted arguments. |
| m4_define([m4_dquote], [[$@]]) |
| |
| |
| # 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]]], |
| [[[$1]],$0(m4_shift($@))])]) |
| |
| |
| # m4_echo(ARGS) |
| # ------------- |
| # Return the ARGS, with the same level of quoting. Whitespace after |
| # unquoted commas are consumed. |
| m4_define([m4_echo], [$@]) |
| |
| |
| # m4_expand(ARG) |
| # _m4_expand(ARG) |
| # --------------- |
| # Return the expansion of ARG as a single string. Unlike |
| # m4_quote($1), this preserves whitespace following single-quoted |
| # commas that appear within ARG. It also deals with shell case |
| # statements. |
| # |
| # m4_define([active], [ACT, IVE]) |
| # m4_define([active2], [[ACT, IVE]]) |
| # m4_quote(active, active2) |
| # => ACT,IVE,ACT, IVE |
| # m4_expand([active, active2]) |
| # => ACT, IVE, ACT, IVE |
| # |
| # Unfortunately, due to limitations in m4, ARG must expand to |
| # something with balanced quotes (use quadrigraphs to get around |
| # this), and should not contain the unlikely delimiters -=<{( or |
| # )}>=-. It is possible to have unbalanced quoted `(' or `)', as well |
| # as unbalanced unquoted `)'. m4_expand can handle unterminated |
| # comments or dnl on the final line, at the expense of speed; it also |
| # aids in detecting attempts to incorrectly change the current |
| # diversion inside ARG. Meanwhile, _m4_expand is faster but must be |
| # given a terminated expansion, and has no safety checks for |
| # mis-diverted text. |
| # |
| # Exploit that extra unquoted () will group unquoted commas and the |
| # following whitespace. m4_bpatsubst can't handle newlines inside $1, |
| # and m4_substr strips quoting. So we (ab)use m4_changequote, using |
| # temporary quotes to remove the delimiters that conveniently included |
| # the unquoted () that were added prior to the changequote. |
| # |
| # Thanks to shell case statements, too many people are prone to pass |
| # underquoted `)', so we try to detect that by passing a marker as a |
| # fourth argument; if the marker is not present, then we assume that |
| # we encountered an early `)', and re-expand the first argument, but |
| # this time with one more `(' in the second argument and in the |
| # open-quote delimiter. We must also ignore the slop from the |
| # previous try. The final macro is thus half line-noise, half art. |
| m4_define([m4_expand], |
| [m4_pushdef([m4_divert], _m4_defn([_m4_divert_unsafe]))]dnl |
| [m4_pushdef([m4_divert_push], _m4_defn([_m4_divert_unsafe]))]dnl |
| [m4_chomp(_$0([$1 |
| ]))_m4_popdef([m4_divert], [m4_divert_push])]) |
| |
| m4_define([_m4_expand], [$0_([$1], [(], -=<{($1)}>=-, [}>=-])]) |
| |
| m4_define([_m4_expand_], |
| [m4_if([$4], [}>=-], |
| [m4_changequote([-=<{$2], [)}>=-])$3m4_changequote([, ])], |
| [$0([$1], [($2], -=<{($2$1)}>=-, [}>=-])m4_ignore$2])]) |
| |
| |
| # m4_ignore(ARGS) |
| # --------------- |
| # Expands to nothing. Useful for conditionally ignoring an arbitrary |
| # number of arguments (see _m4_list_cmp for an example). |
| m4_define([m4_ignore]) |
| |
| |
| # m4_make_list(ARGS) |
| # ------------------ |
| # Similar to m4_dquote, this creates a quoted list of quoted ARGS. This |
| # version is less efficient than m4_dquote, but separates each argument |
| # with a comma and newline, rather than just comma, for readability. |
| # When developing an m4sugar algorithm, you could temporarily use |
| # m4_pushdef([m4_dquote],m4_defn([m4_make_list])) |
| # around your code to make debugging easier. |
| m4_define([m4_make_list], [m4_join([, |
| ], m4_dquote_elt($@))]) |
| |
| |
| # m4_noquote(STRING) |
| # ------------------ |
| # Return the result of ignoring all quotes in STRING and invoking the |
| # macros it contains. Among other things, this is useful for enabling |
| # macro invocations inside strings with [] blocks (for instance regexps |
| # and help-strings). On the other hand, since all quotes are disabled, |
| # any macro expanded during this time that relies on nested [] quoting |
| # will likely crash and burn. This macro is seldom useful; consider |
| # m4_unquote or m4_expand instead. |
| m4_define([m4_noquote], |
| [m4_changequote([-=<{(],[)}>=-])$1-=<{()}>=-m4_changequote([,])]) |
| |
| |
| # m4_quote(ARGS) |
| # -------------- |
| # Return ARGS as a single argument. Any whitespace after unquoted commas |
| # is stripped. There is always output, even when there were no arguments. |
| # |
| # It is important to realize the difference between `m4_quote(exp)' and |
| # `[exp]': in the first case you obtain the quoted *result* of the |
| # expansion of EXP, while in the latter you just obtain the string |
| # `exp'. |
| m4_define([m4_quote], [[$*]]) |
| |
| |
| # _m4_quote(ARGS) |
| # --------------- |
| # Like m4_quote, except that when there are no arguments, there is no |
| # output. For conditional scenarios (such as passing _m4_quote as the |
| # macro name in m4_mapall), this feature can be used to distinguish between |
| # one argument of the empty string vs. no arguments. However, in the |
| # normal case with arguments present, this is less efficient than m4_quote. |
| m4_define([_m4_quote], |
| [m4_if([$#], [0], [], [[$*]])]) |
| |
| |
| # 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]])]) |
| |
| |
| # m4_unquote(ARGS) |
| # ---------------- |
| # Remove one layer of quotes from each ARG, performing one level of |
| # expansion. For one argument, m4_unquote([arg]) is more efficient than |
| # m4_do([arg]), but for multiple arguments, the difference is that |
| # m4_unquote separates arguments with commas while m4_do concatenates. |
| # Follow this macro with [] if concatenation with subsequent text is |
| # undesired. |
| m4_define([m4_unquote], [$*]) |
| |
| |
| ## -------------------------- ## |
| ## 8. Implementing m4 loops. ## |
| ## -------------------------- ## |
| |
| |
| # m4_for(VARIABLE, FIRST, LAST, [STEP = +/-1], EXPRESSION) |
| # -------------------------------------------------------- |
| # Expand EXPRESSION defining VARIABLE to FROM, FROM + 1, ..., TO with |
| # increments of STEP. Both limits are included, and bounds are |
| # checked for consistency. The algorithm is robust to indirect |
| # VARIABLE names. Changing VARIABLE inside EXPRESSION will not impact |
| # the number of iterations. |
| # |
| # Uses _m4_defn for speed, and avoid dnl in the macro body. Factor |
| # the _m4_for call so that EXPRESSION is only parsed once. |
| m4_define([m4_for], |
| [m4_pushdef([$1], m4_eval([$2]))]dnl |
| [m4_cond([m4_eval(([$3]) > ([$2]))], 1, |
| [m4_pushdef([_m4_step], m4_eval(m4_default_quoted([$4], |
| 1)))m4_assert(_m4_step > 0)_$0(_m4_defn([$1]), |
| m4_eval((([$3]) - ([$2])) / _m4_step * _m4_step + ([$2])), _m4_step,], |
| [m4_eval(([$3]) < ([$2]))], 1, |
| [m4_pushdef([_m4_step], m4_eval(m4_default_quoted([$4], |
| -1)))m4_assert(_m4_step < 0)_$0(_m4_defn([$1]), |
| m4_eval((([$2]) - ([$3])) / -(_m4_step) * _m4_step + ([$2])), _m4_step,], |
| [m4_pushdef([_m4_step])_$0(_m4_defn([$1]), _m4_defn([$1]), 0,])]dnl |
| [[m4_define([$1],], [)$5])m4_popdef([_m4_step], [$1])]) |
| |
| # _m4_for(COUNT, LAST, STEP, PRE, POST) |
| # ------------------------------------- |
| # Core of the loop, no consistency checks, all arguments are plain |
| # numbers. Expand PRE[COUNT]POST, then alter COUNT by STEP and |
| # iterate if COUNT is not LAST. |
| m4_define([_m4_for], |
| [$4[$1]$5[]m4_if([$1], [$2], [], |
| [$0(m4_eval([$1 + $3]), [$2], [$3], [$4], [$5])])]) |
| |
| |
| # Implementing `foreach' loops in m4 is much more tricky than it may |
| # seem. For example, the old M4 1.4.4 manual had an incorrect example, |
| # which looked like this (when translated to m4sugar): |
| # |
| # | # foreach(VAR, (LIST), STMT) |
| # | m4_define([foreach], |
| # | [m4_pushdef([$1])_foreach([$1], [$2], [$3])m4_popdef([$1])]) |
| # | m4_define([_arg1], [$1]) |
| # | m4_define([_foreach], |
| # | [m4_if([$2], [()], , |
| # | [m4_define([$1], _arg1$2)$3[]_foreach([$1], (m4_shift$2), [$3])])]) |
| # |
| # But then if you run |
| # |
| # | m4_define(a, 1) |
| # | m4_define(b, 2) |
| # | m4_define(c, 3) |
| # | foreach([f], [([a], [(b], [c)])], [echo f |
| # | ]) |
| # |
| # it gives |
| # |
| # => echo 1 |
| # => echo (2,3) |
| # |
| # which is not what is expected. |
| # |
| # Of course the problem is that many quotes are missing. So you add |
| # plenty of quotes at random places, until you reach the expected |
| # result. Alternatively, if you are a quoting wizard, you directly |
| # reach the following implementation (but if you really did, then |
| # apply to the maintenance of m4sugar!). |
| # |
| # | # foreach(VAR, (LIST), STMT) |
| # | m4_define([foreach], [m4_pushdef([$1])_foreach($@)m4_popdef([$1])]) |
| # | m4_define([_arg1], [[$1]]) |
| # | m4_define([_foreach], |
| # | [m4_if($2, [()], , |
| # | [m4_define([$1], [_arg1$2])$3[]_foreach([$1], [(m4_shift$2)], [$3])])]) |
| # |
| # which this time answers |
| # |
| # => echo a |
| # => echo (b |
| # => echo c) |
| # |
| # Bingo! |
| # |
| # Well, not quite. |
| # |
| # With a better look, you realize that the parens are more a pain than |
| # a help: since anyway you need to quote properly the list, you end up |
| # with always using an outermost pair of parens and an outermost pair |
| # of quotes. Rejecting the parens both eases the implementation, and |
| # simplifies the use: |
| # |
| # | # foreach(VAR, (LIST), STMT) |
| # | m4_define([foreach], [m4_pushdef([$1])_foreach($@)m4_popdef([$1])]) |
| # | m4_define([_arg1], [$1]) |
| # | m4_define([_foreach], |
| # | [m4_if($2, [], , |
| # | [m4_define([$1], [_arg1($2)])$3[]_foreach([$1], [m4_shift($2)], [$3])])]) |
| # |
| # |
| # Now, just replace the `$2' with `m4_quote($2)' in the outer `m4_if' |
| # to improve robustness, and you come up with a nice implementation |
| # that doesn't require extra parentheses in the user's LIST. |
| # |
| # But wait - now the algorithm is quadratic, because every recursion of |
| # the algorithm keeps the entire LIST and merely adds another m4_shift to |
| # the quoted text. If the user has a lot of elements in LIST, you can |
| # bring the system to its knees with the memory m4 then requires, or trip |
| # the m4 --nesting-limit recursion factor. The only way to avoid |
| # quadratic growth is ensure m4_shift is expanded prior to the recursion. |
| # Hence the design below. |
| # |
| # The M4 manual now includes a chapter devoted to this issue, with |
| # the lessons learned from m4sugar. And still, this design is only |
| # optimal for M4 1.6; see foreach.m4 for yet more comments on why |
| # M4 1.4.x uses yet another implementation. |
| |
| |
| # m4_foreach(VARIABLE, LIST, EXPRESSION) |
| # -------------------------------------- |
| # |
| # Expand EXPRESSION assigning each value of the LIST to VARIABLE. |
| # LIST should have the form `item_1, item_2, ..., item_n', i.e. the |
| # whole list must *quoted*. Quote members too if you don't want them |
| # to be expanded. |
| # |
| # This macro is robust to active symbols: |
| # | m4_define(active, [ACT, IVE]) |
| # | m4_foreach(Var, [active, active], [-Var-]) |
| # => -ACT--IVE--ACT--IVE- |
| # |
| # | m4_foreach(Var, [[active], [active]], [-Var-]) |
| # => -ACT, IVE--ACT, IVE- |
| # |
| # | m4_foreach(Var, [[[active]], [[active]]], [-Var-]) |
| # => -active--active- |
| # |
| # This macro is called frequently, so avoid extra expansions such as |
| # m4_ifval and dnl. Also, since $2 might be quite large, try to use it |
| # as little as possible in _m4_foreach; each extra use requires that much |
| # more memory for expansion. So, rather than directly compare $2 against |
| # [] 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, |
| # at which point this looks very much like m4_map_args. |
| m4_define([m4_foreach], |
| [m4_if([$2], [], [], |
| [m4_pushdef([$1])_$0([m4_define([$1],], [)$3], [], |
| $2)m4_popdef([$1])])]) |
| |
| # _m4_foreach(PRE, POST, IGNORED, ARG...) |
| # --------------------------------------- |
| # Form the common basis of the m4_foreach and m4_map macros. For each |
| # ARG, expand PRE[ARG]POST[]. The IGNORED argument makes recursion |
| # easier, and must be supplied rather than implicit. |
| # |
| # Please keep foreach.m4 in sync with any adjustments made here. |
| m4_define([_m4_foreach], |
| [m4_if([$#], [3], [], |
| [$1[$4]$2[]$0([$1], [$2], m4_shift3($@))])]) |
| |
| |
| # m4_foreach_w(VARIABLE, LIST, EXPRESSION) |
| # ---------------------------------------- |
| # Like m4_foreach, but the list is whitespace separated. Depending on |
| # EXPRESSION, it may be more efficient to use m4_map_args_w. |
| # |
| # This macro is robust to active symbols: |
| # m4_foreach_w([Var], [ active |
| # b act\ |
| # ive ], [-Var-])end |
| # => -active--b--active-end |
| # |
| # This used to use a slower implementation based on m4_foreach: |
| # m4_foreach([$1], m4_split(m4_normalize([$2]), [ ]), [$3]) |
| m4_define([m4_foreach_w], |
| [m4_pushdef([$1])m4_map_args_w([$2], |
| [m4_define([$1],], [)$3])m4_popdef([$1])]) |
| |
| |
| # m4_map(MACRO, LIST) |
| # m4_mapall(MACRO, LIST) |
| # ---------------------- |
| # Invoke MACRO($1), MACRO($2) etc. where $1, $2... are the elements of |
| # LIST. $1, $2... must in turn be lists, appropriate for m4_apply. |
| # If LIST contains an empty sublist, m4_map skips the expansion of |
| # MACRO, while m4_mapall expands MACRO with no arguments. |
| # |
| # Since LIST may be quite large, we want to minimize how often it |
| # appears in the expansion. Rather than use m4_car/m4_cdr iteration, |
| # we unbox the list, and use _m4_foreach for iteration. For m4_map, |
| # an empty list behaves like an empty sublist and gets ignored; for |
| # m4_mapall, we must special-case the empty list. |
| m4_define([m4_map], |
| [_m4_foreach([_m4_apply([$1],], [)], [], $2)]) |
| |
| m4_define([m4_mapall], |
| [m4_if([$2], [], [], |
| [_m4_foreach([m4_apply([$1],], [)], [], $2)])]) |
| |
| |
| # m4_map_sep(MACRO, [SEPARATOR], LIST) |
| # m4_mapall_sep(MACRO, [SEPARATOR], LIST) |
| # --------------------------------------- |
| # Invoke MACRO($1), SEPARATOR, MACRO($2), ..., MACRO($N) where $1, |
| # $2... $N are the elements of LIST, and are in turn lists appropriate |
| # for m4_apply. SEPARATOR is expanded, in order to allow the creation |
| # of a list of arguments by using a single-quoted comma as the |
| # separator. For each empty sublist, m4_map_sep skips the expansion |
| # of MACRO and SEPARATOR, while m4_mapall_sep expands MACRO with no |
| # arguments. |
| # |
| # For m4_mapall_sep, merely expand the first iteration without the |
| # 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_define([m4_map_sep], |
| [m4_pushdef([m4_Sep], [m4_define([m4_Sep], _m4_defn([m4_unquote]))])]dnl |
| [_m4_foreach([_m4_apply([m4_Sep([$2])[]$1],], [)], [], $3)m4_popdef([m4_Sep])]) |
| |
| m4_define([m4_mapall_sep], |
| [m4_if([$3], [], [], [_$0([$1], [$2], $3)])]) |
| |
| m4_define([_m4_mapall_sep], |
| [m4_apply([$1], [$3])_m4_foreach([m4_apply([$2[]$1],], [)], m4_shift2($@))]) |
| |
| # m4_map_args(EXPRESSION, ARG...) |
| # ------------------------------- |
| # Expand EXPRESSION([ARG]) for each argument. More efficient than |
| # m4_foreach([var], [ARG...], [EXPRESSION(m4_defn([var]))]) |
| # Shorthand for m4_map_args_sep([EXPRESSION(], [)], [], ARG...). |
| m4_define([m4_map_args], |
| [m4_if([$#], [0], [m4_fatal([$0: too few arguments: $#])], |
| [$#], [1], [], |
| [$#], [2], [$1([$2])[]], |
| [_m4_foreach([$1(], [)], $@)])]) |
| |
| |
| # m4_map_args_pair(EXPRESSION, [END-EXPR = EXPRESSION], ARG...) |
| # ------------------------------------------------------------- |
| # Perform a pairwise grouping of consecutive ARGs, by expanding |
| # EXPRESSION([ARG1], [ARG2]). If there are an odd number of ARGs, the |
| # final argument is expanded with END-EXPR([ARGn]). |
| # |
| # For example: |
| # m4_define([show], [($*)m4_newline])dnl |
| # m4_map_args_pair([show], [], [a], [b], [c], [d], [e])dnl |
| # => (a,b) |
| # => (c,d) |
| # => (e) |
| # |
| # Please keep foreach.m4 in sync with any adjustments made here. |
| m4_define([m4_map_args_pair], |
| [m4_if([$#], [0], [m4_fatal([$0: too few arguments: $#])], |
| [$#], [1], [m4_fatal([$0: too few arguments: $#: $1])], |
| [$#], [2], [], |
| [$#], [3], [m4_default([$2], [$1])([$3])[]], |
| [$#], [4], [$1([$3], [$4])[]], |
| [$1([$3], [$4])[]$0([$1], [$2], m4_shift(m4_shift3($@)))])]) |
| |
| |
| # m4_map_args_sep([PRE], [POST], [SEP], ARG...) |
| # --------------------------------------------- |
| # Expand PRE[ARG]POST for each argument, with SEP between arguments. |
| m4_define([m4_map_args_sep], |
| [m4_if([$#], [0], [m4_fatal([$0: too few arguments: $#])], |
| [$#], [1], [], |
| [$#], [2], [], |
| [$#], [3], [], |
| [$#], [4], [$1[$4]$2[]], |
| [$1[$4]$2[]_m4_foreach([$3[]$1], [$2], m4_shift3($@))])]) |
| |
| |
| # m4_map_args_w(STRING, [PRE], [POST], [SEP]) |
| # ------------------------------------------- |
| # Perform the expansion of PRE[word]POST[] for each word in STRING |
| # separated by whitespace. More efficient than: |
| # m4_foreach_w([var], [STRING], [PRE[]m4_defn([var])POST]) |
| # Additionally, expand SEP between words. |
| # |
| # As long as we have to use m4_bpatsubst to split the string, we might |
| # as well make it also apply PRE and POST; this avoids iteration |
| # altogether. But we must be careful of any \ in PRE or POST. |
| # _m4_strip returns a quoted string, but that's okay, since it also |
| # supplies an empty leading and trailing argument due to our |
| # intentional whitespace around STRING. We use m4_substr to strip the |
| # empty elements and remove the extra layer of quoting. |
| m4_define([m4_map_args_w], |
| [_$0(_m4_split([ ]m4_flatten([$1])[ ], [[ ]+], |
| m4_if(m4_index([$2$3$4], [\]), [-1], [[$3[]$4[]$2]], |
| [m4_bpatsubst([[$3[]$4[]$2]], [\\], [\\\\])])), |
| m4_len([[]$3[]$4]), m4_len([$4[]$2[]]))]) |
| |
| m4_define([_m4_map_args_w], |
| [m4_substr([$1], [$2], m4_eval(m4_len([$1]) - [$2] - [$3]))]) |
| |
| |
| # m4_stack_foreach(MACRO, FUNC) |
| # m4_stack_foreach_lifo(MACRO, FUNC) |
| # ---------------------------------- |
| # Pass each stacked definition of MACRO to the one-argument macro FUNC. |
| # m4_stack_foreach proceeds in FIFO order, while m4_stack_foreach_lifo |
| # processes the topmost definitions first. In addition, FUNC should |
| # not push or pop definitions of MACRO, and should not expect anything about |
| # the active definition of MACRO (it will not be the topmost, and may not |
| # be the one passed to FUNC either). |
| # |
| # Some macros simply can't be examined with this method: namely, |
| # anything involved in the implementation of _m4_stack_reverse. |
| m4_define([m4_stack_foreach], |
| [_m4_stack_reverse([$1], [m4_tmp-$1])]dnl |
| [_m4_stack_reverse([m4_tmp-$1], [$1], [$2(_m4_defn([m4_tmp-$1]))])]) |
| |
| m4_define([m4_stack_foreach_lifo], |
| [_m4_stack_reverse([$1], [m4_tmp-$1], [$2(_m4_defn([m4_tmp-$1]))])]dnl |
| [_m4_stack_reverse([m4_tmp-$1], [$1])]) |
| |
| # m4_stack_foreach_sep(MACRO, [PRE], [POST], [SEP]) |
| # m4_stack_foreach_sep_lifo(MACRO, [PRE], [POST], [SEP]) |
| # ------------------------------------------------------ |
| # Similar to m4_stack_foreach and m4_stack_foreach_lifo, in that every |
| # definition of a pushdef stack will be visited. But rather than |
| # passing the definition as a single argument to a macro, this variant |
| # expands the concatenation of PRE[]definition[]POST, and expands SEP |
| # between consecutive expansions. Note that m4_stack_foreach([a], [b]) |
| # is equivalent to m4_stack_foreach_sep([a], [b(], [)]). |
| m4_define([m4_stack_foreach_sep], |
| [_m4_stack_reverse([$1], [m4_tmp-$1])]dnl |
| [_m4_stack_reverse([m4_tmp-$1], [$1], [$2[]_m4_defn([m4_tmp-$1])$3], [$4[]])]) |
| |
| m4_define([m4_stack_foreach_sep_lifo], |
| [_m4_stack_reverse([$1], [m4_tmp-$1], [$2[]_m4_defn([m4_tmp-$1])$3], [$4[]])]dnl |
| [_m4_stack_reverse([m4_tmp-$1], [$1])]) |
| |
| |
| # _m4_stack_reverse(OLD, NEW, [ACTION], [SEP]) |
| # -------------------------------------------- |
| # A recursive worker for pushdef stack manipulation. Destructively |
| # copy the OLD stack into the NEW, and expanding ACTION for each |
| # iteration. After the first iteration, SEP is promoted to the front |
| # of ACTION (note that SEP should include a trailing [] if it is to |
| # avoid interfering with ACTION). The current definition is examined |
| # after the NEW has been pushed but before OLD has been popped; this |
| # order is important, as ACTION is permitted to operate on either |
| # _m4_defn([OLD]) or _m4_defn([NEW]). Since the operation is |
| # destructive, this macro is generally used twice, with a temporary |
| # macro name holding the swapped copy. |
| m4_define([_m4_stack_reverse], |
| [m4_ifdef([$1], [m4_pushdef([$2], |
| _m4_defn([$1]))$3[]_m4_popdef([$1])$0([$1], [$2], [$4$3])])]) |
| |
| |
| |
| ## --------------------------- ## |
| ## 9. More diversion support. ## |
| ## --------------------------- ## |
| |
| |
| # m4_cleardivert(DIVERSION-NAME...) |
| # --------------------------------- |
| # Discard any text in DIVERSION-NAME. |
| # |
| # This works even inside m4_expand. |
| m4_define([m4_cleardivert], |
| [m4_if([$#], [0], [m4_fatal([$0: missing argument])], |
| [_m4_divert_raw([-1])m4_undivert($@)_m4_divert_raw( |
| _m4_divert(_m4_defn([_m4_divert_diversion]), [-]))])]) |
| |
| |
| # _m4_divert(DIVERSION-NAME or NUMBER, [NOWARN]) |
| # ---------------------------------------------- |
| # If DIVERSION-NAME is the name of a diversion, return its number, |
| # otherwise if it is a NUMBER return it. Issue a warning about |
| # the use of a number instead of a name, unless NOWARN is provided. |
| m4_define([_m4_divert], |
| [m4_ifdef([_m4_divert($1)], |
| [m4_indir([_m4_divert($1)])], |
| [m4_if([$2], [], [m4_warn([syntax], |
| [prefer named diversions])])$1])]) |
| |
| # KILL is only used to suppress output. |
| m4_define([_m4_divert(KILL)], -1) |
| |
| # The empty diversion name is a synonym for 0. |
| m4_define([_m4_divert()], 0) |
| |
| |
| # m4_divert_stack |
| # --------------- |
| # 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_sep_lifo([_m4_divert_stack], [], [], [ |
| ])]) |
| |
| |
| # 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], m4_location[: $1: $2])]) |
| |
| |
| # m4_divert(DIVERSION-NAME) |
| # ------------------------- |
| # Change the diversion stream to DIVERSION-NAME. |
| m4_define([m4_divert], |
| [m4_popdef([_m4_divert_stack])]dnl |
| [m4_define([_m4_divert_diversion], [$1])]dnl |
| [m4_divert_stack_push([$0], [$1])]dnl |
| [_m4_divert_raw(_m4_divert([$1]))]) |
| |
| |
| # m4_divert_push(DIVERSION-NAME, [NOWARN]) |
| # ---------------------------------------- |
| # Change the diversion stream to DIVERSION-NAME, while stacking old values. |
| # For internal use only: if NOWARN is not empty, DIVERSION-NAME can be a |
| # number instead of a name. |
| m4_define([m4_divert_push], |
| [m4_divert_stack_push([$0], [$1])]dnl |
| [m4_pushdef([_m4_divert_diversion], [$1])]dnl |
| [_m4_divert_raw(_m4_divert([$1], [$2]))]) |
| |
| |
| # 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_if([$1], [], [], |
| [$1], _m4_defn([_m4_divert_diversion]), [], |
| [m4_fatal([$0($1): diversion mismatch: |
| ]m4_divert_stack)])]dnl |
| [_m4_popdef([_m4_divert_stack], [_m4_divert_diversion])]dnl |
| [m4_ifdef([_m4_divert_diversion], [], |
| [m4_fatal([too many m4_divert_pop])])]dnl |
| [_m4_divert_raw(_m4_divert(_m4_defn([_m4_divert_diversion]), [-]))]) |
| |
| |
| # m4_divert_text(DIVERSION-NAME, CONTENT) |
| # --------------------------------------- |
| # Output CONTENT into DIVERSION-NAME (which may be a number actually). |
| # An end of line is appended for free to CONTENT. |
| m4_define([m4_divert_text], |
| [m4_divert_push([$1])$2 |
| m4_divert_pop([$1])]) |
| |
| |
| # m4_divert_once(DIVERSION-NAME, CONTENT) |
| # --------------------------------------- |
| # Output CONTENT into DIVERSION-NAME once, if not already there. |
| # An end of line is appended for free to CONTENT. |
| m4_define([m4_divert_once], |
| [m4_expand_once([m4_divert_text([$1], [$2])])]) |
| |
| |
| # _m4_divert_unsafe(DIVERSION-NAME) |
| # --------------------------------- |
| # Issue a warning that the attempt to change the current diversion to |
| # DIVERSION-NAME is unsafe, because this macro is being expanded |
| # during argument collection of m4_expand. |
| m4_define([_m4_divert_unsafe], |
| [m4_fatal([$0: cannot change diversion to `$1' inside m4_expand])]) |
| |
| |
| # 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_if([$#], [0], [m4_fatal([$0: missing argument])], |
| [$#], [1], [_m4_undivert(_m4_divert([$1]))], |
| [m4_map_args([$0], $@)])]) |
| |
| |
| ## --------------------------------------------- ## |
| ## 10. Defining macros with bells and whistles. ## |
| ## --------------------------------------------- ## |
| |
| # `m4_defun' is basically `m4_define' but it equips the macro with the |
| # needed machinery for `m4_require'. A macro must be m4_defun'd if |
| # either it is m4_require'd, or it m4_require's. |
| # |
| # Two things deserve attention and are detailed below: |
| # 1. Implementation of m4_require |
| # 2. Keeping track of the expansion stack |
| # |
| # 1. Implementation of m4_require |
| # =============================== |
| # |
| # Of course m4_defun calls m4_provide, so that a macro which has |
| # been expanded is not expanded again when m4_require'd, but the |
| # difficult part is the proper expansion of macros when they are |
| # m4_require'd. |
| # |
| # The implementation is based on three ideas, (i) using diversions to |
| # prepare the expansion of the macro and its dependencies (by Franc,ois |
| # Pinard), (ii) expand the most recently m4_require'd macros _after_ |
| # the previous macros (by Axel Thimm), and (iii) track instances of |
| # provide before require (by Eric Blake). |
| # |
| # |
| # The first idea: why use diversions? |
| # ----------------------------------- |
| # |
| # When a macro requires another, the other macro is expanded in new |
| # diversion, GROW. When the outer macro is fully expanded, we first |
| # undivert the most nested diversions (GROW - 1...), and finally |
| # undivert GROW. To understand why we need several diversions, |
| # consider the following example: |
| # |
| # | m4_defun([TEST1], [Test...m4_require([TEST2])1]) |
| # | m4_defun([TEST2], [Test...m4_require([TEST3])2]) |
| # | m4_defun([TEST3], [Test...3]) |
| # |
| # Because m4_require is not required to be first in the outer macros, we |
| # must keep the expansions of the various levels of m4_require separated. |
| # Right before executing the epilogue of TEST1, we have: |
| # |
| # GROW - 2: Test...3 |
| # GROW - 1: Test...2 |
| # GROW: Test...1 |
| # BODY: |
| # |
| # Finally the epilogue of TEST1 undiverts GROW - 2, GROW - 1, and |
| # GROW into the regular flow, BODY. |
| # |
| # GROW - 2: |
| # GROW - 1: |
| # GROW: |
| # BODY: Test...3; Test...2; Test...1 |
| # |
| # (The semicolons are here for clarification, but of course are not |
| # emitted.) This is what Autoconf 2.0 (I think) to 2.13 (I'm sure) |
| # implement. |
| # |
| # |
| # The second idea: first required first out |
| # ----------------------------------------- |
| # |
| # The natural implementation of the idea above is buggy and produces |
| # very surprising results in some situations. Let's consider the |
| # following example to explain the bug: |
| # |
| # | m4_defun([TEST1], [m4_require([TEST2a])m4_require([TEST2b])]) |
| # | m4_defun([TEST2a], []) |
| # | m4_defun([TEST2b], [m4_require([TEST3])]) |
| # | m4_defun([TEST3], [m4_require([TEST2a])]) |
| # | |
| # | AC_INIT |
| # | TEST1 |
| # |
| # The dependencies between the macros are: |
| # |
| # 3 --- 2b |
| # / \ is m4_require'd by |
| # / \ left -------------------- right |
| # 2a ------------ 1 |
| # |
| # If you strictly apply the rules given in the previous section you get: |
| # |
| # GROW - 2: TEST3 |
| # GROW - 1: TEST2a; TEST2b |
| # GROW: TEST1 |
| # BODY: |
| # |
| # (TEST2a, although required by TEST3 is not expanded in GROW - 3 |
| # because is has already been expanded before in GROW - 1, so it has |
| # been AC_PROVIDE'd, so it is not expanded again) so when you undivert |
| # the stack of diversions, you get: |
| # |
| # GROW - 2: |
| # GROW - 1: |
| # GROW: |
| # BODY: TEST3; TEST2a; TEST2b; TEST1 |
| # |
| # i.e., TEST2a is expanded after TEST3 although the latter required the |
| # former. |
| # |
| # Starting from 2.50, we use an implementation provided by Axel Thimm. |
| # The idea is simple: the order in which macros are emitted must be the |
| # same as the one in which macros are expanded. (The bug above can |
| # indeed be described as: a macro has been m4_provide'd before its |
| # dependent, but it is emitted after: the lack of correlation between |
| # emission and expansion order is guilty). |
| # |
| # How to do that? You keep the stack of diversions to elaborate the |
| # macros, but each time a macro is fully expanded, emit it immediately. |
| # |
| # In the example above, when TEST2a is expanded, but it's epilogue is |
| # not run yet, you have: |
| # |
| # GROW - 2: |
| # GROW - 1: TEST2a |
| # GROW: Elaboration of TEST1 |
| # BODY: |
| # |
| # The epilogue of TEST2a emits it immediately: |
| # |
| # GROW - 2: |
| # GROW - 1: |
| # GROW: Elaboration of TEST1 |
| # BODY: TEST2a |
| # |
| # TEST2b then requires TEST3, so right before the epilogue of TEST3, you |
| # have: |
| # |
| # GROW - 2: TEST3 |
| # GROW - 1: Elaboration of TEST2b |
| # GROW: Elaboration of TEST1 |
| # BODY: TEST2a |
| # |
| # The epilogue of TEST3 emits it: |
| # |
| # GROW - 2: |
| # GROW - 1: Elaboration of TEST2b |
| # GROW: Elaboration of TEST1 |
| # BODY: TEST2a; TEST3 |
| # |
| # TEST2b is now completely expanded, and emitted: |
| # |
| # GROW - 2: |
| # GROW - 1: |
| # GROW: Elaboration of TEST1 |
| # BODY: TEST2a; TEST3; TEST2b |
| # |
| # and finally, TEST1 is finished and emitted: |
| # |
| # GROW - 2: |
| # GROW - 1: |
| # GROW: |
| # BODY: TEST2a; TEST3; TEST2b: TEST1 |
| # |
| # The idea is simple, but the implementation is a bit involved. If |
| # you are like me, you will want to see the actual functioning of this |
| # implementation to be convinced. The next section gives the full |
| # details. |
| # |
| # |
| # The Axel Thimm implementation at work |
| # ------------------------------------- |
| # |
| # We consider the macros above, and this configure.ac: |
| # |
| # AC_INIT |
| # TEST1 |
| # |
| # You should keep the definitions of _m4_defun_pro, _m4_defun_epi, and |
| # m4_require at hand to follow the steps. |
| # |
| # This implementation tries not to assume that the current diversion is |
| # BODY, so as soon as a macro (m4_defun'd) is expanded, we first |
| # record the current diversion under the name _m4_divert_dump (denoted |
| # DUMP below for short). This introduces an important difference with |
| # the previous versions of Autoconf: you cannot use m4_require if you |
| # are not inside an m4_defun'd macro, and especially, you cannot |
| # m4_require directly from the top level. |
| # |
| # We have not tried to simulate the old behavior (better yet, we |
| # diagnose it), because it is too dangerous: a macro m4_require'd from |
| # the top level is expanded before the body of `configure', i.e., before |
| # any other test was run. I let you imagine the result of requiring |
| # AC_STDC_HEADERS for instance, before AC_PROG_CC was actually run.... |
| # |
| # After AC_INIT was run, the current diversion is BODY. |
| # * AC_INIT was run |
| # DUMP: undefined |
| # diversion stack: BODY |- |
| # |
| # * TEST1 is expanded |
| # The prologue of TEST1 sets _m4_divert_dump, which is the diversion |
| # where the current elaboration will be dumped, to the current |
| # diversion. It also m4_divert_push to GROW, where the full |
| # expansion of TEST1 and its dependencies will be elaborated. |
| # DUMP: BODY |
| # BODY: empty |
| # diversions: GROW, BODY |- |
| # |
| # * TEST1 requires TEST2a |
| # _m4_require_call m4_divert_pushes another temporary diversion, |
| # GROW - 1, and expands TEST2a in there. |
| # DUMP: BODY |
| # BODY: empty |
| # GROW - 1: TEST2a |
| # diversions: GROW - 1, GROW, BODY |- |
| # Then the content of the temporary diversion is moved to DUMP and the |
| # temporary diversion is popped. |
| # DUMP: BODY |
| # BODY: TEST2a |
| # diversions: GROW, BODY |- |
| # |
| # * TEST1 requires TEST2b |
| # Again, _m4_require_call pushes GROW - 1 and heads to expand TEST2b. |
| # DUMP: BODY |
| # BODY: TEST2a |
| # diversions: GROW - 1, GROW, BODY |- |
| # |
| # * TEST2b requires TEST3 |
| # _m4_require_call pushes GROW - 2 and expands TEST3 here. |
| # (TEST3 requires TEST2a, but TEST2a has already been m4_provide'd, so |
| # nothing happens.) |
| # DUMP: BODY |
| # BODY: TEST2a |
| # GROW - 2: TEST3 |
| # diversions: GROW - 2, GROW - 1, GROW, BODY |- |
| # Then the diversion is appended to DUMP, and popped. |
| # DUMP: BODY |
| # BODY: TEST2a; TEST3 |
| # diversions: GROW - 1, GROW, BODY |- |
| # |
| # * TEST1 requires TEST2b (contd.) |
| # The content of TEST2b is expanded... |
| # DUMP: BODY |
| # BODY: TEST2a; TEST3 |
| # GROW - 1: TEST2b, |
| # diversions: GROW - 1, GROW, BODY |- |
| # ... and moved to DUMP. |
| # DUMP: BODY |
| # BODY: TEST2a; TEST3; TEST2b |
| # diversions: GROW, BODY |- |
| # |
| # * TEST1 is expanded: epilogue |
| # TEST1's own content is in GROW... |
| # DUMP: BODY |
| # BODY: TEST2a; TEST3; TEST2b |
| # GROW: TEST1 |
| # diversions: BODY |- |
| # ... and it's epilogue moves it to DUMP and then undefines DUMP. |
| # DUMP: undefined |
| # BODY: TEST2a; TEST3; TEST2b; TEST1 |
| # diversions: BODY |- |
| # |
| # |
| # The third idea: track macros provided before they were required |
| # --------------------------------------------------------------- |
| # |
| # Using just the first two ideas, Autoconf 2.50 through 2.63 still had |
| # a subtle bug for more than seven years. Let's consider the |
| # following example to explain the bug: |
| # |
| # | m4_defun([TEST1], [1]) |
| # | m4_defun([TEST2], [2[]m4_require([TEST1])]) |
| # | m4_defun([TEST3], [3 TEST1 m4_require([TEST2])]) |
| # | TEST3 |
| # |
| # After the prologue of TEST3, we are collecting text in GROW with the |
| # intent of dumping it in BODY during the epilogue. Next, we |
| # encounter the direct invocation of TEST1, which provides the macro |
| # in place in GROW. From there, we encounter a requirement for TEST2, |
| # which must be collected in a new diversion. While expanding TEST2, |
| # we encounter a requirement for TEST1, but since it has already been |
| # expanded, the Axel Thimm algorithm states that we can treat it as a |
| # no-op. But that would lead to an end result of `2 3 1', meaning |
| # that we have once again output a macro (TEST2) prior to its |
| # requirements (TEST1). |
| # |
| # The problem can only occur if a single defun'd macro first provides, |
| # then later indirectly requires, the same macro. Note that directly |
| # expanding then requiring a macro is okay: because the dependency was |
| # met, the require phase can be a no-op. For that matter, the outer |
| # macro can even require two helpers, where the first helper expands |
| # the macro, and the second helper indirectly requires the macro. |
| # Out-of-order expansion is only present if the inner macro is |
| # required by something that will be hoisted in front of where the |
| # direct expansion occurred. In other words, we must be careful not |
| # to warn on: |
| # |
| # | m4_defun([TEST4], [4]) |
| # | m4_defun([TEST5], [5 TEST4 m4_require([TEST4])]) |
| # | TEST5 => 5 4 |
| # |
| # or even the more complex: |
| # |
| # | m4_defun([TEST6], [6]) |
| # | m4_defun([TEST7], [7 TEST6]) |
| # | m4_defun([TEST8], [8 m4_require([TEST6])]) |
| # | m4_defun([TEST9], [9 m4_require([TEST8])]) |
| # | m4_defun([TEST10], [10 m4_require([TEST7]) m4_require([TEST9])]) |
| # | TEST10 => 7 6 8 9 10 |
| # |
| # So, to detect whether a require was direct or indirect, m4_defun and |
| # m4_require track the name of the macro that caused a diversion to be |
| # created (using the stack _m4_diverting, coupled with an O(1) lookup |
| # _m4_diverting([NAME])), and m4_provide stores the name associated |
| # with the diversion at which a macro was provided. A require call is |
| # direct if it occurs within the same diversion where the macro was |
| # provided, or if the diversion associated with the providing context |
| # has been collected. |
| # |
| # The implementation of the warning involves tracking the set of |
| # macros which have been provided since the start of the outermost |
| # defun'd macro (the set is named _m4_provide). When starting an |
| # outermost macro, the set is emptied; when a macro is provided, it is |
| # added to the set; when require expands the body of a macro, it is |
| # removed from the set; and when a macro is indirectly required, the |
| # set is checked. If a macro is in the set, then it has been provided |
| # before it was required, and we satisfy dependencies by expanding the |
| # macro as if it had never been provided; in the example given above, |
| # this means we now output `1 2 3 1'. Meanwhile, a warning is issued |
| # to inform the user that her macros trigger the bug in older autoconf |
| # versions, and that her output file now contains redundant contents |
| # (and possibly new problems, if the repeated macro was not |
| # idempotent). Meanwhile, macros defined by m4_defun_once instead of |
| # m4_defun are idempotent, avoiding any warning or duplicate output. |
| # |
| # |
| # 2. Keeping track of the expansion stack |
| # ======================================= |
| # |
| # When M4 expansion goes wrong it is often extremely hard to find the |
| # path amongst macros that drove to the failure. What is needed is |
| # the stack of macro `calls'. One could imagine that GNU M4 would |
| # maintain a stack of macro expansions, unfortunately it doesn't, so |
| # we do it by hand. This is of course extremely costly, but the help |
| # this stack provides is worth it. Nevertheless to limit the |
| # performance penalty this is implemented only for m4_defun'd macros, |
| # not for define'd macros. |
| # |
| # Each time we enter an m4_defun'd macros, we add a definition in |
| # _m4_expansion_stack, and when we exit the macro, we remove it (thanks |
| # to pushdef/popdef). m4_stack_foreach is used to print the expansion |
| # stack in the rare cases when it's needed. |
| # |
| # In addition, we want to detect circular m4_require dependencies. |
| # Each time we expand a macro FOO we define _m4_expanding(FOO); and |
| # m4_require(BAR) simply checks whether _m4_expanding(BAR) is defined. |
| |
| |
| # m4_expansion_stack |
| # ------------------ |
| # Expands to the entire contents of the expansion stack. The caller |
| # must supply a trailing newline. This macro always prints a |
| # location; check whether _m4_expansion_stack is defined to filter out |
| # the case when no defun'd macro is in force. |
| m4_define([m4_expansion_stack], |
| [m4_stack_foreach_sep_lifo([_$0], [_$0_entry(], [) |
| ])m4_location[: the top level]]) |
| |
| # _m4_expansion_stack_entry(MACRO) |
| # -------------------------------- |
| # Format an entry for MACRO found on the expansion stack. |
| m4_define([_m4_expansion_stack_entry], |
| [_m4_defn([m4_location($1)])[: $1 is expanded from...]]) |
| |
| # m4_expansion_stack_push(MACRO) |
| # ------------------------------ |
| # Form an entry of the expansion stack on entry to MACRO and push it. |
| m4_define([m4_expansion_stack_push], |
| [m4_pushdef([_m4_expansion_stack], [$1])]) |
| |
| |
| # _m4_divert(GROW) |
| # ---------------- |
| # This diversion is used by the m4_defun/m4_require machinery. It is |
| # important to keep room before GROW because for each nested |
| # AC_REQUIRE we use an additional diversion (i.e., two m4_require's |
| # will use GROW - 2. More than 3 levels has never seemed to be |
| # needed.) |
| # |
| # ... |
| # - GROW - 2 |
| # m4_require'd code, 2 level deep |
| # - GROW - 1 |
| # m4_require'd code, 1 level deep |
| # - GROW |
| # m4_defun'd macros are elaborated here. |
| |
| m4_define([_m4_divert(GROW)], 10000) |
| |
| |
| # _m4_defun_pro(MACRO-NAME) |
| # ------------------------- |
| # The prologue for Autoconf macros. |
| # |
| # This is called frequently, so minimize the number of macro invocations |
| # by avoiding dnl and m4_defn overhead. |
| m4_define([_m4_defun_pro], |
| [m4_ifdef([_m4_expansion_stack], [], [_m4_defun_pro_outer([$1])])]dnl |
| [m4_expansion_stack_push([$1])m4_pushdef([_m4_expanding($1)])]) |
| |
| m4_define([_m4_defun_pro_outer], |
| [m4_set_delete([_m4_provide])]dnl |
| [m4_pushdef([_m4_diverting([$1])])m4_pushdef([_m4_diverting], [$1])]dnl |
| [m4_pushdef([_m4_divert_dump], m4_divnum)m4_divert_push([GROW])]) |
| |
| # _m4_defun_epi(MACRO-NAME) |
| # ------------------------- |
| # The Epilogue for Autoconf macros. MACRO-NAME only helps tracing |
| # the PRO/EPI pairs. |
| # |
| # This is called frequently, so minimize the number of macro invocations |
| # by avoiding dnl and m4_popdef overhead. |
| m4_define([_m4_defun_epi], |
| [_m4_popdef([_m4_expanding($1)], [_m4_expansion_stack])]dnl |
| [m4_ifdef([_m4_expansion_stack], [], [_m4_defun_epi_outer([$1])])]dnl |
| [m4_provide([$1])]) |
| |
| m4_define([_m4_defun_epi_outer], |
| [_m4_popdef([_m4_divert_dump], [_m4_diverting([$1])], [_m4_diverting])]dnl |
| [m4_divert_pop([GROW])m4_undivert([GROW])]) |
| |
| |
| # _m4_divert_dump |
| # --------------- |
| # If blank, we are outside of any defun'd macro. Otherwise, expands |
| # to the diversion number (not name) where require'd macros should be |
| # moved once completed. |
| m4_define([_m4_divert_dump]) |
| |
| |
| # 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_if(_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], _m4_divert([$1], [-]))])]) |
| |
| |
| # m4_defun(NAME, EXPANSION, [MACRO = m4_define]) |
| # ---------------------------------------------- |
| # Define a macro NAME which automatically provides itself. Add |
| # machinery so the macro automatically switches expansion to the |
| # diversion stack if it is not already using it, prior to EXPANSION. |
| # In this case, once finished, it will bring back all the code |
| # accumulated in the diversion stack. This, combined with m4_require, |
| # achieves the topological ordering of macros. We don't use this |
| # macro to define some frequently called macros that are not involved |
| # in ordering constraints, to save m4 processing. |
| # |
| # MACRO is an undocumented argument; when set to m4_pushdef, and NAME |
| # is already defined, the new definition is added to the pushdef |
| # stack, rather than overwriting the current definition. It can thus |
| # be used to write self-modifying macros, which pop themselves to a |
| # previously m4_define'd definition so that subsequent use of the |
| # macro is faster. |
| m4_define([m4_defun], |
| [m4_define([m4_location($1)], m4_location)]dnl |
| [m4_default([$3], [m4_define])([$1], |
| [_m4_defun_pro(]m4_dquote($[0])[)$2[]_m4_defun_epi(]m4_dquote($[0])[)])]) |
| |
| |
| # m4_defun_init(NAME, INIT, COMMON) |
| # --------------------------------- |
| # Like m4_defun, but split EXPANSION into two portions: INIT which is |
| # done only the first time NAME is invoked, and COMMON which is |
| # expanded every time. |
| # |
| # For now, the COMMON definition is always m4_define'd, giving an even |
| # lighter-weight definition. m4_defun allows self-providing, but once |
| # a macro is provided, m4_require no longer cares if it is m4_define'd |
| # or m4_defun'd. m4_defun also provides location tracking to identify |
| # dependency bugs, but once the INIT has been expanded, we know there |
| # are no dependency bugs. However, if a future use needs COMMON to be |
| # m4_defun'd, we can add a parameter, similar to the third parameter |
| # to m4_defun. |
| m4_define([m4_defun_init], |
| [m4_define([$1], [$3[]])m4_defun([$1], |
| [$2[]_m4_popdef(]m4_dquote($[0])[)m4_indir(]m4_dquote($[0])dnl |
| [m4_if(]m4_dquote($[#])[, [0], [], ]m4_dquote([,$]@)[))], [m4_pushdef])]) |
| |
| |
| # m4_defun_once(NAME, EXPANSION) |
| # ------------------------------ |
| # Like m4_defun, but guarantee that EXPANSION only happens once |
| # (thereafter, using NAME is a no-op). |
| # |
| # If _m4_divert_dump is empty, we are called at the top level; |
| # otherwise, we must ensure that we are required in front of the |
| # current defun'd macro. Use a helper macro so that EXPANSION need |
| # only occur once in the definition of NAME, since it might be large. |
| m4_define([m4_defun_once], |
| [m4_define([m4_location($1)], m4_location)]dnl |
| [m4_define([$1], [_m4_defun_once([$1], [$2], m4_if(_m4_divert_dump, [], |
| [[_m4_defun_pro([$1])m4_unquote(], [)_m4_defun_epi([$1])]], |
| m4_ifdef([_m4_diverting([$1])], [-]), [-], [[m4_unquote(], [)]], |
| [[_m4_require_call([$1],], [, _m4_divert_dump)]]))])]) |
| |
| m4_define([_m4_defun_once], |
| [m4_pushdef([$1])$3[$2[]m4_provide([$1])]$4]) |
| |
| |
| # m4_pattern_forbid(ERE, [WHY]) |
| # ----------------------------- |
| # Declare that no token matching the forbidden extended regular |
| # expression ERE should be seen in the output unless... |
| m4_define([m4_pattern_forbid], []) |
| |
| |
| # m4_pattern_allow(ERE) |
| # --------------------- |
| # ... that token also matches the allowed extended regular expression ERE. |
| # Both used via traces. |
| m4_define([m4_pattern_allow], []) |
| |
| |
| ## --------------------------------- ## |
| ## 11. Dependencies between macros. ## |
| ## --------------------------------- ## |
| |
| |
| # m4_before(THIS-MACRO-NAME, CALLED-MACRO-NAME) |
| # --------------------------------------------- |
| # Issue a warning if CALLED-MACRO-NAME was called before THIS-MACRO-NAME. |
| m4_define([m4_before], |
| [m4_provide_if([$2], |
| [m4_warn([syntax], [$2 was called before $1])])]) |
| |
| |
| # m4_require(NAME-TO-CHECK, [BODY-TO-EXPAND = NAME-TO-CHECK]) |
| # ----------------------------------------------------------- |
| # If NAME-TO-CHECK has never been expanded (actually, if it is not |
| # m4_provide'd), expand BODY-TO-EXPAND *before* the current macro |
| # expansion; follow the expansion with a newline. Once expanded, emit |
| # it in _m4_divert_dump. Keep track of the m4_require chain in |
| # _m4_expansion_stack. |
| # |
| # The normal cases are: |
| # |
| # - NAME-TO-CHECK == BODY-TO-EXPAND |
| # Which you can use for regular macros with or without arguments, e.g., |
| # m4_require([AC_PROG_CC], [AC_PROG_CC]) |
| # m4_require([AC_CHECK_HEADERS(threads.h)], [AC_CHECK_HEADERS(threads.h)]) |
| # which is just the same as |
| # m4_require([AC_PROG_CC]) |
| # m4_require([AC_CHECK_HEADERS(threads.h)]) |
| # |
| # - BODY-TO-EXPAND == m4_indir([NAME-TO-CHECK]) |
| # In the case of macros with irregular names. For instance: |
| # m4_require([AC_LANG_COMPILER(C)], [indir([AC_LANG_COMPILER(C)])]) |
| # which means `if the macro named `AC_LANG_COMPILER(C)' (the parens are |
| # part of the name, it is not an argument) has not been run, then |
| # call it.' |
| # Had you used |
| # m4_require([AC_LANG_COMPILER(C)], [AC_LANG_COMPILER(C)]) |
| # then m4_require would have tried to expand `AC_LANG_COMPILER(C)', i.e., |
| # call the macro `AC_LANG_COMPILER' with `C' as argument. |
| # |
| # You could argue that `AC_LANG_COMPILER', when it receives an argument |
| # such as `C' should dispatch the call to `AC_LANG_COMPILER(C)'. But this |
| # `extension' prevents `AC_LANG_COMPILER' from having actual arguments that |
| # it passes to `AC_LANG_COMPILER(C)'. |
| # |
| # This is called frequently, so minimize the number of macro invocations |
| # by avoiding dnl and other overhead on the common path. |
| m4_define([m4_require], |
| [m4_ifdef([_m4_expanding($1)], |
| [m4_fatal([$0: circular dependency of $1])])]dnl |
| [m4_if(_m4_divert_dump, [], |
| [m4_fatal([$0($1): cannot be used outside of an ]dnl |
| m4_if([$0], [m4_require], [[m4_defun]], [[AC_DEFUN]])['d macro])])]dnl |
| [m4_provide_if([$1], [m4_set_contains([_m4_provide], [$1], |
| [_m4_require_check([$1], _m4_defn([m4_provide($1)]), [$0])], [m4_ignore])], |
| [_m4_require_call])([$1], [$2], _m4_divert_dump)]) |
| |
| |
| # _m4_require_call(NAME-TO-CHECK, [BODY-TO-EXPAND = NAME-TO-CHECK], |
| # DIVERSION-NUMBER) |
| # ----------------------------------------------------------------- |
| # If m4_require decides to expand the body, it calls this macro. The |
| # expansion is placed in DIVERSION-NUMBER. |
| # |
| # This is called frequently, so minimize the number of macro invocations |
| # by avoiding dnl and other overhead on the common path. |
| m4_define([_m4_require_call], |
| [m4_pushdef([_m4_divert_grow], m4_decr(_m4_divert_grow))]dnl |
| [m4_pushdef([_m4_diverting([$1])])m4_pushdef([_m4_diverting], [$1])]dnl |
| [m4_divert_push(_m4_divert_grow, [-])]dnl |
| [m4_if([$2], [], [$1], [$2]) |
| m4_provide_if([$1], [m4_set_remove([_m4_provide], [$1])], |
| [m4_warn([syntax], [$1 is m4_require'd but not m4_defun'd])])]dnl |
| [_m4_divert_raw($3)_m4_undivert(_m4_divert_grow)]dnl |
| [m4_divert_pop(_m4_divert_grow)_m4_popdef([_m4_divert_grow], |
| [_m4_diverting([$1])], [_m4_diverting])]) |
| |
| |
| # _m4_require_check(NAME-TO-CHECK, OWNER, CALLER) |
| # ----------------------------------------------- |
| # NAME-TO-CHECK has been identified as previously expanded in the |
| # diversion owned by OWNER. If this is a problem, warn on behalf of |
| # CALLER and return _m4_require_call; otherwise return m4_ignore. |
| m4_define([_m4_require_check], |
| [m4_if(_m4_defn([_m4_diverting]), [$2], [m4_ignore], |
| m4_ifdef([_m4_diverting([$2])], [-]), [-], [m4_warn([syntax], |
| [$3: `$1' was expanded before it was required |
| http://www.gnu.org/software/autoconf/manual/autoconf.html#Expanded-Before-Required])_m4_require_call], |
| [m4_ignore])]) |
| |
| |
| # _m4_divert_grow |
| # --------------- |
| # The counter for _m4_require_call. |
| m4_define([_m4_divert_grow], _m4_divert([GROW])) |
| |
| |
| # m4_expand_once(TEXT, [WITNESS = TEXT]) |
| # -------------------------------------- |
| # If TEXT has never been expanded, expand it *here*. Use WITNESS as |
| # as a memory that TEXT has already been expanded. |
| m4_define([m4_expand_once], |
| [m4_provide_if(m4_default_quoted([$2], [$1]), |
| [], |
| [m4_provide(m4_default_quoted([$2], [$1]))[]$1])]) |
| |
| |
| # m4_provide(MACRO-NAME) |
| # ---------------------- |
| m4_define([m4_provide], |
| [m4_ifdef([m4_provide($1)], [], |
| [m4_set_add([_m4_provide], [$1], [m4_define([m4_provide($1)], |
| m4_ifdef([_m4_diverting], [_m4_defn([_m4_diverting])]))])])]) |
| |
| |
| # m4_provide_if(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) |
| # ------------------------------------------------------- |
| # If MACRO-NAME is provided do IF-PROVIDED, else IF-NOT-PROVIDED. |
| # The purpose of this macro is to provide the user with a means to |
| # check macros which are provided without letting her know how the |
| # information is coded. |
| m4_define([m4_provide_if], |
| [m4_ifdef([m4_provide($1)], |
| [$2], [$3])]) |
| |
| |
| ## --------------------- ## |
| ## 12. Text processing. ## |
| ## --------------------- ## |
| |
| |
| # m4_cr_letters |
| # m4_cr_LETTERS |
| # m4_cr_Letters |
| # ------------- |
| m4_define([m4_cr_letters], [abcdefghijklmnopqrstuvwxyz]) |
| m4_define([m4_cr_LETTERS], [ABCDEFGHIJKLMNOPQRSTUVWXYZ]) |
| m4_define([m4_cr_Letters], |
| m4_defn([m4_cr_letters])dnl |
| m4_defn([m4_cr_LETTERS])dnl |
| ) |
| |
| |
| # m4_cr_digits |
| # ------------ |
| m4_define([m4_cr_digits], [0123456789]) |
| |
| |
| # m4_cr_alnum |
| # ----------- |
| m4_define([m4_cr_alnum], |
| m4_defn([m4_cr_Letters])dnl |
| m4_defn([m4_cr_digits])dnl |
| ) |
| |
| |
| # m4_cr_symbols1 |
| # m4_cr_symbols2 |
| # -------------- |
| m4_define([m4_cr_symbols1], |
| m4_defn([m4_cr_Letters])dnl |
| _) |
| |
| m4_define([m4_cr_symbols2], |
| m4_defn([m4_cr_symbols1])dnl |
| m4_defn([m4_cr_digits])dnl |
| ) |
| |
| # m4_cr_all |
| # --------- |
| # The character range representing everything, with `-' as the last |
| # character, since it is special to m4_translit. Use with care, because |
| # it contains characters special to M4 (fortunately, both ASCII and EBCDIC |
| # have [] in order, so m4_defn([m4_cr_all]) remains a valid string). It |
| # also contains characters special to terminals, so it should never be |
| # displayed in an error message. Also, attempts to map [ and ] to other |
| # characters via m4_translit must deal with the fact that m4_translit does |
| # not add quotes to the output. |
| # |
| # In EBCDIC, $ is immediately followed by *, which leads to problems |
| # if m4_cr_all is inlined into a macro definition; so swap them. |
| # |
| # It is mainly useful in generating inverted character range maps, for use |
| # in places where m4_translit is faster than an equivalent m4_bpatsubst; |
| # the regex `[^a-z]' is equivalent to: |
| # m4_translit(m4_dquote(m4_defn([m4_cr_all])), [a-z]) |
| m4_define([m4_cr_all], |
| m4_translit(m4_dquote(m4_format(m4_dquote(m4_for( |
| ,1,255,,[[%c]]))m4_for([i],1,255,,[,i]))), [$*-], [*$])-) |
| |
| |
| # _m4_define_cr_not(CATEGORY) |
| # --------------------------- |
| # Define m4_cr_not_CATEGORY as the inverse of m4_cr_CATEGORY. |
| m4_define([_m4_define_cr_not], |
| [m4_define([m4_cr_not_$1], |
| m4_translit(m4_dquote(m4_defn([m4_cr_all])), |
| m4_defn([m4_cr_$1])))]) |
| |
| |
| # m4_cr_not_letters |
| # m4_cr_not_LETTERS |
| # m4_cr_not_Letters |
| # m4_cr_not_digits |
| # m4_cr_not_alnum |
| # m4_cr_not_symbols1 |
| # m4_cr_not_symbols2 |
| # ------------------ |
| # Inverse character sets |
| _m4_define_cr_not([letters]) |
| _m4_define_cr_not([LETTERS]) |
| _m4_define_cr_not([Letters]) |
| _m4_define_cr_not([digits]) |
| _m4_define_cr_not([alnum]) |
| _m4_define_cr_not([symbols1]) |
| _m4_define_cr_not([symbols2]) |
| |
| |
| # m4_newline([STRING]) |
| # -------------------- |
| # Expands to a newline, possibly followed by STRING. Exists mostly for |
| # formatting reasons. |
| m4_define([m4_newline], [ |
| $1]) |
| |
| |
| # m4_re_escape(STRING) |
| # -------------------- |
| # Escape RE active characters in STRING. |
| m4_define([m4_re_escape], |
| [m4_bpatsubst([$1], |
| [[][*+.?\^$]], [\\\&])]) |
| |
| |
| # m4_re_string |
| # ------------ |
| # Regexp for `[a-zA-Z_0-9]*' |
| # m4_dquote provides literal [] for the character class. |
| m4_define([m4_re_string], |
| m4_dquote(m4_defn([m4_cr_symbols2]))dnl |
| [*]dnl |
| ) |
| |
| |
| # m4_re_word |
| # ---------- |
| # Regexp for `[a-zA-Z_][a-zA-Z_0-9]*' |
| m4_define([m4_re_word], |
| m4_dquote(m4_defn([m4_cr_symbols1]))dnl |
| m4_defn([m4_re_string])dnl |
| ) |
| |
| |
| # m4_tolower(STRING) |
| # m4_toupper(STRING) |
| # ------------------ |
| # These macros convert STRING to lowercase or uppercase. |
| # |
| # Rather than expand the m4_defn each time, we inline them up front. |
| m4_define([m4_tolower], |
| [m4_translit([[$1]], ]m4_dquote(m4_defn([m4_cr_LETTERS]))[, |
| ]m4_dquote(m4_defn([m4_cr_letters]))[)]) |
| m4_define([m4_toupper], |
| [m4_translit([[$1]], ]m4_dquote(m4_defn([m4_cr_letters]))[, |
| ]m4_dquote(m4_defn([m4_cr_LETTERS]))[)]) |
| |
| |
| # m4_split(STRING, [REGEXP]) |
| # -------------------------- |
| # Split STRING into an m4 list of quoted elements. The elements are |
| # quoted with [ and ]. Beginning spaces and end spaces *are kept*. |
| # Use m4_strip to remove them. |
| # |
| # REGEXP specifies where to split. Default is [\t ]+. |
| # |
| # If STRING is empty, the result is an empty list. |
| # |
| # Pay attention to the m4_changequotes. When m4 reads the definition of |
| # m4_split, it still has quotes set to [ and ]. Luckily, these are matched |
| # in the macro body, so the definition is stored correctly. Use the same |
| # alternate quotes as m4_noquote; it must be unlikely to appear in $1. |
| # |
| # Also, notice that $1 is quoted twice, since we want the result to |
| # be quoted. Then you should understand that the argument of |
| # patsubst is -=<{(STRING)}>=- (i.e., with additional -=<{( and )}>=-). |
| # |
| # This macro is safe on active symbols, i.e.: |
| # m4_define(active, ACTIVE) |
| # m4_split([active active ])end |
| # => [active], [active], []end |
| # |
| # Optimize on regex of ` ' (space), since m4_foreach_w already guarantees |
| # that the list contains single space separators, and a common case is |
| # splitting a single-element list. This macro is called frequently, |
| # so avoid unnecessary dnl inside the definition. |
| m4_define([m4_split], |
| [m4_if([$1], [], [], |
| [$2], [ ], [m4_if(m4_index([$1], [ ]), [-1], [[[$1]]], |
| [_$0([$1], [$2], [, ])])], |
| [$2], [], [_$0([$1], [[ ]+], [, ])], |
| [_$0([$1], [$2], [, ])])]) |
| |
| m4_define([_m4_split], |
| [m4_changequote([-=<{(],[)}>=-])]dnl |
| [[m4_bpatsubst(-=<{(-=<{($1)}>=-)}>=-, -=<{($2)}>=-, |
| -=<{(]$3[)}>=-)]m4_changequote([, ])]) |
| |
| |
| # m4_chomp(STRING) |
| # m4_chomp_all(STRING) |
| # -------------------- |
| # Return STRING quoted, but without a trailing newline. m4_chomp |
| # removes at most one newline, while m4_chomp_all removes all |
| # consecutive trailing newlines. Embedded newlines are not touched, |
| # and a trailing backslash-newline leaves just a trailing backslash. |
| # |
| # m4_bregexp is slower than m4_index, and we don't always want to |
| # remove all newlines; hence the two variants. We massage characters |
| # to give a nicer pattern to match, particularly since m4_bregexp is |
| # line-oriented. Both versions must guarantee a match, to avoid bugs |
| # with precision -1 in m4_format in older m4. |
| m4_define([m4_chomp], |
| [m4_format([[%.*s]], m4_index(m4_translit([[$1]], [ |
| /.], [/ ])[./.], [/.]), [$1])]) |
| |
| m4_define([m4_chomp_all], |
| [m4_format([[%.*s]], m4_bregexp(m4_translit([[$1]], [ |
| /], [/ ]), [/*$]), [$1])]) |
| |
| |
| # m4_flatten(STRING) |
| # ------------------ |
| # If STRING contains end of lines, replace them with spaces. If there |
| # are backslashed end of lines, remove them. This macro is safe with |
| # active symbols. |
| # m4_define(active, ACTIVE) |
| # m4_flatten([active |
| # act\ |
| # ive])end |
| # => active activeend |
| # |
| # In m4, m4_bpatsubst is expensive, so first check for a newline. |
| m4_define([m4_flatten], |
| [m4_if(m4_index([$1], [ |
| ]), [-1], [[$1]], |
| [m4_translit(m4_bpatsubst([[[$1]]], [\\ |
| ]), [ |
| ], [ ])])]) |
| |
| |
| # m4_strip(STRING) |
| # ---------------- |
| # Expands into STRING with tabs and spaces singled out into a single |
| # space, and removing leading and trailing spaces. |
| # |
| # This macro is robust to active symbols. |
| # m4_define(active, ACTIVE) |
| # m4_strip([ active <tab> <tab>active ])end |
| # => active activeend |
| # |
| # First, notice that we guarantee trailing space. Why? Because regular |
| # expressions are greedy, and `.* ?' would always group the space into the |
| # .* portion. The algorithm is simpler by avoiding `?' at the end. The |
| # algorithm correctly strips everything if STRING is just ` '. |
| # |
| # Then notice the second pattern: it is in charge of removing the |
| # leading/trailing spaces. Why not just `[^ ]'? Because they are |
| # applied to over-quoted strings, i.e. more or less [STRING], due |
| # to the limitations of m4_bpatsubsts. So the leading space in STRING |
| # is the *second* character; equally for the trailing space. |
| m4_define([m4_strip], |
| [m4_bpatsubsts([$1 ], |
| [[ ]+], [ ], |
| [^. ?\(.*\) .$], [[[\1]]])]) |
| |
| |
| # m4_normalize(STRING) |
| # -------------------- |
| # Apply m4_flatten and m4_strip to STRING. |
| # |
| # The argument is quoted, so that the macro is robust to active symbols: |
| # |
| # m4_define(active, ACTIVE) |
| # m4_normalize([ act\ |
| # ive |
| # active ])end |
| # => active activeend |
| |
| m4_define([m4_normalize], |
| [m4_strip(m4_flatten([$1]))]) |
| |
| |
| |
| # m4_join(SEP, ARG1, ARG2...) |
| # --------------------------- |
| # Produce ARG1SEPARG2...SEPARGn. Avoid back-to-back SEP when a given ARG |
| # is the empty string. No expansion is performed on SEP or ARGs. |
| # |
| # Since the number of arguments to join can be arbitrarily long, we |
| # want to avoid having more than one $@ in the macro definition; |
| # otherwise, the expansion would require twice the memory of the already |
| # long list. Hence, m4_join merely looks for the first non-empty element, |
| # and outputs just that element; while _m4_join looks for all non-empty |
| # 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]], |
| [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift2($@))])]) |
| m4_define([_m4_join], |
| [m4_if([$#$2], [2], [], |
| [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift2($@))])]) |
| |
| # m4_joinall(SEP, ARG1, ARG2...) |
| # ------------------------------ |
| # 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($@))])]) |
| |
| # m4_combine([SEPARATOR], PREFIX-LIST, [INFIX], SUFFIX...) |
| # -------------------------------------------------------- |
| # Produce the pairwise combination of every element in the quoted, |
| # comma-separated PREFIX-LIST with every element from the SUFFIX arguments. |
| # Each pair is joined with INFIX, and pairs are separated by SEPARATOR. |
| # No expansion occurs on SEPARATOR, INFIX, or elements of either list. |
| # |
| # For example: |
| # m4_combine([, ], [[a], [b], [c]], [-], [1], [2], [3]) |
| # => a-1, a-2, a-3, b-1, b-2, b-3, c-1, c-2, c-3 |
| # |
| # This definition is a bit hairy; the thing to realize is that we want |
| # to construct m4_map_args_sep([[prefix$3]], [], [[$1]], m4_shift3($@)) |
| # as the inner loop, using each prefix generated by the outer loop, |
| # and without recalculating m4_shift3 every outer iteration. |
| m4_define([m4_combine], |
| [m4_if([$2], [], [], m4_eval([$# > 3]), [1], |
| [m4_map_args_sep([m4_map_args_sep(m4_dquote(], [)[[$3]], [], [[$1]],]]]dnl |
| [m4_dquote(m4_dquote(m4_shift3($@)))[[)], [[$1]], $2)])]) |
| |
| |
| # m4_append(MACRO-NAME, STRING, [SEPARATOR]) |
| # ------------------------------------------ |
| # Redefine MACRO-NAME to hold its former content plus `SEPARATOR`'STRING' |
| # at the end. It is valid to use this macro with MACRO-NAME undefined, |
| # in which case no SEPARATOR is added. Be aware that the criterion is |
| # `not being defined', and not `not being empty'. |
| # |
| # Note that neither STRING nor SEPARATOR are expanded here; rather, when |
| # you expand MACRO-NAME, they will be expanded at that point in time. |
| # |
| # This macro is robust to active symbols. It can be used to grow |
| # strings. |
| # |
| # | m4_define(active, ACTIVE)dnl |
| # | m4_append([sentence], [This is an])dnl |
| # | m4_append([sentence], [ active ])dnl |
| # | m4_append([sentence], [symbol.])dnl |
| # | sentence |
| # | m4_undefine([active])dnl |
| # | sentence |
| # => This is an ACTIVE symbol. |
| # => This is an active symbol. |
| # |
| # It can be used to define hooks. |
| # |
| # | m4_define(active, ACTIVE)dnl |
| # | m4_append([hooks], [m4_define([act1], [act2])])dnl |
| # | m4_append([hooks], [m4_define([act2], [active])])dnl |
| # | m4_undefine([active])dnl |
| # | act1 |
| # | hooks |
| # | act1 |
| # => act1 |
| # => |
| # => active |
| # |
| # It can also be used to create lists, although this particular usage was |
| # broken prior to autoconf 2.62. |
| # | m4_append([list], [one], [, ])dnl |
| # | m4_append([list], [two], [, ])dnl |
| # | m4_append([list], [three], [, ])dnl |
| # | list |
| # | m4_dquote(list) |
| # => one, two, three |
| # => [one],[two],[three] |
| # |
| # Note that m4_append can benefit from amortized O(n) m4 behavior, if |
| # the underlying m4 implementation is smart enough to avoid copying existing |
| # contents when enlarging a macro's definition into any pre-allocated storage |
| # (m4 1.4.x unfortunately does not implement this optimization). We do |
| # not implement m4_prepend, since it is inherently O(n^2) (pre-allocated |
| # storage only occurs at the end of a macro, so the existing contents must |
| # always be moved). |
| # |
| # Use _m4_defn for speed. |
| m4_define([m4_append], |
| [m4_define([$1], m4_ifdef([$1], [_m4_defn([$1])[$3]])[$2])]) |
| |
| |
| # m4_append_uniq(MACRO-NAME, STRING, [SEPARATOR], [IF-UNIQ], [IF-DUP]) |
| # -------------------------------------------------------------------- |
| # Like `m4_append', but append only if not yet present. Additionally, |
| # expand IF-UNIQ if STRING was appended, or IF-DUP if STRING was already |
| # present. Also, warn if SEPARATOR is not empty and occurs within STRING, |
| # as the algorithm no longer guarantees uniqueness. |
| # |
| # Note that while m4_append can be O(n) (depending on the quality of the |
| # underlying M4 implementation), m4_append_uniq is inherently O(n^2) |
| # because each append operation searches the entire string. |
| m4_define([m4_append_uniq], |
| [m4_ifval([$3], [m4_if(m4_index([$2], [$3]), [-1], [], |
| [m4_warn([syntax], |
| [$0: `$2' contains `$3'])])])_$0($@)]) |
| m4_define([_m4_append_uniq], |
| [m4_ifdef([$1], |
| [m4_if(m4_index([$3]_m4_defn([$1])[$3], [$3$2$3]), [-1], |
| [m4_append([$1], [$2], [$3])$4], [$5])], |
| [m4_define([$1], [$2])$4])]) |
| |
| # m4_append_uniq_w(MACRO-NAME, STRINGS) |
| # ------------------------------------- |
| # For each of the words in the whitespace separated list STRINGS, append |
| # only the unique strings to the definition of MACRO-NAME. |
| # |
| # Use _m4_defn for speed. |
| m4_define([m4_append_uniq_w], |
| [m4_map_args_w([$2], [_m4_append_uniq([$1],], [, [ ])])]) |
| |
| |
| # m4_escape(STRING) |
| # ----------------- |
| # Output quoted STRING, but with embedded #, $, [ and ] turned into |
| # quadrigraphs. |
| # |
| # It is faster to check if STRING is already good using m4_translit |
| # than to blindly perform four m4_bpatsubst. |
| # |
| # Because the translit is stripping quotes, it must also neutralize |
| # anything that might be in a macro name, as well as comments, commas, |
| # and parentheses. All the problem characters are unified so that a |
| # single m4_index can scan the result. |
| # |
| # Rather than expand m4_defn every time m4_escape is expanded, we |
| # inline its expansion up front. |
| m4_define([m4_escape], |
| [m4_if(m4_index(m4_translit([$1], |
| [[]#,()]]m4_dquote(m4_defn([m4_cr_symbols2]))[, [$$$]), [$]), |
| [-1], [m4_echo], [_$0])([$1])]) |
| |
| m4_define([_m4_escape], |
| [m4_changequote([-=<{(],[)}>=-])]dnl |
| [m4_bpatsubst(m4_bpatsubst(m4_bpatsubst(m4_bpatsubst( |
| -=<{(-=<{(-=<{(-=<{(-=<{($1)}>=-)}>=-)}>=-)}>=-)}>=-, |
| -=<{(#)}>=-, -=<{(@%:@)}>=-), |
| -=<{(\[)}>=-, -=<{(@<:@)}>=-), |
| -=<{(\])}>=-, -=<{(@:>@)}>=-), |
| -=<{(\$)}>=-, -=<{(@S|@)}>=-)m4_changequote([,])]) |
| |
| |
| # m4_text_wrap(STRING, [PREFIX], [FIRST-PREFIX], [WIDTH]) |
| # ------------------------------------------------------- |
| # Expands into STRING wrapped to hold in WIDTH columns (default = 79). |
| # If PREFIX is given, each line is prefixed with it. If FIRST-PREFIX is |
| # specified, then the first line is prefixed with it. As a special case, |
| # if the length of FIRST-PREFIX is greater than that of PREFIX, then |
| # FIRST-PREFIX will be left alone on the first line. |
| # |
| # No expansion occurs on the contents STRING, PREFIX, or FIRST-PREFIX, |
| # although quadrigraphs are correctly recognized. More precisely, |
| # you may redefine m4_qlen to recognize whatever escape sequences that |
| # you will post-process. |
| # |
| # Typical outputs are: |
| # |
| # m4_text_wrap([Short string */], [ ], [/* ], 20) |
| # => /* Short string */ |
| # |
| # m4_text_wrap([Much longer string */], [ ], [/* ], 20) |
| # => /* Much longer |
| # => string */ |
| # |
| # m4_text_wrap([Short doc.], [ ], [ --short ], 30) |
| # => --short Short doc. |
| # |
| # m4_text_wrap([Short doc.], [ ], [ --too-wide ], 30) |
| # => --too-wide |
| # => Short doc. |
| # |
| # m4_text_wrap([Super long documentation.], [ ], [ --too-wide ], 30) |
| # => --too-wide |
| # => Super long |
| # => documentation. |
| # |
| # FIXME: there is no checking of a longer PREFIX than WIDTH, but do |
| # we really want to bother with people trying each single corner |
| # of a software? |
| # |
| # This macro does not leave a trailing space behind the last word of a line, |
| # which complicates it a bit. The algorithm is otherwise stupid and simple: |
| # all the words are preceded by m4_Separator which is defined to empty for |
| # the first word, and then ` ' (single space) for all the others. |
| # |
| # The algorithm uses a helper that uses $2 through $4 directly, rather than |
| # using local variables, to avoid m4_defn overhead, or expansion swallowing |
| # any $. It also bypasses m4_popdef overhead with _m4_popdef since no user |
| # macro expansion occurs in the meantime. Also, the definition is written |
| # with m4_do, to avoid time wasted on dnl during expansion (since this is |
| # already a time-consuming macro). |
| m4_define([m4_text_wrap], |
| [_$0(m4_escape([$1]), [$2], m4_default_quoted([$3], [$2]), |
| m4_default_quoted([$4], [79]))]) |
| |
| m4_define([_m4_text_wrap], |
| m4_do(dnl set up local variables, to avoid repeated calculations |
| [[m4_pushdef([m4_Indent], m4_qlen([$2]))]], |
| [[m4_pushdef([m4_Cursor], m4_qlen([$3]))]], |
| [[m4_pushdef([m4_Separator], [m4_define([m4_Separator], [ ])])]], |
| dnl expand the first prefix, then check its length vs. regular prefix |
| dnl same length: nothing special |
| dnl prefix1 longer: output on line by itself, and reset cursor |
| dnl prefix1 shorter: pad to length of prefix, and reset cursor |
| [[[$3]m4_cond([m4_Cursor], m4_Indent, [], |
| [m4_eval(m4_Cursor > m4_Indent)], [1], [ |
| [$2]m4_define([m4_Cursor], m4_Indent)], |
| [m4_format([%*s], m4_max([0], |
| m4_eval(m4_Indent - m4_Cursor)), [])m4_define([m4_Cursor], m4_Indent)])]], |
| dnl now, for each word, compute the cursor after the word is output, then |
| dnl check if the cursor would exceed the wrap column |
| dnl if so, reset cursor, and insert newline and prefix |
| dnl if not, insert the separator (usually a space) |
| dnl either way, insert the word |
| [[m4_map_args_w([$1], [$0_word(], [, [$2], [$4])])]], |
| dnl finally, clean up the local variables |
| [[_m4_popdef([m4_Separator], [m4_Cursor], [m4_Indent])]])) |
| |
| m4_define([_m4_text_wrap_word], |
| [m4_define([m4_Cursor], m4_eval(m4_Cursor + m4_qlen([$1]) + 1))]dnl |
| [m4_if(m4_eval(m4_Cursor > ([$3])), |
| [1], [m4_define([m4_Cursor], m4_eval(m4_Indent + m4_qlen([$1]) + 1)) |
| [$2]], |
| [m4_Separator[]])[$1]]) |
| |
| # m4_text_box(MESSAGE, [FRAME-CHARACTER = `-']) |
| # --------------------------------------------- |
| # Turn MESSAGE into: |
| # ## ------- ## |
| # ## MESSAGE ## |
| # ## ------- ## |
| # using FRAME-CHARACTER in the border. |
| # |
| # Quadrigraphs are correctly recognized. More precisely, you may |
| # redefine m4_qlen to recognize whatever escape sequences that you |
| # will post-process. |
| m4_define([m4_text_box], |
| [m4_pushdef([m4_Border], |
| m4_translit(m4_format([[[%*s]]], m4_decr(m4_qlen(_m4_expand([$1 |
| ]))), []), [ ], m4_default_quoted([$2], [-])))]dnl |
| [[##] _m4_defn([m4_Border]) [##] |
| [##] $1 [##] |
| [##] _m4_defn([m4_Border]) [##]_m4_popdef([m4_Border])]) |
| |
| |
| # m4_qlen(STRING) |
| # --------------- |
| # Expands to the length of STRING after autom4te converts all quadrigraphs. |
| # |
| # If you use some other means of post-processing m4 output rather than |
| # autom4te, then you may redefine this macro to recognize whatever |
| # escape sequences your post-processor will handle. For that matter, |
| # m4_define([m4_qlen], m4_defn([m4_len])) is sufficient if you don't |
| # do any post-processing. |
| # |
| # Avoid bpatsubsts for the common case of no quadrigraphs. Cache |
| # results, as configure scripts tend to ask about lengths of common |
| # strings like `/*' and `*/' rather frequently. Minimize the number |
| # of times that $1 occurs in m4_qlen, so there is less text to parse |
| # on a cache hit. |
| m4_define([m4_qlen], |
| [m4_ifdef([$0-$1], [_m4_defn([$0-]], [_$0(])[$1])]) |
| m4_define([_m4_qlen], |
| [m4_define([m4_qlen-$1], |
| m4_if(m4_index([$1], [@]), [-1], [m4_len([$1])], |
| [m4_len(m4_bpatsubst([[$1]], |
| [@\(\(<:\|:>\|S|\|%:\|\{:\|:\}\)\(@\)\|&t@\)], |
| [\3]))]))_m4_defn([m4_qlen-$1])]) |
| |
| # m4_copyright_condense(TEXT) |
| # --------------------------- |
| # Condense the copyright notice in TEXT to only display the final |
| # year, wrapping the results to fit in 80 columns. |
| m4_define([m4_copyright_condense], |
| [m4_text_wrap(m4_bpatsubst(m4_flatten([[$1]]), |
| [(C)[- ,0-9]*\([1-9][0-9][0-9][0-9]\)], [(C) \1]))]) |
| |
| ## ----------------------- ## |
| ## 13. Number processing. ## |
| ## ----------------------- ## |
| |
| # m4_cmp(A, B) |
| # ------------ |
| # Compare two integer expressions. |
| # A < B -> -1 |
| # A = B -> 0 |
| # A > B -> 1 |
| m4_define([m4_cmp], |
| [m4_eval((([$1]) > ([$2])) - (([$1]) < ([$2])))]) |
| |
| |
| # m4_list_cmp(A, B) |
| # ----------------- |
| # |
| # Compare the two lists of integer expressions A and B. For instance: |
| # m4_list_cmp([1, 0], [1]) -> 0 |
| # m4_list_cmp([1, 0], [1, 0]) -> 0 |
| # m4_list_cmp([1, 2], [1, 0]) -> 1 |
| # m4_list_cmp([1, 2, 3], [1, 2]) -> 1 |
| # m4_list_cmp([1, 2, -3], [1, 2]) -> -1 |
| # m4_list_cmp([1, 0], [1, 2]) -> -1 |
| # m4_list_cmp([1], [1, 2]) -> -1 |
| # m4_define([xa], [oops])dnl |
| # m4_list_cmp([[0xa]], [5+5]) -> 0 |
| # |
| # Rather than face the overhead of m4_case, we use a helper function whose |
| # expansion includes the name of the macro to invoke on the tail, either |
| # m4_ignore or m4_unquote. This is particularly useful when comparing |
| # 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. 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_shift2($@)], $1)]) |
| |
| m4_define([_m4_list_cmp_2], |
| [_m4_list_cmp([$1$3], m4_cmp([$3+0], [$1+0]))( |
| [_m4_list_cmp_1(m4_dquote(m4_shift3($@)), $2)])]) |
| |
| # m4_max(EXPR, ...) |
| # m4_min(EXPR, ...) |
| # ----------------- |
| # Return the decimal value of the maximum (or minimum) in a series of |
| # integer expressions. |
| # |
| # 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])], |
| [$#$1], [2$2], [m4_eval([$1])], |
| [$#], [2], [_$0($@)], |
| [_m4_minmax([_$0], $@)])]) |
| |
| m4_define([_m4_max], |
| [m4_eval((([$1]) > ([$2])) * ([$1]) + (([$1]) <= ([$2])) * ([$2]))]) |
| |
| m4_define([m4_min], |
| [m4_if([$#], [0], [m4_fatal([too few arguments to $0])], |
| [$#], [1], [m4_eval([$1])], |
| [$#$1], [2$2], [m4_eval([$1])], |
| [$#], [2], [_$0($@)], |
| [_m4_minmax([_$0], $@)])]) |
| |
| m4_define([_m4_min], |
| [m4_eval((([$1]) < ([$2])) * ([$1]) + (([$1]) >= ([$2])) * ([$2]))]) |
| |
| # _m4_minmax(METHOD, ARG1, ARG2...) |
| # --------------------------------- |
| # 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($@))])]) |
| |
| |
| # m4_sign(A) |
| # ---------- |
| # The sign of the integer expression A. |
| m4_define([m4_sign], |
| [m4_eval((([$1]) > 0) - (([$1]) < 0))]) |
| |
| |
| |
| ## ------------------------ ## |
| ## 14. Version processing. ## |
| ## ------------------------ ## |
| |
| |
| # m4_version_unletter(VERSION) |
| # ---------------------------- |
| # Normalize beta version numbers with letters to numeric expressions, which |
| # can then be handed to m4_eval for the purpose of comparison. |
| # |
| # Nl -> (N+1).-1.(l#) |
| # |
| # for example: |
| # [2.14a] -> [0,2,14+1,-1,[0r36:a]] -> 2.15.-1.10 |
| # [2.14b] -> [0,2,15+1,-1,[0r36:b]] -> 2.15.-1.11 |
| # [2.61aa.b] -> [0,2.61,1,-1,[0r36:aa],+1,-1,[0r36:b]] -> 2.62.-1.370.1.-1.11 |
| # [08] -> [0,[0r10:0]8] -> 8 |
| # |
| # This macro expects reasonable version numbers, but can handle double |
| # letters and does not expand any macros. Original version strings can |
| # use both `.' and `-' separators. |
| # |
| # Inline constant expansions, to avoid m4_defn overhead. |
| # _m4_version_unletter is the real workhorse used by m4_version_compare, |
| # but since [0r36:a] and commas are less readable than 10 and dots, we |
| # provide a wrapper for human use. |
| m4_define([m4_version_unletter], |
| [m4_substr(m4_map_args([.m4_eval], m4_unquote(_$0([$1]))), [3])]) |
| m4_define([_m4_version_unletter], |
| [m4_bpatsubst(m4_bpatsubst(m4_translit([[[[0,$1]]]], [.-], [,,]),]dnl |
| m4_dquote(m4_dquote(m4_defn([m4_cr_Letters])))[[+], |
| [+1,-1,[0r36:\&]]), [,0], [,[0r10:0]])]) |
| |
| |
| # m4_version_compare(VERSION-1, VERSION-2) |
| # ---------------------------------------- |
| # Compare the two version numbers and expand into |
| # -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_raw(_m4_version_unletter([$1]), _m4_version_unletter([$2]))]) |
| |
| |
| # m4_PACKAGE_NAME |
| # m4_PACKAGE_TARNAME |
| # m4_PACKAGE_VERSION |
| # m4_PACKAGE_STRING |
| # m4_PACKAGE_BUGREPORT |
| # -------------------- |
| # If m4sugar/version.m4 is present, then define version strings. This |
| # file is optional, provided by Autoconf but absent in Bison. |
| m4_sinclude([m4sugar/version.m4]) |
| |
| |
| # m4_version_prereq(VERSION, [IF-OK], [IF-NOT = FAIL]) |
| # ---------------------------------------------------- |
| # Check this Autoconf version against VERSION. |
| m4_define([m4_version_prereq], |
| m4_ifdef([m4_PACKAGE_VERSION], |
| [[m4_if(m4_version_compare(]m4_dquote(m4_defn([m4_PACKAGE_VERSION]))[, [$1]), |
| [-1], |
| [m4_default([$3], |
| [m4_fatal([Autoconf version $1 or higher is required], |
| [63])])], |
| [$2])]], |
| [[m4_fatal([m4sugar/version.m4 not found])]])) |
| |
| |
| ## ------------------ ## |
| ## 15. Set handling. ## |
| ## ------------------ ## |
| |
| # Autoconf likes to create arbitrarily large sets; for example, as of |
| # this writing, the configure.ac for coreutils tracks a set of more |
| # than 400 AC_SUBST. How do we track all of these set members, |
| # without introducing duplicates? We could use m4_append_uniq, with |
| # the set NAME residing in the contents of the macro NAME. |
| # Unfortunately, m4_append_uniq is quadratic for set creation, because |
| # it costs O(n) to search the string for each of O(n) insertions; not |
| # to mention that with m4 1.4.x, even using m4_append is slow, costing |
| # O(n) rather than O(1) per insertion. Other set operations, not used |
| # by Autoconf but still possible by manipulation of the definition |
| # tracked in macro NAME, include O(n) deletion of one element and O(n) |
| # computation of set size. Because the set is exposed to the user via |
| # the definition of a single macro, we cannot cache any data about the |
| # set without risking the cache being invalidated by the user |
| # redefining NAME. |
| # |
| # Can we do better? Yes, because m4 gives us an O(1) search function |
| # for free: ifdef. Additionally, even m4 1.4.x gives us an O(1) |
| # insert operation for free: pushdef. But to use these, we must |
| # represent the set via a group of macros; to keep the set consistent, |
| # we must hide the set so that the user can only manipulate it through |
| # accessor macros. The contents of the set are maintained through two |
| # access points; _m4_set([name]) is a pushdef stack of values in the |
| # set, useful for O(n) traversal of the set contents; while the |
| # existence of _m4_set([name],value) with no particular value is |
| # useful for O(1) querying of set membership. And since the user |
| # cannot externally manipulate the set, we are free to add additional |
| # caching macros for other performance improvements. Deletion can be |
| # O(1) per element rather than O(n), by reworking the definition of |
| # _m4_set([name],value) to be 0 or 1 based on current membership, and |
| # adding _m4_set_cleanup(name) to defer the O(n) cleanup of |
| # _m4_set([name]) until we have another reason to do an O(n) |
| # traversal. The existence of _m4_set_cleanup(name) can then be used |
| # elsewhere to determine if we must dereference _m4_set([name],value), |
| # or assume that definition implies set membership. Finally, size can |
| # be tracked in an O(1) fashion with _m4_set_size(name). |
| # |
| # The quoting in _m4_set([name],value) is chosen so that there is no |
| # ambiguity with a set whose name contains a comma, and so that we can |
| # supply the value via _m4_defn([_m4_set([name])]) without needing any |
| # quote manipulation. |
| |
| # m4_set_add(SET, VALUE, [IF-UNIQ], [IF-DUP]) |
| # ------------------------------------------- |
| # Add VALUE as an element of SET. Expand IF-UNIQ on the first |
| # addition, and IF-DUP if it is already in the set. Addition of one |
| # element is O(1), such that overall set creation is O(n). |
| # |
| # We do not want to add a duplicate for a previously deleted but |
| # unpruned element, but it is just as easy to check existence directly |
| # as it is to query _m4_set_cleanup($1). |
| m4_define([m4_set_add], |
| [m4_ifdef([_m4_set([$1],$2)], |
| [m4_if(m4_indir([_m4_set([$1],$2)]), [0], |
| [m4_define([_m4_set([$1],$2)], |
| [1])_m4_set_size([$1], [m4_incr])$3], [$4])], |
| [m4_define([_m4_set([$1],$2)], |
| [1])m4_pushdef([_m4_set([$1])], |
| [$2])_m4_set_size([$1], [m4_incr])$3])]) |
| |
| # m4_set_add_all(SET, VALUE...) |
| # ----------------------------- |
| # Add each VALUE into SET. This is O(n) in the number of VALUEs, and |
| # can be faster than calling m4_set_add for each VALUE. |
| # |
| # Implement two recursion helpers; the check variant is slower but |
| # handles the case where an element has previously been removed but |
| # 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_define([_m4_set_add_all], |
| [m4_if([$#], [2], [], |
| [m4_ifdef([_m4_set([$1],$3)], [], |
| [m4_define([_m4_set([$1],$3)], [1])m4_pushdef([_m4_set([$1])], |
| [$3])-])$0([$1], m4_shift2($@))])]) |
| |
| m4_define([_m4_set_add_all_check], |
| [m4_if([$#], [2], [], |
| [m4_set_add([$1], [$3])$0([$1], m4_shift2($@))])]) |
| |
| # m4_set_contains(SET, VALUE, [IF-PRESENT], [IF-ABSENT]) |
| # ------------------------------------------------------ |
| # Expand IF-PRESENT if SET contains VALUE, otherwise expand IF-ABSENT. |
| # This is always O(1). |
| m4_define([m4_set_contains], |
| [m4_ifdef([_m4_set_cleanup($1)], |
| [m4_if(m4_ifdef([_m4_set([$1],$2)], |
| [m4_indir([_m4_set([$1],$2)])], [0]), [1], [$3], [$4])], |
| [m4_ifdef([_m4_set([$1],$2)], [$3], [$4])])]) |
| |
| # m4_set_contents(SET, [SEP]) |
| # --------------------------- |
| # Expand to a single string containing all the elements in SET, |
| # separated by SEP, without modifying SET. No provision is made for |
| # disambiguating set elements that contain non-empty SEP as a |
| # sub-string, or for recognizing a set that contains only the empty |
| # string. Order of the output is not guaranteed. If any elements |
| # have been previously removed from the set, this action will prune |
| # the unused memory. This is O(n) in the size of the set before |
| # pruning. |
| # |
| # Use _m4_popdef for speed. The existence of _m4_set_cleanup($1) |
| # determines which version of _1 helper we use. |
| m4_define([m4_set_contents], |
| [m4_set_map_sep([$1], [], [], [[$2]])]) |
| |
| # _m4_set_contents_1(SET) |
| # _m4_set_contents_1c(SET) |
| # _m4_set_contents_2(SET, [PRE], [POST], [SEP]) |
| # --------------------------------------------- |
| # Expand to a list of quoted elements currently in the set, each |
| # surrounded by PRE and POST, and moving SEP in front of PRE on |
| # recursion. To avoid nesting limit restrictions, the algorithm must |
| # be broken into two parts; _1 destructively copies the stack in |
| # reverse into _m4_set_($1), producing no output; then _2 |
| # destructively copies _m4_set_($1) back into the stack in reverse. |
| # If no elements were deleted, then this visits the set in the order |
| # that elements were inserted. Behavior is undefined if PRE/POST/SEP |
| # tries to recursively list or modify SET in any way other than |
| # calling m4_set_remove on the current element. Use _1 if all entries |
| # in the stack are guaranteed to be in the set, and _1c to prune |
| # removed entries. Uses _m4_defn and _m4_popdef for speed. |
| m4_define([_m4_set_contents_1], |
| [_m4_stack_reverse([_m4_set([$1])], [_m4_set_($1)])]) |
| |
| m4_define([_m4_set_contents_1c], |
| [m4_ifdef([_m4_set([$1])], |
| [m4_set_contains([$1], _m4_defn([_m4_set([$1])]), |
| [m4_pushdef([_m4_set_($1)], _m4_defn([_m4_set([$1])]))], |
| [_m4_popdef([_m4_set([$1],]_m4_defn( |
| [_m4_set([$1])])[)])])_m4_popdef([_m4_set([$1])])$0([$1])], |
| [_m4_popdef([_m4_set_cleanup($1)])])]) |
| |
| m4_define([_m4_set_contents_2], |
| [_m4_stack_reverse([_m4_set_($1)], [_m4_set([$1])], |
| [$2[]_m4_defn([_m4_set_($1)])$3], [$4[]])]) |
| |
| # m4_set_delete(SET) |
| # ------------------ |
| # Delete all elements in SET, and reclaim any memory occupied by the |
| # set. This is O(n) in the set size. |
| # |
| # Use _m4_defn and _m4_popdef for speed. |
| m4_define([m4_set_delete], |
| [m4_ifdef([_m4_set([$1])], |
| [_m4_popdef([_m4_set([$1],]_m4_defn([_m4_set([$1])])[)], |
| [_m4_set([$1])])$0([$1])], |
| [m4_ifdef([_m4_set_cleanup($1)], |
| [_m4_popdef([_m4_set_cleanup($1)])])m4_ifdef( |
| [_m4_set_size($1)], |
| [_m4_popdef([_m4_set_size($1)])])])]) |
| |
| # m4_set_difference(SET1, SET2) |
| # ----------------------------- |
| # Produce a LIST of quoted elements that occur in SET1 but not SET2. |
| # Output a comma prior to any elements, to distinguish the empty |
| # string from no elements. This can be directly used as a series of |
| # arguments, such as for m4_join, or wrapped inside quotes for use in |
| # m4_foreach. Order of the output is not guaranteed. |
| # |
| # Short-circuit the idempotence relation. |
| m4_define([m4_set_difference], |
| [m4_if([$1], [$2], [], [m4_set_map_sep([$1], [_$0([$2],], [)])])]) |
| |
| m4_define([_m4_set_difference], |
| [m4_set_contains([$1], [$2], [], [,[$2]])]) |
| |
| # m4_set_dump(SET, [SEP]) |
| # ----------------------- |
| # Expand to a single string containing all the elements in SET, |
| # separated by SEP, then delete SET. In general, if you only need to |
| # list the contents once, this is faster than m4_set_contents. No |
| # provision is made for disambiguating set elements that contain |
| # non-empty SEP as a sub-string. Order of the output is not |
| # guaranteed. This is O(n) in the size of the set before pruning. |
| # |
| # Use _m4_popdef for speed. Use existence of _m4_set_cleanup($1) to |
| # decide if more expensive recursion is needed. |
| m4_define([m4_set_dump], |
| [m4_ifdef([_m4_set_size($1)], |
| [_m4_popdef([_m4_set_size($1)])])m4_ifdef([_m4_set_cleanup($1)], |
| [_$0_check], [_$0])([$1], [], [$2])]) |
| |
| # _m4_set_dump(SET, [SEP], [PREP]) |
| # _m4_set_dump_check(SET, [SEP], [PREP]) |
| # -------------------------------------- |
| # Print SEP and the current element, then delete the element and |
| # recurse with empty SEP changed to PREP. The check variant checks |
| # whether the element has been previously removed. Use _m4_defn and |
| # _m4_popdef for speed. |
| m4_define([_m4_set_dump], |
| [m4_ifdef([_m4_set([$1])], |
| [[$2]_m4_defn([_m4_set([$1])])_m4_popdef([_m4_set([$1],]_m4_defn( |
| [_m4_set([$1])])[)], [_m4_set([$1])])$0([$1], [$2$3])])]) |
| |
| m4_define([_m4_set_dump_check], |
| [m4_ifdef([_m4_set([$1])], |
| [m4_set_contains([$1], _m4_defn([_m4_set([$1])]), |
| [[$2]_m4_defn([_m4_set([$1])])])_m4_popdef( |
| [_m4_set([$1],]_m4_defn([_m4_set([$1])])[)], |
| [_m4_set([$1])])$0([$1], [$2$3])], |
| [_m4_popdef([_m4_set_cleanup($1)])])]) |
| |
| # m4_set_empty(SET, [IF-EMPTY], [IF-ELEMENTS]) |
| # -------------------------------------------- |
| # Expand IF-EMPTY if SET has no elements, otherwise IF-ELEMENTS. |
| m4_define([m4_set_empty], |
| [m4_ifdef([_m4_set_size($1)], |
| [m4_if(m4_indir([_m4_set_size($1)]), [0], [$2], [$3])], [$2])]) |
| |
| # m4_set_foreach(SET, VAR, ACTION) |
| # -------------------------------- |
| # For each element of SET, define VAR to the element and expand |
| # ACTION. ACTION should not recursively list SET's contents, add |
| # elements to SET, nor delete any element from SET except the one |
| # currently in VAR. The order that the elements are visited in is not |
| # guaranteed. This is faster than the corresponding m4_foreach([VAR], |
| # m4_indir([m4_dquote]m4_set_listc([SET])), [ACTION]) |
| m4_define([m4_set_foreach], |
| [m4_pushdef([$2])m4_set_map_sep([$1], [m4_define([$2],], [)$3])]) |
| |
| # m4_set_intersection(SET1, SET2) |
| # ------------------------------- |
| # Produce a LIST of quoted elements that occur in both SET1 or SET2. |
| # Output a comma prior to any elements, to distinguish the empty |
| # string from no elements. This can be directly used as a series of |
| # arguments, such as for m4_join, or wrapped inside quotes for use in |
| # m4_foreach. Order of the output is not guaranteed. |
| # |
| # Iterate over the smaller set, and short-circuit the idempotence |
| # relation. |
| m4_define([m4_set_intersection], |
| [m4_if([$1], [$2], [m4_set_listc([$1])], |
| m4_eval(m4_set_size([$2]) < m4_set_size([$1])), [1], [$0([$2], [$1])], |
| [m4_set_map_sep([$1], [_$0([$2],], [)])])]) |
| |
| m4_define([_m4_set_intersection], |
| [m4_set_contains([$1], [$2], [,[$2]])]) |
| |
| # m4_set_list(SET) |
| # m4_set_listc(SET) |
| # ----------------- |
| # Produce a LIST of quoted elements of SET. This can be directly used |
| # as a series of arguments, such as for m4_join or m4_set_add_all, or |
| # wrapped inside quotes for use in m4_foreach or m4_map. With |
| # m4_set_list, there is no way to distinguish an empty set from a set |
| # containing only the empty string; with m4_set_listc, a leading comma |
| # is output if there are any elements. |
| m4_define([m4_set_list], |
| [m4_set_map_sep([$1], [], [], [,])]) |
| |
| m4_define([m4_set_listc], |
| [m4_set_map_sep([$1], [,])]) |
| |
| # m4_set_map(SET, ACTION) |
| # ----------------------- |
| # For each element of SET, expand ACTION with a single argument of the |
| # current element. ACTION should not recursively list SET's contents, |
| # add elements to SET, nor delete any element from SET except the one |
| # passed as an argument. The order that the elements are visited in |
| # is not guaranteed. This is faster than either of the corresponding |
| # m4_map_args([ACTION]m4_set_listc([SET])) |
| # m4_set_foreach([SET], [VAR], [ACTION(m4_defn([VAR]))]) |
| m4_define([m4_set_map], |
| [m4_set_map_sep([$1], [$2(], [)])]) |
| |
| # m4_set_map_sep(SET, [PRE], [POST], [SEP]) |
| # ----------------------------------------- |
| # For each element of SET, expand PRE[value]POST[], and expand SEP |
| # between elements. |
| m4_define([m4_set_map_sep], |
| [m4_ifdef([_m4_set_cleanup($1)], [_m4_set_contents_1c], |
| [_m4_set_contents_1])([$1])_m4_set_contents_2($@)]) |
| |
| # m4_set_remove(SET, VALUE, [IF-PRESENT], [IF-ABSENT]) |
| # ---------------------------------------------------- |
| # If VALUE is an element of SET, delete it and expand IF-PRESENT. |
| # Otherwise expand IF-ABSENT. Deleting a single value is O(1), |
| # although it leaves memory occupied until the next O(n) traversal of |
| # the set which will compact the set. |
| # |
| # Optimize if the element being removed is the most recently added, |
| # since defining _m4_set_cleanup($1) slows down so many other macros. |
| # In particular, this plays well with m4_set_foreach and m4_set_map. |
| m4_define([m4_set_remove], |
| [m4_set_contains([$1], [$2], [_m4_set_size([$1], |
| [m4_decr])m4_if(_m4_defn([_m4_set([$1])]), [$2], |
| [_m4_popdef([_m4_set([$1],$2)], [_m4_set([$1])])], |
| [m4_define([_m4_set_cleanup($1)])m4_define( |
| [_m4_set([$1],$2)], [0])])$3], [$4])]) |
| |
| # m4_set_size(SET) |
| # ---------------- |
| # Expand to the number of elements currently in SET. This operation |
| # is O(1), and thus more efficient than m4_count(m4_set_list([SET])). |
| m4_define([m4_set_size], |
| [m4_ifdef([_m4_set_size($1)], [m4_indir([_m4_set_size($1)])], [0])]) |
| |
| # _m4_set_size(SET, ACTION) |
| # ------------------------- |
| # ACTION must be either m4_incr or m4_decr, and the size of SET is |
| # changed accordingly. If the set is empty, ACTION must not be |
| # m4_decr. |
| m4_define([_m4_set_size], |
| [m4_define([_m4_set_size($1)], |
| m4_ifdef([_m4_set_size($1)], [$2(m4_indir([_m4_set_size($1)]))], |
| [1]))]) |
| |
| # m4_set_union(SET1, SET2) |
| # ------------------------ |
| # Produce a LIST of double quoted elements that occur in either SET1 |
| # or SET2, without duplicates. Output a comma prior to any elements, |
| # to distinguish the empty string from no elements. This can be |
| # directly used as a series of arguments, such as for m4_join, or |
| # wrapped inside quotes for use in m4_foreach. Order of the output is |
| # not guaranteed. |
| # |
| # We can rely on the fact that m4_set_listc prunes SET1, so we don't |
| # need to check _m4_set([$1],element) for 0. Short-circuit the |
| # idempotence relation. |
| m4_define([m4_set_union], |
| [m4_set_listc([$1])m4_if([$1], [$2], [], |
| [m4_set_map_sep([$2], [_$0([$1],], [)])])]) |
| |
| m4_define([_m4_set_union], |
| [m4_ifdef([_m4_set([$1],$2)], [], [,[$2]])]) |
| |
| |
| ## ------------------- ## |
| ## 16. File handling. ## |
| ## ------------------- ## |
| |
| |
| # It is a real pity that M4 comes with no macros to bind a diversion |
| # to a file. So we have to deal without, which makes us a lot more |
| # fragile than we should. |
| |
| |
| # m4_file_append(FILE-NAME, CONTENT) |
| # ---------------------------------- |
| m4_define([m4_file_append], |
| [m4_syscmd([cat >>$1 <<_m4eof |
| $2 |
| _m4eof |
| ]) |
| m4_if(m4_sysval, [0], [], |
| [m4_fatal([$0: cannot write: $1])])]) |
| |
| |
| |
| ## ------------------------ ## |
| ## 17. Setting M4sugar up. ## |
| ## ------------------------ ## |
| |
| # _m4_divert_diversion should be defined. |
| m4_divert_push([KILL]) |
| |
| # m4_init |
| # ------- |
| # Initialize the m4sugar language. |
| m4_define([m4_init], |
| [# All the M4sugar macros start with `m4_', except `dnl' kept as is |
| # for sake of simplicity. |
| m4_pattern_forbid([^_?m4_]) |
| m4_pattern_forbid([^dnl$]) |
| |
| # If __m4_version__ is defined, we assume that we are being run by M4 |
| # 1.6 or newer, thus $@ recursion is linear, and debugmode(+do) |
| # is available for faster checks of dereferencing undefined macros |
| # and forcing dumpdef to print to stderr regardless of debugfile. |
| # 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. Also, m4 prior to 1.4.8 loses track of location |
| # during m4wrap text; __line__ should never be 0. |
| # |
| # Use the raw builtin to avoid tripping up include tracing. |
| # Meanwhile, avoid m4_copy, since it temporarily undefines m4_defn. |
| m4_ifdef([__m4_version__], |
| [m4_debugmode([+do]) |
| m4_define([m4_defn], _m4_defn([_m4_defn])) |
| m4_define([m4_dumpdef], _m4_defn([_m4_dumpdef])) |
| m4_define([m4_popdef], _m4_defn([_m4_popdef])) |
| m4_define([m4_undefine], _m4_defn([_m4_undefine]))], |
| [m4_builtin([include], [m4sugar/foreach.m4]) |
| m4_wrap_lifo([m4_if(__line__, [0], [m4_pushdef([m4_location], |
| ]]m4_dquote(m4_dquote(m4_dquote(__file__:__line__)))[[)])])]) |
| |
| # Rewrite the first entry of the diversion stack. |
| m4_divert([KILL]) |
| |
| # Check the divert push/pop perfect balance. |
| # 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])]) |
| ]) |