m4-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


From: Eric Blake
Subject: Re: collecting arguments for esyscmd while sending the output to stdin
Date: Fri, 30 Jul 2010 06:53:26 -0600
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.7) Gecko/20100720 Fedora/3.1.1-1.fc13 Lightning/1.0b2pre Mnenhy/0.8.3 Thunderbird/3.1.1

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   address@hidden    +1-801-349-2682
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]