divert(-1)# -*- Autoconf -*-# This file is part of Autoconf.# Base M4 layer.# Requires GNU M4.## Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software# Foundation, Inc.## 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 2, 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.## You should have received a copy of the GNU General Public License# along with this program; if not, write to the Free Software# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA# 02110-1301, USA.## As a special exception, the Free Software Foundation gives unlimited# permission to copy, distribute and modify the configure scripts that# are the output of Autoconf. You need not follow the terms of the GNU# General Public License when using or distributing such scripts, even# though portions of the text of Autoconf appear in them. The GNU# General Public License (GPL) does govern all other use of the material# that constitutes the Autoconf program.## Certain portions of the Autoconf source text are designed to be copied# (in certain cases, depending on the input) into the output of# Autoconf. We call these the "data" portions. The rest of the Autoconf# source text consists of comments plus executable code that decides which# of the data portions to output in any given case. We call these# comments and executable code the "non-data" portions. Autoconf never# copies any of the non-data portions into its output.## This special exception to the GPL applies to versions of Autoconf# released by the Free Software Foundation. When you make and# distribute a modified version of Autoconf, you may extend this special# exception to the GPL to apply to your modified version as well, *unless*# your modified version has the potential to copy into its output some# of the text that was the non-data portion of the version that you started# with. (In other words, unless your change moves or copies text from# the non-data portions to the data portions.) If your modification has# such potential, you must delete any notice of this special exception# to the GPL from your modified version.## 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 orset the M4 environment variable to its absolute file name.)m4exit(2)])## ------------------------------- #### 1. Simulate --prefix-builtins. #### ------------------------------- ### m4_define# m4_defn# m4_undefinedefine([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 will certainly prefer to see `to'.m4_define([m4_copy],[m4_define([$2], m4_defn([$1]))])# m4_rename(SRC, DST)# -------------------# Rename the macro SRC as DST.m4_define([m4_rename],[m4_copy([$1], [$2])m4_undefine([$1])])# m4_rename_m4(MACRO-NAME)# ------------------------# Rename MACRO-NAME as m4_MACRO-NAME.m4_define([m4_rename_m4],[m4_rename([$1], [m4_$1])])# m4_copy_unm4(m4_MACRO-NAME)# ---------------------------# Copy m4_MACRO-NAME as 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'.m4_rename_m4([builtin])m4_rename_m4([changecom])m4_rename_m4([changequote])m4_rename_m4([debugfile])m4_rename_m4([debugmode])m4_rename_m4([decr])m4_undefine([divert])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_rename_m4([ifdef])m4_rename([ifelse], [m4_if])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_rename([m4wrap], [m4_wrap])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_undefine([popdef])m4_rename_m4([pushdef])m4_rename([regexp], [m4_bregexp])m4_rename_m4([shift])m4_undefine([sinclude])m4_rename_m4([substr])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_undefine([undivert])## ------------------- #### 2. Error messages. #### ------------------- ### m4_location# -----------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])dnlm4_expansion_stack_dump()dnlm4_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.# The STACK-TRACE is a \n-separated list of "LOCATION: MESSAGE".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_defn([m4_expansion_stack])m4_location[: the top level]]))dnl])## ------------------- #### 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# quite nobody quotes 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])])dnlm4_define([m4_include($1)])])# m4_include(FILE)# ----------------# As the builtin include, but warns against multiple inclusions.m4_define([m4_include],[m4_include_unique([$1])dnlm4_builtin([include], [$1])])# m4_sinclude(FILE)# -----------------# As the builtin sinclude, but warns against multiple inclusions.m4_define([m4_sinclude],[m4_include_unique([$1])dnlm4_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 a variation of `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_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.m4_define([m4_case],[m4_if([$#], 0, [],[$#], 1, [],[$#], 2, [$2],[$1], [$2], [$3],[$0([$1], m4_shiftn(3, $@))])])# 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.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_shiftn(3, $@))],[$3])])])# m4_car(LIST)# m4_cdr(LIST)# ------------# Manipulate m4 lists.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_map(MACRO, LIST)# -------------------# Invoke MACRO($1), MACRO($2) etc. where $1, $2... are the elements# of LIST (which can be lists themselves, for multiple arguments MACROs).m4_define([m4_fst], [$1])m4_define([m4_map],[m4_if([$2], [[]], [],[_m4_map([$1], [$2])])])m4_define([_m4_map],[m4_ifval([$2],[$1(m4_fst($2))[]_m4_map([$1], m4_cdr($2))])])# m4_map_sep(MACRO, SEPARATOR, LIST)# ----------------------------------# Invoke MACRO($1), SEPARATOR, MACRO($2), ..., MACRO($N) where $1, $2... $N# are the elements of LIST (which can be lists themselves, for multiple# arguments MACROs).m4_define([m4_map_sep],[m4_if([$3], [[]], [],[$1(m4_fst($3))[]_m4_map([$2[]$1], m4_cdr($3))])])## ---------------------------------------- #### 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.m4_define([m4_bpatsubsts],[m4_if([$#], 0, [m4_fatal([$0: too few arguments: $#])],[$#], 1, [m4_fatal([$0: too few arguments: $#: $1])],[$#], 2, [m4_builtin([patsubst], $@)],[$0(m4_builtin([patsubst], [[$1]], [$2], [$3]),m4_shiftn(3, $@))])])# 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.m4_define([m4_do],[m4_if($#, 0, [],$#, 1, [$1],[$1[]m4_do(m4_shift($@))])])# 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)# ----------------------# Returns EXP1 if non empty, otherwise EXP2.m4_define([m4_default],[m4_ifval([$1], [$1], [$2])])# m4_defn(NAME)# -------------# Unlike to the original, don't tolerate popping something which is# undefined.m4_define([m4_defn],[m4_ifndef([$1],[m4_fatal([$0: undefined macro: $1])])dnlm4_builtin([defn], $@)])# _m4_dumpdefs_up(NAME)# ---------------------m4_define([_m4_dumpdefs_up],[m4_ifdef([$1],[m4_pushdef([_m4_dumpdefs], m4_defn([$1]))dnlm4_dumpdef([$1])dnlm4_popdef([$1])dnl_m4_dumpdefs_up([$1])])])# _m4_dumpdefs_down(NAME)# -----------------------m4_define([_m4_dumpdefs_down],[m4_ifdef([_m4_dumpdefs],[m4_pushdef([$1], m4_defn([_m4_dumpdefs]))dnlm4_popdef([_m4_dumpdefs])dnl_m4_dumpdefs_down([$1])])])# m4_dumpdefs(NAME)# -----------------# Similar to `m4_dumpdef(NAME)', but if NAME was m4_pushdef'ed, display its# value stack (most recent displayed first).m4_define([m4_dumpdefs],[_m4_dumpdefs_up([$1])dnl_m4_dumpdefs_down([$1])])# m4_popdef(NAME)# ---------------# Unlike to the original, don't tolerate popping something which is# undefined.m4_define([m4_popdef],[m4_ifndef([$1],[m4_fatal([$0: undefined macro: $1])])dnlm4_builtin([popdef], $@)])# m4_quote(ARGS)# --------------# Return ARGS as a single 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_define([m4_dquote], [[$@]])# m4_noquote(STRING)# ------------------# Return the result of ignoring all quotes in STRING and invoking the# macros it contains. Amongst other things useful for enabling macro# invocations inside strings with [] blocks (for instance regexps and# help-strings).m4_define([m4_noquote],[m4_changequote(-=<{,}>=-)$1-=<{}>=-m4_changequote([,])])# m4_shiftn(N, ...)# -----------------# Returns ... shifted N times. Useful for recursive "varargs" constructs.m4_define([m4_shiftn],[m4_assert(($1 >= 0) && ($# > $1))dnl_m4_shiftn($@)])m4_define([_m4_shiftn],[m4_if([$1], 0,[m4_shift($@)],[_m4_shiftn(m4_eval([$1]-1), m4_shift(m4_shift($@)))])])# m4_undefine(NAME)# -----------------# Unlike to the original, don't tolerate undefining something which is# undefined.m4_define([m4_undefine],[m4_ifndef([$1],[m4_fatal([$0: undefined macro: $1])])dnlm4_builtin([undefine], $@)])## -------------------------- #### 7. Implementing m4 loops. #### -------------------------- ### m4_for(VARIABLE, FIRST, LAST, [STEP = +/-1], EXPRESSION)# --------------------------------------------------------# Expand EXPRESSION defining VARIABLE to FROM, FROM + 1, ..., TO.# Both limits are included, and bounds are checked for consistency.m4_define([m4_for],[m4_pushdef([$1], m4_eval([$2]))dnlm4_if(m4_eval(([$3]) > $1), 1,[m4_pushdef([_m4_step], m4_eval(m4_default([$4], 1)))dnlm4_assert(_m4_step > 0)dnl_m4_for([$1], m4_eval((([$3]) - $1) / _m4_step * _m4_step + $1), _m4_step, [$5])],m4_eval(([$3]) < $1), 1,[m4_pushdef([_m4_step], m4_eval(m4_default([$4], -1)))dnlm4_assert(_m4_step < 0)dnl_m4_for([$1], m4_eval(($1 - ([$3])) / -(_m4_step) * _m4_step + $1), _m4_step, [$5])],[m4_pushdef(_m4_step,[])dnl$5])[]dnlm4_popdef([_m4_step])dnlm4_popdef([$1])])# _m4_for(VARIABLE, LAST, STEP, EXPRESSION)# -----------------------------------------# Core of the loop, no consistency checks, all arguments are plain numbers.m4_define([_m4_for],[$4[]dnlm4_if($1, [$2], [],[m4_define([$1], m4_eval($1+[$3]))_m4_for([$1], [$2], [$3], [$4])])])# Implementing `foreach' loops in m4 is much more tricky than it may# seem. Actually, the example of a `foreach' loop in the m4# documentation is wrong: it does not quote the arguments properly,# which leads to undesirable expansions.## The example in the documentation is:## | # 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],# | (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],# | [(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],# | [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 quite satisfactory# 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-m4_define([m4_foreach],[m4_pushdef([$1])_m4_foreach($@)m4_popdef([$1])])m4_define([_m4_foreach],[m4_ifval([$2],[m4_define([$1], m4_car($2))$3[]dnl_m4_foreach([$1], m4_cdr($2), [$3])])])# m4_foreach_w(VARIABLE, LIST, EXPRESSION)# ----------------------------------------## Like m4_foreach, but the list is whitespace separated.## This macro is robust to active symbols:# m4_foreach_w([Var], [ active# b act\# ive ], [-Var-])end# => -active--b--active-end#m4_define([m4_foreach_w],[m4_foreach([$1], m4_split(m4_normalize([$2])), [$3])])## --------------------------- #### 8. More diversion support. #### --------------------------- ### _m4_divert(DIVERSION-NAME or NUMBER)# ------------------------------------# If DIVERSION-NAME is the name of a diversion, return its number,# otherwise if it is a NUMBER return it.m4_define([_m4_divert],[m4_ifdef([_m4_divert($1)],[m4_indir([_m4_divert($1)])],[$1])])# KILL is only used to suppress output.m4_define([_m4_divert(KILL)], -1)# _m4_divert_n_stack# ------------------# Print m4_divert_stack with newline prepended, if it's nonempty.m4_define([_m4_divert_n_stack],[m4_ifdef([m4_divert_stack], [m4_defn([m4_divert_stack])])])# m4_divert(DIVERSION-NAME)# -------------------------# Change the diversion stream to DIVERSION-NAME.m4_define([m4_divert],[m4_define([m4_divert_stack], m4_location[: $0: $1]_m4_divert_n_stack)dnlm4_builtin([divert], _m4_divert([$1]))dnl])# m4_divert_push(DIVERSION-NAME)# ------------------------------# Change the diversion stream to DIVERSION-NAME, while stacking old values.m4_define([m4_divert_push],[m4_pushdef([m4_divert_stack], m4_location[: $0: $1]_m4_divert_n_stack)dnlm4_pushdef([_m4_divert_diversion], [$1])dnlm4_builtin([divert], _m4_divert([$1]))dnl])# 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_ifndef([_m4_divert_diversion],[m4_fatal([too many m4_divert_pop])])dnlm4_if([$1], [], [],[$1], m4_defn([_m4_divert_diversion]), [],[m4_fatal([$0($1): diversion mismatch: ]_m4_divert_n_stack)])dnlm4_popdef([m4_divert_stack])dnlm4_popdef([_m4_divert_diversion])dnlm4_builtin([divert],m4_ifdef([_m4_divert_diversion],[_m4_divert(m4_defn([_m4_divert_diversion]))],-1))dnl])# 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])dnl$2m4_divert_pop([$1])dnl])# m4_divert_once(DIVERSION-NAME, CONTENT)# ---------------------------------------# Output once CONTENT into DIVERSION-NAME (which may be a number# actually). An end of line is appended for free to CONTENT.m4_define([m4_divert_once],[m4_expand_once([m4_divert_text([$1], [$2])])])# m4_undivert(DIVERSION-NAME)# ---------------------------# Undivert DIVERSION-NAME.m4_define([m4_undivert],[m4_builtin([undivert], _m4_divert([$1]))])## -------------------------------------------- #### 8. 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 AC_PROVIDE's the macro, 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 two ideas, (i) using diversions to# prepare the expansion of the macro and its dependencies (by Franc,ois# Pinard), and (ii) expand the most recently m4_require'd macros _after_# the previous macros (by Axel Thimm).### The first idea: why using 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...REQUIRE([TEST2])1])# | m4_defun([TEST2], [Test...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 level 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], [REQUIRE([TEST2a])REQUIRE([TEST2b])])# | m4_defun([TEST2a], [])# | m4_defun([TEST2b], [REQUIRE([TEST3])])# | m4_defun([TEST3], [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, uses 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 macro are expanded. (The bug above can# indeed be described as: a macro has been AC_PROVIDE'd, but it is# emitted after: the lack of correlation between emission and expansion# order is guilty).## How to do that? You keeping 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 evolved. 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 implements 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 |-# Than 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 |-# Than 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 |-### 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.## The scheme is simplistic: each time we enter an m4_defun'd macros,# we prepend its name in m4_expansion_stack, and when we exit the# macro, we remove it (thanks to pushdef/popdef).## 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_push(TEXT)# -----------------------------m4_define([m4_expansion_stack_push],[m4_pushdef([m4_expansion_stack],[$1]m4_ifdef([m4_expansion_stack], [m4_defn([m4_expansion_stack])]))])# m4_expansion_stack_pop# ----------------------m4_define([m4_expansion_stack_pop],[m4_popdef([m4_expansion_stack])])# m4_expansion_stack_dump# -----------------------# Dump the expansion stack.m4_define([m4_expansion_stack_dump],[m4_ifdef([m4_expansion_stack],[m4_errprintn(m4_defn([m4_expansion_stack]))])dnlm4_errprintn(m4_location[: the top level])])# _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.m4_define([_m4_defun_pro],[m4_ifndef([m4_expansion_stack], [_m4_defun_pro_outer[]])dnlm4_expansion_stack_push(m4_defn([m4_location($1)])[: $1 is expanded from...])dnlm4_pushdef([_m4_expanding($1)])dnl])m4_define([_m4_defun_pro_outer],[m4_copy([_m4_divert_diversion], [_m4_divert_dump])dnlm4_divert_push([GROW])dnl])# _m4_defun_epi(MACRO-NAME)# -------------------------# The Epilogue for Autoconf macros. MACRO-NAME only helps tracing# the PRO/EPI pairs.m4_define([_m4_defun_epi],[m4_popdef([_m4_expanding($1)])dnlm4_expansion_stack_pop()dnlm4_ifndef([m4_expansion_stack], [_m4_defun_epi_outer[]])dnlm4_provide([$1])dnl])m4_define([_m4_defun_epi_outer],[m4_undefine([_m4_divert_dump])dnlm4_divert_pop([GROW])dnlm4_undivert([GROW])dnl])# m4_defun(NAME, EXPANSION)# -------------------------# Define a macro which automatically provides itself. Add machinery# so the macro automatically switches expansion to the diversion# stack if it is not already using it. 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.m4_define([m4_defun],[m4_define([m4_location($1)], m4_location)dnlm4_define([$1],[_m4_defun_pro([$1])$2[]_m4_defun_epi([$1])])])# m4_defun_once(NAME, EXPANSION)# ------------------------------# As m4_defun, but issues the EXPANSION only once, and warns if used# several times.m4_define([m4_defun_once],[m4_define([m4_location($1)], m4_location)dnlm4_define([$1],[m4_provide_if([$1],[m4_warn([syntax], [$1 invoked multiple times])],[_m4_defun_pro([$1])$2[]_m4_defun_epi([$1])])])])# m4_pattern_forbid(ERE, [WHY])# -----------------------------# Declare that no token matching the extended regular expression ERE# should be seen in the output but if...m4_define([m4_pattern_forbid], [])# m4_pattern_allow(ERE)# ---------------------# ... but if that token matches the extended regular expression ERE.# Both used via traces.m4_define([m4_pattern_allow], [])## ----------------------------- #### Dependencies between macros. #### ----------------------------- ### m4_before(THIS-MACRO-NAME, CALLED-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. 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(limits.h)], [AC_CHECK_HEADERS(limits.h)])# which is just the same as# m4_require([AC_PROG_CC])# m4_require([AC_CHECK_HEADERS(limits.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)'.m4_define([m4_require],[m4_ifdef([_m4_expanding($1)],[m4_fatal([$0: circular dependency of $1])])dnlm4_ifndef([_m4_divert_dump],[m4_fatal([$0($1): cannot be used outside of an ]dnlm4_bmatch([$0], [^AC_], [[AC_DEFUN]], [[m4_defun]])['d macro])])dnlm4_provide_if([$1],[],[_m4_require_call([$1], [$2])])dnl])# _m4_require_call(BODY-TO-EXPAND)# --------------------------------# If m4_require decides to expand the body, it calls this macro.m4_define([_m4_require_call],[m4_define([_m4_divert_grow], m4_decr(_m4_divert_grow))dnlm4_divert_push(_m4_divert_grow)dnlm4_default([$2], [$1])m4_provide_if([$1],[],[m4_warn([syntax],[$1 is m4_require'd but not m4_defun'd])])dnlm4_divert(m4_defn([_m4_divert_dump]))dnlm4_undivert(_m4_divert_grow)dnlm4_divert_pop(_m4_divert_grow)dnlm4_define([_m4_divert_grow], m4_incr(_m4_divert_grow))dnl])# _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_ifval([$2], [[$2]], [[$1]]),[],[m4_provide(m4_ifval([$2], [[$2]], [[$1]]))[]$1])])# m4_provide(MACRO-NAME)# ----------------------m4_define([m4_provide],[m4_define([m4_provide($1)])])# 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])])## -------------------- #### 9. 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])dnlm4_defn([m4_cr_LETTERS])dnl)# m4_cr_digits# ------------m4_define([m4_cr_digits], [0123456789])# 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])dnlm4_defn([m4_cr_digits])dnl)# 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]))dnlm4_defn([m4_re_string])dnl)# m4_tolower(STRING)# m4_toupper(STRING)# ------------------# These macros lowercase and uppercase strings.m4_define([m4_tolower],[m4_translit([$1], m4_defn([m4_cr_LETTERS]), m4_defn([m4_cr_letters]))])m4_define([m4_toupper],[m4_translit([$1], m4_defn([m4_cr_letters]), 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.## 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], []endm4_define([m4_split],[m4_ifval([$1], [_m4_split($@)])])m4_define([_m4_split],[m4_changequote(``, '')dnl[dnl Can't use m4_default here instead of m4_if, because m4_default usesdnl [ and ] as quotes.m4_bpatsubst(````$1'''',m4_if(``$2'',, ``[ ]+'', ``$2''),``], ['')]dnlm4_changequote([, ])])# 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 activeendm4_define([m4_flatten],[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## Because we want to preserve active symbols, STRING must be double-quoted.## Then notice the 2 last patterns: they are in charge of removing the# leading/trailing spaces. Why not just `[^ ]'? Because they are# applied to doubly quoted strings, i.e. more or less [[STRING]]. So# if there is a leading space in STRING, then it is the *third*# character, since there are two leading `['; equally for the last pattern.m4_define([m4_strip],[m4_bpatsubsts([[$1]],[[ ]+], [ ],[^\(..\) ], [\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 activeendm4_define([m4_normalize],[m4_strip(m4_flatten([$1]))])# m4_join(SEP, ARG1, ARG2...)# ---------------------------# Produce ARG1SEPARG2...SEPARGn.m4_defun([m4_join],[m4_case([$#],[1], [],[2], [[$2]],[[$2][$1]$0([$1], m4_shiftn(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'.## This macro is robust to active symbols. It can be used to grow# strings.## | m4_define(active, ACTIVE)# | m4_append([sentence], [This is an])# | m4_append([sentence], [ active ])# | m4_append([sentence], [symbol.])# | 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)# | m4_append([hooks], [m4_define([act1], [act2])])# | m4_append([hooks], [m4_define([act2], [active])])# | m4_undefine([active])# | act1# | hooks# | act1# => act1# =># => activem4_define([m4_append],[m4_define([$1],m4_ifdef([$1], [m4_defn([$1])$3])[$2])])# m4_append_uniq(MACRO-NAME, STRING, [SEPARATOR])# -----------------------------------------------# As `m4_append', but append only if not yet present.m4_define([m4_append_uniq],[m4_ifdef([$1],[m4_bmatch([$3]m4_defn([$1])[$3], m4_re_escape([$3$2$3]), [],[m4_append($@)])],[m4_append($@)])])# 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.## 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,# what complicates it a bit. The algorithm is stupid 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.m4_define([m4_text_wrap],[m4_pushdef([m4_Prefix], [$2])dnlm4_pushdef([m4_Prefix1], m4_default([$3], [m4_Prefix]))dnlm4_pushdef([m4_Width], m4_default([$4], 79))dnlm4_pushdef([m4_Cursor], m4_qlen(m4_Prefix1))dnlm4_pushdef([m4_Separator], [])dnlm4_Prefix1[]dnlm4_if(m4_eval(m4_qlen(m4_Prefix1) > m4_len(m4_Prefix)),1, [m4_define([m4_Cursor], m4_len(m4_Prefix))m4_Prefix],m4_if(m4_eval(m4_qlen(m4_Prefix1) < m4_len(m4_Prefix)),[0], [],[m4_define([m4_Cursor], m4_len(m4_Prefix))[]dnlm4_for(m4_Space, m4_qlen(m4_Prefix1), m4_eval(m4_len(m4_Prefix) - 1),[], [ ])])[]dnl)[]dnlm4_foreach_w([m4_Word], [$1],[m4_define([m4_Cursor], m4_eval(m4_Cursor + m4_qlen(m4_defn([m4_Word])) + 1))dnldnl New line if too long, else insert a space unless it is the firstdnl of the words.m4_if(m4_eval(m4_Cursor > m4_Width),1, [m4_define([m4_Cursor],m4_eval(m4_len(m4_Prefix) + m4_qlen(m4_defn([m4_Word])) + 1))]m4_Prefix,[m4_Separator])[]dnlm4_defn([m4_Word])[]dnlm4_define([m4_Separator], [ ])])dnlm4_popdef([m4_Separator])dnlm4_popdef([m4_Cursor])dnlm4_popdef([m4_Width])dnlm4_popdef([m4_Prefix1])dnlm4_popdef([m4_Prefix])dnl])# m4_text_box(MESSAGE, [FRAME-CHARACTER = `-'])# ---------------------------------------------m4_define([m4_text_box],[@%:@@%:@ m4_bpatsubst([$1], [.], m4_if([$2], [], [[-]], [[$2]])) @%:@@%:@@%:@@%:@ $1 @%:@@%:@@%:@@%:@ m4_bpatsubst([$1], [.], m4_if([$2], [], [[-]], [[$2]])) @%:@@%:@[]dnl])# m4_qlen(STRING)# ---------------# Expands to the length of STRING after autom4te converts all quadrigraphs.m4_define([m4_qlen],[m4_len(m4_bpatsubsts([[$1]], [@\(<:\|:>\|S|\|%:\)@], [P], [@&t@]))])# m4_qdelta(STRING)# -----------------# Expands to the net change in the length of STRING from autom4te converting the# quadrigraphs in STRING. This number is always negative or zero.m4_define([m4_qdelta],[m4_eval(m4_qlen([$1]) - m4_len([$1]))])## ----------------------- #### 10. Number processing. #### ----------------------- ### m4_sign(A)# ----------## The sign of the integer A.m4_define([m4_sign],[m4_bmatch([$1],[^-], -1,[^0+], 0,1)])# m4_cmp(A, B)# ------------## Compare two integers.# A < B -> -1# A = B -> 0# A > B -> 1m4_define([m4_cmp],[m4_sign(m4_eval([$1 - $2]))])# m4_list_cmp(A, B)# -----------------## Compare the two lists of integers 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)) -> -1m4_define([m4_list_cmp],[m4_if([$1$2], [()()], 0,[$1], [()], [$0((0), [$2])],[$2], [()], [$0([$1], (0))],[m4_case(m4_cmp(m4_car$1, m4_car$2),-1, -1,1, 1,0, [$0((m4_shift$1), (m4_shift$2))])])])## ------------------------ #### 11. Version processing. #### ------------------------ ### m4_version_unletter(VERSION)# ----------------------------# Normalize beta version numbers with letters to numbers only for comparison.## Nl -> (N+1).-1.(l#)##i.e., 2.14a -> 2.15.-1.1, 2.14b -> 2.15.-1.2, etc.# This macro is absolutely not robust to active macro, it expects# reasonable version numbers and is valid up to `z', no double letters.m4_define([m4_version_unletter],[m4_translit(m4_bpatsubsts([$1],[\([0-9]+\)\([abcdefghi]\)],[m4_eval(\1 + 1).-1.\2],[\([0-9]+\)\([jklmnopqrs]\)],[m4_eval(\1 + 1).-1.1\2],[\([0-9]+\)\([tuvwxyz]\)],[m4_eval(\1 + 1).-1.2\2]),[abcdefghijklmnopqrstuvwxyz],[12345678901234567890123456])])# 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 >m4_define([m4_version_compare],[m4_list_cmp((m4_split(m4_version_unletter([$1]), [\.])),(m4_split(m4_version_unletter([$2]), [\.])))])# m4_PACKAGE_NAME# m4_PACKAGE_TARNAME# m4_PACKAGE_VERSION# m4_PACKAGE_STRING# m4_PACKAGE_BUGREPORT# --------------------m4_include([m4sugar/version.m4])# m4_version_prereq(VERSION, [IF-OK], [IF-NOT = FAIL])# ----------------------------------------------------# Check this Autoconf version against VERSION.m4_define([m4_version_prereq],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]), [$1]), -1,[m4_default([$3],[m4_fatal([Autoconf version $1 or higher is required],63)])],[$2])[]dnl])## ------------------- #### 12. 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 that 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])])])## ------------------------ #### 13. Setting M4sugar up. #### ------------------------ ### m4_init# -------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$])# _m4_divert_diversion should be defined:m4_divert_push([KILL])# Check the divert push/pop perfect balance.m4_wrap([m4_divert_pop([])m4_ifdef([_m4_divert_diversion],[m4_fatal([$0: unbalanced m4_divert_push:]_m4_divert_n_stack)])[]])])