mirror of
git://git.sv.gnu.org/autoconf
synced 2025-03-25 14:50:24 +08:00
Create libm4.m4.
* Makefile.am: Adjusted for libm4.m4. * acgeneral.m4 (m4_errprint, m4_warn, m4_fatal, m4_prefix, m4_eval, m4_shift, m4_format, m4_include_unique, m4_include, m4_sinclude, m4_quote, m4_split, m4_join, m4_strip, m4_append, m4_list_append, ifval, ifset, m4_default, m4_case, m4_match, m4_foreach): Moved from here, to... * libm4.m4: here. * acgeneral.m4 (AC_WRAP): Moved from here, to... * libm4.m4 (m4_wrap): here. All callers changed. * acgeneral.m4: Don't include acversion.m4. * autoconf.m4: Include libm4.m4 and acversion.m4. * autoheader.m4: Likewise.
This commit is contained in:
parent
b519547b61
commit
6b8dfc89ca
19
ChangeLog
19
ChangeLog
@ -1,3 +1,22 @@
|
||||
2000-02-07 Akim Demaille <akim@epita.fr>
|
||||
|
||||
Create libm4.m4.
|
||||
|
||||
* Makefile.am: Adjusted for libm4.m4.
|
||||
|
||||
* acgeneral.m4 (m4_errprint, m4_warn, m4_fatal, m4_prefix,
|
||||
m4_eval, m4_shift, m4_format, m4_include_unique, m4_include,
|
||||
m4_sinclude, m4_quote, m4_split, m4_join, m4_strip, m4_append,
|
||||
m4_list_append, ifval, ifset, m4_default, m4_case, m4_match,
|
||||
m4_foreach): Moved from here, to...
|
||||
* libm4.m4: here.
|
||||
* acgeneral.m4 (AC_WRAP): Moved from here, to...
|
||||
* libm4.m4 (m4_wrap): here. All callers changed.
|
||||
|
||||
* acgeneral.m4: Don't include acversion.m4.
|
||||
* autoconf.m4: Include libm4.m4 and acversion.m4.
|
||||
* autoheader.m4: Likewise.
|
||||
|
||||
2000-02-07 Akim Demaille <akim@epita.fr>
|
||||
|
||||
AC_CHECK_SIZEOF: Fix a bug, use standard default headers, and
|
||||
|
13
Makefile.am
13
Makefile.am
@ -1,7 +1,7 @@
|
||||
## Process this file with automake to create Makefile.in.
|
||||
|
||||
## Makefile for Autoconf.
|
||||
## Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
## Copyright (C) 1999, 2000 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
|
||||
@ -38,7 +38,7 @@ EXTRA_SCRIPTS = autoscan
|
||||
|
||||
distpkgdataDATA = \
|
||||
acfunctions acheaders acidentifiers acmakevars acprograms \
|
||||
acgeneral.m4 acoldnames.m4 acspecific.m4 autoconf.m4 autoheader.m4
|
||||
libm4.m4 acgeneral.m4 acoldnames.m4 acspecific.m4 autoconf.m4 autoheader.m4
|
||||
|
||||
nodistpkgdataDATA = autoconf.m4f autoheader.m4f acversion.m4
|
||||
|
||||
@ -95,13 +95,12 @@ editpl = sed -e 's,@''datadir''@,$(pkgdatadir),g' -e 's,@''PERL''@,$(PERL),g' \
|
||||
.m4.m4f:
|
||||
@case `$(M4) --help </dev/null 2>&1` in \
|
||||
*reload-state*) echo freezing $*.m4; \
|
||||
$(M4) -F $*.m4f -I${srcdir} ${srcdir}/$*.m4 ;; \
|
||||
*traditional*) ;; \
|
||||
*) echo Error: Autoconf requires GNU m4 1.1 or later; exit 1 ;; \
|
||||
$(M4) -F $*.m4f -I$(srcdir) $(srcdir)/$*.m4 ;; \
|
||||
*) echo Error: Autoconf requires GNU m4 1.4 or later; exit 1 ;; \
|
||||
esac
|
||||
|
||||
autoconf.m4f: autoconf.m4 acgeneral.m4 acspecific.m4 acoldnames.m4 acversion.m4
|
||||
autoheader.m4f: autoheader.m4 acgeneral.m4 acspecific.m4 acoldnames.m4 acversion.m4
|
||||
autoconf.m4f: autoconf.m4 libm4.m4 acgeneral.m4 acspecific.m4 acoldnames.m4 acversion.m4
|
||||
autoheader.m4f: autoheader.m4 libm4.m4 acgeneral.m4 acspecific.m4 acoldnames.m4 acversion.m4
|
||||
|
||||
|
||||
# The documentation
|
||||
|
11
Makefile.in
11
Makefile.in
@ -81,7 +81,7 @@ EXTRA_SCRIPTS = autoscan
|
||||
# s/nodistpackageDATA/nodist_pkgdata_DATA/
|
||||
# and adapt dependencies once we use a more recent Automake
|
||||
|
||||
distpkgdataDATA = acfunctions acheaders acidentifiers acmakevars acprograms acgeneral.m4 acoldnames.m4 acspecific.m4 autoconf.m4 autoheader.m4
|
||||
distpkgdataDATA = acfunctions acheaders acidentifiers acmakevars acprograms libm4.m4 acgeneral.m4 acoldnames.m4 acspecific.m4 autoconf.m4 autoheader.m4
|
||||
|
||||
|
||||
nodistpkgdataDATA = autoconf.m4f autoheader.m4f acversion.m4
|
||||
@ -605,13 +605,12 @@ install-data-hook: INSTALL.txt
|
||||
.m4.m4f:
|
||||
@case `$(M4) --help </dev/null 2>&1` in \
|
||||
*reload-state*) echo freezing $*.m4; \
|
||||
$(M4) -F $*.m4f -I${srcdir} ${srcdir}/$*.m4 ;; \
|
||||
*traditional*) ;; \
|
||||
*) echo Error: Autoconf requires GNU m4 1.1 or later; exit 1 ;; \
|
||||
$(M4) -F $*.m4f -I$(srcdir) $(srcdir)/$*.m4 ;; \
|
||||
*) echo Error: Autoconf requires GNU m4 1.4 or later; exit 1 ;; \
|
||||
esac
|
||||
|
||||
autoconf.m4f: autoconf.m4 acgeneral.m4 acspecific.m4 acoldnames.m4 acversion.m4
|
||||
autoheader.m4f: autoheader.m4 acgeneral.m4 acspecific.m4 acoldnames.m4 acversion.m4
|
||||
autoconf.m4f: autoconf.m4 libm4.m4 acgeneral.m4 acspecific.m4 acoldnames.m4 acversion.m4
|
||||
autoheader.m4f: autoheader.m4 libm4.m4 acgeneral.m4 acspecific.m4 acoldnames.m4 acversion.m4
|
||||
|
||||
# The documentation
|
||||
|
||||
|
476
acgeneral.m4
476
acgeneral.m4
@ -49,399 +49,6 @@ dnl Written by David MacKenzie, with help from
|
||||
dnl Franc,ois Pinard, Karl Berry, Richard Pixley, Ian Lance Taylor,
|
||||
dnl Roland McGrath, Noah Friedman, david d zuhn, and many others.
|
||||
dnl
|
||||
divert(-1)dnl Throw away output until AC_INIT is called.
|
||||
changequote([, ])
|
||||
|
||||
include(acversion.m4)
|
||||
|
||||
dnl Some old m4's don't support m4exit. But they provide
|
||||
dnl equivalent functionality by core dumping because of the
|
||||
dnl long macros we define.
|
||||
ifdef([__gnu__], , [errprint(Autoconf requires GNU m4.
|
||||
Install it before installing Autoconf or set the
|
||||
M4 environment variable to its path name.
|
||||
)m4exit(2)])
|
||||
|
||||
|
||||
dnl m4_errprint(MSG)
|
||||
dnl ----------------
|
||||
dnl Same as `errprint', but reports the file and line.
|
||||
define(m4_errprint, [errprint(__file__:__line__: [$1
|
||||
])])
|
||||
|
||||
|
||||
dnl m4_warn(MSG)
|
||||
dnl ------------
|
||||
dnl Warn the user.
|
||||
define(m4_warn, [m4_errprint([warning: $1])])
|
||||
|
||||
|
||||
dnl m4_fatal(MSG, [EXIT-STATUS])
|
||||
dnl ----------------------------
|
||||
dnl Fatal the user. :)
|
||||
define(m4_fatal,
|
||||
[m4_errprint([error: $1])dnl
|
||||
m4exit(ifelse([$2],, 1, [$2]))])
|
||||
|
||||
|
||||
dnl Some m4 internals have names colliding with tokens we might use.
|
||||
dnl Rename them a` la `m4 --prefix-builtins'.
|
||||
define([m4_prefix],
|
||||
[define([m4_$1], defn([$1]))
|
||||
undefine([$1])])
|
||||
|
||||
m4_prefix([eval])
|
||||
m4_prefix([shift])
|
||||
m4_prefix([format])
|
||||
|
||||
|
||||
dnl We also want to neutralize include (and sinclude for symmetry),
|
||||
dnl but we want to extend them slightly: warn when a file is included
|
||||
dnl several times. This is in general a dangerous operation because
|
||||
dnl quite nobody quotes the first argument of define.
|
||||
dnl
|
||||
dnl For instance in the following case:
|
||||
dnl define(foo, [bar])
|
||||
dnl then a second reading will turn into
|
||||
dnl define(bar, [bar])
|
||||
dnl which is certainly not what was meant.
|
||||
|
||||
|
||||
dnl m4_include_unique(FILE)
|
||||
dnl -----------------------
|
||||
dnl Declare that the FILE was loading; and warn if it has already
|
||||
dnl been included.
|
||||
define(m4_include_unique,
|
||||
[ifdef([m4_include($1)],
|
||||
[m4_warn([file `$1' included several times])])dnl
|
||||
define([m4_include($1)])])
|
||||
|
||||
|
||||
dnl m4_include(FILE)
|
||||
dnl ----------------
|
||||
dnl As the builtin include, but warns against multiple inclusions.
|
||||
define(m4_include,
|
||||
[m4_include_unique([$1])dnl
|
||||
builtin([include], [$1])])
|
||||
|
||||
|
||||
dnl m4_sinclude(FILE)
|
||||
dnl -----------------
|
||||
dnl As the builtin sinclude, but warns against multiple inclusions.
|
||||
define(m4_sinclude,
|
||||
[m4_include_unique([$1])dnl
|
||||
builtin([sinclude], [$1])])
|
||||
|
||||
dnl Neutralize include and sinclude.
|
||||
undefine([include])
|
||||
undefine([sinclude])
|
||||
|
||||
dnl ------------------------------------------------------------
|
||||
dnl Text processing in m4.
|
||||
dnl ------------------------------------------------------------
|
||||
|
||||
dnl m4_quote(STRING)
|
||||
dnl ----------------
|
||||
dnl Return STRING quoted.
|
||||
dnl
|
||||
dnl It is important to realize the difference between `quote(exp)' and
|
||||
dnl `[exp]': in the first case you obtain the quoted *result* of the
|
||||
dnl expansion of EXP, while in the latter you just obtain the string
|
||||
dnl `exp'.
|
||||
define([m4_quote], [[$@]])
|
||||
|
||||
|
||||
dnl m4_split(STRING, [REGEXP])
|
||||
dnl --------------------------
|
||||
dnl Split STRING into an m4 list of quoted elements. The elements are
|
||||
dnl quoted with [ and ]. Beginning spaces and end spaces *are kept*.
|
||||
dnl Use m4_strip to remove them.
|
||||
dnl
|
||||
dnl REGEXP specifies where to split. Default is [\t ]+.
|
||||
dnl
|
||||
dnl Pay attention to the changequotes. Inner changequotes exist for
|
||||
dnl obvious reasons (we want to insert square brackets). Outer
|
||||
dnl changequotes are needed because otherwise the m4 parser, when it
|
||||
dnl sees the closing bracket we add to the result, believes it is the
|
||||
dnl end of the body of the macro we define.
|
||||
dnl
|
||||
dnl Also, notice that $1 is quoted twice, since we want the result to be
|
||||
dnl quoted. Then you should understand that the argument of patsubst is
|
||||
dnl ``STRING'' (i.e., with additional `` and '').
|
||||
dnl
|
||||
dnl This macro is safe on active symbols, i.e.:
|
||||
dnl define(active, ACTIVE)
|
||||
dnl m4_split([active active ])end
|
||||
dnl => [active], [active], []end
|
||||
changequote(<<, >>)
|
||||
define(<<m4_split>>,
|
||||
<<changequote(``, '')dnl
|
||||
[dnl Can't use m4_default here instead of ifelse, because m4_default uses
|
||||
dnl [ and ] as quotes.
|
||||
patsubst(````$1'''',
|
||||
ifelse(``$2'',, ``[ ]+'', ``$2''),
|
||||
``], ['')]dnl
|
||||
changequote([, ])>>)
|
||||
changequote([, ])
|
||||
|
||||
|
||||
dnl m4_join(STRING)
|
||||
dnl ---------------
|
||||
dnl If STRING contains end of lines, replace them with spaces. If there
|
||||
dnl are backslashed end of lines, remove them. This macro is safe with
|
||||
dnl active symbols.
|
||||
dnl define(active, ACTIVE)
|
||||
dnl m4_join([active
|
||||
dnl act\
|
||||
dnl ive])end
|
||||
dnl => active activeend
|
||||
define([m4_join],
|
||||
[translit(patsubst([[[$1]]], [\\
|
||||
]), [
|
||||
], [ ])])
|
||||
|
||||
|
||||
dnl m4_strip(STRING)
|
||||
dnl ----------------
|
||||
dnl Expands into STRING with tabs and spaces singled out into a single
|
||||
dnl space, and removing leading and trailing spaces.
|
||||
dnl
|
||||
dnl This macro is robust to active symbols.
|
||||
dnl define(active, ACTIVE)
|
||||
dnl m4_strip([ active active ])end
|
||||
dnl => active activeend
|
||||
dnl
|
||||
dnl This macro is fun! Because we want to preserve active symbols, STRING
|
||||
dnl must be quoted for each evaluation, which explains there are 4 levels
|
||||
dnl of brackets around $1 (don't forget that the result must be quoted
|
||||
dnl too, hence one more quoting than applications).
|
||||
dnl
|
||||
dnl Then notice the patsubst of the middle: it is in charge of removing
|
||||
dnl the leading space. Why not just `patsubst(..., [^ ])'? Because this
|
||||
dnl macro will receive the output of the preceding patsubst, i.e. more or
|
||||
dnl less [[STRING]]. So if there is a leading space in STRING, then it is
|
||||
dnl the *third* character, since there are two leading `['; Equally for
|
||||
dnl the outer patsubst.
|
||||
define([m4_strip],
|
||||
[patsubst(patsubst(patsubst([[[[$1]]]],
|
||||
[[ ]+], [ ]),
|
||||
[^\(..\) ], [\1]),
|
||||
[ \(.\)$], [\1])])
|
||||
|
||||
|
||||
|
||||
dnl m4_append(MACRO-NAME, STRING)
|
||||
dnl -----------------------------
|
||||
dnl Redefine MACRO-NAME to hold its former content plus STRING at the
|
||||
dnl end. It is valid to use this macro with MACRO-NAME undefined.
|
||||
dnl
|
||||
dnl This macro is robust to active symbols. It can be used to grow
|
||||
dnl strings.
|
||||
dnl
|
||||
dnl | define(active, ACTIVE)
|
||||
dnl | m4_append([sentence], [This is an])
|
||||
dnl | m4_append([sentence], [ active ])
|
||||
dnl | m4_append([sentence], [symbol.])
|
||||
dnl | sentence
|
||||
dnl | undefine([active])dnl
|
||||
dnl | sentence
|
||||
dnl => This is an ACTIVE symbol.
|
||||
dnl => This is an active symbol.
|
||||
dnl
|
||||
dnl It can be used to define hooks.
|
||||
dnl
|
||||
dnl | define(active, ACTIVE)
|
||||
dnl | m4_append([hooks], [define([act1], [act2])])
|
||||
dnl | m4_append([hooks], [define([act2], [active])])
|
||||
dnl | undefine([active])
|
||||
dnl | act1
|
||||
dnl | hooks
|
||||
dnl | act1
|
||||
dnl => act1
|
||||
dnl =>
|
||||
dnl => active
|
||||
define(m4_append,
|
||||
[define([$1],
|
||||
ifdef([$1], [defn([$1])])[$2])])
|
||||
|
||||
|
||||
dnl m4_list_append(MACRO-NAME, STRING)
|
||||
dnl ----------------------------------
|
||||
dnl Same as `m4_append', but each element is separated by `, '.
|
||||
define(m4_list_append,
|
||||
[define([$1],
|
||||
ifdef([$1], [defn([$1]), ])[$2])])
|
||||
|
||||
|
||||
dnl ------------------------------------------------------------
|
||||
dnl Some additional m4 structural control.
|
||||
dnl ------------------------------------------------------------
|
||||
|
||||
dnl Both `ifval' and `ifset' tests against the empty string. The
|
||||
dnl difference is that `ifset' is specialized on macros.
|
||||
dnl
|
||||
dnl In case of arguments of macros, eg $[1], it makes little difference.
|
||||
dnl In the case of a macro `FOO', you don't want to check `ifval(FOO,
|
||||
dnl TRUE)', because if `FOO' expands with commas, there is a shifting of
|
||||
dnl the arguments. So you want to run `ifval([FOO])', but then you just
|
||||
dnl compare the *string* `FOO' against `', which, of course fails.
|
||||
dnl
|
||||
dnl So you want a variation of `ifset' that expects a macro name as $[1].
|
||||
dnl If this macro is both defined and defined to a non empty value, then
|
||||
dnl it runs TRUE etc.
|
||||
|
||||
|
||||
dnl ifval(COND, IF-TRUE[, IF-FALSE])
|
||||
dnl --------------------------------
|
||||
dnl If COND is not the empty string, expand IF-TRUE, otherwise IF-FALSE.
|
||||
dnl Comparable to ifdef.
|
||||
define([ifval], [ifelse([$1],[],[$3],[$2])])
|
||||
|
||||
|
||||
dnl ifset(MACRO, IF-TRUE[, IF-FALSE])
|
||||
dnl --------------------------------
|
||||
dnl If MACRO has no definition, or of its definition is the empty string,
|
||||
dnl expand IF-FALSE, otherwise IF-TRUE.
|
||||
define([ifset],
|
||||
[ifdef([$1],
|
||||
[ifelse(defn([$1]), [], [$3], [$2])],
|
||||
[$3])])
|
||||
|
||||
|
||||
dnl m4_default(EXP1, EXP2)
|
||||
dnl ----------------------
|
||||
dnl Returns EXP1 if non empty, otherwise EXP2.
|
||||
define([m4_default], [ifval([$1], [$1], [$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.
|
||||
define(m4_case,
|
||||
[ifelse([$#], 0, [],
|
||||
[$#], 1, [],
|
||||
[$#], 2, [$2],
|
||||
[$1], [$2], [$3],
|
||||
[m4_case([$1], m4_shift(m4_shift(m4_shift($@))))])])
|
||||
|
||||
|
||||
# m4_match(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.
|
||||
define(m4_match,
|
||||
[ifelse([$#], 0, [],
|
||||
[$#], 1, [],
|
||||
[$#], 2, [$2],
|
||||
regexp([$1], [$2]), -1, [m4_match([$1],
|
||||
m4_shift(m4_shift(m4_shift($@))))],
|
||||
[$3])])
|
||||
|
||||
|
||||
## --------------------- ##
|
||||
## Implementing m4 loops ##
|
||||
## --------------------- ##
|
||||
|
||||
|
||||
# Implementing loops (`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 undesired expansions.
|
||||
#
|
||||
# The example in the documentation is:
|
||||
#
|
||||
# | # foreach(x, (item_1, item_2, ..., item_n), stmt)
|
||||
# | define(`foreach',
|
||||
# | `pushdef(`$1', `')_foreach(`$1', `$2', `$3')popdef(`$1')')
|
||||
# | define(`_arg1', `$1')
|
||||
# | define(`_foreach',
|
||||
# | `ifelse(`$2', `()', ,
|
||||
# | `define(`$1', _arg1$2)$3`'_foreach(`$1', (shift$2), `$3')')')
|
||||
#
|
||||
# But then if you run
|
||||
#
|
||||
# | define(a, 1)
|
||||
# | define(b, 2)
|
||||
# | define(c, 3)
|
||||
# | foreach(`f', `(`a', `(b', `c)')', `echo f
|
||||
# | ')
|
||||
#
|
||||
# it gives
|
||||
#
|
||||
# => echo 1
|
||||
# => echo (2,3)
|
||||
#
|
||||
# which is not what is expected.
|
||||
#
|
||||
# Once you understood this, you turn yourself into a quoting wizard,
|
||||
# and come up with the following solution:
|
||||
#
|
||||
# | # foreach(x, (item_1, item_2, ..., item_n), stmt)
|
||||
# | define(`foreach', `pushdef(`$1', `')_foreach($@)popdef(`$1')')
|
||||
# | define(`_arg1', ``$1'')
|
||||
# | define(`_foreach',
|
||||
# | `ifelse($2, `()', ,
|
||||
# | `define(`$1', `_arg1$2')$3`'_foreach(`$1', `(shift$2)', `$3')')')
|
||||
#
|
||||
# which this time answers
|
||||
#
|
||||
# => echo a
|
||||
# => echo (b
|
||||
# => echo c)
|
||||
#
|
||||
# Bingo!
|
||||
|
||||
|
||||
# m4_foreach(VARIABLE, LIST, EXPRESSION)
|
||||
# --------------------------------------
|
||||
# Expand EXPRESSION assigning to VARIABLE each value of the LIST
|
||||
# (LIST should have the form `[(item_1, item_2, ..., item_n)]'),
|
||||
# i.e. the whole list should be *quoted*. Quote members too if
|
||||
# you don't want them to be expanded.
|
||||
#
|
||||
# This macro is robust to active symbols:
|
||||
# define(active, ACTIVE)
|
||||
# m4_foreach([Var], [([active], [b], [active])], [-Var-])end
|
||||
# => -active--b--active-end
|
||||
define(m4_foreach,
|
||||
[pushdef([$1], [])_m4_foreach($@)popdef([$1])])
|
||||
|
||||
dnl Low level macros used to define m4_foreach
|
||||
define(m4_car, [[$1]])
|
||||
define(_m4_foreach,
|
||||
[ifelse($2, [()], ,
|
||||
[define([$1], [m4_car$2])$3[]_m4_foreach([$1],
|
||||
[(m4_shift$2)],
|
||||
[$3])])])
|
||||
|
||||
|
||||
|
||||
|
||||
dnl ### Defining macros
|
||||
|
||||
@ -733,74 +340,9 @@ AC_DEFUN(AC_SPECIALIZE,
|
||||
[indir([$1], m4_shift($@))])])
|
||||
|
||||
|
||||
dnl ## --------------------------------- ##
|
||||
dnl ## Helping macros to display strings ##
|
||||
dnl ## --------------------------------- ##
|
||||
|
||||
|
||||
dnl AC_WRAP(STRING [, PREFIX[, FIRST-PREFIX[, WIDTH]]]]))
|
||||
dnl -----------------------------------------------------
|
||||
dnl Expands into STRING wrapped to hold in WIDTH columns (default = 79).
|
||||
dnl If prefix is set, each line is prefixed with it. If FIRST-PREFIX is
|
||||
dnl specified, then the first line is prefixed with it. As a special
|
||||
dnl case, if the length of the first prefix is greater than that of
|
||||
dnl PREFIX, then FIRST-PREFIX will be left alone on the first line.
|
||||
dnl
|
||||
dnl Typical outputs are:
|
||||
dnl
|
||||
dnl AC_WRAP([Short string */], [ ], [/* ], 20)
|
||||
dnl => /* Short string */
|
||||
dnl
|
||||
dnl AC_WRAP([Much longer string */], [ ], [/* ], 20)
|
||||
dnl => /* Much longer
|
||||
dnl => string */
|
||||
dnl
|
||||
dnl AC_WRAP([Short doc.], [ ], [ --short ], 30)
|
||||
dnl => --short Short doc.
|
||||
dnl
|
||||
dnl AC_WRAP([Short doc.], [ ], [ --too-wide ], 30)
|
||||
dnl => --too-wide
|
||||
dnl => Short doc.
|
||||
dnl
|
||||
dnl AC_WRAP([Super long documentation.], [ ], [ --too-wide ], 30)
|
||||
dnl => --too-wide
|
||||
dnl => Super long
|
||||
dnl => documentation.
|
||||
dnl
|
||||
dnl FIXME: there is no checking of a longer PREFIX than WIDTH, but do
|
||||
dnl we really want to bother with people trying each single corner
|
||||
dnl of a software?
|
||||
dnl
|
||||
dnl This macro does not leave a trailing space behind the last word,
|
||||
dnl what complicates it a bit. The algorithm is stupid simple: all the
|
||||
dnl words are preceded by AC_Separator which is defined to empty for the
|
||||
dnl first word, and then ` ' (single space) for all the others.
|
||||
define([AC_WRAP],
|
||||
[pushdef([AC_Prefix], m4_default([$2], []))dnl
|
||||
pushdef([AC_Prefix1], m4_default([$3], [AC_Prefix]))dnl
|
||||
pushdef([AC_Width], m4_default([$4], 79))dnl
|
||||
pushdef([AC_Cursor], len(AC_Prefix1))dnl
|
||||
pushdef([AC_Separator], [])dnl
|
||||
AC_Prefix1[]dnl
|
||||
ifelse(m4_eval(AC_Cursor > len(AC_Prefix)),
|
||||
1, [define([AC_Cursor], len(AC_Prefix))
|
||||
AC_Prefix])[]dnl
|
||||
AC_FOREACH([AC_Word], [$1],
|
||||
[define([AC_Cursor], m4_eval(AC_Cursor + len(AC_Word) + 1))dnl
|
||||
dnl New line if too long, else insert a space unless it is the first
|
||||
dnl of the words.
|
||||
ifelse(m4_eval(AC_Cursor > AC_Width),
|
||||
1, [define([AC_Cursor], m4_eval(len(AC_Prefix) + len(AC_Word) + 1))]
|
||||
AC_Prefix,
|
||||
[AC_Separator])[]dnl
|
||||
AC_Word[]dnl
|
||||
define([AC_Separator], [ ])])dnl
|
||||
popdef([AC_Separator])dnl
|
||||
popdef([AC_Cursor])dnl
|
||||
popdef([AC_Width])dnl
|
||||
popdef([AC_Prefix1])dnl
|
||||
popdef([AC_Prefix])dnl
|
||||
])
|
||||
## --------------------------------- ##
|
||||
## Helping macros to display strings ##
|
||||
## --------------------------------- ##
|
||||
|
||||
|
||||
dnl AC_HELP_STRING(LHS, RHS[, COLUMN])
|
||||
@ -847,7 +389,7 @@ dnl
|
||||
define([AC_HELP_STRING],
|
||||
[pushdef([AC_Prefix], m4_default([$3], [ ]))dnl
|
||||
pushdef([AC_Prefix_Format], [ %-]m4_eval(len(AC_Prefix) - 3)[s ])dnl [ %-23s ]
|
||||
AC_WRAP([$2], AC_Prefix, m4_format(AC_Prefix_Format, [$1]))dnl
|
||||
m4_wrap([$2], AC_Prefix, m4_format(AC_Prefix_Format, [$1]))dnl
|
||||
popdef([AC_Prefix_Format])dnl
|
||||
popdef([AC_Prefix])dnl
|
||||
])
|
||||
@ -859,7 +401,7 @@ dnl AC_INIT_NOTICE
|
||||
dnl --------------
|
||||
AC_DEFUN(AC_INIT_NOTICE,
|
||||
[# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated automatically using Autoconf version] AC_ACVERSION [
|
||||
# Generated automatically using Autoconf version ]AC_ACVERSION[
|
||||
# Copyright (C) 1992, 93, 94, 95, 96, 98, 1999 Free Software Foundation, Inc.
|
||||
#
|
||||
# This configure script is free software; the Free Software Foundation
|
||||
@ -3490,16 +3032,16 @@ dnl so uname gets run too.
|
||||
|
||||
# Files that config.status was made for.
|
||||
ifset([AC_LIST_FILES], [config_files="\\
|
||||
AC_WRAP(AC_LIST_FILES, [ ])"
|
||||
m4_wrap(AC_LIST_FILES, [ ])"
|
||||
])dnl
|
||||
ifset([AC_LIST_HEADERS], [config_headers="\\
|
||||
AC_WRAP(AC_LIST_HEADERS, [ ])"
|
||||
m4_wrap(AC_LIST_HEADERS, [ ])"
|
||||
])dnl
|
||||
ifset([AC_LIST_LINKS], [config_links="\\
|
||||
AC_WRAP(AC_LIST_LINKS, [ ])"
|
||||
m4_wrap(AC_LIST_LINKS, [ ])"
|
||||
])dnl
|
||||
ifset([AC_LIST_COMMANDS], [config_commands="\\
|
||||
AC_WRAP(AC_LIST_COMMANDS, [ ])"
|
||||
m4_wrap(AC_LIST_COMMANDS, [ ])"
|
||||
])dnl
|
||||
|
||||
ac_cs_usage="\\
|
||||
|
@ -20,9 +20,11 @@ dnl 02111-1307, USA.
|
||||
dnl
|
||||
dnl Written by David MacKenzie.
|
||||
dnl
|
||||
include(acgeneral.m4)dnl
|
||||
builtin(include, acspecific.m4)dnl
|
||||
builtin(include, acoldnames.m4)dnl
|
||||
include(libm4.m4)dnl
|
||||
m4_include(acversion.m4)dnl
|
||||
m4_include(acgeneral.m4)dnl
|
||||
m4_include(acspecific.m4)dnl
|
||||
m4_include(acoldnames.m4)dnl
|
||||
dnl Do not sinclude acsite.m4 here, because it may not be installed
|
||||
dnl yet when Autoconf is frozen.
|
||||
dnl Do not sinclude ./aclocal.m4 here, to prevent it from being frozen.
|
||||
|
@ -19,7 +19,9 @@ dnl 02111-1307, USA.
|
||||
dnl
|
||||
dnl Written by Roland McGrath.
|
||||
dnl
|
||||
include(acgeneral.m4)dnl
|
||||
include(libm4.m4)dnl
|
||||
m4_include(acversion.m4)dnl
|
||||
m4_include(acgeneral.m4)dnl
|
||||
m4_include(acspecific.m4)dnl
|
||||
m4_include(acoldnames.m4)dnl
|
||||
|
||||
@ -111,7 +113,7 @@ dnl Issue an autoheader template for KEY, i.e., a comment composed
|
||||
dnl of DESCRIPTION (properly wrapped), and then #undef KEY.
|
||||
define([AH_TEMPLATE],
|
||||
[AH_VERBATIM([$1],
|
||||
AC_WRAP([$2 */], [ ], [/* ])[
|
||||
m4_wrap([$2 */], [ ], [/* ])[
|
||||
#undef $1])])
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
## Process this file with automake to create Makefile.in.
|
||||
|
||||
## Makefile for Autoconf.
|
||||
## Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
## Copyright (C) 1999, 2000 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
|
||||
@ -38,7 +38,7 @@ EXTRA_SCRIPTS = autoscan
|
||||
|
||||
distpkgdataDATA = \
|
||||
acfunctions acheaders acidentifiers acmakevars acprograms \
|
||||
acgeneral.m4 acoldnames.m4 acspecific.m4 autoconf.m4 autoheader.m4
|
||||
libm4.m4 acgeneral.m4 acoldnames.m4 acspecific.m4 autoconf.m4 autoheader.m4
|
||||
|
||||
nodistpkgdataDATA = autoconf.m4f autoheader.m4f acversion.m4
|
||||
|
||||
@ -95,13 +95,12 @@ editpl = sed -e 's,@''datadir''@,$(pkgdatadir),g' -e 's,@''PERL''@,$(PERL),g' \
|
||||
.m4.m4f:
|
||||
@case `$(M4) --help </dev/null 2>&1` in \
|
||||
*reload-state*) echo freezing $*.m4; \
|
||||
$(M4) -F $*.m4f -I${srcdir} ${srcdir}/$*.m4 ;; \
|
||||
*traditional*) ;; \
|
||||
*) echo Error: Autoconf requires GNU m4 1.1 or later; exit 1 ;; \
|
||||
$(M4) -F $*.m4f -I$(srcdir) $(srcdir)/$*.m4 ;; \
|
||||
*) echo Error: Autoconf requires GNU m4 1.4 or later; exit 1 ;; \
|
||||
esac
|
||||
|
||||
autoconf.m4f: autoconf.m4 acgeneral.m4 acspecific.m4 acoldnames.m4 acversion.m4
|
||||
autoheader.m4f: autoheader.m4 acgeneral.m4 acspecific.m4 acoldnames.m4 acversion.m4
|
||||
autoconf.m4f: autoconf.m4 libm4.m4 acgeneral.m4 acspecific.m4 acoldnames.m4 acversion.m4
|
||||
autoheader.m4f: autoheader.m4 libm4.m4 acgeneral.m4 acspecific.m4 acoldnames.m4 acversion.m4
|
||||
|
||||
|
||||
# The documentation
|
||||
|
@ -81,7 +81,7 @@ EXTRA_SCRIPTS = autoscan
|
||||
# s/nodistpackageDATA/nodist_pkgdata_DATA/
|
||||
# and adapt dependencies once we use a more recent Automake
|
||||
|
||||
distpkgdataDATA = acfunctions acheaders acidentifiers acmakevars acprograms acgeneral.m4 acoldnames.m4 acspecific.m4 autoconf.m4 autoheader.m4
|
||||
distpkgdataDATA = acfunctions acheaders acidentifiers acmakevars acprograms libm4.m4 acgeneral.m4 acoldnames.m4 acspecific.m4 autoconf.m4 autoheader.m4
|
||||
|
||||
|
||||
nodistpkgdataDATA = autoconf.m4f autoheader.m4f acversion.m4
|
||||
@ -605,13 +605,12 @@ install-data-hook: INSTALL.txt
|
||||
.m4.m4f:
|
||||
@case `$(M4) --help </dev/null 2>&1` in \
|
||||
*reload-state*) echo freezing $*.m4; \
|
||||
$(M4) -F $*.m4f -I${srcdir} ${srcdir}/$*.m4 ;; \
|
||||
*traditional*) ;; \
|
||||
*) echo Error: Autoconf requires GNU m4 1.1 or later; exit 1 ;; \
|
||||
$(M4) -F $*.m4f -I$(srcdir) $(srcdir)/$*.m4 ;; \
|
||||
*) echo Error: Autoconf requires GNU m4 1.4 or later; exit 1 ;; \
|
||||
esac
|
||||
|
||||
autoconf.m4f: autoconf.m4 acgeneral.m4 acspecific.m4 acoldnames.m4 acversion.m4
|
||||
autoheader.m4f: autoheader.m4 acgeneral.m4 acspecific.m4 acoldnames.m4 acversion.m4
|
||||
autoconf.m4f: autoconf.m4 libm4.m4 acgeneral.m4 acspecific.m4 acoldnames.m4 acversion.m4
|
||||
autoheader.m4f: autoheader.m4 libm4.m4 acgeneral.m4 acspecific.m4 acoldnames.m4 acversion.m4
|
||||
|
||||
# The documentation
|
||||
|
||||
|
@ -20,9 +20,11 @@ dnl 02111-1307, USA.
|
||||
dnl
|
||||
dnl Written by David MacKenzie.
|
||||
dnl
|
||||
include(acgeneral.m4)dnl
|
||||
builtin(include, acspecific.m4)dnl
|
||||
builtin(include, acoldnames.m4)dnl
|
||||
include(libm4.m4)dnl
|
||||
m4_include(acversion.m4)dnl
|
||||
m4_include(acgeneral.m4)dnl
|
||||
m4_include(acspecific.m4)dnl
|
||||
m4_include(acoldnames.m4)dnl
|
||||
dnl Do not sinclude acsite.m4 here, because it may not be installed
|
||||
dnl yet when Autoconf is frozen.
|
||||
dnl Do not sinclude ./aclocal.m4 here, to prevent it from being frozen.
|
||||
|
@ -49,399 +49,6 @@ dnl Written by David MacKenzie, with help from
|
||||
dnl Franc,ois Pinard, Karl Berry, Richard Pixley, Ian Lance Taylor,
|
||||
dnl Roland McGrath, Noah Friedman, david d zuhn, and many others.
|
||||
dnl
|
||||
divert(-1)dnl Throw away output until AC_INIT is called.
|
||||
changequote([, ])
|
||||
|
||||
include(acversion.m4)
|
||||
|
||||
dnl Some old m4's don't support m4exit. But they provide
|
||||
dnl equivalent functionality by core dumping because of the
|
||||
dnl long macros we define.
|
||||
ifdef([__gnu__], , [errprint(Autoconf requires GNU m4.
|
||||
Install it before installing Autoconf or set the
|
||||
M4 environment variable to its path name.
|
||||
)m4exit(2)])
|
||||
|
||||
|
||||
dnl m4_errprint(MSG)
|
||||
dnl ----------------
|
||||
dnl Same as `errprint', but reports the file and line.
|
||||
define(m4_errprint, [errprint(__file__:__line__: [$1
|
||||
])])
|
||||
|
||||
|
||||
dnl m4_warn(MSG)
|
||||
dnl ------------
|
||||
dnl Warn the user.
|
||||
define(m4_warn, [m4_errprint([warning: $1])])
|
||||
|
||||
|
||||
dnl m4_fatal(MSG, [EXIT-STATUS])
|
||||
dnl ----------------------------
|
||||
dnl Fatal the user. :)
|
||||
define(m4_fatal,
|
||||
[m4_errprint([error: $1])dnl
|
||||
m4exit(ifelse([$2],, 1, [$2]))])
|
||||
|
||||
|
||||
dnl Some m4 internals have names colliding with tokens we might use.
|
||||
dnl Rename them a` la `m4 --prefix-builtins'.
|
||||
define([m4_prefix],
|
||||
[define([m4_$1], defn([$1]))
|
||||
undefine([$1])])
|
||||
|
||||
m4_prefix([eval])
|
||||
m4_prefix([shift])
|
||||
m4_prefix([format])
|
||||
|
||||
|
||||
dnl We also want to neutralize include (and sinclude for symmetry),
|
||||
dnl but we want to extend them slightly: warn when a file is included
|
||||
dnl several times. This is in general a dangerous operation because
|
||||
dnl quite nobody quotes the first argument of define.
|
||||
dnl
|
||||
dnl For instance in the following case:
|
||||
dnl define(foo, [bar])
|
||||
dnl then a second reading will turn into
|
||||
dnl define(bar, [bar])
|
||||
dnl which is certainly not what was meant.
|
||||
|
||||
|
||||
dnl m4_include_unique(FILE)
|
||||
dnl -----------------------
|
||||
dnl Declare that the FILE was loading; and warn if it has already
|
||||
dnl been included.
|
||||
define(m4_include_unique,
|
||||
[ifdef([m4_include($1)],
|
||||
[m4_warn([file `$1' included several times])])dnl
|
||||
define([m4_include($1)])])
|
||||
|
||||
|
||||
dnl m4_include(FILE)
|
||||
dnl ----------------
|
||||
dnl As the builtin include, but warns against multiple inclusions.
|
||||
define(m4_include,
|
||||
[m4_include_unique([$1])dnl
|
||||
builtin([include], [$1])])
|
||||
|
||||
|
||||
dnl m4_sinclude(FILE)
|
||||
dnl -----------------
|
||||
dnl As the builtin sinclude, but warns against multiple inclusions.
|
||||
define(m4_sinclude,
|
||||
[m4_include_unique([$1])dnl
|
||||
builtin([sinclude], [$1])])
|
||||
|
||||
dnl Neutralize include and sinclude.
|
||||
undefine([include])
|
||||
undefine([sinclude])
|
||||
|
||||
dnl ------------------------------------------------------------
|
||||
dnl Text processing in m4.
|
||||
dnl ------------------------------------------------------------
|
||||
|
||||
dnl m4_quote(STRING)
|
||||
dnl ----------------
|
||||
dnl Return STRING quoted.
|
||||
dnl
|
||||
dnl It is important to realize the difference between `quote(exp)' and
|
||||
dnl `[exp]': in the first case you obtain the quoted *result* of the
|
||||
dnl expansion of EXP, while in the latter you just obtain the string
|
||||
dnl `exp'.
|
||||
define([m4_quote], [[$@]])
|
||||
|
||||
|
||||
dnl m4_split(STRING, [REGEXP])
|
||||
dnl --------------------------
|
||||
dnl Split STRING into an m4 list of quoted elements. The elements are
|
||||
dnl quoted with [ and ]. Beginning spaces and end spaces *are kept*.
|
||||
dnl Use m4_strip to remove them.
|
||||
dnl
|
||||
dnl REGEXP specifies where to split. Default is [\t ]+.
|
||||
dnl
|
||||
dnl Pay attention to the changequotes. Inner changequotes exist for
|
||||
dnl obvious reasons (we want to insert square brackets). Outer
|
||||
dnl changequotes are needed because otherwise the m4 parser, when it
|
||||
dnl sees the closing bracket we add to the result, believes it is the
|
||||
dnl end of the body of the macro we define.
|
||||
dnl
|
||||
dnl Also, notice that $1 is quoted twice, since we want the result to be
|
||||
dnl quoted. Then you should understand that the argument of patsubst is
|
||||
dnl ``STRING'' (i.e., with additional `` and '').
|
||||
dnl
|
||||
dnl This macro is safe on active symbols, i.e.:
|
||||
dnl define(active, ACTIVE)
|
||||
dnl m4_split([active active ])end
|
||||
dnl => [active], [active], []end
|
||||
changequote(<<, >>)
|
||||
define(<<m4_split>>,
|
||||
<<changequote(``, '')dnl
|
||||
[dnl Can't use m4_default here instead of ifelse, because m4_default uses
|
||||
dnl [ and ] as quotes.
|
||||
patsubst(````$1'''',
|
||||
ifelse(``$2'',, ``[ ]+'', ``$2''),
|
||||
``], ['')]dnl
|
||||
changequote([, ])>>)
|
||||
changequote([, ])
|
||||
|
||||
|
||||
dnl m4_join(STRING)
|
||||
dnl ---------------
|
||||
dnl If STRING contains end of lines, replace them with spaces. If there
|
||||
dnl are backslashed end of lines, remove them. This macro is safe with
|
||||
dnl active symbols.
|
||||
dnl define(active, ACTIVE)
|
||||
dnl m4_join([active
|
||||
dnl act\
|
||||
dnl ive])end
|
||||
dnl => active activeend
|
||||
define([m4_join],
|
||||
[translit(patsubst([[[$1]]], [\\
|
||||
]), [
|
||||
], [ ])])
|
||||
|
||||
|
||||
dnl m4_strip(STRING)
|
||||
dnl ----------------
|
||||
dnl Expands into STRING with tabs and spaces singled out into a single
|
||||
dnl space, and removing leading and trailing spaces.
|
||||
dnl
|
||||
dnl This macro is robust to active symbols.
|
||||
dnl define(active, ACTIVE)
|
||||
dnl m4_strip([ active active ])end
|
||||
dnl => active activeend
|
||||
dnl
|
||||
dnl This macro is fun! Because we want to preserve active symbols, STRING
|
||||
dnl must be quoted for each evaluation, which explains there are 4 levels
|
||||
dnl of brackets around $1 (don't forget that the result must be quoted
|
||||
dnl too, hence one more quoting than applications).
|
||||
dnl
|
||||
dnl Then notice the patsubst of the middle: it is in charge of removing
|
||||
dnl the leading space. Why not just `patsubst(..., [^ ])'? Because this
|
||||
dnl macro will receive the output of the preceding patsubst, i.e. more or
|
||||
dnl less [[STRING]]. So if there is a leading space in STRING, then it is
|
||||
dnl the *third* character, since there are two leading `['; Equally for
|
||||
dnl the outer patsubst.
|
||||
define([m4_strip],
|
||||
[patsubst(patsubst(patsubst([[[[$1]]]],
|
||||
[[ ]+], [ ]),
|
||||
[^\(..\) ], [\1]),
|
||||
[ \(.\)$], [\1])])
|
||||
|
||||
|
||||
|
||||
dnl m4_append(MACRO-NAME, STRING)
|
||||
dnl -----------------------------
|
||||
dnl Redefine MACRO-NAME to hold its former content plus STRING at the
|
||||
dnl end. It is valid to use this macro with MACRO-NAME undefined.
|
||||
dnl
|
||||
dnl This macro is robust to active symbols. It can be used to grow
|
||||
dnl strings.
|
||||
dnl
|
||||
dnl | define(active, ACTIVE)
|
||||
dnl | m4_append([sentence], [This is an])
|
||||
dnl | m4_append([sentence], [ active ])
|
||||
dnl | m4_append([sentence], [symbol.])
|
||||
dnl | sentence
|
||||
dnl | undefine([active])dnl
|
||||
dnl | sentence
|
||||
dnl => This is an ACTIVE symbol.
|
||||
dnl => This is an active symbol.
|
||||
dnl
|
||||
dnl It can be used to define hooks.
|
||||
dnl
|
||||
dnl | define(active, ACTIVE)
|
||||
dnl | m4_append([hooks], [define([act1], [act2])])
|
||||
dnl | m4_append([hooks], [define([act2], [active])])
|
||||
dnl | undefine([active])
|
||||
dnl | act1
|
||||
dnl | hooks
|
||||
dnl | act1
|
||||
dnl => act1
|
||||
dnl =>
|
||||
dnl => active
|
||||
define(m4_append,
|
||||
[define([$1],
|
||||
ifdef([$1], [defn([$1])])[$2])])
|
||||
|
||||
|
||||
dnl m4_list_append(MACRO-NAME, STRING)
|
||||
dnl ----------------------------------
|
||||
dnl Same as `m4_append', but each element is separated by `, '.
|
||||
define(m4_list_append,
|
||||
[define([$1],
|
||||
ifdef([$1], [defn([$1]), ])[$2])])
|
||||
|
||||
|
||||
dnl ------------------------------------------------------------
|
||||
dnl Some additional m4 structural control.
|
||||
dnl ------------------------------------------------------------
|
||||
|
||||
dnl Both `ifval' and `ifset' tests against the empty string. The
|
||||
dnl difference is that `ifset' is specialized on macros.
|
||||
dnl
|
||||
dnl In case of arguments of macros, eg $[1], it makes little difference.
|
||||
dnl In the case of a macro `FOO', you don't want to check `ifval(FOO,
|
||||
dnl TRUE)', because if `FOO' expands with commas, there is a shifting of
|
||||
dnl the arguments. So you want to run `ifval([FOO])', but then you just
|
||||
dnl compare the *string* `FOO' against `', which, of course fails.
|
||||
dnl
|
||||
dnl So you want a variation of `ifset' that expects a macro name as $[1].
|
||||
dnl If this macro is both defined and defined to a non empty value, then
|
||||
dnl it runs TRUE etc.
|
||||
|
||||
|
||||
dnl ifval(COND, IF-TRUE[, IF-FALSE])
|
||||
dnl --------------------------------
|
||||
dnl If COND is not the empty string, expand IF-TRUE, otherwise IF-FALSE.
|
||||
dnl Comparable to ifdef.
|
||||
define([ifval], [ifelse([$1],[],[$3],[$2])])
|
||||
|
||||
|
||||
dnl ifset(MACRO, IF-TRUE[, IF-FALSE])
|
||||
dnl --------------------------------
|
||||
dnl If MACRO has no definition, or of its definition is the empty string,
|
||||
dnl expand IF-FALSE, otherwise IF-TRUE.
|
||||
define([ifset],
|
||||
[ifdef([$1],
|
||||
[ifelse(defn([$1]), [], [$3], [$2])],
|
||||
[$3])])
|
||||
|
||||
|
||||
dnl m4_default(EXP1, EXP2)
|
||||
dnl ----------------------
|
||||
dnl Returns EXP1 if non empty, otherwise EXP2.
|
||||
define([m4_default], [ifval([$1], [$1], [$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.
|
||||
define(m4_case,
|
||||
[ifelse([$#], 0, [],
|
||||
[$#], 1, [],
|
||||
[$#], 2, [$2],
|
||||
[$1], [$2], [$3],
|
||||
[m4_case([$1], m4_shift(m4_shift(m4_shift($@))))])])
|
||||
|
||||
|
||||
# m4_match(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.
|
||||
define(m4_match,
|
||||
[ifelse([$#], 0, [],
|
||||
[$#], 1, [],
|
||||
[$#], 2, [$2],
|
||||
regexp([$1], [$2]), -1, [m4_match([$1],
|
||||
m4_shift(m4_shift(m4_shift($@))))],
|
||||
[$3])])
|
||||
|
||||
|
||||
## --------------------- ##
|
||||
## Implementing m4 loops ##
|
||||
## --------------------- ##
|
||||
|
||||
|
||||
# Implementing loops (`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 undesired expansions.
|
||||
#
|
||||
# The example in the documentation is:
|
||||
#
|
||||
# | # foreach(x, (item_1, item_2, ..., item_n), stmt)
|
||||
# | define(`foreach',
|
||||
# | `pushdef(`$1', `')_foreach(`$1', `$2', `$3')popdef(`$1')')
|
||||
# | define(`_arg1', `$1')
|
||||
# | define(`_foreach',
|
||||
# | `ifelse(`$2', `()', ,
|
||||
# | `define(`$1', _arg1$2)$3`'_foreach(`$1', (shift$2), `$3')')')
|
||||
#
|
||||
# But then if you run
|
||||
#
|
||||
# | define(a, 1)
|
||||
# | define(b, 2)
|
||||
# | define(c, 3)
|
||||
# | foreach(`f', `(`a', `(b', `c)')', `echo f
|
||||
# | ')
|
||||
#
|
||||
# it gives
|
||||
#
|
||||
# => echo 1
|
||||
# => echo (2,3)
|
||||
#
|
||||
# which is not what is expected.
|
||||
#
|
||||
# Once you understood this, you turn yourself into a quoting wizard,
|
||||
# and come up with the following solution:
|
||||
#
|
||||
# | # foreach(x, (item_1, item_2, ..., item_n), stmt)
|
||||
# | define(`foreach', `pushdef(`$1', `')_foreach($@)popdef(`$1')')
|
||||
# | define(`_arg1', ``$1'')
|
||||
# | define(`_foreach',
|
||||
# | `ifelse($2, `()', ,
|
||||
# | `define(`$1', `_arg1$2')$3`'_foreach(`$1', `(shift$2)', `$3')')')
|
||||
#
|
||||
# which this time answers
|
||||
#
|
||||
# => echo a
|
||||
# => echo (b
|
||||
# => echo c)
|
||||
#
|
||||
# Bingo!
|
||||
|
||||
|
||||
# m4_foreach(VARIABLE, LIST, EXPRESSION)
|
||||
# --------------------------------------
|
||||
# Expand EXPRESSION assigning to VARIABLE each value of the LIST
|
||||
# (LIST should have the form `[(item_1, item_2, ..., item_n)]'),
|
||||
# i.e. the whole list should be *quoted*. Quote members too if
|
||||
# you don't want them to be expanded.
|
||||
#
|
||||
# This macro is robust to active symbols:
|
||||
# define(active, ACTIVE)
|
||||
# m4_foreach([Var], [([active], [b], [active])], [-Var-])end
|
||||
# => -active--b--active-end
|
||||
define(m4_foreach,
|
||||
[pushdef([$1], [])_m4_foreach($@)popdef([$1])])
|
||||
|
||||
dnl Low level macros used to define m4_foreach
|
||||
define(m4_car, [[$1]])
|
||||
define(_m4_foreach,
|
||||
[ifelse($2, [()], ,
|
||||
[define([$1], [m4_car$2])$3[]_m4_foreach([$1],
|
||||
[(m4_shift$2)],
|
||||
[$3])])])
|
||||
|
||||
|
||||
|
||||
|
||||
dnl ### Defining macros
|
||||
|
||||
@ -733,74 +340,9 @@ AC_DEFUN(AC_SPECIALIZE,
|
||||
[indir([$1], m4_shift($@))])])
|
||||
|
||||
|
||||
dnl ## --------------------------------- ##
|
||||
dnl ## Helping macros to display strings ##
|
||||
dnl ## --------------------------------- ##
|
||||
|
||||
|
||||
dnl AC_WRAP(STRING [, PREFIX[, FIRST-PREFIX[, WIDTH]]]]))
|
||||
dnl -----------------------------------------------------
|
||||
dnl Expands into STRING wrapped to hold in WIDTH columns (default = 79).
|
||||
dnl If prefix is set, each line is prefixed with it. If FIRST-PREFIX is
|
||||
dnl specified, then the first line is prefixed with it. As a special
|
||||
dnl case, if the length of the first prefix is greater than that of
|
||||
dnl PREFIX, then FIRST-PREFIX will be left alone on the first line.
|
||||
dnl
|
||||
dnl Typical outputs are:
|
||||
dnl
|
||||
dnl AC_WRAP([Short string */], [ ], [/* ], 20)
|
||||
dnl => /* Short string */
|
||||
dnl
|
||||
dnl AC_WRAP([Much longer string */], [ ], [/* ], 20)
|
||||
dnl => /* Much longer
|
||||
dnl => string */
|
||||
dnl
|
||||
dnl AC_WRAP([Short doc.], [ ], [ --short ], 30)
|
||||
dnl => --short Short doc.
|
||||
dnl
|
||||
dnl AC_WRAP([Short doc.], [ ], [ --too-wide ], 30)
|
||||
dnl => --too-wide
|
||||
dnl => Short doc.
|
||||
dnl
|
||||
dnl AC_WRAP([Super long documentation.], [ ], [ --too-wide ], 30)
|
||||
dnl => --too-wide
|
||||
dnl => Super long
|
||||
dnl => documentation.
|
||||
dnl
|
||||
dnl FIXME: there is no checking of a longer PREFIX than WIDTH, but do
|
||||
dnl we really want to bother with people trying each single corner
|
||||
dnl of a software?
|
||||
dnl
|
||||
dnl This macro does not leave a trailing space behind the last word,
|
||||
dnl what complicates it a bit. The algorithm is stupid simple: all the
|
||||
dnl words are preceded by AC_Separator which is defined to empty for the
|
||||
dnl first word, and then ` ' (single space) for all the others.
|
||||
define([AC_WRAP],
|
||||
[pushdef([AC_Prefix], m4_default([$2], []))dnl
|
||||
pushdef([AC_Prefix1], m4_default([$3], [AC_Prefix]))dnl
|
||||
pushdef([AC_Width], m4_default([$4], 79))dnl
|
||||
pushdef([AC_Cursor], len(AC_Prefix1))dnl
|
||||
pushdef([AC_Separator], [])dnl
|
||||
AC_Prefix1[]dnl
|
||||
ifelse(m4_eval(AC_Cursor > len(AC_Prefix)),
|
||||
1, [define([AC_Cursor], len(AC_Prefix))
|
||||
AC_Prefix])[]dnl
|
||||
AC_FOREACH([AC_Word], [$1],
|
||||
[define([AC_Cursor], m4_eval(AC_Cursor + len(AC_Word) + 1))dnl
|
||||
dnl New line if too long, else insert a space unless it is the first
|
||||
dnl of the words.
|
||||
ifelse(m4_eval(AC_Cursor > AC_Width),
|
||||
1, [define([AC_Cursor], m4_eval(len(AC_Prefix) + len(AC_Word) + 1))]
|
||||
AC_Prefix,
|
||||
[AC_Separator])[]dnl
|
||||
AC_Word[]dnl
|
||||
define([AC_Separator], [ ])])dnl
|
||||
popdef([AC_Separator])dnl
|
||||
popdef([AC_Cursor])dnl
|
||||
popdef([AC_Width])dnl
|
||||
popdef([AC_Prefix1])dnl
|
||||
popdef([AC_Prefix])dnl
|
||||
])
|
||||
## --------------------------------- ##
|
||||
## Helping macros to display strings ##
|
||||
## --------------------------------- ##
|
||||
|
||||
|
||||
dnl AC_HELP_STRING(LHS, RHS[, COLUMN])
|
||||
@ -847,7 +389,7 @@ dnl
|
||||
define([AC_HELP_STRING],
|
||||
[pushdef([AC_Prefix], m4_default([$3], [ ]))dnl
|
||||
pushdef([AC_Prefix_Format], [ %-]m4_eval(len(AC_Prefix) - 3)[s ])dnl [ %-23s ]
|
||||
AC_WRAP([$2], AC_Prefix, m4_format(AC_Prefix_Format, [$1]))dnl
|
||||
m4_wrap([$2], AC_Prefix, m4_format(AC_Prefix_Format, [$1]))dnl
|
||||
popdef([AC_Prefix_Format])dnl
|
||||
popdef([AC_Prefix])dnl
|
||||
])
|
||||
@ -859,7 +401,7 @@ dnl AC_INIT_NOTICE
|
||||
dnl --------------
|
||||
AC_DEFUN(AC_INIT_NOTICE,
|
||||
[# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated automatically using Autoconf version] AC_ACVERSION [
|
||||
# Generated automatically using Autoconf version ]AC_ACVERSION[
|
||||
# Copyright (C) 1992, 93, 94, 95, 96, 98, 1999 Free Software Foundation, Inc.
|
||||
#
|
||||
# This configure script is free software; the Free Software Foundation
|
||||
@ -3490,16 +3032,16 @@ dnl so uname gets run too.
|
||||
|
||||
# Files that config.status was made for.
|
||||
ifset([AC_LIST_FILES], [config_files="\\
|
||||
AC_WRAP(AC_LIST_FILES, [ ])"
|
||||
m4_wrap(AC_LIST_FILES, [ ])"
|
||||
])dnl
|
||||
ifset([AC_LIST_HEADERS], [config_headers="\\
|
||||
AC_WRAP(AC_LIST_HEADERS, [ ])"
|
||||
m4_wrap(AC_LIST_HEADERS, [ ])"
|
||||
])dnl
|
||||
ifset([AC_LIST_LINKS], [config_links="\\
|
||||
AC_WRAP(AC_LIST_LINKS, [ ])"
|
||||
m4_wrap(AC_LIST_LINKS, [ ])"
|
||||
])dnl
|
||||
ifset([AC_LIST_COMMANDS], [config_commands="\\
|
||||
AC_WRAP(AC_LIST_COMMANDS, [ ])"
|
||||
m4_wrap(AC_LIST_COMMANDS, [ ])"
|
||||
])dnl
|
||||
|
||||
ac_cs_usage="\\
|
||||
|
514
libm4.m4
Normal file
514
libm4.m4
Normal file
@ -0,0 +1,514 @@
|
||||
divert(-1) -*- Autoconf -*-
|
||||
# This file is part of Autoconf.
|
||||
# Base m4 layer.
|
||||
# Requires GNU m4.
|
||||
# Copyright (C) 1999 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., 59 Temple Place - Suite 330, Boston, MA
|
||||
# 02111-1307, 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.
|
||||
#
|
||||
|
||||
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(Autoconf requires GNU m4. Install it before installing Autoconf or
|
||||
set the M4 environment variable to its path name.)
|
||||
m4exit(2)])
|
||||
|
||||
## --------------------------------------------- ##
|
||||
## Move some m4 builtins to a safer name space. ##
|
||||
## --------------------------------------------- ##
|
||||
|
||||
# m4_errprint(MSG)
|
||||
# ----------------
|
||||
# Same as `errprint', but reports the file and line.
|
||||
define(m4_errprint, [errprint(__file__:__line__: [$1
|
||||
])])
|
||||
|
||||
|
||||
# m4_warn(MSG)
|
||||
# ------------
|
||||
# Warn the user.
|
||||
define(m4_warn, [m4_errprint([warning: $1])])
|
||||
|
||||
|
||||
# m4_fatal(MSG, [EXIT-STATUS])
|
||||
# ----------------------------
|
||||
# Fatal the user. :)
|
||||
define(m4_fatal,
|
||||
[m4_errprint([error: $1])dnl
|
||||
m4exit(ifelse([$2],, 1, [$2]))])
|
||||
|
||||
|
||||
# Some m4 internals have names colliding with tokens we might use.
|
||||
# Rename them a` la `m4 --prefix-builtins'.
|
||||
define([m4_prefix],
|
||||
[define([m4_$1], defn([$1]))
|
||||
undefine([$1])])
|
||||
|
||||
m4_prefix([eval])
|
||||
m4_prefix([shift])
|
||||
m4_prefix([format])
|
||||
|
||||
|
||||
# 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 define.
|
||||
#
|
||||
# For instance in the following case:
|
||||
# define(foo, [bar])
|
||||
# then a second reading will turn into
|
||||
# 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.
|
||||
define(m4_include_unique,
|
||||
[ifdef([m4_include($1)],
|
||||
[m4_warn([file `$1' included several times])])dnl
|
||||
define([m4_include($1)])])
|
||||
|
||||
|
||||
# m4_include(FILE)
|
||||
# ----------------
|
||||
# As the builtin include, but warns against multiple inclusions.
|
||||
define(m4_include,
|
||||
[m4_include_unique([$1])dnl
|
||||
builtin([include], [$1])])
|
||||
|
||||
|
||||
# m4_sinclude(FILE)
|
||||
# -----------------
|
||||
# As the builtin sinclude, but warns against multiple inclusions.
|
||||
define(m4_sinclude,
|
||||
[m4_include_unique([$1])dnl
|
||||
builtin([sinclude], [$1])])
|
||||
|
||||
# Neutralize include and sinclude.
|
||||
undefine([include])
|
||||
undefine([sinclude])
|
||||
|
||||
|
||||
## --------------------------------------- ##
|
||||
## Some additional m4 structural control. ##
|
||||
## --------------------------------------- ##
|
||||
|
||||
# Both `ifval' and `ifset' tests against the empty string. The
|
||||
# difference is that `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 `ifval(FOO,
|
||||
# TRUE)', because if `FOO' expands with commas, there is a shifting of
|
||||
# the arguments. So you want to run `ifval([FOO])', but then you just
|
||||
# compare the *string* `FOO' against `', which, of course fails.
|
||||
#
|
||||
# So you want a variation of `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.
|
||||
|
||||
|
||||
# ifval(COND, IF-TRUE[, IF-FALSE])
|
||||
# --------------------------------
|
||||
# If COND is not the empty string, expand IF-TRUE, otherwise IF-FALSE.
|
||||
# Comparable to ifdef.
|
||||
define([ifval], [ifelse([$1],[],[$3],[$2])])
|
||||
|
||||
|
||||
# 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.
|
||||
define([ifset],
|
||||
[ifdef([$1],
|
||||
[ifelse(defn([$1]), [], [$3], [$2])],
|
||||
[$3])])
|
||||
|
||||
|
||||
# m4_default(EXP1, EXP2)
|
||||
# ----------------------
|
||||
# Returns EXP1 if non empty, otherwise EXP2.
|
||||
define([m4_default], [ifval([$1], [$1], [$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.
|
||||
define(m4_case,
|
||||
[ifelse([$#], 0, [],
|
||||
[$#], 1, [],
|
||||
[$#], 2, [$2],
|
||||
[$1], [$2], [$3],
|
||||
[m4_case([$1], m4_shift(m4_shift(m4_shift($@))))])])
|
||||
|
||||
|
||||
# m4_match(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.
|
||||
define(m4_match,
|
||||
[ifelse([$#], 0, [],
|
||||
[$#], 1, [],
|
||||
[$#], 2, [$2],
|
||||
regexp([$1], [$2]), -1, [m4_match([$1],
|
||||
m4_shift(m4_shift(m4_shift($@))))],
|
||||
[$3])])
|
||||
|
||||
|
||||
## --------------------- ##
|
||||
## Implementing m4 loops ##
|
||||
## --------------------- ##
|
||||
|
||||
|
||||
# Implementing loops (`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 undesired expansions.
|
||||
#
|
||||
# The example in the documentation is:
|
||||
#
|
||||
# | # foreach(x, (item_1, item_2, ..., item_n), stmt)
|
||||
# | define(`foreach',
|
||||
# | `pushdef(`$1', `')_foreach(`$1', `$2', `$3')popdef(`$1')')
|
||||
# | define(`_arg1', `$1')
|
||||
# | define(`_foreach',
|
||||
# | `ifelse(`$2', `()', ,
|
||||
# | `define(`$1', _arg1$2)$3`'_foreach(`$1', (shift$2), `$3')')')
|
||||
#
|
||||
# But then if you run
|
||||
#
|
||||
# | define(a, 1)
|
||||
# | define(b, 2)
|
||||
# | define(c, 3)
|
||||
# | foreach(`f', `(`a', `(b', `c)')', `echo f
|
||||
# | ')
|
||||
#
|
||||
# it gives
|
||||
#
|
||||
# => echo 1
|
||||
# => echo (2,3)
|
||||
#
|
||||
# which is not what is expected.
|
||||
#
|
||||
# Once you understood this, you turn yourself into a quoting wizard,
|
||||
# and come up with the following solution:
|
||||
#
|
||||
# | # foreach(x, (item_1, item_2, ..., item_n), stmt)
|
||||
# | define(`foreach', `pushdef(`$1', `')_foreach($@)popdef(`$1')')
|
||||
# | define(`_arg1', ``$1'')
|
||||
# | define(`_foreach',
|
||||
# | `ifelse($2, `()', ,
|
||||
# | `define(`$1', `_arg1$2')$3`'_foreach(`$1', `(shift$2)', `$3')')')
|
||||
#
|
||||
# which this time answers
|
||||
#
|
||||
# => echo a
|
||||
# => echo (b
|
||||
# => echo c)
|
||||
#
|
||||
# Bingo!
|
||||
|
||||
|
||||
# m4_foreach(VARIABLE, LIST, EXPRESSION)
|
||||
# --------------------------------------
|
||||
# Expand EXPRESSION assigning to VARIABLE each value of the LIST
|
||||
# (LIST should have the form `[(item_1, item_2, ..., item_n)]'),
|
||||
# i.e. the whole list should be *quoted*. Quote members too if
|
||||
# you don't want them to be expanded.
|
||||
#
|
||||
# This macro is robust to active symbols:
|
||||
# define(active, ACTIVE)
|
||||
# m4_foreach([Var], [([active], [b], [active])], [-Var-])end
|
||||
# => -active--b--active-end
|
||||
define(m4_foreach,
|
||||
[pushdef([$1], [])_m4_foreach($@)popdef([$1])])
|
||||
|
||||
# Low level macros used to define m4_foreach
|
||||
define(m4_car, [[$1]])
|
||||
define(_m4_foreach,
|
||||
[ifelse($2, [()], ,
|
||||
[define([$1], [m4_car$2])$3[]_m4_foreach([$1],
|
||||
[(m4_shift$2)],
|
||||
[$3])])])
|
||||
|
||||
|
||||
## ----------------------- ##
|
||||
## Text processing in m4. ##
|
||||
## ----------------------- ##
|
||||
|
||||
# m4_quote(STRING)
|
||||
# ----------------
|
||||
# Return STRING quoted.
|
||||
#
|
||||
# It is important to realize the difference between `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'.
|
||||
define([m4_quote], [[$@]])
|
||||
|
||||
|
||||
# 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 ]+.
|
||||
#
|
||||
# Pay attention to the changequotes. Inner changequotes exist for
|
||||
# obvious reasons (we want to insert square brackets). Outer
|
||||
# changequotes are needed because otherwise the m4 parser, when it
|
||||
# sees the closing bracket we add to the result, believes it is the
|
||||
# end of the body of the macro we define.
|
||||
#
|
||||
# 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.:
|
||||
# define(active, ACTIVE)
|
||||
# m4_split([active active ])end
|
||||
# => [active], [active], []end
|
||||
changequote(<<, >>)
|
||||
define(<<m4_split>>,
|
||||
<<changequote(``, '')dnl
|
||||
[dnl Can't use m4_default here instead of ifelse, because m4_default uses
|
||||
dnl [ and ] as quotes.
|
||||
patsubst(````$1'''',
|
||||
ifelse(``$2'',, ``[ ]+'', ``$2''),
|
||||
``], ['')]dnl
|
||||
changequote([, ])>>)
|
||||
changequote([, ])
|
||||
|
||||
|
||||
# m4_join(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.
|
||||
# define(active, ACTIVE)
|
||||
# m4_join([active
|
||||
# act\
|
||||
# ive])end
|
||||
# => active activeend
|
||||
define([m4_join],
|
||||
[translit(patsubst([[[$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.
|
||||
# define(active, ACTIVE)
|
||||
# m4_strip([ active active ])end
|
||||
# => active activeend
|
||||
#
|
||||
# This macro is fun! Because we want to preserve active symbols, STRING
|
||||
# must be quoted for each evaluation, which explains there are 4 levels
|
||||
# of brackets around $1 (don't forget that the result must be quoted
|
||||
# too, hence one more quoting than applications).
|
||||
#
|
||||
# Then notice the patsubst of the middle: it is in charge of removing
|
||||
# the leading space. Why not just `patsubst(..., [^ ])'? Because this
|
||||
# macro will receive the output of the preceding patsubst, 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 outer patsubst.
|
||||
define([m4_strip],
|
||||
[patsubst(patsubst(patsubst([[[[$1]]]],
|
||||
[[ ]+], [ ]),
|
||||
[^\(..\) ], [\1]),
|
||||
[ \(.\)$], [\1])])
|
||||
|
||||
|
||||
|
||||
# m4_append(MACRO-NAME, STRING)
|
||||
# -----------------------------
|
||||
# Redefine MACRO-NAME to hold its former content plus STRING at the
|
||||
# end. It is valid to use this macro with MACRO-NAME undefined.
|
||||
#
|
||||
# This macro is robust to active symbols. It can be used to grow
|
||||
# strings.
|
||||
#
|
||||
# | define(active, ACTIVE)
|
||||
# | m4_append([sentence], [This is an])
|
||||
# | m4_append([sentence], [ active ])
|
||||
# | m4_append([sentence], [symbol.])
|
||||
# | sentence
|
||||
# | undefine([active])dnl
|
||||
# | sentence
|
||||
# => This is an ACTIVE symbol.
|
||||
# => This is an active symbol.
|
||||
#
|
||||
# It can be used to define hooks.
|
||||
#
|
||||
# | define(active, ACTIVE)
|
||||
# | m4_append([hooks], [define([act1], [act2])])
|
||||
# | m4_append([hooks], [define([act2], [active])])
|
||||
# | undefine([active])
|
||||
# | act1
|
||||
# | hooks
|
||||
# | act1
|
||||
# => act1
|
||||
# =>
|
||||
# => active
|
||||
define(m4_append,
|
||||
[define([$1],
|
||||
ifdef([$1], [defn([$1])])[$2])])
|
||||
|
||||
|
||||
# m4_list_append(MACRO-NAME, STRING)
|
||||
# ----------------------------------
|
||||
# Same as `m4_append', but each element is separated by `, '.
|
||||
define(m4_list_append,
|
||||
[define([$1],
|
||||
ifdef([$1], [defn([$1]), ])[$2])])
|
||||
|
||||
|
||||
|
||||
|
||||
## --------------------------------- ##
|
||||
## Helping macros to display strings ##
|
||||
## --------------------------------- ##
|
||||
|
||||
|
||||
# m4_wrap(STRING, [PREFIX], [FIRST-PREFIX], [WIDTH])
|
||||
# --------------------------------------------------
|
||||
# Expands into STRING wrapped to hold in WIDTH columns (default = 79).
|
||||
# If prefix is set, 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 the first prefix is greater than that of
|
||||
# PREFIX, then FIRST-PREFIX will be left alone on the first line.
|
||||
#
|
||||
# Typical outputs are:
|
||||
#
|
||||
# m4_wrap([Short string */], [ ], [/* ], 20)
|
||||
# => /* Short string */
|
||||
#
|
||||
# m4_wrap([Much longer string */], [ ], [/* ], 20)
|
||||
# => /* Much longer
|
||||
# => string */
|
||||
#
|
||||
# m4_wrap([Short doc.], [ ], [ --short ], 30)
|
||||
# => --short Short doc.
|
||||
#
|
||||
# m4_wrap([Short doc.], [ ], [ --too-wide ], 30)
|
||||
# => --too-wide
|
||||
# => Short doc.
|
||||
#
|
||||
# m4_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.
|
||||
define([m4_wrap],
|
||||
[pushdef([m4_Prefix], m4_default([$2], []))dnl
|
||||
pushdef([m4_Prefix1], m4_default([$3], [m4_Prefix]))dnl
|
||||
pushdef([m4_Width], m4_default([$4], 79))dnl
|
||||
pushdef([m4_Cursor], len(m4_Prefix1))dnl
|
||||
pushdef([m4_Separator], [])dnl
|
||||
m4_Prefix1[]dnl
|
||||
ifelse(m4_eval(m4_Cursor > len(m4_Prefix)),
|
||||
1, [define([m4_Cursor], len(m4_Prefix))
|
||||
m4_Prefix])[]dnl
|
||||
m4_foreach([m4_Word], (m4_split(m4_strip(m4_join([$1])))),
|
||||
[define([m4_Cursor], m4_eval(m4_Cursor + len(m4_Word) + 1))dnl
|
||||
dnl New line if too long, else insert a space unless it is the first
|
||||
dnl of the words.
|
||||
ifelse(m4_eval(m4_Cursor > m4_Width),
|
||||
1, [define([m4_Cursor], m4_eval(len(m4_Prefix) + len(m4_Word) + 1))]
|
||||
m4_Prefix,
|
||||
[m4_Separator])[]dnl
|
||||
m4_Word[]dnl
|
||||
define([m4_Separator], [ ])])dnl
|
||||
popdef([m4_Separator])dnl
|
||||
popdef([m4_Cursor])dnl
|
||||
popdef([m4_Width])dnl
|
||||
popdef([m4_Prefix1])dnl
|
||||
popdef([m4_Prefix])dnl
|
||||
])
|
Loading…
x
Reference in New Issue
Block a user