Next: , Previous: Programming in M4sugar, Up: Programming in M4


8.4 Programming in M4sh

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”.]
  1. A mass of mixed ingredients reduced to a soft pulpy state by beating or pressure....
  2. A mixture of meal or bran and water fed to animals.
  3. A mess; trouble. [Obs.] –Beau. & Fl.

For the time being, it is not mature enough to be widely used.

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-doc 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.

M4sh provides portable alternatives for some common shell constructs that unfortunately are not portable in practice.

— Macro: AS_BOURNE_COMPATIBLE

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.

— Macro: AS_CASE (word, [pattern1], [if-matched1], ..., [default])

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.

— Macro: AS_DIRNAME (file-name)

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'.

— Macro: AS_IF (test1, [run-if-true1], ..., [run-if-false])

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-false1 is empty. For example,

          AS_IF([test "$foo" = yes], [HANDLE_FOO([yes])],
                [test "$foo" != no], [HANDLE_FOO([maybe])],
                [echo foo not specified])
     

ensures any required macros of HANDLE_FOO are expanded before the first test.

— Macro: AS_INIT

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. Finally, it changes the current diversion to BODY.

— Macro: AS_MKDIR_P (file-name)

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. 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 Particular Programs).

— Macro: AS_SHELL_SANITIZE

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 Special Shell Variables.

— Macro: AS_TR_CPP (expression)

Transform expression into a valid right-hand side for a C #define. For example:

          # This outputs "#define HAVE_CHAR_P 1".
          type="char *"
          echo "#define AS_TR_CPP([HAVE_$type]) 1"
     
— Macro: AS_TR_SH (expression)

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 "$HAVE_sys_some_file_h" = yes; then echo "Have it!"; fi
     
— Macro: AS_SET_CATFILE (var, dir, file)

Set the shell variable var to dir/file, but optimizing the common cases (dir or file is `.', file is absolute, etc.).