mirror of
git://git.sv.gnu.org/autoconf
synced 2025-01-24 10:54:42 +08:00
Merge branch 'master' of /home/eggert/src/gnu/autoconf-savannah/
This commit is contained in:
commit
a574f37683
95
ChangeLog
95
ChangeLog
@ -1,3 +1,98 @@
|
||||
2007-10-16 Eric Blake <ebb9@byu.net>
|
||||
|
||||
m4_map is a looping construct.
|
||||
* lib/m4sugar/m4sugar.m4 (m4_map, _m4_map, m4_map_sep): Move.
|
||||
|
||||
Fix m4_map, and add some more utility macros.
|
||||
* lib/m4sugar/m4sugar.m4 (m4_apply, m4_count, m4_dquote_elt)
|
||||
(m4_echo, m4_make_list): New documented macros.
|
||||
(_m4_quote, _m4_shift2): New helper macros.
|
||||
(m4_map): Change semantics to allow calling macro without
|
||||
arguments.
|
||||
(m4_map_sep): Likewise. Also change semantics to quote separator,
|
||||
to match m4_join and m4_append.
|
||||
(m4_version_unletter): Fix use of m4_map.
|
||||
* doc/autoconf.texi (Evaluation Macros): Document m4_apply,
|
||||
m4_count, m4_dquote_elt, m4_echo, m4_make_list.
|
||||
(Text processing Macros): Mention m4_dquote as a faster
|
||||
alternative to joining with commas.
|
||||
(Looping constructs): Document m4_map, m4_map_sep.
|
||||
* NEWS: Mention new macros.
|
||||
|
||||
A few more m4sugar improvements, to benefit libtool.
|
||||
* lib/m4sugar/m4sugar.m4 (m4_bpatsubsts, _m4_shiftn): Reduce size
|
||||
of expansion by avoiding extra uses of $@.
|
||||
(m4_shiftn): Avoid extra dnl, and forbid shifting by 0.
|
||||
(_m4_cdr): New helper macro.
|
||||
(_m4_map, m4_map_sep): Use it to reduce size of expansion.
|
||||
(_m4_shift3): New helper macro.
|
||||
(_m4_foreach): Swap argument order, and use new macro to reduce
|
||||
size of expansion.
|
||||
* doc/autoconf.texi (Looping constructs) <m4_shiftn>: Mention that
|
||||
count must be positive.
|
||||
|
||||
* doc/autoconf.texi (Evaluation Macros) <m4_expand>: Fix typo.
|
||||
Reported by Ralf Wildenhues.
|
||||
|
||||
2007-10-15 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
|
||||
|
||||
* doc/autoconf.texi (Portable Shell): Improve description of zsh
|
||||
4.x function subshell bug with exit and trap.
|
||||
|
||||
2007-10-15 Eric Blake <ebb9@byu.net>
|
||||
|
||||
Enhance AS_HELP_STRING.
|
||||
* lib/m4sugar/m4sugar.m4 (m4_text_wrap): Don't expand arguments,
|
||||
and reduce number of expansions.
|
||||
* lib/m4sugar/m4sh.m4 (AS_HELP_STRING): Rework to use m4_expand,
|
||||
and to take indent and wrap column numbers.
|
||||
* tests/m4sh.at (AS@&t@_HELP_STRING): Update the test.
|
||||
* doc/autoconf.texi (Pretty Help Strings): Document details about
|
||||
arguments.
|
||||
(Text processing Macros): Minor tweaks.
|
||||
* NEWS: Document this change.
|
||||
|
||||
Fix 2007-10-03 regression with AT_SETUP([a, b]).
|
||||
* lib/m4sugar/m4sugar.m4 (m4_expand): New macro.
|
||||
(m4_text_box): Use it.
|
||||
* lib/autotest/general.m4 (AT_SETUP): Use it.
|
||||
* lib/m4sugar/m4sh.m4 (_AS_RUN): Use it.
|
||||
* tests/autotest.at (AT_CHECK_AT_TITLE_CHAR): Test this.
|
||||
* NEWS: Revert caveat about semantics change on comma.
|
||||
* doc/autoconf.texi (Evaluation Macros): Document m4_expand.
|
||||
|
||||
2007-10-13 Eric Blake <ebb9@byu.net>
|
||||
|
||||
Change m4_join to match libtool's ltsugar semantics.
|
||||
* lib/m4sugar/m4sugar.m4 (m4_join): Just define this, not defun.
|
||||
Ignore empty arguments, using...
|
||||
(_m4_join): ...this new helper.
|
||||
* tests/m4sugar.at (m4@&t@_join): New test.
|
||||
* doc/autoconf.texi (Text processing Macros): Document new
|
||||
semantics of m4_join.
|
||||
|
||||
Make AC_PREREQ faster and more robust.
|
||||
* lib/m4sugar/m4sugar.m4 (m4_ignore, m4_unquote): New macros.
|
||||
(m4_version_prereq): Inline constant expansions.
|
||||
(m4_list_cmp): Reduce number of expansions, by avoiding m4_case.
|
||||
Rewrite in terms of [] list, not () list.
|
||||
(_m4_list_cmp, _m4_version_unletter): New helper macros.
|
||||
(m4_version_unletter): Write wrapper around new implementation to
|
||||
preserve old semantics.
|
||||
(m4_version_compare): Pass correct type of list, and avoid
|
||||
overhead of flattening expressions too early.
|
||||
(m4_do): Move to be near other quoting macros.
|
||||
(m4_max, m4_min): Always result in decimal output.
|
||||
* doc/autoconf.texi (Looping constructs): Add m4_car, m4_cdr.
|
||||
Move m4_do...
|
||||
(Evaluation Macros): ...here. Add m4_ignore, m4_unquote.
|
||||
(Text processing Macros): Move m4_version_compare...
|
||||
(Number processing Macros): ...to this new node; document m4_cmp,
|
||||
m4_list_cmp, m4_sign, m4_max, m4_min.
|
||||
* tests/m4sugar.at (m4@&t@_version_compare): Enhance test, to pick
|
||||
up on bugs fixed by this patch.
|
||||
* NEWS: Document new macros.
|
||||
|
||||
2007-10-12 Eric Blake <ebb9@byu.net>
|
||||
|
||||
* doc/autoconf.texi (Text processing Macros): Fix bad merge.
|
||||
|
33
NEWS
33
NEWS
@ -50,7 +50,13 @@ GNU Autoconf NEWS - User visible changes.
|
||||
|
||||
** AC_USE_SYSTEM_EXTENSIONS now defines _ALL_SOURCE for Interix platforms.
|
||||
|
||||
** AS_HELP_STRING no longer underquotes its first argument.
|
||||
** AS_HELP_STRING no longer underquotes its first argument; it also handles
|
||||
the case where the first argument contains single-quoted commas.
|
||||
For example, "AS_HELP_STRING([-a, [--arg[=foo]]], [bar])" produces:
|
||||
" -a, --arg=[foo] bar"
|
||||
Additionally, the macro now takes two additional arguments,
|
||||
indent-column and wrap-column; these should not normally be needed,
|
||||
but can be used to fine-tune how the output text is wrapped.
|
||||
|
||||
** The command 'autoconf -' now correctly processes a file from stdin.
|
||||
|
||||
@ -61,10 +67,7 @@ GNU Autoconf NEWS - User visible changes.
|
||||
expanded libdir value of /usr/lib, not /usr//lib.
|
||||
|
||||
** AT_SETUP now handles macro expansions properly when calculating line
|
||||
length. However, as a side effect, any whitespace immediately
|
||||
following a single-quoted comma is lost. If you previously used
|
||||
AT_SETUP([a, b]), you could change to AT_SETUP([a,[] b]) to keep
|
||||
the space.
|
||||
length.
|
||||
|
||||
** Autotest now determines $srcdir correctly.
|
||||
|
||||
@ -78,18 +81,20 @@ GNU Autoconf NEWS - User visible changes.
|
||||
- The following macros were previously available as undocumented
|
||||
interfaces; the macros are now documented as stable interfaces.
|
||||
|
||||
__oline__ m4_assert m4_bmatch m4_bpatsubsts m4_case
|
||||
m4_default m4_divert_once m4_divert_pop m4_divert_push
|
||||
__oline__ m4_assert m4_bmatch m4_bpatsubsts m4_car m4_case
|
||||
m4_cdr m4_default m4_divert_once m4_divert_pop m4_divert_push
|
||||
m4_divert_text m4_do m4_errprintn m4_fatal m4_flatten
|
||||
m4_ifndef m4_ifset m4_ifval m4_ifvaln m4_location
|
||||
m4_n m4_shiftn m4_strip m4_version_compare m4_warn
|
||||
m4_n m4_shiftn m4_strip m4_warn
|
||||
|
||||
- The following macros were previously available as undocumented
|
||||
interfaces, but had bugs. Packages that relied on the
|
||||
undocumented and buggy behavior should analyze their code to make
|
||||
sure it still works with the new documented behavior.
|
||||
interfaces, but had bug fixes or semantic changes as part of this
|
||||
release. Packages that relied on the undocumented behavior
|
||||
should be analyzed to make sure they will still work with the
|
||||
new documented behavior.
|
||||
|
||||
m4_join m4_text_box m4_text_wrap
|
||||
m4_cmp m4_list_cmp m4_join m4_map m4_map_sep m4_sign
|
||||
m4_text_box m4_text_wrap m4_version_compare
|
||||
|
||||
- Packages using the undocumented m4sugar macro m4_PACKAGE_VERSION
|
||||
should consider using the new AC_AUTOCONF_VERSION instead.
|
||||
@ -115,7 +120,9 @@ GNU Autoconf NEWS - User visible changes.
|
||||
be used to take action depending on whether anything was appended.
|
||||
|
||||
** The following m4sugar macros are new:
|
||||
m4_cond m4_newline m4_shift2 m4_shift3
|
||||
m4_apply m4_cond m4_count m4_dquote_elt m4_echo m4_expand
|
||||
m4_ignore m4_make_list m4_max m4_min m4_newline m4_shift2
|
||||
m4_shift3 m4_unquote
|
||||
|
||||
** Warnings are now generated by default when an installer invokes
|
||||
'configure' with an unknown --enable-* or --with-* option.
|
||||
|
@ -455,6 +455,7 @@ Programming in M4sugar
|
||||
* Looping constructs:: Iteration in M4
|
||||
* Evaluation Macros:: More quotation and evaluation control
|
||||
* Text processing Macros:: String manipulation in M4
|
||||
* Number processing Macros:: Arithmetic computation in M4
|
||||
* Forbidden Patterns:: Catching unexpanded macros
|
||||
|
||||
Writing Autoconf Macros
|
||||
@ -10087,6 +10088,7 @@ define your own macros into these namespaces.
|
||||
* Looping constructs:: Iteration in M4
|
||||
* Evaluation Macros:: More quotation and evaluation control
|
||||
* Text processing Macros:: String manipulation in M4
|
||||
* Number processing Macros:: Arithmetic computation in M4
|
||||
* Forbidden Patterns:: Catching unexpanded macros
|
||||
@end menu
|
||||
|
||||
@ -10585,7 +10587,42 @@ Expand to @var{text}, and add a newline if @var{text} is not empty.
|
||||
@node Looping constructs
|
||||
@subsection Looping constructs
|
||||
|
||||
The following macros implement loops in M4.
|
||||
The following macros are useful in implementing recursive algorithms in
|
||||
M4, including loop operations. An M4 list is formed by quoting a list
|
||||
of quoted elements; generally the lists are comma-separated, although
|
||||
@code{m4_foreach_w} is whitespace-separated. For example, the list
|
||||
@samp{[[a], [b,c]]} contains two elements: @samp{[a]} and @samp{[b,c]}.
|
||||
It is common to see lists with unquoted elements when those elements are
|
||||
not likely to be macro names, as in @samp{[fputc_unlocked,
|
||||
fgetc_unlocked]}.
|
||||
|
||||
@defmac m4_car (@var{list})
|
||||
@msindex{car}
|
||||
Expands to the quoted first element of the comma-separated quoted
|
||||
@var{list}. Often used with @code{m4_cdr} to recursively iterate
|
||||
through a list. Generally, when using quoted lists of quoted elements,
|
||||
@code{m4_car} should be called without any extra quotes.
|
||||
@end defmac
|
||||
|
||||
@defmac m4_cdr (@var{list})
|
||||
@msindex{cdr}
|
||||
Expands to a quoted list of all but the first element of the
|
||||
comma-separated quoted @var{list}, or the empty string if @var{list} had
|
||||
only one element. Generally, when using quoted lists of quoted
|
||||
elements, @code{m4_cdr} should be called without any extra quotes.
|
||||
|
||||
For example, this is a simple implementation of @code{m4_map}; note how
|
||||
each iteration checks for the end of recursion, then merely applies the
|
||||
first argument to the first element of the list, then recurses with the
|
||||
rest of the list. (The actual implementation in M4sugar is a bit more
|
||||
involved, to gain some speed and share code with @code{m4_map_sep}).
|
||||
@example
|
||||
m4_define([m4_map], [m4_ifval([$2],
|
||||
[m4_apply([$1], m4_car($2))[]$0([$1], m4_cdr($2))])])dnl
|
||||
m4_map([ m4_eval], [[[1]], [[1+1]], [[10],[16]]])
|
||||
@result{} 1 2 a
|
||||
@end example
|
||||
@end defmac
|
||||
|
||||
@defmac m4_for (@var{var}, @var{first}, @var{last}, @ovar{step}, @
|
||||
@var{expression})
|
||||
@ -10607,8 +10644,9 @@ outputs two lines:
|
||||
@example
|
||||
m4_foreach([myvar], [[foo], [bar, baz]],
|
||||
[echo myvar
|
||||
])
|
||||
|
||||
])dnl
|
||||
@result{}echo foo
|
||||
@result{}echo bar, baz
|
||||
@end example
|
||||
@end defmac
|
||||
|
||||
@ -10622,13 +10660,26 @@ The deprecated macro @code{AC_FOREACH} is an alias of
|
||||
@code{m4_foreach_w}.
|
||||
@end defmac
|
||||
|
||||
The following macros are useful in implementing recursive algorithms.
|
||||
|
||||
@defmac m4_do (@dots{})
|
||||
@msindex{do}
|
||||
This macro loops over its arguments and expands each one in sequence.
|
||||
Its main use is for readability; it allows the use of indentation and
|
||||
fewer @code{dnl} to result in the same expansion.
|
||||
@defmac m4_map (@var{macro}, @var{list})
|
||||
@defmacx m4_map_sep (@var{macro}, @var{separator}, @var{list})
|
||||
Loop over the comma separated quoted list of argument descriptions in
|
||||
@var{list}, and invoke @var{macro} with the arguments. An argument
|
||||
description is in turn a comma-separated quoted list of quoted elements,
|
||||
suitable for @code{m4_apply}, making it possible to invoke @var{macro}
|
||||
without arguments if an argument description is empty.
|
||||
@code{m4_map_sep} additionally outputs @var{separator} between macro
|
||||
invocations, with no additional expansion of the separator.
|
||||
@example
|
||||
m4_map([m4_count], [])
|
||||
@result{}
|
||||
m4_map([ m4_count], [[],
|
||||
[[1]],
|
||||
[[1], [2]]])
|
||||
@result{} 0 1 2
|
||||
m4_map_sep([m4_eval], [,], [[[1+2]],
|
||||
[[10], [16]]])
|
||||
@result{}3,a
|
||||
@end example
|
||||
@end defmac
|
||||
|
||||
@defmac m4_shiftn (@var{count}, @dots{})
|
||||
@ -10639,7 +10690,8 @@ fewer @code{dnl} to result in the same expansion.
|
||||
@msindex{shiftn}
|
||||
@code{m4_shiftn} performs @var{count} iterations of @code{m4_shift},
|
||||
along with validation that enough arguments were passed in to match the
|
||||
shift count. @code{m4_shift2} and @code{m4_shift3} are specializations
|
||||
shift count, and that the count is positive. @code{m4_shift2} and
|
||||
@code{m4_shift3} are specializations
|
||||
of @code{m4_shiftn}, introduced in Autoconf 2.62, and are more efficient
|
||||
for two and three shifts, respectively.
|
||||
@end defmac
|
||||
@ -10649,53 +10701,188 @@ for two and three shifts, respectively.
|
||||
@subsection Evaluation Macros
|
||||
|
||||
The following macros give some control over the order of the evaluation
|
||||
by adding or removing levels of quotes. They are meant for hard-core M4
|
||||
programmers.
|
||||
by adding or removing levels of quotes.
|
||||
|
||||
@defmac m4_apply (@var{macro}, @var{list})
|
||||
@msindex apply
|
||||
Apply the elements of the quoted, comma-separated @var{list} as the
|
||||
arguments to @var{macro}. If @var{list} is empty, invoke @var{macro}
|
||||
without arguments.
|
||||
@example
|
||||
m4_apply([m4_count], [])
|
||||
@result{}0
|
||||
m4_apply([m4_count], [[]])
|
||||
@result{}1
|
||||
m4_apply([m4_count], [[1], [2]])
|
||||
@result{}2
|
||||
m4_apply([m4_join], [[|], [1], [2]])
|
||||
@result{}1|2
|
||||
@end example
|
||||
@end defmac
|
||||
|
||||
@defmac m4_count (@var{arg1}, @dots{})
|
||||
@msindex{count}
|
||||
This macro returns the decimal count of the number of arguments it was
|
||||
passed.
|
||||
@end defmac
|
||||
|
||||
@defmac m4_do (@var{arg1}, @dots{})
|
||||
@msindex{do}
|
||||
This macro loops over its arguments and expands each @var{arg} in
|
||||
sequence. Its main use is for readability; it allows the use of
|
||||
indentation and fewer @code{dnl} to result in the same expansion.
|
||||
@end defmac
|
||||
|
||||
@defmac m4_dquote (@var{arg1}, @dots{})
|
||||
@msindex{dquote}
|
||||
Return the arguments as a quoted list of quoted arguments.
|
||||
Conveniently, if there is just one @var{arg}, this effectively adds a
|
||||
level of quoting.
|
||||
@end defmac
|
||||
|
||||
@defmac m4_dquote_elt (@var{arg1}, @dots{})
|
||||
@msindex{dquote_elt}
|
||||
Return the arguments as a series of double-quoted arguments. Whereas
|
||||
@code{m4_dquote} returns a single argument, @code{m4_dquote_elt} returns
|
||||
as many arguments as it was passed.
|
||||
@end defmac
|
||||
|
||||
@defmac m4_echo (@var{arg1}, @dots{})
|
||||
@msindex{echo}
|
||||
Return the arguments, with the same level of quoting. Other than
|
||||
discarding whitespace after unquoted commas, this macro is a no-op.
|
||||
@end defmac
|
||||
|
||||
@defmac m4_expand (@var{arg})
|
||||
@msindex{expand}
|
||||
Return the expansion of @var{arg} as a quoted string. Whereas
|
||||
@code{m4_quote} is designed to collect expanded text into a single
|
||||
argument, @code{m4_expand} is designed to perform one level of expansion
|
||||
on quoted text. The distinction is in the treatment of whitespace
|
||||
following a comma in the original @var{arg}. Any time multiple
|
||||
arguments are collected into one with @code{m4_quote}, the M4 argument
|
||||
collection rules discard the whitespace. However, with @code{m4_expand},
|
||||
whitespace is discarded only if it results from unquoted commas in the
|
||||
expansion of macros contained in @var{arg}.
|
||||
|
||||
@example
|
||||
m4_define([active], [ACT, IVE])dnl
|
||||
m4_define([active2], [[ACT, IVE]])dnl
|
||||
m4_quote(active, active)
|
||||
@result{}ACT,IVE,ACT,IVE
|
||||
m4_expand([active, active])
|
||||
@result{}ACT,IVE, ACT,IVE
|
||||
m4_quote(active2, active2)
|
||||
@result{}ACT, IVE,ACT, IVE
|
||||
m4_expand([active2, active2])
|
||||
@result{}ACT, IVE, ACT, IVE
|
||||
@end example
|
||||
@end defmac
|
||||
|
||||
@defmac m4_ignore (@dots{})
|
||||
@msindex{ignore}
|
||||
This macro was introduced in Autoconf 2.62. Expands to nothing,
|
||||
ignoring all of its arguments. By itself, this isn't very useful.
|
||||
However, it can be used to conditionally ignore an arbitrary number of
|
||||
arguments, by making a decision about which macro name to apply to a
|
||||
list of arguments.
|
||||
@example
|
||||
dnl foo outputs a message only if [debug] is defined.
|
||||
m4_define([foo],
|
||||
[m4_ifdef([debug],[AC_MSG_NOTICE],[m4_ignore])([debug message])])
|
||||
@end example
|
||||
|
||||
Note that for earlier versions of Autoconf, the macro @code{__gnu__} can
|
||||
serve the same purpose, although it is less readable.
|
||||
@end defmac
|
||||
|
||||
@defmac m4_make_list (@var{arg1}, @dots{})
|
||||
@msindex{make_list}
|
||||
This macro exists to aid debugging of M4sugar algorithms. Its net
|
||||
effect is similar to @code{m4_dquote}---it produces a quoted list of
|
||||
quoted arguments, for each @var{arg}. The difference is that this
|
||||
version uses a comma-newline separator instead of just comma, to improve
|
||||
readability of the list; with the result that it is less efficient than
|
||||
@code{m4_dquote}.
|
||||
@example
|
||||
m4_define([zero],[0])m4_define([one],[1])m4_define([two],[2])dnl
|
||||
m4_dquote(zero, [one], [[two]])
|
||||
@result{}[0],[one],[[two]]
|
||||
m4_make_list(zero, [one], [[two]])
|
||||
@result{}[0],
|
||||
@result{}[one],
|
||||
@result{}[[two]]
|
||||
m4_foreach([number], m4_dquote(zero, [one], [[two]]), [ number])
|
||||
@result{} 0 1 two
|
||||
m4_foreach([number], m4_make_list(zero, [one], [[two]]), [ number])
|
||||
@result{} 0 1 two
|
||||
@end example
|
||||
@end defmac
|
||||
|
||||
@c m4_noquote is too dangerous to document - it invokes macros that
|
||||
@c probably rely on @samp{[]} nested quoting for proper operation. The
|
||||
@c user should generally prefer m4_unquote instead.
|
||||
|
||||
@defmac m4_quote (@var{arg1}, @dots{})
|
||||
@msindex{quote}
|
||||
Return the arguments as a single entity, i.e., wrap them into a pair of
|
||||
quotes.
|
||||
quotes. This effectively collapses multiple arguments into one,
|
||||
although it loses whitespace after unquoted commas in the process.
|
||||
@end defmac
|
||||
|
||||
The following example aims at emphasizing the difference between (i), not
|
||||
using these macros, (ii), using @code{m4_quote}, and (iii), using
|
||||
@code{m4_dquote}.
|
||||
@defmac m4_unquote (@var{arg1}, @dots{})
|
||||
@msindex{unquote}
|
||||
This macro was introduced in Autoconf 2.62. Expand each argument,
|
||||
separated by commas. For a single @var{arg}, this effectively removes a
|
||||
layer of quoting, and @code{m4_unquote([@var{arg}])} is more efficient
|
||||
than the equivalent @code{m4_do([@var{arg}])}. For multiple arguments,
|
||||
this results in an unquoted list of expansions. This is commonly used
|
||||
with @code{m4_split}, in order to convert a single quoted list into a
|
||||
series of quoted elements.
|
||||
@end defmac
|
||||
|
||||
The following example aims at emphasizing the difference between several
|
||||
scenarios: not using these macros, using @code{m4_defn}, using
|
||||
@code{m4_quote}, using @code{m4_dquote}, and using @code{m4_expand}.
|
||||
|
||||
@example
|
||||
$ @kbd{cat example.m4}
|
||||
# Overquote, so that quotes are visible.
|
||||
m4_define([show], [$[]1 = [$1], $[]@@ = [$@@]])
|
||||
m4_define([mkargs], [1, 2, 3])
|
||||
m4_define([a], [A])
|
||||
m4_define([mkargs], [1, 2[,] 3])
|
||||
m4_define([arg1], [[$1]])
|
||||
m4_divert(0)dnl
|
||||
m4_divert([0])dnl
|
||||
show(a, b)
|
||||
show([a, b])
|
||||
show(m4_quote(a, b))
|
||||
show(m4_dquote(a, b))
|
||||
show(m4_expand([a, b]))
|
||||
|
||||
arg1(mkargs)
|
||||
arg1([mkargs])
|
||||
arg1(m4_defn([mkargs]))
|
||||
arg1(m4_quote(mkargs))
|
||||
arg1(m4_dquote(mkargs))
|
||||
arg1(m4_expand([mkargs]))
|
||||
$ @kbd{autom4te -l m4sugar example.m4}
|
||||
$1 = a, $@@ = [a],[b]
|
||||
$1 = a,b, $@@ = [a,b]
|
||||
$1 = [a],[b], $@@ = [[a],[b]]
|
||||
$1 = A, $@@ = [A],[b]
|
||||
$1 = a, b, $@@ = [a, b]
|
||||
$1 = A,b, $@@ = [A,b]
|
||||
$1 = [A],[b], $@@ = [[A],[b]]
|
||||
$1 = A, b, $@@ = [A, b]
|
||||
|
||||
1
|
||||
mkargs
|
||||
1, 2, 3
|
||||
1,2,3
|
||||
[1],[2],[3]
|
||||
1, 2[,] 3
|
||||
1,2, 3
|
||||
[1],[2, 3]
|
||||
1,2, 3
|
||||
@end example
|
||||
|
||||
|
||||
@node Text processing Macros
|
||||
@subsection Text processing Macros
|
||||
@subsection String manipulation in M4
|
||||
|
||||
The following macros may be used to manipulate strings in M4.
|
||||
They are not intended for casual use.
|
||||
@ -10714,9 +10901,9 @@ are expanded during this macro; instead, they are expanded when
|
||||
|
||||
@code{m4_append} can be used to grow strings, and @code{m4_append_uniq}
|
||||
to grow strings without duplicating substrings. Additionally,
|
||||
@code{m4_append_uniq} takes two optional parameters; @var{if-uniq} is
|
||||
expanded if @var{string} was appended, and @var{if-duplicate} is
|
||||
expanded if @var{string} was already present.
|
||||
@code{m4_append_uniq} takes two optional parameters as of Autoconf 2.62;
|
||||
@var{if-uniq} is expanded if @var{string} was appended, and
|
||||
@var{if-duplicate} is expanded if @var{string} was already present.
|
||||
|
||||
@example
|
||||
m4_define([active], [ACTIVE])dnl
|
||||
@ -10760,8 +10947,18 @@ still a quoted string.
|
||||
|
||||
@defmac m4_join (@ovar{separator}, @var{args}@dots{})
|
||||
@msindex{join}
|
||||
Concatenate each @var{arg}, separated by @var{separator}. The result is
|
||||
a quoted string.
|
||||
Concatenate each @var{arg}, separated by @var{separator}, with the
|
||||
exception that no back-to-back separators are issued for empty
|
||||
arguments. The result is a quoted string.
|
||||
@example
|
||||
m4_define([active], [ACTIVE])dnl
|
||||
m4_join([|], [one], [], [active], [two])
|
||||
@result{}one|active|two
|
||||
@end example
|
||||
|
||||
Note that if all you intend to do is join @var{args} with commas between
|
||||
them, to form a quoted list suitable for @code{m4_foreach}, it is more
|
||||
efficient to use @code{m4_dquote}.
|
||||
@end defmac
|
||||
|
||||
@defmac m4_newline
|
||||
@ -10822,25 +11019,27 @@ format those words to wrap within @var{width} columns, and without
|
||||
trailing whitespace. If given, @var{prefix1} is prepended to the first
|
||||
line, and @var{prefix} is prepended to each continuation line. As a
|
||||
special case, if @var{prefix1} is longer than @var{prefix}, the first
|
||||
line will consist solely of @var{prefix1}.
|
||||
line will consist solely of @var{prefix1}. No expansions occur on
|
||||
@var{prefix}, @var{prefix1}, or the words of @var{string}, although
|
||||
quadrigraphs are recognized.
|
||||
|
||||
For some examples:
|
||||
@example
|
||||
m4_text_wrap([Short string */], [@ @ @ ], [/* ], [20])
|
||||
m4_text_wrap([Short string */], [ ], [/* ], [20])
|
||||
@result{}/* Short string */
|
||||
m4_text_wrap([Much longer string */], [@ @ @ ], [/* ], [20])
|
||||
m4_text_wrap([Much longer string */], [ ], [/* ], [20])
|
||||
@result{}/* Much longer
|
||||
@result{}@ @ @ string */
|
||||
m4_text_wrap([Short doc.], [@ @ @ @ @ @ @ @ @ @ ], [@ @ --short ], [30])
|
||||
@result{}@ @ --short Short doc.
|
||||
m4_text_wrap([Short doc.], [@ @ @ @ @ @ @ @ @ @ ], [@ @ --too-wide ], [30])
|
||||
@result{}@ @ --too-wide
|
||||
@result{}@ @ @ @ @ @ @ @ @ @ Short doc.
|
||||
m4_text_wrap([Super long documentation.], [@ @ @ @ @ ],
|
||||
[@ @ --too-wide ], 30)
|
||||
@result{}@ @ --too-wide
|
||||
@result{}@ @ @ @ @ Super long
|
||||
@result{}@ @ @ @ @ documentation.
|
||||
@result{} string */
|
||||
m4_text_wrap([Short doc.], [ ], [ --short ], [30])
|
||||
@result{} --short Short doc.
|
||||
m4_text_wrap([Short doc.], [ ], [ --too-wide ], [30])
|
||||
@result{} --too-wide
|
||||
@result{} Short doc.
|
||||
m4_text_wrap([Super long documentation.], [ ],
|
||||
[ --too-wide ], 30)
|
||||
@result{} --too-wide
|
||||
@result{} Super long
|
||||
@result{} documentation.
|
||||
@end example
|
||||
@end defmac
|
||||
|
||||
@ -10852,17 +11051,76 @@ Return @var{string} with letters converted to upper or lower case,
|
||||
respectively.
|
||||
@end defmac
|
||||
|
||||
@node Number processing Macros
|
||||
@subsection Arithmetic computation in M4
|
||||
|
||||
The following macros make it easier to deal with arithmetic operations.
|
||||
Where a parameter is documented as taking an arithmetic expression, you
|
||||
can use anything that can be parsed by @code{m4_eval}.
|
||||
|
||||
@defmac m4_cmp (@var{expr-1}, @var{expr-2})
|
||||
@msindex{cmp}
|
||||
Compare the arithmetic expressions @var{expr-1} and @var{expr-2}, and
|
||||
expand to @samp{-1} if @var{expr-1} is smaller, @samp{0} if they are
|
||||
equal, and @samp{1} if @var{expr-1} is larger.
|
||||
@end defmac
|
||||
|
||||
@defmac m4_list_cmp (@var{list-1}, @var{list-2})
|
||||
@msindex{list_cmp}
|
||||
Compare the two M4 lists consisting of comma-separated arithmetic
|
||||
expressions, left to right. Expand to @samp{-1} for the first element
|
||||
pairing where the value from @var{list-1} is smaller, @samp{1} where the
|
||||
value from @var{list-2} is smaller, or @samp{0} if both lists have the
|
||||
same values. If one list is shorter than the other, the remaining
|
||||
elements of the longer list are compared against 0.
|
||||
@example
|
||||
m4_list_cmp([1, 0], [1])
|
||||
@result{}0
|
||||
m4_list_cmp([1, [1 * 0]], [1, 0])
|
||||
@result{}0
|
||||
m4_list_cmp([1, 2], [1, 0])
|
||||
@result{}1
|
||||
m4_list_cmp([1, [1+1], 3],[1, 2])
|
||||
@result{}1
|
||||
m4_list_cmp([1, 2, -3], [1, 2])
|
||||
@result{}-1
|
||||
m4_list_cmp([1, 0], [1, 2])
|
||||
@result{}-1
|
||||
m4_list_cmp([1], [1, 2])
|
||||
@result{}-1
|
||||
@end example
|
||||
@end defmac
|
||||
|
||||
@defmac m4_max (@var{arg1}, @dots{})
|
||||
@msindex{max}
|
||||
This macro was introduced in Autoconf 2.62. Expand to the decimal value
|
||||
of the maximum arithmetic expression among all the arguments.
|
||||
@end defmac
|
||||
|
||||
@defmac m4_min (@var{arg1}, @dots{})
|
||||
@msindex{min}
|
||||
This macro was introduced in Autoconf 2.62. Expand to the decimal value
|
||||
of the minimum arithmetic expression among all the arguments.
|
||||
@end defmac
|
||||
|
||||
@defmac m4_sign (@var{expr})
|
||||
@msindex{sign}
|
||||
Expand to @samp{-1} if the arithmetic expression @var{expr} is negative,
|
||||
@samp{1} if it is positive, and @samp{0} if it is zero.
|
||||
@end defmac
|
||||
|
||||
@anchor{m4_version_compare}
|
||||
@defmac m4_version_compare (@var{version-1}, @var{version-2})
|
||||
@msindex{version_compare}
|
||||
This macro was introduced in Autoconf 2.53. Compare the version strings
|
||||
@var{version-1} and @var{version-2}, and expand to @samp{-1} if
|
||||
@var{version-1} is smaller, @samp{0} if they are the same, or @samp{1}
|
||||
@var{version-2} is smaller. Version strings must be a list of elements
|
||||
separated by @samp{.}, where each element is a number along with an
|
||||
optional lower case letter. The comparison stops at the leftmost
|
||||
element that contains a difference, although a 0 element compares equal
|
||||
to a missing element.
|
||||
This macro was introduced in Autoconf 2.53, but had a number of
|
||||
usability limitations that were not lifted until Autoconf 2.62. Compare
|
||||
the version strings @var{version-1} and @var{version-2}, and expand to
|
||||
@samp{-1} if @var{version-1} is smaller, @samp{0} if they are the same,
|
||||
or @samp{1} @var{version-2} is smaller. Version strings must be a list
|
||||
of elements separated by @samp{.}, where each element is a number along
|
||||
with optional case-insensitive letters designating beta releases. The
|
||||
comparison stops at the leftmost element that contains a difference,
|
||||
although a 0 element compares equal to a missing element.
|
||||
|
||||
@example
|
||||
m4_version_compare([1.1], [2.0])
|
||||
@ -10875,6 +11133,8 @@ m4_version_compare([1.2], [1.1.1a])
|
||||
@result{}1
|
||||
m4_version_compare([1.0], [1])
|
||||
@result{}0
|
||||
m4_version_compare([1.1pre], [1.1PRE])
|
||||
@result{}0
|
||||
m4_version_compare([1.1a], [1,10])
|
||||
@result{}-1
|
||||
@end example
|
||||
@ -11800,15 +12060,13 @@ that are not found in all Bourne-compatible shells; restrict yourself
|
||||
to the lowest common denominator. Even @code{unset} is not supported
|
||||
by all shells!
|
||||
|
||||
Shell functions are considered portable nowadays, though Autoconf
|
||||
still does not use them (Autotest does). However, inside a shell
|
||||
function you should not be using @code{$?} to check the return code
|
||||
of a subshell invocation; in general, since the caller of a shell
|
||||
function might look at the function's return code, make sure that the
|
||||
last statement of a shell function does not invoke a subshell.
|
||||
Using subshells triggers bugs in zsh 4.x; while Autoconf tries
|
||||
to find a shell that does not exhibit the bug, zsh might be the
|
||||
only shell present on the user's machine.
|
||||
Shell functions are considered portable nowadays, though Autoconf still
|
||||
does not use them (Autotest does). However, inside a shell function,
|
||||
you should not rely on the error status of a subshell if the last
|
||||
command of that subshell was @code{exit} or @code{trap}, as this
|
||||
triggers bugs in zsh 4.x; while Autoconf tries to find a shell that
|
||||
does not exhibit the bug, zsh might be the only shell present on the
|
||||
user's machine.
|
||||
|
||||
Some ancient systems have quite
|
||||
small limits on the length of the @samp{#!} line; for instance, 32
|
||||
@ -17025,7 +17283,8 @@ your own @samp{help strings} to line up in the appropriate columns of
|
||||
strings} do. This is the purpose of the @code{AS_HELP_STRING} macro.
|
||||
|
||||
@anchor{AS_HELP_STRING}
|
||||
@defmac AS_HELP_STRING (@var{left-hand-side}, @var{right-hand-side})
|
||||
@defmac AS_HELP_STRING (@var{left-hand-side}, @var{right-hand-side} @
|
||||
@dvar{indent-column, 26}, @dvar{wrap-column, 79})
|
||||
@asindex{HELP_STRING}
|
||||
|
||||
Expands into an help string that looks pretty when the user executes
|
||||
@ -17041,9 +17300,6 @@ AC_ARG_WITH([foo],
|
||||
[use_foo=no])
|
||||
@end example
|
||||
|
||||
The second argument of @code{AS_HELP_STRING} is
|
||||
not a literal, and should not be double quoted.
|
||||
@xref{Autoconf Language}, for a more detailed explanation.
|
||||
Then the last few lines of @samp{configure --help} appear like
|
||||
this:
|
||||
|
||||
@ -17052,16 +17308,42 @@ this:
|
||||
--with-foo use foo (default is no)
|
||||
@end example
|
||||
|
||||
Macro expansion is performed on the first argument. However, the second
|
||||
argument of @code{AS_HELP_STRING} is treated as a whitespace separated
|
||||
list of text to be reformatted, and is not subject to macro expansion.
|
||||
Since it is not expanded, it should not be double quoted.
|
||||
@xref{Autoconf Language}, for a more detailed explanation.
|
||||
|
||||
The @code{AS_HELP_STRING} macro is particularly helpful when the
|
||||
@var{left-hand-side} and/or @var{right-hand-side} are composed of macro
|
||||
arguments, as shown in the following example.
|
||||
|
||||
@example
|
||||
AC_DEFUN([MY_ARG_WITH],
|
||||
[AC_ARG_WITH([$1],
|
||||
[AS_HELP_STRING([--with-$1], [use $1 (default is $2)])],
|
||||
[AC_ARG_WITH(m4_translit([[$1]], [_], [-]),
|
||||
[AS_HELP_STRING([--with-m4_translit([$1], [_], [-])],
|
||||
[use $1 (default is $2)])],
|
||||
[use_[]$1=$withval],
|
||||
[use_[]$1=$2])])
|
||||
MY_ARG_WITH([a_b], [no])
|
||||
@end example
|
||||
@noindent
|
||||
Here, the last few lines of @samp{configure --help} will include:
|
||||
|
||||
@example
|
||||
--enable and --with options recognized:
|
||||
--with-a-b use a_b (default is no)
|
||||
@end example
|
||||
|
||||
The parameters @var{indent-column} and @var{wrap-column} were introduced
|
||||
in Autoconf 2.62. Generally, they should not be specified; they exist
|
||||
for fine-tuning of the wrapping.
|
||||
@example
|
||||
AS_HELP_STRING([--option], [description of option])
|
||||
@result{} --option description of option
|
||||
AS_HELP_STRING([--option], [description of option], [15], [30])
|
||||
@result{} --option description of
|
||||
@result{} option
|
||||
@end example
|
||||
@end defmac
|
||||
|
||||
|
@ -1289,7 +1289,7 @@ m4_define([AT_SETUP],
|
||||
m4_define([AT_capture_files], [])
|
||||
m4_define([AT_line], AT_LINE)
|
||||
m4_define([AT_xfail], [at_xfail=no])
|
||||
m4_define([AT_description], m4_quote($1))
|
||||
m4_define([AT_description], m4_expand([$1]))
|
||||
m4_define([AT_ordinal], m4_incr(AT_ordinal))
|
||||
m4_append([AT_groups_all], [ ]m4_defn([AT_ordinal]))
|
||||
m4_divert_push([TEST_FUNCTIONS])dnl
|
||||
|
@ -197,7 +197,7 @@ _AS_BOURNE_COMPATIBLE
|
||||
$1
|
||||
_ASEOF
|
||||
}],
|
||||
[(eval "AS_ESCAPE(m4_quote($1))")])])
|
||||
[(eval "AS_ESCAPE(m4_expand([$1]))")])])
|
||||
|
||||
|
||||
# _AS_DETECT_REQUIRED(TEST)
|
||||
@ -1158,14 +1158,21 @@ m4_define([_AS_BOX_INDIR],
|
||||
_ASBOX])
|
||||
|
||||
|
||||
# AS_HELP_STRING(LHS, RHS, [COLUMN])
|
||||
# ----------------------------------
|
||||
# AS_HELP_STRING(LHS, RHS, [INDENT-COLUMN = 26], [WRAP-COLUMN = 79])
|
||||
# ------------------------------------------------------------------
|
||||
#
|
||||
# Format a help string so that it looks pretty when
|
||||
# the user executes "script --help". This macro takes three
|
||||
# arguments, a "left hand side" (LHS), a "right hand side" (RHS), and
|
||||
# the COLUMN which is a string of white spaces which leads to the
|
||||
# the RHS column (default: 26 white spaces).
|
||||
# Format a help string so that it looks pretty when the user executes
|
||||
# "script --help". This macro takes up to four arguments, a
|
||||
# "left hand side" (LHS), a "right hand side" (RHS), a decimal
|
||||
# INDENT-COLUMN which is the column where wrapped lines should begin
|
||||
# (the default of 26 is recommended), and a decimal WRAP-COLUMN which is
|
||||
# the column where lines should wrap (the default of 79 is recommended).
|
||||
# LHS is expanded, RHS is not.
|
||||
#
|
||||
# For backwards compatibility not documented in the manual, INDENT-COLUMN
|
||||
# can also be specified as a string of white spaces, whose width
|
||||
# determines the indentation column. Using TABs in INDENT-COLUMN is not
|
||||
# recommended, since screen width of TAB is not computed.
|
||||
#
|
||||
# The resulting string is suitable for use in other macros that require
|
||||
# a help string (e.g. AC_ARG_WITH).
|
||||
@ -1185,9 +1192,9 @@ _ASBOX])
|
||||
# "--with-readline", while the RHS is "support fancy command line
|
||||
# editing".
|
||||
#
|
||||
# If the LHS contains more than (COLUMN - 3) characters, then the LHS is
|
||||
# terminated with a newline so that the RHS starts on a line of its own
|
||||
# beginning with COLUMN. In the default case, this corresponds to an
|
||||
# If the LHS contains more than (INDENT-COLUMN - 3) characters, then the
|
||||
# LHS is terminated with a newline so that the RHS starts on a line of its
|
||||
# own beginning at INDENT-COLUMN. In the default case, this corresponds to an
|
||||
# LHS with more than 23 characters.
|
||||
#
|
||||
# Therefore, in the example, if the LHS were instead
|
||||
@ -1206,12 +1213,10 @@ _ASBOX])
|
||||
# know quadrigraphs.
|
||||
#
|
||||
m4_define([AS_HELP_STRING],
|
||||
[m4_pushdef([AS_Prefix], m4_default([$3], [ ]))dnl
|
||||
m4_pushdef([AS_Prefix_Format],
|
||||
[ %-]m4_eval(m4_len(AS_Prefix) - 3)[s ])dnl [ %-23s ]
|
||||
m4_text_wrap([$2], AS_Prefix, m4_format(AS_Prefix_Format, [[$1]]))dnl
|
||||
m4_popdef([AS_Prefix_Format])dnl
|
||||
m4_popdef([AS_Prefix])dnl
|
||||
[m4_text_wrap([$2], m4_cond([[$3]], [], [ ],
|
||||
[m4_eval([$3]+0)], [0], [[$3]],
|
||||
[m4_format([[%*s]], [$3], [])]),
|
||||
m4_expand([ $1 ]), [$4])dnl
|
||||
])# AS_HELP_STRING
|
||||
|
||||
|
||||
|
@ -398,6 +398,18 @@ m4_define([m4_cdr],
|
||||
[$#], 1, [],
|
||||
[m4_dquote(m4_shift($@))])])
|
||||
|
||||
# _m4_cdr(LIST)
|
||||
# -------------
|
||||
# Like m4_cdr, except include a leading comma unless only one element
|
||||
# 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])
|
||||
# -------------------------------------------------------------------
|
||||
@ -435,29 +447,6 @@ m4_define([m4_cond],
|
||||
[m4_if($1, [$2], [$3], [$0(m4_shift3($@))])])])
|
||||
|
||||
|
||||
# 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. ##
|
||||
## ---------------------------------------- ##
|
||||
@ -483,7 +472,7 @@ m4_define([m4_map_sep],
|
||||
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], $@)],
|
||||
[$#], 2, [m4_builtin([patsubst], [$1], [$2])],
|
||||
[_$0($@m4_if(m4_eval($# & 1), 0, [,]))])])
|
||||
m4_define([_m4_bpatsubsts],
|
||||
[m4_if([$#], 2, [$1],
|
||||
@ -491,18 +480,6 @@ m4_define([_m4_bpatsubsts],
|
||||
m4_shift3($@))])])
|
||||
|
||||
|
||||
|
||||
# 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.
|
||||
@ -577,14 +554,24 @@ m4_define([m4_popdef],
|
||||
# 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 ().
|
||||
m4_define([m4_shiftn],
|
||||
[m4_assert(0 <= $1 && $1 < $#)dnl
|
||||
_m4_shiftn($@)])
|
||||
[m4_assert(0 < $1 && $1 < $#)_$0($@)])
|
||||
|
||||
m4_define([_m4_shiftn],
|
||||
[m4_if([$1], 0,
|
||||
[m4_shift($@)],
|
||||
[_m4_shiftn(m4_eval([$1]-1), m4_shift(m4_shift($@)))])])
|
||||
[m4_if([$1], 1, [m4_shift(],
|
||||
[$0(m4_decr([$1])]), m4_shift(m4_shift($@)))])
|
||||
|
||||
# m4_shift2(...)
|
||||
# m4_shift3(...)
|
||||
@ -593,6 +580,21 @@ m4_define([_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 don't tolerate undefining something which is
|
||||
@ -610,16 +612,31 @@ m4_define([m4_undefine],
|
||||
## 7. Quoting manipulation. ##
|
||||
## ------------------------- ##
|
||||
|
||||
# m4_quote(ARGS)
|
||||
|
||||
# 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.
|
||||
m4_define([m4_apply],
|
||||
[m4_if([$2], [], [$1], [$1($2)])[]])
|
||||
|
||||
|
||||
# m4_count(ARGS)
|
||||
# --------------
|
||||
# Return ARGS as a single argument. Any whitespace after unquoted commas
|
||||
# is stripped.
|
||||
#
|
||||
# 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], [[$*]])
|
||||
# Return a count of how many ARGS are present.
|
||||
m4_define([m4_count], [$#])
|
||||
|
||||
|
||||
# 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_dquote(ARGS)
|
||||
@ -628,16 +645,116 @@ m4_define([m4_quote], [[$*]])
|
||||
m4_define([m4_dquote], [[$@]])
|
||||
|
||||
|
||||
# m4_dquote_elt(ARGS)
|
||||
# -------------------
|
||||
# Return ARGS as an unquoted list of double-quoted arguments.
|
||||
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)
|
||||
# --------------
|
||||
# Return the expansion of ARG as a single string. Unlike m4_quote($1), this
|
||||
# correctly preserves whitespace following single-quoted commas that appeared
|
||||
# within ARG (however, it does not preserve whitespace after any unquoted
|
||||
# commas encountered in the expansion).
|
||||
#
|
||||
# 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
|
||||
#
|
||||
# Splitting a quoted ARG on `,' preserves space, but produces a quoted list.
|
||||
# Unquote the list, then expand each argument while preserving the leading
|
||||
# spaces; finally, collect each argument back into the final string.
|
||||
m4_define([m4_expand],
|
||||
[m4_quote(_$0(m4_unquote(m4_split([$1], [,]))))])
|
||||
|
||||
# _m4_expand(ARGS)
|
||||
# ----------------
|
||||
# Return the expansion of each ARG, separated by `,'. Less efficient than
|
||||
# m4_unquote, but preserves quoted leading space in each ARG.
|
||||
m4_define([_m4_expand],
|
||||
[m4_if([$#], [0], [],
|
||||
[$#], [1], [$1],
|
||||
[$1,$0(m4_shift($@))])])
|
||||
|
||||
|
||||
# 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. Amongst other things, this is useful for enabling
|
||||
# macro invocations inside strings with [] blocks (for instance regexps
|
||||
# and help-strings).
|
||||
# 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 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_map), 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_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.
|
||||
m4_define([m4_unquote], [$*])
|
||||
|
||||
|
||||
## -------------------------- ##
|
||||
## 8. Implementing m4 loops. ##
|
||||
## -------------------------- ##
|
||||
@ -779,13 +896,18 @@ m4_if(m4_defn([$1]), [$2], [],
|
||||
# => -active--active-
|
||||
#
|
||||
# This macro is called frequently, so avoid extra expansions such as
|
||||
# m4_ifval and dnl.
|
||||
# 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) and use _m4_shift3
|
||||
# to detect when recursion is complete.
|
||||
m4_define([m4_foreach],
|
||||
[m4_pushdef([$1])_$0($@)m4_popdef([$1])])
|
||||
[m4_pushdef([$1])_$0([$1], [$3]m4_if([$2], [], [], [, $2]))m4_popdef([$1])])
|
||||
|
||||
m4_define([_m4_foreach],
|
||||
[m4_if([$2], [], [],
|
||||
[m4_define([$1], m4_car($2))$3[]$0([$1], m4_cdr($2), [$3])])])
|
||||
[m4_if([$#], [2], [],
|
||||
[m4_define([$1], [$3])$2[]$0([$1], [$2]_m4_shift3($@))])])
|
||||
|
||||
|
||||
# m4_foreach_w(VARIABLE, LIST, EXPRESSION)
|
||||
@ -803,6 +925,31 @@ m4_define([m4_foreach_w],
|
||||
[m4_foreach([$1], m4_split(m4_normalize([$2]), [ ]), [$3])])
|
||||
|
||||
|
||||
# m4_map(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.
|
||||
#
|
||||
# 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_shift2 to detect the end of recursion.
|
||||
m4_define([m4_map],
|
||||
[m4_if([$2], [], [],
|
||||
[_$0([$1], $2)])])
|
||||
m4_define([_m4_map],
|
||||
[m4_if([$#], [1], [],
|
||||
[m4_apply([$1], [$2])$0([$1]_m4_shift2($@))])])
|
||||
|
||||
|
||||
# m4_map_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 not further expanded.
|
||||
m4_define([m4_map_sep],
|
||||
[m4_if([$3], [], [],
|
||||
[m4_apply([$1], m4_car($3))m4_map([[$2]$1]_m4_cdr($3))])])
|
||||
|
||||
|
||||
## --------------------------- ##
|
||||
## 9. More diversion support. ##
|
||||
@ -1645,13 +1792,24 @@ m4_define([m4_normalize],
|
||||
|
||||
# m4_join(SEP, ARG1, ARG2...)
|
||||
# ---------------------------
|
||||
# Produce ARG1SEPARG2...SEPARGn.
|
||||
m4_defun([m4_join],
|
||||
[m4_case([$#],
|
||||
[1], [],
|
||||
[2], [[$2]],
|
||||
[[$2][$1]$0([$1], m4_shift2($@))])])
|
||||
|
||||
# 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 `_'.
|
||||
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_append(MACRO-NAME, STRING, [SEPARATOR])
|
||||
@ -1726,6 +1884,9 @@ m4_define([m4_append_uniq],
|
||||
# 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.
|
||||
#
|
||||
# Typical outputs are:
|
||||
#
|
||||
# m4_text_wrap([Short string */], [ ], [/* ], 20)
|
||||
@ -1756,44 +1917,49 @@ m4_define([m4_append_uniq],
|
||||
# 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 overquotes m4_Prefix1 to avoid m4_defn overhead, and bypasses
|
||||
# m4_popdef overhead with m4_builtin since no user macro expansion occurs in
|
||||
# the meantime.
|
||||
# The algorithm overquotes m4_Prefix and m4_Prefix1 to avoid m4_defn
|
||||
# overhead, and bypasses m4_popdef overhead with m4_builtin 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],
|
||||
[m4_pushdef([m4_Prefix], [$2])dnl
|
||||
m4_pushdef([m4_Prefix1], m4_dquote(m4_default([$3], [m4_Prefix])))dnl
|
||||
m4_pushdef([m4_Width], m4_default([$4], 79))dnl
|
||||
m4_pushdef([m4_Cursor], m4_qlen(m4_Prefix1))dnl
|
||||
m4_pushdef([m4_Separator], [])dnl
|
||||
m4_Prefix1[]dnl
|
||||
m4_cond([m4_eval(m4_qlen(m4_Prefix1) > m4_len(m4_Prefix))],
|
||||
[1], [m4_define([m4_Cursor], m4_len(m4_Prefix))
|
||||
m4_Prefix],
|
||||
[m4_eval(m4_qlen(m4_Prefix1) < m4_len(m4_Prefix))],
|
||||
[0], [],
|
||||
[m4_define([m4_Cursor], m4_len(m4_Prefix))[]dnl
|
||||
m4_format([%*s],
|
||||
m4_max([0], m4_eval(m4_len(m4_Prefix) - m4_qlen(m4_Prefix1))),
|
||||
[])])[]dnl
|
||||
m4_foreach_w([m4_Word], [$1],
|
||||
[m4_define([m4_Cursor],
|
||||
m4_eval(m4_Cursor + m4_qlen(m4_builtin([defn], [m4_Word])) + 1))dnl
|
||||
dnl New line if too long, else insert a space unless it is the first
|
||||
dnl 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_builtin([defn], [m4_Word])) + 1))]
|
||||
m4_Prefix,
|
||||
[m4_Separator])[]dnl
|
||||
m4_builtin([defn], [m4_Word])[]dnl
|
||||
m4_define([m4_Separator], [ ])])dnl
|
||||
m4_builtin([popdef], [m4_Separator])dnl
|
||||
m4_builtin([popdef], [m4_Cursor])dnl
|
||||
m4_builtin([popdef], [m4_Width])dnl
|
||||
m4_builtin([popdef], [m4_Prefix1])dnl
|
||||
m4_builtin([popdef], [m4_Prefix])dnl
|
||||
])
|
||||
m4_do(dnl set up local variables, to avoid repeated calculations
|
||||
[[m4_pushdef([m4_Prefix], [[$2]])]],
|
||||
[[m4_pushdef([m4_Prefix1], m4_if([$3], [], [m4_Prefix], [[[$3]]]))]],
|
||||
[[m4_pushdef([m4_Width], m4_default([$4], 79))]],
|
||||
[[m4_pushdef([m4_Indent], m4_qlen(m4_Prefix))]],
|
||||
[[m4_pushdef([m4_Cursor], m4_qlen(m4_Prefix1))]],
|
||||
[[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
|
||||
[[m4_Prefix1[]m4_cond([m4_Cursor], m4_Indent, [],
|
||||
[m4_eval(m4_Cursor > m4_Indent)], [1], [
|
||||
m4_Prefix[]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 curser 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_foreach_w([m4_Word], [$1],
|
||||
[m4_define([m4_Cursor],
|
||||
m4_eval(m4_Cursor + m4_qlen(m4_builtin([defn], [m4_Word]))
|
||||
+ 1))m4_if(m4_eval(m4_Cursor > m4_Width),
|
||||
[1], [m4_define([m4_Cursor],
|
||||
m4_eval(m4_Indent
|
||||
+ m4_qlen(m4_builtin([defn], [m4_Word])) + 1))
|
||||
m4_Prefix[]],
|
||||
[m4_Separator[]])m4_builtin([defn], [m4_Word])])]],
|
||||
dnl finally, clean up the local variabls
|
||||
[[m4_builtin([popdef], [m4_Separator])]],
|
||||
[[m4_builtin([popdef], [m4_Cursor])]],
|
||||
[[m4_builtin([popdef], [m4_Indent])]],
|
||||
[[m4_builtin([popdef], [m4_Width])]],
|
||||
[[m4_builtin([popdef], [m4_Prefix1])]],
|
||||
[[m4_builtin([popdef], [m4_Prefix])]]))
|
||||
|
||||
|
||||
# m4_text_box(MESSAGE, [FRAME-CHARACTER = `-'])
|
||||
@ -1805,7 +1971,7 @@ m4_builtin([popdef], [m4_Prefix])dnl
|
||||
# using FRAME-CHARACTER in the border.
|
||||
m4_define([m4_text_box],
|
||||
[m4_pushdef([m4_Border],
|
||||
m4_translit(m4_format([%*s], m4_qlen(m4_quote($1)), []),
|
||||
m4_translit(m4_format([%*s], m4_qlen(m4_expand([$1])), []),
|
||||
[ ], m4_if([$2], [], [[-]], [[$2]])))dnl
|
||||
@%:@@%:@ m4_Border @%:@@%:@
|
||||
@%:@@%:@ $1 @%:@@%:@
|
||||
@ -1850,42 +2016,50 @@ m4_define([m4_cmp],
|
||||
# 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)) -> -1
|
||||
# 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 to determine when to recurse.
|
||||
m4_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))])])])
|
||||
[m4_if([$1$2], [], 0,
|
||||
[$1], [], [$0(0, [$2])],
|
||||
[$2], [], [$0([$1], 0)],
|
||||
[$1], [$2], 0,
|
||||
[_$0(m4_cmp(m4_car($1), m4_car($2)))([$0(m4_cdr($1), m4_cdr($2))])])])
|
||||
m4_define([_m4_list_cmp],
|
||||
[m4_if([$1], 0, [m4_unquote], [$1m4_ignore])])
|
||||
|
||||
# m4_max(A, B, ...)
|
||||
# m4_min(A, B, ...)
|
||||
# m4_max(EXPR, ...)
|
||||
# m4_min(EXPR, ...)
|
||||
# -----------------
|
||||
# Return the maximum (or minimum) of a series of integer expressions.
|
||||
# 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).
|
||||
m4_define([m4_max],
|
||||
[m4_if([$#], [0], [m4_fatal([too few arguments to $0])],
|
||||
[$#], [1], [$1],
|
||||
[$#$1], [2$2], [$1],
|
||||
[$#], [1], [m4_eval([$1])],
|
||||
[$#$1], [2$2], [m4_eval([$1])],
|
||||
[$#], [2],
|
||||
[m4_eval((([$1]) > ([$2])) * ([$1]) + (([$1]) <= ([$2])) * ([$2]))],
|
||||
[$0($0([$1], [$2]), m4_shift2($@))])])
|
||||
m4_define([m4_min],
|
||||
[m4_if([$#], [0], [m4_fatal([too few arguments to $0])],
|
||||
[$#], [1], [$1],
|
||||
[$#$1], [2$2], [$1],
|
||||
[$#], [1], [m4_eval([$1])],
|
||||
[$#$1], [2$2], [m4_eval([$1])],
|
||||
[$#], [2],
|
||||
[m4_eval((([$1]) < ([$2])) * ([$1]) + (([$1]) >= ([$2])) * ([$2]))],
|
||||
[$0($0([$1], [$2]), m4_shift2($@))])])
|
||||
@ -1906,23 +2080,29 @@ m4_define([m4_sign],
|
||||
|
||||
# m4_version_unletter(VERSION)
|
||||
# ----------------------------
|
||||
# Normalize beta version numbers with letters to numbers only for comparison.
|
||||
# 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#)
|
||||
#
|
||||
#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.
|
||||
# for example:
|
||||
# [2.14a] -> [2.14+1.-1.[0r36:a]] -> 2.15.-1.10
|
||||
# [2.14b] -> [2.15+1.-1.[0r36:b]] -> 2.15.-1.11
|
||||
# [2.61aa.b] -> [2.61+1.-1.[0r36:aa],+1.-1.[0r36:b]] -> 2.62.-1.370.1.-1.11
|
||||
#
|
||||
# This macro expects reasonable version numbers, but can handle double
|
||||
# letters and does not expand one-letter macros. Inline constant expansions,
|
||||
# to avoid m4_defn overhead. _m4_version_unletter is the real workhorse
|
||||
# used by m4_version_compare, but since [0r36:a] is less readable than 10,
|
||||
# we provide a wrapper for human use.
|
||||
m4_define([m4_version_unletter],
|
||||
[m4_translit(m4_bpatsubsts(m4_tolower([[$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_map_sep([m4_eval], [.],
|
||||
m4_dquote(m4_dquote_elt(m4_unquote(_$0([$1])))))])
|
||||
m4_define([_m4_version_unletter],
|
||||
[m4_translit(m4_bpatsubst([[[$1]]], ]dnl
|
||||
m4_dquote(m4_dquote(m4_defn([m4_cr_Letters])))[[+],
|
||||
[+1.-1.[0r36:\&]]),
|
||||
[.], [,])])
|
||||
|
||||
|
||||
# m4_version_compare(VERSION-1, VERSION-2)
|
||||
@ -1932,8 +2112,7 @@ m4_define([m4_version_unletter],
|
||||
# 0 if =
|
||||
# 1 if >
|
||||
m4_define([m4_version_compare],
|
||||
[m4_list_cmp((m4_translit(m4_version_unletter([$1]), [.], [,])),
|
||||
(m4_translit(m4_version_unletter([$2]), [.], [,])))])
|
||||
[m4_list_cmp(_m4_version_unletter([$1]), _m4_version_unletter([$2]))])
|
||||
|
||||
|
||||
# m4_PACKAGE_NAME
|
||||
@ -1949,12 +2128,12 @@ m4_include([m4sugar/version.m4])
|
||||
# ----------------------------------------------------
|
||||
# Check this Autoconf version against VERSION.
|
||||
m4_define([m4_version_prereq],
|
||||
[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]), [$1]), -1,
|
||||
[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])[]dnl
|
||||
])
|
||||
[63])])],
|
||||
[$2])])
|
||||
|
||||
|
||||
|
||||
|
@ -290,7 +290,7 @@ AT_CHECK_AT_TITLE_CHAR([Backslash], [\])
|
||||
AT_CHECK_AT_TITLE_CHAR([Brackets], [[[]]], [[]])
|
||||
AT_CHECK_AT_TITLE_CHAR([Pound], [[#]], [#])
|
||||
AT_CHECK_AT_TITLE_CHAR([Quoted comma],[[,]], [,])
|
||||
AT_CHECK_AT_TITLE_CHAR([Comma], [,[]], [,])
|
||||
AT_CHECK_AT_TITLE_CHAR([Comma], [,], [,])
|
||||
|
||||
AT_CHECK_AT_TITLE_CHAR([Quoted Macro], [[macro_name]], [macro_name])
|
||||
AT_CHECK_AT_TITLE_CHAR([Macro], [macro_name], [macro_expanded])
|
||||
|
@ -490,10 +490,8 @@ AT_CLEANUP
|
||||
## AS_HELP_STRING ##
|
||||
## -------------- ##
|
||||
|
||||
# I'm not totally certain that we want to enforce the defaults here,
|
||||
# but at least it is being tested.
|
||||
|
||||
AT_SETUP([AS@&t@_HELP_STRING])
|
||||
AT_KEYWORDS([m4@&t@_text_wrap])
|
||||
|
||||
AT_DATA_M4SH([script.as],
|
||||
[[AS_INIT
|
||||
@ -545,6 +543,18 @@ echo "AS_HELP_STRING([[--foo[=bar]123456789012]],
|
||||
[some other t[]t which should wrap at our default of 80 characters.])"
|
||||
echo "AS_HELP_STRING([[--foo[=bar]1234567890123]],
|
||||
[some other t[]t which should wrap at our default of 80 characters.])"
|
||||
m4_define([mac], [MACRO])dnl
|
||||
echo "AS_HELP_STRING([--mac], [mac])"
|
||||
echo "AS_HELP_STRING([--o1, --o2], [two
|
||||
options, one description])"
|
||||
echo "AS_HELP_STRING([--tune1], [check out the tuned formatting],
|
||||
[ ])"
|
||||
echo "AS_HELP_STRING([--tune2], [check out the tuned formatting],
|
||||
[12])"
|
||||
echo "AS_HELP_STRING([--tune3], [check out the tuned formatting],
|
||||
[], [40])"
|
||||
echo "AS_HELP_STRING([--tune4], [check out the tuned formatting],
|
||||
[12], [40])"
|
||||
]])
|
||||
|
||||
AT_CHECK_M4SH
|
||||
@ -600,6 +610,15 @@ AT_CHECK([./script], [0],
|
||||
--foo[=bar]1234567890123
|
||||
some other t[]t which should wrap at our default of
|
||||
80 characters.
|
||||
--MACRO mac
|
||||
--o1, --o2 two options, one description
|
||||
--tune1 check out the tuned formatting
|
||||
--tune2 check out the tuned formatting
|
||||
--tune3 check out the
|
||||
tuned
|
||||
formatting
|
||||
--tune4 check out the tuned
|
||||
formatting
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
@ -44,6 +44,8 @@ AT_CHECK_M4SUGAR([-o-],, [$2], [$3])
|
||||
#
|
||||
# - m4_append
|
||||
#
|
||||
# - m4_join
|
||||
#
|
||||
# - m4_text_wrap
|
||||
# uses m4_split code.
|
||||
|
||||
@ -251,6 +253,43 @@ one, two, three
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## --------- ##
|
||||
## m4_join. ##
|
||||
## --------- ##
|
||||
|
||||
AT_SETUP([m4@&t@_join])
|
||||
|
||||
AT_CHECK_M4SUGAR_TEXT(
|
||||
[[m4_define([active], [ACTIVE])
|
||||
m4_join
|
||||
m4_join([|])
|
||||
m4_join([, ], [one], [two])
|
||||
m4_dquote(m4_join([, ], [one], [two]))
|
||||
m4_join([|], [active], [active])
|
||||
m4_join([|], ,,,[one])
|
||||
m4_join([|], [one],,,)
|
||||
m4_join([], ,,,[two])
|
||||
m4_join([], [two],,,)
|
||||
m4_join([ active ], [one], , [two])
|
||||
m4_join([], [one], [two])
|
||||
]],
|
||||
[[
|
||||
|
||||
|
||||
one, two
|
||||
[one, two]
|
||||
active|active
|
||||
one
|
||||
one
|
||||
two
|
||||
two
|
||||
one active two
|
||||
onetwo
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## -------------- ##
|
||||
## m4_text_wrap. ##
|
||||
## -------------- ##
|
||||
@ -313,6 +352,11 @@ m4_version_compare([1.2], [1.1.1a])
|
||||
m4_version_compare([1.0], [1])
|
||||
m4_version_compare([1.0a], [1.0a])
|
||||
m4_version_compare([1.1a], [1.1a.1])
|
||||
m4_version_compare([1.10], [1.1a])
|
||||
m4_version_compare([1.1a], [1.1A])
|
||||
m4_define([a], [oops])dnl
|
||||
m4_version_compare([1.1a], [1.1A])
|
||||
m4_version_compare([1z], [1aa])
|
||||
]],
|
||||
[[-1
|
||||
1
|
||||
@ -322,6 +366,10 @@ m4_version_compare([1.1a], [1.1a.1])
|
||||
0
|
||||
0
|
||||
-1
|
||||
1
|
||||
0
|
||||
0
|
||||
-1
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
Loading…
Reference in New Issue
Block a user