| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
M4sh, pronounced "mash", is aiming at producing portable Bourne shell scripts. This name was coined by Lars J. Aas, who notes that, according to the Webster's Revised Unabridged Dictionary (1913):
Mash \Mash\, n. [Akin to G. meisch, maisch, meische, maische, mash, wash, and prob. to AS. miscian to mix. See "Mix".]
- A mass of mixed ingredients reduced to a soft pulpy state by beating or pressure....
- A mixture of meal or bran and water fed to animals.
- A mess; trouble. [Obs.] -Beau. & Fl.
M4sh reserves the M4 macro namespace `^_AS_' for internal use, and the namespace `^AS_' for M4sh macros. It also reserves the shell and environment variable namespace `^as_', and the here-document delimiter namespace `^_AS[A-Z]' in the output file. You should not define your own macros or output shell code that conflicts with these namespaces.
| 9.1 Common Shell Constructs | Portability layer for common shell constructs | |
| 9.2 Support for indirect variable names | ||
| 9.3 Initialization Macros | Macros to establish a sane shell environment | |
| 9.4 File Descriptor Macros | File descriptor macros for input and output |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
M4sh provides portable alternatives for some common shell constructs that unfortunately are not portable in practice.
Expand into a shell `case' statement, where word is matched against one or more patterns. if-matched is run if the corresponding pattern matched word, else default is run. Avoids several portability issues (see Limitations of Shell Builtins).
Output the directory portion of file-name. For example,
if $file is `/one/two/three', the command
dir=`AS_DIRNAME(["$file"])` sets dir to `/one/two'.
This interface may be improved in the future to avoid forks and losing trailing newlines.
Emits word to the standard output, followed by a newline. word
must be a single shell word (typically a quoted string). The bytes of
word are output as-is, even if it starts with "-" or contains "\".
Redirections can be placed outside the macro invocation. This is much
more portable than using echo (see Limitations of Shell Builtins).
Emits word to the standard output, without a following newline. word must be a single shell word (typically a quoted string) and, for portability, should not include more than one newline. The bytes of word are output as-is, even if it starts with "-" or contains "\". Redirections can be placed outside the macro invocation.
Expands to string, with any characters in chars escaped with
a backslash (`\'). chars should be at most four bytes long,
and only contain characters from the set ``\"$'; however,
characters may be safely listed more than once in chars for the
sake of syntax highlighting editors. The current implementation expands
string after adding escapes; if string contains macro calls
that in turn expand to text needing shell quoting, you can use
AS_ESCAPE(m4_dquote(m4_expand([string]))).
The default for chars (`\"$`') is the set of characters needing escapes when string will be used literally within double quotes. One common variant is the set of characters to protect when string will be used literally within back-ticks or an unquoted here-document (`\$`'). Another common variant is `""', which can be used to form a double-quoted string containing the same expansions that would have occurred if string were expanded in an unquoted here-document; however, when using this variant, care must be taken that string does not use double quotes within complex variable expansions (such as `${foo-`echo "hi"`}') that would be broken with improper escapes.
This macro is often used with AS_ECHO. For an example, observe
the output generated by the shell code generated from this snippet:
foo=bar AS_ECHO(["AS_ESCAPE(["$foo" = ])AS_ESCAPE(["$foo"], [""])"]) ⇒"$foo" = "bar" m4_define([macro], [a, [\b]]) AS_ECHO(["AS_ESCAPE([[macro]])"]) ⇒macro AS_ECHO(["AS_ESCAPE([macro])"]) ⇒a, b AS_ECHO(["AS_ESCAPE(m4_dquote(m4_expand([macro])))"]) ⇒a, \b |
To escape a string that will be placed within single quotes, use:
m4_bpatsubst([[string]], ['], ['\\'']) |
Emit code to exit the shell with status, defaulting to `$?'.
This macro
works around shells that see the exit status of the command prior to
exit inside a `trap 0' handler (see Limitations of Shell Builtins).
Run shell code test1. If test1 exits with a zero status then run shell code run-if-true1, else examine further tests. If no test exits with a zero status, run shell code run-if-false, with simplifications if either run-if-true1 or run-if-false is empty. For example,
AS_IF([test "x$foo" = xyes], [HANDLE_FOO([yes])],
[test "x$foo" != xno], [HANDLE_FOO([maybe])],
[echo foo not specified])
|
ensures any required macros of HANDLE_FOO
are expanded before the first test.
Make the directory file-name, including intervening directories
as necessary. This is equivalent to `mkdir -p -- file-name',
except that it is portable to older versions of mkdir that
lack support for the `-p' option or for the `--'
delimiter (see Limitations of Usual Tools). Also,
AS_MKDIR_P
succeeds if file-name is a symbolic link to an existing directory,
even though Posix is unclear whether `mkdir -p' should
succeed in that case. If creation of file-name fails, exit the
script.
Also see the AC_PROG_MKDIR_P macro (see section Particular Program Checks).
Emit shell code to set the value of `$?' to status, as
efficiently as possible. However, this is not guaranteed to abort a
shell running with set -e (see Limitations of Shell Builtins). This should also be used at the end of a complex shell
function instead of `return' (see section Shell Functions) to avoid
a DJGPP shell bug.
Transform expression into a valid right-hand side for a C #define.
For example:
# This outputs "#define HAVE_CHAR_P 1". # Notice the m4 quoting around #, to prevent an m4 comment type="char *" echo "[#]define AS_TR_CPP([HAVE_$type]) 1" |
Transform expression into a valid shell variable name. For example:
# This outputs "Have it!". header="sys/some file.h" AS_TR_SH([HAVE_$header])=yes if test "x$HAVE_sys_some_file_h" = xyes; then echo "Have it!"; fi |
Set the shell variable var to dir/file, but optimizing the common cases (dir or file is `.', file is absolute, etc.).
Unsets the shell variable var, working around bugs in older shells (see Limitations of Shell Builtins). var can be a literal or indirect variable name.
Compare two strings version-1 and version-2, possibly containing shell variables, as version strings, and expand action-if-less, action-if-equal, or action-if-greater depending upon the result. The algorithm to compare is similar to the one used by strverscmp in glibc (see (libc)String/Array Comparison section `String/Array Comparison' in The GNU C Library).
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Often, it is convenient to write a macro that will emit shell code operating on a shell variable. The simplest case is when the variable name is known. But a more powerful idiom is writing shell code that can work through an indirection, where another variable or command substitution produces the name of the variable to actually manipulate. M4sh supports the notion of polymorphic shell variables, making it easy to write a macro that can deal with either literal or indirect variable names and output shell code appropriate for both use cases. Behavior is undefined if expansion of an indirect variable does not result in a literal variable name.
If the expansion of expression is definitely a shell literal,
expand if-literal. If the expansion of expression looks
like it might contain shell indirections (such as $var or
`expr`), then if-not is expanded. In order to reduce the
time spent deciding whether an expression is literal, the implementation
is somewhat conservative (for example, `'[$]'' is a single-quoted
shell literal, but causes if-not to be expanded). While this
macro is often used for recognizing shell variable names, it can also be
used in other contexts.
AC_DEFUN([MY_ACTION], [AS_LITERAL_IF([$1], [echo "$1"], [AS_VAR_COPY([tmp], [$1]) echo "$tmp"])]) |
Emit shell code to append the shell expansion of text to the end of the current contents of the polymorphic shell variable var, taking advantage of shells that provide the `+=' extension for more efficient scaling.
For situations where the final contents of var are relatively
short (less than 256 bytes), it is more efficient to use the simpler
code sequence of var=${var}text (or its
polymorphic equivalent of AS_VAR_COPY([tmp], [var]) and
AS_VAR_SET([var], ["$tmp"text])). But in the case
when the script will be repeatedly appending text into var,
issues of scaling start to become apparent. A naive implementation
requires execution time linear to the length of the current contents of
var as well as the length of text for a single append, for
an overall quadratic scaling with multiple appends. This macro takes
advantage of shells which provide the extension
var+=text, which can provide amortized constant time
for a single append, for an overall linear scaling with multiple
appends. Note that unlike AS_VAR_SET, this macro requires that
text be quoted properly to avoid field splitting and file name
expansion.
Emit shell code to compute the arithmetic expansion of expression,
assigning the result as the contents of the polymorphic shell variable
var. The code takes advantage of shells that provide `$(())'
for fewer forks, but uses expr as a fallback. Therefore, the
syntax for a valid expression is rather limited: all operators
must occur as separate shell arguments and with proper quoting, there is
no portable equality operator, all variables containing numeric values
must be expanded prior to the computation, all numeric values must be
provided in decimal without leading zeroes, and the first shell argument
should not be a negative number. In the following example, this snippet
will print `(2+3)*4 == 20'.
bar=3 AS_VAR_ARITH([foo], [\( 2 + $bar \) \* 4]) echo "(2+$bar)*4 == $foo" |
Emit shell code to assign the contents of the polymorphic shell variable source to the polymorphic shell variable dest. For example, executing this M4sh snippet will output `bar hi':
foo=bar bar=hi AS_VAR_COPY([a], [foo]) AS_VAR_COPY([b], [$foo]) echo "$a $b" |
When it is necessary to access the contents of an indirect variable inside a shell double-quoted context, the recommended idiom is to first copy the contents into a temporary literal shell variable.
for header in stdint_h inttypes_h ; do AS_VAR_COPY([var], [ac_cv_header_$header]) echo "$header detected: $var" done |
Output a shell conditional statement. If the contents of the polymorphic shell variable var match the string value, execute if-equal; otherwise execute if-not-equal. Avoids shell bugs if an interrupt signal arrives while a command substitution in var is being expanded.
A common M4sh idiom involves composing shell variable names from an m4
argument (for example, writing a macro that uses a cache variable).
value can be an arbitrary string, which will be transliterated
into a valid shell name by AS_TR_SH. In order to access the
composed variable name based on value, it is easier to declare a
temporary m4 macro m4-name with AS_VAR_PUSHDEF, then use
that macro as the argument to subsequent AS_VAR macros as a
polymorphic variable name, and finally free the temporary macro with
AS_VAR_POPDEF. These macros are often followed with dnl,
to avoid excess newlines in the output.
Here is an involved example, that shows the power of writing macros that can handle composed shell variable names:
m4_define([MY_CHECK_HEADER], [AS_VAR_PUSHDEF([my_Header], [ac_cv_header_$1])dnl AS_VAR_IF([my_Header], [yes], [echo "header $1 available"])dnl AS_VAR_POPDEF([my_Header])dnl ]) MY_CHECK_HEADER([stdint.h]) for header in inttypes.h stdlib.h ; do MY_CHECK_HEADER([$header]) done |
In the above example, MY_CHECK_HEADER can operate on polymorphic
variable names. In the first invocation, the m4 argument is
stdint.h, which transliterates into a literal stdint_h.
As a result, the temporary macro my_Header expands to the literal
shell name `ac_cv_header_stdint_h'. In the second invocation, the
m4 argument to MY_CHECK_HEADER is $header, and the
temporary macro my_Header expands to the indirect shell name
`$as_my_Header'. During the shell execution of the for loop, when
`$header' contains `inttypes.h', then `$as_my_Header'
contains `ac_cv_header_inttypes_h'. If this script is then run on a
platform where all three headers have been previously detected, the
output of the script will include:
header stdint.h detected header inttypes.h detected header stdlib.h detected |
Emit shell code to assign the contents of the polymorphic shell variable var to the shell expansion of value. value is not subject to field splitting or file name expansion, so if command substitution is used, it may be done with ``""`' rather than using an intermediate variable (see section Shell Substitutions). However, value does undergo rescanning for additional macro names; behavior is unspecified if late expansion results in any shell meta-characters.
Emit a shell conditional statement, which executes if-set if the
polymorphic shell variable var is set to any value, and
if-undef otherwise.
Emit a shell statement that results in a successful exit status only if
the polymorphic shell variable var is set.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Set up the shell to be more compatible with the Bourne shell as
standardized by Posix, if possible. This may involve setting
environment variables, or setting options, or similar
implementation-specific actions. This macro is deprecated, since
AS_INIT already invokes it.
Initialize the M4sh environment. This macro calls m4_init, then
outputs the #! /bin/sh line, a notice about where the output was
generated from, and code to sanitize the environment for the rest of the
script. Among other initializations, this sets SHELL to the shell
chosen to run the script (see CONFIG_SHELL), and LC_ALL to
ensure the C locale. Finally, it changes the current diversion to
BODY. AS_INIT is called automatically by AC_INIT
and AT_INIT, so shell code in `configure',
`config.status', and `testsuite' all benefit from a sanitized
shell environment.
Emit shell code to start the creation of a subsidiary shell script in
file, including changing file to be executable. This macro
populates the child script with information learned from the parent
(thus, the emitted code is equivalent in effect, but more efficient,
than the code output by AS_INIT, AS_BOURNE_COMPATIBLE, and
AS_SHELL_SANITIZE). If present, comment is output near the
beginning of the child, prior to the shell initialization code, and is
subject to parameter expansion, command substitution, and backslash
quote removal. The
parent script should check the exit status after this macro, in case
file could not be properly created (for example, if the disk was
full). If successfully created, the parent script can then proceed to
append additional M4sh constructs into the child script.
Note that the child script starts life without a log file open, so if
the parent script uses logging (see AS_MESSAGE_LOG_FD), you
must temporarily disable any attempts to use the log file until after
emitting code to open a log within the child. On the other hand, if the
parent script has AS_MESSAGE_FD redirected somewhere besides
`1', then the child script already has code that copies stdout to
that descriptor. Currently, the suggested
idiom for writing a M4sh shell script from within another script is:
AS_INIT_GENERATED([file], [[# My child script.
]]) || { AS_ECHO(["Failed to create child script"]); AS_EXIT; }
m4_pushdef([AS_MESSAGE_LOG_FD])dnl
cat >> "file" <<\__EOF__
# Code to initialize AS_MESSAGE_LOG_FD
m4_popdef([AS_MESSAGE_LOG_FD])dnl
# Additional code
__EOF__
|
This, however, may change in the future as the M4sh interface is stabilized further.
Also, be aware that use of LINENO within the child script may
report line numbers relative to their location in the parent script,
even when using AS_LINENO_PREPARE, if the parent script was
unable to locate a shell with working LINENO support.
Find a shell that supports the special variable LINENO, which
contains the number of the currently executing line. This macro is
automatically invoked by AC_INIT in configure scripts.
Set up variable as_me to be the basename of the currently executing
script. This macro is automatically invoked by AC_INIT in
configure scripts.
Initialize the shell suitably for configure scripts. This has
the effect of AS_BOURNE_COMPATIBLE, and sets some other
environment variables for predictable results from configuration tests.
For example, it sets LC_ALL to change to the default C locale.
See section Special Shell Variables. This macro is deprecated, since
AS_INIT already invokes it.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The following macros define file descriptors used to output messages (or input values) from `configure' scripts. For example:
echo "$wombats found" >&AS_MESSAGE_LOG_FD echo 'Enter desired kangaroo count:' >&AS_MESSAGE_FD read kangaroos <&AS_ORIGINAL_STDIN_FD` |
However doing so is seldom needed, because Autoconf provides higher level macros as described below.
The file descriptor for `checking for...' messages and results.
By default, AS_INIT sets this to `1' for standalone M4sh
clients. However, AC_INIT shuffles things around to another file
descriptor, in order to allow the `-q' option of
configure to choose whether messages should go to the script's
standard output or be discarded.
If you want to display some messages, consider using one of the printing macros (see section Printing Messages) instead. Copies of messages output via these macros are also recorded in `config.log'.
This must either be empty, or expand to a file descriptor for log
messages. By default, AS_INIT sets this macro to the empty
string for standalone M4sh clients, thus disabling logging. However,
AC_INIT shuffles things around so that both configure
and config.status use `config.log' for log messages.
Macros that run tools, like AC_COMPILE_IFELSE (see section Running the Compiler), redirect all output to this descriptor. You may want to do
so if you develop such a low-level macro.
This must expand to a file descriptor for the original standard input.
By default, AS_INIT sets this macro to `0' for standalone
M4sh clients. However, AC_INIT shuffles things around for
safety.
When configure runs, it may accidentally execute an
interactive command that has the same name as the non-interactive meant
to be used or checked. If the standard input was the terminal, such
interactive programs would cause configure to stop, pending
some user input. Therefore configure redirects its standard
input from `/dev/null' during its initialization. This is not
normally a problem, since configure normally does not need
user input.
In the extreme case where your `configure' script really needs to
obtain some values from the original standard input, you can read them
explicitly from AS_ORIGINAL_STDIN_FD.
| [ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated on January, 20 2010 using texi2html 1.76.