Re: collecting arguments for esyscmd while sending the output to stdin

Eric Blake <[email protected]>
Newsgroups gmane.comp.gnu.m4.general
Organization Red Hat
Message-ID <[email protected]>
On 07/17/2010 03:08 PM, daniel daniel wrote:

Hello daniel, and sorry for not replying sooner (you caught me on vacation),

> Say you have a `function' named _streamRevert
> that takes two arguments. The first argument is
> the number of the stream to collect, the second
> argument is the number of the stream to which
> to dump the collected stream.
> To accomplish this, you make use of four auxiliary
> functions: SAVE, push_divert, pop_divert, and
> _streamDump. Their definitions are as follows:
> 
> define(`push_divert',`
> `'pushdef(`savedivert',divnum)dnl
> `'divert($1)dnl
> `'pushdef(`lastdivnum',divnum)dnl
> ')
> define(`pop_divert',`
> `'divert(savedivert)dnl
> `'popdef(`savedivert')dnl
> ')
> define(`SAVE',`
> `'push_divert($2)$1`'pop_divert()dnl
> ')
> define(`_streamDump',``esyscmd'(`echo 'undivert($1)` > /dev/fd/0')')

It looks like you are trying to make a child process feed back m4's
output back into m4, but I don't see how this can be expected to work
reliably.  undivert is documented as going directly to the current
diversion, without any further m4 scanning.  The use of /dev/fd/0 is
system-specific (not all systems have /dev/fd/0), and treading on shaky
ground for possible deadlock if you output more than an atomic pipe
buffer's worth of data (since you now have m4 doing simultaneous input
and output from the same child process).

> How do you get esyscmd to collect the result of the expansion
> of undivert($1) as an argument to esyscmd?

In general, you can't.  If you want to collect strings for later
rescanning, I'd recommend collecting those strings into named macros
rather than diversions.  Something like:

# SAVE(text,num) - append TEXT to saved string NUM
define(`SAVE',
`define(`$2',defn(`$2')`$1')')
# RESTORE(num) - call back saved test from string NUM
define(`RESTORE',
`defn(`$1')')

> Right now it seems like esyscmd expands undivert($1) but
> does not capture the result of the expansion as an argument.

Correct - the expansion of undivert is _always_ the empty string; the
undiverted text was instead routed to the current diversion without any
further m4 scanning.  If the current diversion is 0, then your esyscmd
games with /dev/fd/0 may be able to see it.  But if the current
diversion is anything else, there's no way that esyscmd can intercept
the data as it moves between diversions.

-- 
Eric Blake   [email protected]    +1-801-349-2682
Libvirt virtualization library http://libvirt.org
signature.asc (application/pgp-signature, 619 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.14 (GNU/Linux)
Comment: Public key at http://people.redhat.com/eblake/eblake.gpg
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iQEcBAEBCAAGBQJMUstGAAoJEKeha0olJ0NqrK0IAKwTfevOOY9vFnpbF3GwAZzX
HQyYD5aSqDnkrAGC+aLwlnCz9wd2ZMQIctn7Wy30qSSl/nGcYBE2bUYRmaAh66kn
MJBkEn803C7KEemqgt/40HsOTVBxz9Mxxt7zBwNr59tlGVov7UBFrDOKdo5ug/Xk
kldY4SlYTxaZLXFDia2t0i+JR9Opcvi0u+nFnb6K9jVjgcGQfMoF30SmOUmuU8ZJ
vE0uwv7mnDwC6zJAhnGg5pT7TzA+VWOTqMAFZJtbrugnjNzp/2DxBQtiK+8rQAkV
BBxGuF8m1Mx90no8792Kp2ReO2qXMGmTbhPrvZnyDih+EblL+OczISY0+i6uXKY=
=57vi
-----END PGP SIGNATURE-----
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.