GNU macro processor - 15. Compatibility with other versions of m4

Go to the first, previous, next, last section, table of contents.

# 15. Compatibility with other versions of `m4`

This chapter describes the differences between this implementation of `m4`, and the implementation found under UNIX, notably System V, Release 3.

There are also differences in BSD flavors of `m4`. No attempt is made to summarize these here.

## 15.1 Extensions in GNU `m4`

This version of `m4` contains a few facilities, that do not exist in System V `m4`. These extra facilities are all suppressed by using the ``-G'` command line option, unless overridden by other command line options.

- In the `$`n notation for macro arguments, n can contain several digits, while the System V `m4` only accepts one digit. This allows macros in GNU `m4` to take any number of arguments, and not only nine (see section 4.2 Arguments to macros).
- Files included with `include` and `sinclude` are sought in a user specified search path, if they are not found in the working directory. The search path is specified by the ``-I'` option and the ``M4PATH'` environment variable (see section 8.2 Searching for include files).
- Arguments to `undivert` can be non-numeric, in which case the named file will be included uninterpreted in the output (see section 9.2 Undiverting output).
- Formatted output is supported through the `format` builtin, which is modeled after the C library function `printf` (see section 10.7 Formatted output).
- Searches and text substitution through regular expressions are supported by the `regexp` (see section 10.3 Searching for regular expressions) and `patsubst` (see section 10.6 Substituting text by regular expression) builtins.
- The output of shell commands can be read into `m4` with `esyscmd` (see section 12.2 Reading the output of commands).
- There is indirect access to any builtin macro with `builtin` (see section 4.8 Indirect call of builtins).
- Macros can be called indirectly through `indir` (see section 4.7 Indirect call of macros).
- The name of the current input file and the current input line number are accessible through the builtins `__file__` and `__line__` (see section 13.1 Printing error messages).
- The format of the output from `dumpdef` and macro tracing can be controlled with `debugmode` (see section 6.3 Controlling debugging output).
- The destination of trace and debug output can be controlled with `debugfile` (see section 6.4 Saving debugging output).

In addition to the above extensions, GNU `m4` implements the following command line options: ``-F'`, ``-G'`, ``-I'`, ``-L'`, ``-R'`, ``-V'`, ``-W'`, ``-d'`, ``-l'`, ``-o'` and ``-t'`. See section 1.3 Invoking `m4`, for a description of these options.

Also, the debugging and tracing facilities in GNU `m4` are much more extensive than in most other versions of `m4`.

## 15.2 Facilities in System V `m4` not in GNU `m4`

The version of `m4` from System V contains a few facilities that have not been implemented in GNU `m4` yet.

- System V `m4` supports multiple arguments to `defn`. This is not implemented in GNU `m4`. Its usefulness is unclear to me.

## 15.3 Other incompatibilities

There are a few other incompatibilities between this implementation of `m4`, and the System V version.

- GNU `m4` implements sync lines differently from System V `m4`, when text is being diverted. GNU `m4` outputs the sync lines when the text is being diverted, and System V `m4` when the diverted text is being brought back. The problem is which lines and filenames should be attached to text that is being, or has been, diverted. System V `m4` regards all the diverted text as being generated by the source line containing the `undivert` call, whereas GNU `m4` regards the diverted text as being generated at the time it is diverted. I expect the sync line option to be used mostly when using `m4` as a front end to a compiler. If a diverted line causes a compiler error, the error messages should most probably refer to the place where the diversion were made, and not where it was inserted again.
- GNU `m4` makes no attempt at prohiting autoreferential definitions like:

      define(`x', `x')
      define(`x', `x ')

  There is nothing inherently wrong with defining ``x'` to return ``x'`. The wrong thing is to expand ``x'` unquoted. In `m4`, one might use macros to hold strings, as we do for variables in other programming languages, further checking them with:

      ifelse(defn(`holder'), `value', ...)

  In cases like this one, an interdiction for a macro to hold its own name would be a useless limitation. Of course, this leave more rope for the GNU `m4` user to hang himself! Rescanning hangs may be avoided through careful programming, a little like for endless loops in traditional programming languages.
- GNU `m4` without ``-G'` option will define the macro `__gnu__` to expand to the empty string. On UNIX systems, GNU `m4` without the ``-G'` option will define the macro `__unix__`, otherwise the macro `unix`. Both will expand to the empty string.

Go to the first, previous, next, last section, table of contents.