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

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

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

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


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


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


defn() is your qexpand() function.

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

would output HELLO, and


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:


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 .