Re: error on using $# and m4wrap

Eric Blake <[email protected]>
Newsgroups gmane.comp.gnu.m4.bugs
Organization Red Hat, Inc.
Message-ID <[email protected]>
On 7/26/20 9:12 AM, Hyunho Cho wrote:
> m4 (GNU M4) 1.4.18
> Operating System: Ubuntu 20.04 LTS
> Kernel: Linux 5.4.0-33-generic
> Architecture: x86-64
> 
> ### 1. if i define $# as macro body then error occurred
> 
> $ m4 <<\@
> define(`foo', $2)
> foo(100,200,300)
> @
> 
> 200                          # OK
> ---------------------
> 
> $ m4 <<\@
> define(`foo', $#)
> foo(100,200,300)
> @
> m4:stdin:1: ERROR: end of file in argument list

That is expected behavior.  Any unquoted # starts a comment, and the 
comment doesn't end until newline.  The ) you placed in the comment is 
therefore not recognized as the end of the define macro call, hence m4 
errors out that you ended input in the middle of a macro call.

> -----------------------
> 
> $ m4 <<\@
> define(`foo', `$#')         # must quote `$#'
> foo(100,200,300)
> @
> 
> 3                            # OK

And yes, this is the correct solution to that issue.

> 
> ###################################################
> 
> ### 2. if i invocate m4wrap just once then return macro body
> 
> $ m4 <<\@
> define(`foo', 11111)dnl
> define(`bar', 22222)dnl
> define(`zoo', 33333)dnl
> m4wrap(`zoo')dnl
> 99999
> @
> 99999
> 33333      <---- not zoo but 33333

This is correct behavior.  When reaching end of input, all wrapped code 
is concatenated and expanded, and all you have collected is 'zoo' which 
is a macro name, so it is expanded.

> 
> $ m4 <<\@
> define(`foo', 11111)dnl
> define(`bar', 22222)dnl
> define(`zoo', 33333)dnl
> m4wrap(`foo')dnl
> m4wrap(`bar')dnl
> m4wrap(`zoo')dnl
> 99999
> @
> 99999
> zoobarfoo

This is also correct behavior.  The concatenated text is zoobarfoo, 
which is not a macro name, and therefore output as-is.  If you want to 
guarantee that each m4wrap is viewed as code in isolation, the easiest 
way is to insert empty quotes at the conclusion of each text you wrap:

$ m4 <<\@
define(`foo', 11111)dnl
define(`bar', 22222)dnl
define(`zoo', 33333)dnl
m4wrap(`foo`'')dnl
m4wrap(`bar`'')dnl
m4wrap(`zoo`'')dnl
99999
@
99999
333332222211111

because the resulting concatenated wrapped text is now zoo`'bar`'foo`', 
which indeed has three recognized macros.

I don't see any bug in the behavior you have reported.

-- 
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.