Re: defn() with multiple arguments
Eric Blake <ebb9 <at> byu.net>
2007-08-09 04:31:39 GMT
According to Schwarz, Konrad on 8/6/2007 1:54 AM:
> However, I think the following example motivates this feature, should
> you in fact have need of motivation.
Actually, on further thought, you brought up a valid use for this
POSIX-mandated feature. When I became the M4 maintainer, the M4 1.4.4
manual said this:
System V m4 supports multiple arguments to `defn'. This is
not implemented in GNU m4. Its usefulness is unclear to me.
I deleted the sentence (first person disclaimers in a manual is rather
tacky) but did nothing about the lack of implementation.
But since POSIX requires it, and since it can, indeed, be used to
concatenate macros that would otherwise contain unbalanced quotes if
expanded in isolation, I think it is worth adding to M4 1.4.11. Patch to
follow soon. However, for the 1.4.x series, I will simply bail out if you
try to use defn to concatenate a builtin with a text, as the GNU m4
plumbing isn't currently built to handle that (I still hope to get it in
for m4 2.0, but that's another story).
> In other words, that defn() be implemented to concatenate its arguments
> first, then to quote the resulting string as a whole.
Sorry, but for compatibility with other implementations, it can't quite
work like that. Each macro definition is quoted, then those quoted
strings are concatenated. However, because the entire concatenation
option happens before any reparsing is done, you can get away with it as
long as you finally balance things back again. Whereas, as you noted,
using defn on a single macro with unbalanced quotes causes problems the
moment it is reparsed, prior to any subsequent text it would be
Here's a test case I tried on Solaris' m4, as well as CVS head, to make
sure the handling of the concatenated quotes is done correctly:
Note how for q1, defn([l]) expands to [<a[a>], which is then rescanned as
an unterminated string containing a nested [a>]; then the text defn([r]))
is read in as part of the string, and I had to add another ]) to close out
the string. But for q2, defn([l],[r]) expands to [<a[a>][<a]a>], with an
embedded end-of-string start-of-string; which, after rescanning, leaves
unquoted <a, the string [a>], the string [<a], and another unquoted a> as
the desired definition for q2.
Don't work too hard, make some time for fun as well!
Eric Blake ebb9 <at> byu.net