Re: more m4p bugs
Eric Blake <[email protected]> Mon, 19 May 2025 13:35:53 -0500
| Newsgroups | gmane.comp.gnu.m4.general |
|---|---|
| Message-ID | <l4ddnri4y3h2kgay5jfghtgd3jvy4qh4h4tbp6blqv6r55dx2a@pxsj7pabgqrp> |
On Mon, May 19, 2025 at 02:05:28PM -0400, Nikolaos Chatzikonstantinou wrote: > On Mon, May 19, 2025, 1:27 PM Eric Blake <[email protected]> wrote: > > > On Mon, May 19, 2025 at 10:46:10AM -0500, Eric Blake wrote: > > > On Fri, May 16, 2025 at 08:16:24AM -0500, Eric Blake wrote: > > > > Since you continue to patch things as fast as I report them (now > > > > testing with commit a4cc0f3c): > > > > > > Now testing with b686ed, you have a problem with redefining a macro as > > > empty if it has been undefined in the meantime: > > > > > > $ echo 'changequote([,])define(a)undefine([a])define(a)' | m4p > > > Traceback (most recent call last): > > > File "/home/eblake/m4p/.venv/bin/m4p", line 8, in <module> > > > sys.exit(main()) > > > ~~~~^^ > > > ... > > > File "/home/eblake/m4p/m4p/parser.py", line 279, in add_define > > > self.macros[ident][-1] = defn > > > ~~~~~~~~~~~~~~~~~~^^^^ > > > IndexError: list assignment index out of range > > > > This appears to fix it for me: > > > > diff --git i/m4p/parser.py w/m4p/parser.py > > index 4793c8a..83c69df 100644 > > --- i/m4p/parser.py > > +++ w/m4p/parser.py > > @@ -272,7 +272,7 @@ class Parser: > > > > def add_define(self, ident: bytes, defn: bytes | Builtin): > > """Equivalent to m4_define(ident, defn).""" > > - if self.macros.get(ident) is None: > > + if not self.macros.get(ident, []): > > self.macros[ident] = [defn] > > else: > > # GNU ext define: replace top. Others: replace all with 1. > > > > That looks good, I hoped something of the sort would have fixed it. I can > commit it when I'm back home. Glad to hear it. This next one will be tougher: $ m4p -I ~/m4p/tests/resources/ define(`nl',` ')dnl define(`a', translit((include(long_file.txt)),nl,`,'))dnl len(a) 8895 define(`a', translit((syscmd(:)include(long_file.txt)),nl,`,')) (m4:stdin:5: Warning: excess arguments to builtin `define' ignored ) len(a) 1 m4 reports the same value for len(a) for both translit() wrappings of long_file.txt, which gives a hint as to where m4p went wrong. I'm guessing that your code for syscmd() flushes pending output to diversion 0 (since any output from syscmd itself must appear at that point, and is not intercepted by m4 because it is not esyscmd); but even when syscmd has no output, that act of flushing must NOT interfere with pending text being accumulated in the parameter of a macro invocation. Tracing m4p shows that because syscmd(:) flushed the '(' prematurely, at which point translit() is being called with $1 not starting with '(', which in turn means the code is trying to invoke "define(`a', 1,2,...)" instead of the intended "define(`a', (1,2,...)". -- Eric Blake, Principal Software Engineer Red Hat, Inc. Virtualization: qemu.org | libguestfs.org