GNU M4 Notes

Source: http://www.gnu.org/software/m4/manual/m4.html

GNU M4 1.4.16 macro processor

2 Invoking m4

The format of the m4 command is:

     m4 [option...] [file...]

All options begin with ‘’, or if long option names are used, with ‘’.

The argumentis a marker to denote the end of options.

In other words, m4 -QPDfoo -d a -df is equivalent to m4 -Q -P -D foo -d -df -- ./a, although the latter form is considered canonical.

2.1 Command line options for operation modes

-E
--fatal-warnings
Controls the effect of warnings. If unspecified, then execution continues and exit status is unaffected when a warning is printed.
-i
--interactive
-e
Makes this invocation of m4 interactive. This means that all output will be unbuffered, and interrupts will be ignored.
-P
--prefix-builtins
Internally modify allbuiltin macro names so they all start with the prefix ‘m4_’.
-Q
--quiet
--silent
Suppress warnings, such as missing or superfluous arguments in macro calls, or treating the empty string as zero.
--warn-macro-sequence[=regexp]
Issue a warning if the regular expression regexp has a non-empty match in any macro definition (either by define or pushdef). Empty matches are ignored; therefore, supplying the empty string as regexp disables any warning. If the optional regexpis not supplied, then the default regular expression is ‘\$\({[^}]*}\|[0-9][0-9]+\)’ (a literal ‘$’ followed by multiple digits or by an open brace),
-W regexp
--word-regexp=regexp
Use regexp as an alternative syntax for macro names.

2.2 Command line options for preprocessor features

-D name[=value]
--define=name[=value]
This enters nameinto the symbol table. If ‘=value’ is missing, the value is taken to be the empty string.
-I directory
--include=directory
Make m4 search directory for included files that are not found in the current working directory.
-s
--synclines
Generate synchronization lines, for use by the C preprocessor or other similar tools.
-U name
--undefine=name
This deletes any predefined meaning name might have.

2.3 Command line options for limits control

-g
--gnu
Enable all the extensions in this implementation. I
-G
--traditional
Suppress all the extensions made in this implementation, compared to the System V version.
-H num
--hashsize=num
Make the internal hash table for symbol lookup be num entries big.
-L num
--nesting-limit=num
Artificially limit the nesting of macro calls to num levels, stopping program execution if this limit is ever exceeded.
-B num
-S num
-T num
These options are present for compatibility with System V m4, but do nothing in this implementation.
-N num
--diversions=num
These options are present only for compatibility with previous versions of GNU m4, and were controlling the number of possible diversions which could be used at the same time.

2.4 Command line options for frozen state

-F file
--freeze-state=file
Once execution is finished, write out the frozen state on the specified file.
-R file
--reload-state=file
Before execution starts, recover the internal state from the specified frozen file.

2.5 Command line options for debugging

-d[flags]
--debug[=flags]
Set the debug-level according to the flags flags.
--debugfile[=file]
-o file
--error-output=file
Redirect dumpdef output, debug messages, and trace output to the named file.
-l num
--arglength=num
Restrict the size of the output generated by macro tracing to num characters per trace line.
-t name
--trace=name
This enables tracing for the macro name, at any point where it is defined.

3.3 Comments in m4 input

Comments in m4are normally delimited by the characters ‘#’ and newline.

The commenting effect of the begin-comment string can be inhibited by quoting it.
     `quoting inhibits' `#' `comments'quoting inhibits # comments

4.1 Macro invocation

For a macro call to have no arguments, the parentheses must be left out. The macro call

     name()

is a macro call with one argument, which is the empty string, not a call with no arguments.

4.2 Preventing macro invocation

The output of macro evaluations is always rescanned. In the following example, the input ‘x`’y’ yields the string ‘bCD’, exactly as if m4has been given ‘substr(ab`’cde, `1′, `3′)’ as input:

     define(`cde', `CDE')define(`x', `substr(ab')define(`y', `cde, `1', `3')')x`'ybCD

Unquoted strings on either side of a quoted string are subject to being recognized as macro names. In the following example, quoting the empty string allows for the second macro to be recognized as such:

     define(`macro', `m')macro(`m')macrommacro
     macro(`m')`'macromm

Quoting may prevent recognizing as a macro name the concatenation of a macro expansion with the surrounding characters. In this example:

     define(`macro', `di$1')macro(`v')`ert'divert
     macro(`v')ert

the input will produce the string ‘divert’. When the quotes were removed, the divert builtin was called instead.

4.4 On Quoting Arguments to macros

The quoting rule of thumb of one level of quoting per parentheses has a nice property: when a macro name appears inside parentheses, you can determine when it will be expanded. If it is not quoted, it will be expanded prior to the outer macro, so that its expansion becomes the argument. If it is single-quoted, it will be expanded after the outer macro. And if it is double-quoted, it will be used as literal text instead of a macro name.

     define(`active', `ACT, IVE')define(`show', `$1 $1')show(active)ACT ACT
     show(`active')ACT, IVE ACT, IVE
     show(``active'')active active

4.5 Macro expansion

Taking a very simple example, if fooexpands to ‘bar’, and barexpands to ‘Hello’, the input

     $ m4 -Dbar=Hello -Dfoo=bar
     fooHello

will expand first to ‘bar’, and when this is reread and expanded, into ‘Hello’.

5.1 Defining a macro

The normal way to define or redefine macros is to use the builtin define:

Builtin: define (name, [expansion])

Defines name to expand to expansion. If expansion is not given, it is taken to be empty.

The expansion of define is void. The macro define is recognized only with parameters.

The first argument to define should be quoted; otherwise, if the macro is already defined, you will be defining a different macro. This example shows the problems with underquoting, since we did not want to redefine one:

     define(foo, one)define(foo, two)onetwo

Arrays and associative arrays can be simulated by using non-standard macro names.

Composite: array (index)
— Composite: array_set (index, [value])

Provide access to entries within an array. array reads the entry at location index, and array_set assigns value to location index.

     define(`array', `defn(format(``array[%d]'', `$1'))')define(`array_set', `define(format(``array[%d]'', `$1'), `$2')')array_set(`4', `array element no. 4')array_set(`17', `array element no. 17')array(`4')array element no. 4
     array(eval(`10 + 7'))array element no. 17

Change the ‘%d’ to ‘%s’ and it is an associative array.

5.2 Arguments to macros

Macros can have arguments. The nth argument is denoted by $n in the expansion text, and is replaced by the nth actual argument, when the macro is expanded.

As a special case, the zeroth argument, $0, is always the name of the macro being expanded.

     define(`test', ``Macro name: $0'')testMacro name: test

5.3 Special arguments to macros

The number of actual arguments in a macro call is denoted by $# in the expansion text.

Composite: nargs ()

Expands to a count of the number of arguments supplied.

     define(`nargs', `$#')nargs0
     nargs()1
     nargs(`arg1', `arg2', `arg3')3
     nargs(`commas can be quoted, like this')1
     nargs(arg1#inside comments, commas do not separate arguments
     still arg1)1
     nargs((unquoted parentheses, like this, group arguments))1

Remember that ‘#’ defaults to the comment character; if you forget quotes to inhibit the comment behavior, your macro definition may not end where you expected.

     dnl Attempt to define a macro to just `$#'
     define(underquoted, $#)
     oops)underquoted0)oops

The notation $* can be used in the expansion text to denote all the actual arguments, unquoted, with commas in between. For example

     define(`echo', `$*')echo(arg1, arg2, arg3 , arg4)arg1,arg2,arg3 ,arg4

Often each argument should be quoted, and the notation $@ handles that. It is just like $*, except that it quotes each argument. A simple example of that is:

     define(`echo', `$@')echo(arg1, arg2, arg3 , arg4)arg1,arg2,arg3 ,arg4

Where did the quotes go? Of course, they were eaten, when the expanded text were reread by m4. To show the difference, try

     define(`echo1', `$*')define(`echo2', `$@')define(`foo', `This is macro `foo'.')echo1(foo)This is macro This is macro foo..
     echo1(`foo')This is macro foo.
     echo2(foo)This is macro foo.
     echo2(`foo')foo

5.4 Deleting a macro

A macro definition can be removed with undefine:

Builtin: undefine (name)

For each argument, remove the macro name. The macro names must necessarily be quoted, since they will be expanded otherwise.

5.5 Renaming macros

It is possible to rename an already defined macro. To do this, you need the builtin defn:

Builtin: defn (name)

Expands to the quoted definition of each name. If an argument is not a defined macro, the expansion for that argument is empty.

The macro defn is recognized only with parameters.

Its normal use is best understood through an example, which shows how to rename undefine to zap:

     define(`zap', defn(`undefine'))zap(`undefine')undefine(`zap')undefine(zap)

Thus it is a good idea to avoid unbalanced end-quotes in macro definitions or arguments to macros.

     define(`foo', a'a)define(`a', `A')define(`echo', `$@')fooA'A
     defn(`foo')aA'
     echo(foo)AA'

This is particularly useful when one has used several macros to accumulate text that M4 should rescan as a whole. In the example below, note how the use of defn on l in isolation opens a string, which is not closed until the next line; but used on l and r together results in nested quoting.

     define(`l', `<[>')define(`r', `<]>')changequote(`[', `]')defn([l])defn([r])
     ])<[>]defn([r]))
     defn([l], [r])<[>][<]>

5.6 Temporarily redefining macros

It is possible to redefine a macro temporarily, reverting to the previous definition at a later time. This is done with the builtins pushdef and popdef:

Builtin: pushdef (name, [expansion])
— Builtin: popdef (name)

5.7 Indirect call of macros

Any macro can be called indirectly with indir:

Builtin: indir (name, [args])

Results in a call to the macro name, which is passed the rest of the arguments args. If name is not defined, an error message is printed, and the expansion is void.

This can be used to call macros with computed or “invalid” names (define allows such names to be defined):

     define(`$$internal$macro', `Internal macro (name `$0')')$$internal$macro$$internal$macro
     indir(`$$internal$macro')Internal macro (name $$internal$macro)

5.8 Indirect call of builtins

Builtin macros can be called indirectly with builtin:

Builtin: builtin (name, [args])

Results in a call to the builtin name, which is passed the rest of the arguments args. If name does not name a builtin, an error message is printed, and the expansion is void.

6.1 Testing if a macro is defined

There are two different builtin conditionals in m4. The first is ifdef:

Builtin: ifdef (name, string-1, [string-2])

If name is defined as a macro, ifdef expands to string-1, otherwise to string-2. If string-2 is omitted, it is taken to be the empty string (according to the normal rules).

6.2 If-else construct, or multibranch

The other conditional, ifelse, is much more powerful. It can be used as a way to introduce a long comment, as an if-else construct, or as a multibranch, depending on the number of arguments supplied:

Builtin: ifelse (comment)
— Builtin: ifelse (string-1, string-2, equal, [not-equal])
— Builtin: ifelse (string-1, string-2, equal-1, string-3, string-4, equal-2, , [not-equal])

Used with only one argument, the ifelse simply discards it and produces no output.

If called with three or four arguments, ifelse expands into equal, if string-1 and string-2 are equal (character for character), otherwise it expands to not-equal. A final fifth argument is ignored, after triggering a warning.

If called with six or more arguments, and string-1 and string-2 are equal, ifelse expands into equal-1, otherwise the first three arguments are discarded and the processing starts again.

6.3 Recursion in m4

There is no direct support for loops in m4, but macros can be recursive. There is no limit on the number of recursion levels, other than those enforced by your hardware and operating system.

There is a builtin macro, shift, which can, among other things, be used for iterating through the actual arguments to a macro:

Builtin: shift (arg1, )

     shiftshift
     shift(`bar')shift(`foo', `bar', `baz')bar,baz

Composite: reverse ()

Takes any number of arguments, and reverses their order.

It is implemented as:

     define(`reverse', `ifelse(`$#', `0', , `$#', `1', ``$1'',
                               `reverse(shift($@)), `$1'')')

Composite: cond (test-1, string-1, equal-1, [test-2], [string-2], [equal-2], , [not-equal])

Composite: join ([separator], [args])
— Composite: joinall ([separator], [args])

Generate a single-quoted string, consisting of each arg separated by separator. While joinall always outputs a separator between arguments, join avoids the separator for an empty arg

Composite: quote ()
— Composite: dquote ()
— Composite: dquote_elt ()

Takes any number of arguments, and adds quoting. With quote, only one level of quoting is added, effectively removing whitespace after commas and turning multiple arguments into a single string. With dquote, two levels of quoting are added, one around each element, and one around the list. And with dquote_elt, two levels of quoting are added around each element.

Composite: argn (n, )

Expands to argument n out of the remaining arguments. nmust be a positive number. Usually invoked as ‘argn(`n‘,$@)’.

6.4 Iteration by counting

Composite: forloop (iterator, start, end, text)

Takes the name in iterator, which must be a valid macro name, and successively assign it each integer value from start to end, inclusive. For each assignment to iterator, append text to the expansion of the forloop. text may refer to iterator. Any definition of iterator prior to this invocation is restored.

It can, for example, be used for simple counting:

     $ m4 -I examples
     include(`forloop.m4')forloop(`i', `1', `8', `i ')1 2 3 4 5 6 7 8 

For-loops can be nested, like:

     $ m4 -I examples
     include(`forloop.m4')forloop(`i', `1', `4', `forloop(`j', `1', `8', ` (i, j)')
     ')(1, 1) (1, 2) (1, 3) (1, 4) (1, 5) (1, 6) (1, 7) (1, 8)(2, 1) (2, 2) (2, 3) (2, 4) (2, 5) (2, 6) (2, 7) (2, 8)(3, 1) (3, 2) (3, 3) (3, 4) (3, 5) (3, 6) (3, 7) (3, 8)(4, 1) (4, 2) (4, 3) (4, 4) (4, 5) (4, 6) (4, 7) (4, 8)

6.5 Iteration by list contents

Here is an example of a loop macro that implements list iteration.

Composite: foreach (iterator, paren-list, text)
— Composite: foreachq (iterator, quote-list, text)

Takes the name in iterator, which must be a valid macro name, and successively assign it each value from paren-list or quote-list. In foreach, paren-list is a comma-separated list of elements contained in parentheses. In foreachq, quote-list is a comma-separated list of elements contained in a quoted string. For each assignment to iterator, append text to the overall expansion. text may refer to iterator. Any definition of iterator prior to this invocation is restored.

As an example, this displays each word in a list inside of a sentence, using an implementation of foreachdistributed asm4-1.4.16/examples/foreach.m4, and foreachqinm4-1.4.16/examples/foreachq.m4.

     $ m4 -I examples
     include(`foreach.m4')foreach(`x', (foo, bar, foobar), `Word was: x
     ')dnlWord was: fooWord was: barWord was: foobar
     include(`foreachq.m4')foreachq(`x', `foo, bar, foobar', `Word was: x
     ')dnlWord was: fooWord was: barWord was: foobar

6.6 Working with definition stacks

Thanks to pushdef, manipulation of a stack is an intrinsic operation in m4. Normally, only the topmost definition in a stack is important, but sometimes, it is desirable to manipulate the entire definition stack.

Composite: stack_foreach (macro, action)
— Composite: stack_foreach_lifo (macro, action)

6.7 Building macros with macros

Since m4 is a macro language, it is possible to write macros that can build other macros. First on the list is a way to automate the creation of blind macros.

Composite: define_blind (name, [value])

Defines name as a blind macro, such that name will expand to value only when given explicit arguments. value should not be the result of defn (see Defn). This macro is only recognized with parameters, and results in an empty string.

Composite: curry (macro, )

Expand to a macro call that takes exactly one argument, then appends that argument to the original arguments and invokes macro with the resulting list of arguments.

Composite: copy (source, dest)
— Composite: rename (source, dest)

Ensure that dest is undefined, then define it to the same stack of definitions currently in source. copy leaves source unchanged, while rename undefines source. There are only a few macros, such as copy or defn, which cannot be copied via this macro.

7.1 Displaying macro definitions

If you want to see what a name expands into, you can use the builtin dumpdef:

Builtin: dumpdef ([names])

Accepts any number of arguments. If called without any arguments, it displays the definitions of all known names, otherwise it displays the definitions of the names given. The output is printed to the current debug file (usually standard error), and is sorted by name. If an unknown name is encountered, a warning is printed.

7.2 Tracing macro calls

It is possible to trace macro calls and expansions through the builtins traceon and traceoff:

Builtin: traceon ([names])
— Builtin: traceoff ([names])

When called without any arguments, traceon and traceoff will turn tracing on and off, respectively, for all currently defined macros.

When called with arguments, only the macros listed in names are affected, whether or not they are currently defined.

7.4 Saving debugging output

Debug and tracing output can be redirected to files using either the–debugfileoption to m4 (see Invoking m4), or with the builtin macro debugfile:

Builtin: debugfile ([file])

Sends all further debug and trace output to file, opened in append mode. If file is the empty string, debug and trace output are discarded. If debugfile is called without any arguments, debug and trace output are sent to standard error. This does not affect warnings, error messages, or errprint output, which are always sent to standard error. If file cannot be opened, the current debug file is unchanged, and an error is issued.

8.1 Deleting whitespace in input

The builtin dnl stands for “Discard to Next Line”:

Builtin: dnl

All characters, up to and including the next newline, are discarded without performing any macro expansion. A warning is issued if the end of the file is encountered without a newline.

The expansion of dnl is void.

8.2 Changing the quote characters

The default quote delimiters can be changed with the builtin changequote:

Builtin: changequote ([start = ‘`], [end = ‘])

This sets start as the new begin-quote delimiter and end as the new end-quote delimiter. If both arguments are missing, the default quotes (` and ') are used. If start is void, then quoting is disabled. Otherwise, if end is missing or void, the default end-quote delimiter (') is used. The quote delimiters can be of any length.

The expansion of changequote is void.

     changequote(`[', `]')define([foo], [Macro [foo].])fooMacro foo.

8.3 Changing the comment delimiters

The default comment delimiters can be changed with the builtin macro changecom:

Builtin: changecom ([start], [end = ‘<NL>])

This sets start as the new begin-comment delimiter and end as the new end-comment delimiter. If both arguments are missing, or start is void, then comments are disabled. Otherwise, if end is missing or void, the default end-comment delimiter of newline is used. The comment delimiters can be of any length.

9.1 Including named files

There are two builtin macros in m4 for including files:

Builtin: include (file)
— Builtin: sinclude (file)

Both macros cause the file named file to be read by m4. When the end of the file is reached, input is resumed from the previous input file.

The expansion of include and sinclude is therefore the contents of file.

If file does not exist, is a directory, or cannot otherwise be read, the expansion is void, and include will fail with an error while sinclude is silent. The empty string counts as a file that does not exist

11.1 Calculating length of strings

The length of a string can be calculated by len:

Builtin: len (string)

Expands to the length of string, as a decimal number.

The macro len is recognized only with parameters.

     len()0
     len(`abcdef')6

11.2 Searching for substrings

Searching for substrings is done with index:

Builtin: index (string, substring)

Expands to the index of the first occurrence of substring in string. The first character in string has index 0. If substring does not occur in string, indexexpands to ‘-1’.

The macro index is recognized only with parameters.

     index(`gnus, gnats, and armadillos', `nat')7
     index(`gnus, gnats, and armadillos', `dag')-1

11.3 Searching for regular expressions

Searching for regular expressions is done with the builtin regexp:

Builtin: regexp (string, regexp, [replacement])

Searches for regexp in string. The syntax for regular expressions is the same as in GNU Emacs, which is similar to BRE, Basic Regular Expressions in POSIX.

11.4 Extracting substrings

Substrings are extracted with substr:

Builtin: substr (string, from, [length])

Expands to the substring of string, which starts at index from, and extends for length characters, or to the end of string, if length is omitted. The starting index of a string is always 0. The expansion is empty if there is an error parsing from or length, if from is beyond the end of string, or if length is negative.

The macro substr is recognized only with parameters.

     substr(`gnus, gnats, and armadillos', `6')gnats, and armadillos
     substr(`gnus, gnats, and armadillos', `6', `5')gnats

11.5 Translating characters

Character translation is done with translit:

Builtin: translit (string, chars, [replacement])

Expands to string, with each character that occurs in chars translated into the character from replacement with the same index.

11.6 Substituting text by regular expression

Global substitution in a string is done by patsubst:

Builtin: patsubst (string, regexp, [replacement])

Searches string for matches of regexp, and substitutes replacement for each match.

Composite: upcase (text)
— Composite: downcase (text)
— Composite: capitalize (text)

Expand to text, but with capitalization changed: upcase changes all letters to upper case, downcase changes all letters to lower case, and capitalize changes the first character of each word to upper case and the remaining characters to lower case.

11.7 Formatting strings (printf-like)

Formatted output can be made with format:

Builtin: format (format-string, )

Works much like the C function printf. The first argument format-stringcan contain ‘%’ specifications which are satisfied by additional arguments, and the expansion of format is the formatted string.

12.1 Decrement and increment operators

Increment and decrement of integers are supported using the builtins incr and decr:

Builtin: incr (number)
— Builtin: decr (number)

Expand to the numerical value of number, incremented or decremented, respectively, by one. Except for the empty string, the expansion is empty if number could not be parsed.

12.2 Evaluating integer expressions

Integer expressions are evaluated with eval:

Builtin: eval (expression, [radix = ‘10], [width])

Expands to the value of expression. The expansion is empty if a problem is encountered while parsing the arguments. If specified, radix and width control the format of the output.

Calculations are done with 32-bit signed numbers. Overflow silently results in wraparound. A warning is issued if division by zero is attempted, or if expression could not be parsed.

13.2 Executing simple commands

Any shell command can be executed, using syscmd:

Builtin: syscmd (shell-command)

Executes shell-command as a shell command.

13.3 Reading the output of commands

If you want m4 to read the output of a shell command, use esyscmd:

Builtin: esyscmd (shell-command)

Expands to the standard output of the shell command shell-command.

13.4 Exit status

To see whether a shell command succeeded, use sysval:

Builtin: sysval

Expands to the exit status of the last shell command run with syscmd or esyscmd. Expands to 0 if no command has been run yet.

13.5 Making temporary files

Commands specified to syscmd or esyscmd might need a temporary file, for output or for some other purpose. There is a builtin macro, mkstemp, for making a temporary file:

Builtin: mkstemp (template)
— Builtin: maketemp (template)

Expands to the quoted name of a new, empty file, made from the string template, which should end with the string ‘XXXXXX’. The six ‘X’ characters are then replaced with random characters matching the regular expression ‘[a-zA-Z0-9._-]’, in order to make the file name unique. If fewer than six ‘X’ characters are found at the end of template, the result will be longer than the template. The created file will have access permissions as if by chmod =rw,go=, meaning that the current umask of the m4 process is taken into account, and at most only the current user can read and write the file.

14.1 Printing error messages

You can print error messages using errprint:

Builtin: errprint (message, )

Prints messageand the rest of the arguments to standard error, separated by spaces. Standard error is used, regardless of the–debugfileoption (see Invoking m4).

14.2 Printing current location

To make it possible to specify the location of an error, three utility builtins exist:

Builtin: __file__
— Builtin: __line__
— Builtin: __program__

Expand to the quoted name of the current input file, the current input line number in that file, and the quoted name of the current invocation of m4.

     errprint(__program__:__file__:__line__: `input error
     ')
     error-->m4:stdin:1: input error

14.3 Exiting from m4

If you need to exit from m4 before the entire input has been read, you can use m4exit:

Builtin: m4exit ([code = ‘0])

Causes m4 to exit, with exit status code.

A common use of this is to abort processing:

Composite: fatal_error (message)

Abort processing with an error message and non-zero status.

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*