Re: divert(-1) does not work in argument

Eric Blake <[email protected]>
Newsgroups gmane.comp.gnu.m4.bugs
Organization Red Hat, Inc.
Message-ID <[email protected]>
On 11/18/19 2:13 PM, Enshan Wang wrote:
> enswan@ws/bin$ m4 <<<'changequote()changequote([,])divert(-1)good[]divert[]show'
> show
> enswan@ws/bin$ m4 <<<'changequote()changequote([,])include(divert(-1)good[]divert[]show)'
> m4:stdin:1: cannot open `goodshow': No such file or directory
> 
> Maybe it's not a bug, but I think the 2nd m4 call should show that `show': No such file or directory.
> Looks include call still see the `good' which I want to divert to -1 i.e. it should be discarded.

Not a bug in m4, but in your expectations.  Let's follow exactly what 
happens as m4 expands things:

First version:
m4 <<<'changequote()changequote([,])divert(-1)good[]divert[]show'

m4 parses 'changequote(' and sees that it has to collect arguments; it 
then parses ')' and calls changequote with a single empty argument '' 
which expands to the empty string to the current output stream 0 (plus 
the side effect of resetting quote chars).  Next, m4 parses 
'changequote(', sees that it has to collect arguments, and collects the 
two arguments '[' and ']' before the closing ')', which again expands to 
the empty string '' to the current output stream 0 (as well as a side 
effect of new quote chars).  Next, m4 parses 'divert(', collects the 
single argument '-1', and expands the macro upon seeing ')'; this 
expands to the empty string but had the side effect of setting the 
current stream to -1 for discarding all expanded output.  Next m4 parses 
'good', sees that it is not a macro, and outputs it as-is (but output to 
stream -1 does nothing), parses '[]' as a string and outputs it with the 
quotes removed (but the empty string has nothing to output), then parses 
'divert' and sees that it is a macro, and invokes it with 0 arguments. 
This expands to empty text, but has the side effect of restoring the 
output stream back to 0.  Next m4 parses '[]' as another string that 
results in no output, then the text 'show' which is not a macro name and 
is output as-is.

Your other example:
m4 <<<'changequote()changequote([,])include(divert(-1)good[]divert[]show)'

starts the same for the two changequote macros.  Then m4 parses 
'include(' and sees that it has to perform argument collection. During 
that argument collection, it parses 'divert(' and sees that it has to 
start a nested macro invocation.  It then parses '-1' as the argument 
and ')' to expand the divert macro, which changes the output stream to 
-1; but we are still collecting arguments to 'include' rather than 
generating output to the output stream; so far, we collected an empty 
string '' from the expansion of divert.  Next, m4 parses 'good', sees 
that it is not a macro name, and appends it to the argument being 
collected.  Similarly for parsing '[]' which gets quotes stripped and 
appends '' to the argument being collected.  Then 'divert' which is a 
macro call with 0 arguments, restoring the output stream to 0 with NO 
output having been produced to any output stream in the meantime, 
appending another '' to the argument collection.  Then '[]' which 
appends another '', and finally 'show' which is appended as is.  Putting 
it all together, when m4 finally sees ')', it has collected a single 
argument 'goodshow', which m4 correctly tells you is not the name of an 
existing file to be included.


> 
> My version is 1.4.18. I did not try 1.6 version of m4. (BTW what's the status of m4 1.6? should I use m4 1.6 or 1.4...?)

m4 1.4.x is the latest stable version.  I need to post a refresh version 
(there have been FTBFS reports where the existing m4 release is 
incompatible with newer glibc headers), but that's not difficult. 
Getting 1.6 complete will require more time on my part, which I have not 
seemed to have lately.

> CONFIDENTIALITY AND PRIVACY NOTICE: This e-mail and any attachments are for the exclusive and confidential

Claims like this are unenforceable on publicly-archived mailing lists. 
You may wish to send future emails from other than your employer's 
servers that slams this garbage legalese on your outgoing mails.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3226
Virtualization:  qemu.org | libvirt.org
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.