Thanks Eric.  I think that will do the trick.  I'll e-mail the list again if
it doesn't work out for me.

As an aside, if y'all are planning a m4 v2.0 release (like I think I've seen
in the m4-discuss archive)
I'd like to suggest that the ability to ignore duplicate included files be
built into the m4 program itself,
rather than pushdef/ifdef example.  Maybe enabled with a
--ignore-duplicate-include option.
I'd like the option to also manage the sinclude() lines also at the same
time.
I'd implement in the C code by keeping track of the files ready by inode
number and device mounted
on (rather than the path), like I thought about in my icky work-around.

Thanks again....

-Roger


On Tue, Sep 30, 2008 at 6:19 PM, Eric Blake <[EMAIL PROTECTED]> wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> According to [EMAIL PROTECTED] on 9/30/2008 4:49 PM:
> > Without using ifdef or something similar, is there a way to prevent m4
> from
> > entering an infinite recursion with a file like:
> >
> > % cat foo
> >    include(`foo')
>
> No.  But WITH ifdef, there is a way, and in fact, autoconf uses it to
> prohibit including a file more than once (not because of the fear of
> infinite recursion, but because of the surprising number of .m4 include
> files out there that define a macro with the first argument underquoted -
> re-including the file would define a new macro, named by the definition of
> the original macro, rather than being a no-op).
>
> > I realize I can probably do something like define a macro in the file,
> > and then not include
> > the file if the macro is defined... HOWEVER, in my particular
> > application, I cannot control all
> > of the m4 files...
>
> The trick is not doing it in the file, but before the file.  In other
> words, redefine include to do additional work.  In other words, the act of
> calling include defines a witness macro, such that if the witness macro is
> defined, you are recursively (or repeatedly) trying to re-include the file.
>
> pushdef(`include', `ifelse(`$#', `0', ``$0'',
>  `ifdef(`include($1)',
>   `ifelse(`$1 has been seen;
>           replace this no-op comment with m4exit if desired')',
>   `define(`include($1)')builtin(`$0', $@)')')')
> pushdef(`sinclude', defn(`include'))
>
> The ifelse comment there can be turned into a warning (via errprint) or
> error (via m4exit) if desired.  And this works independently of the file
> contents (so you can protect yourself against malicious include files, as
> appears to be your goal).
>
> > And my m4 go off into an infinite loop.  I can control command line
> > options, but
> > when I tried --nesting-limit=1, that didn't seem to help.
>
> - --nesting-limit only controls textual nesting (such as
> "include(include(foo))"), not recursive invocation.  In the case of
> recursive invocation, each macro is expanded at the outermost level of
> textual nesting.
>
> >
> > About all I could think of is to have my Perl script I'm calling m4 from
> > pre-process the
> > files looking for include or sinclude lines, taking into account the
> > M4PATH environment
> > files, and making sure I don't repeat files (using something like stat()
> > and the inode and
> > device to make sure I handle symlinks).
>
> I agree - that seems gross.  And as autoconf developers have already
> noted, m4 is the best language for parsing m4 - it is almost impossible to
> write robust perl scripts that still handle all cases of m4 input reliably.
>
> - --
> Don't work too hard, make some time for fun as well!
>
> Eric Blake             [EMAIL PROTECTED]
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.9 (Cygwin)
> Comment: Public key at 
> home.comcast.net/~ericblake/eblake.gpg<http://home.comcast.net/%7Eericblake/eblake.gpg>
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
>
> iEYEARECAAYFAkji0A8ACgkQ84KuGfSFAYAywwCgn76hkIQ89pgN2BxkzxnWu3on
> Hx8AnROy+XNuVZYcjdgpSWA+tHV56UNX
> =NUHy
> -----END PGP SIGNATURE-----
>
>
_______________________________________________
m4-discuss mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/m4-discuss

Reply via email to