3

In m4, is it possible to expand a macro and to immediately put it in quotes? That is, instead of

define(HELLO, `Hello!')dnl
define(MACRO, `HELLO')dnl
MACRO

expanding to Hello!, I would love to have some function qexpand, for example, such that

define(HELLO, `Hello!')dnl
define(MACRO, `HELLO')dnl
qexpand(`MACRO')

expands to HELLO. But any other line after the first two that expands MACRO into a string would do as well, of course.


Background. I want to operate substitutions on the expansion of a macro using patsubst, say substituting commas in it. Unfortunately

define(`MACRO',`x,y,z')dnl
patsubst(`MACRO',`,',`.')

yields x,y,z, as the substitution is performed on the string MACRO. But if the expansion of the macro contains commas, the variant

define(`MACRO',`x,y,z')dnl
patsubst(MACRO,`,',`.')

has the second line first expand to patsubst(x,y,z,`,',`.'), giving the error Warning: excess arguments to builtin `patsubst' ignored. The possibility of expanding a macro into quotes would solve this.

1 Answer 1

4

defn() is your qexpand() function.

define(HELLO, `Hello!')dnl
define(MACRO, `HELLO')dnl
defn(`MACRO')

would output HELLO, and

define(`MACRO',`x,y,z')dnl
patsubst(defn(`MACRO'),`,',`.')

would output x.y.z.

defn() returns the quoted definition of each of its arguments. In the second example above, we use it to get the quoted string x,y,z (the quoted value of MACRO). This is then handed over to patsubst which will change the commas into dots.

The POSIX standard for m4 has this to say about this macro:

defn

The defining text of the defn macro shall be the quoted definition (using the current quoting strings) of its arguments. The behavior is unspecified if defn is not immediately followed by a <left-parenthesis>.

For BSD m4, the defn() macro is documented as

defn(name, ...)

Returns the quoted definition for each argument. This can be used to rename macro definitions (even for built-in macros).

GNU m4 has (in the m4 info documentation),

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.

If NAME is a user-defined macro, the quoted definition is simply the quoted expansion text. If, instead, there is only one NAME and it is a builtin, the expansion is a special token, which points to the builtin's internal definition. This token is only meaningful as the second argument to define (and pushdef), and is silently converted to an empty string in most other contexts. Combining a builtin with anything else is not supported; a warning is issued and the builtin is omitted from the final expansion.

The macro defn is recognized only with parameters.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .