autoconf
[Top][All Lists]
Advanced

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

Re: m4_foreach_w and "options"


From: Eric Blake
Subject: Re: m4_foreach_w and "options"
Date: Mon, 02 Jul 2012 11:02:19 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:13.0) Gecko/20120615 Thunderbird/13.0.1

On 07/01/2012 04:11 AM, Vincent Torri wrote:

> But I would like to write am m4 macro that would be used like that:
> 
> my_macro([foo1 foo2], [bar1 bar2])
> 
> and I would like to "associate" bar1 to foo1 and bar2 to foo2 (bar*
> would options for the macros called by m4_foreach_w() in my_check (see
> above)), that is
> 
> for foo1, my_check would be called with bar1
> for foo2, my_check would be called with bar2
> 
> is it possible ?

Not directly with a single m4_foreach_w, but it would be possible with
other macro constructs.  Note that m4 is better suited for
comma-separated lists instead of whitespace-separated lists, as the
first part of my suggestion below is just to convert my_macro into a
call to _my_macro with my preferred comma separation.

m4_define([my_macro],
[_$0(m4_dquote(m4_map_args_w([$1], [], [], [,])),
     m4_dquote(m4_map_args_w([$2], [], [], [,])))])
m4_define([_my_macro],
[m4_for([i], [1], m4_count($1), [],
  [my_pair(m4_argn(i, $1), m4_argn(i, $2))])])

Then define my_pair([arg1], [arg2]) do do whatever you want with an
individual pair.

I just tested it myself, and satisfied myself that:

my_macro([a b c], [1 2 3])

invokes

_my_macro([[a], [b], [c]], [[1], [2], [3]])

invokes

my_pair([a], [1])my_pair([b], [2])my_pair([c], [3])

You can also add some sanity checking in _my_macro, such as whether
m4_count($1) and m4_count($2) are equal.

Do be aware that what I've written is inherently quadratic at best,
since m4_argn is O(n) rather than O(1) in the amount of text that it
parses, and you are calling m4_argn with O(n) iterations - if users
start passing huge lists of names to be paired, they will experience a
noticeable slowdown due to the scaling effects.  There may be a more
efficient way to crawl through two whitespace-separated lists at once
and form pairs in a single O(n) pass, but such an operation is not
natively provided by m4, and would probably involve a lot of black magic
abuse of the m4 language (the sort of thing that m4sugar is already
doing for you in its implementation of m4_foreach_w); but I don't think
autoconf has such a method already available.

Maybe you should also consider having your users pass in the arguments
already paired, as in:

my_macro([[foo1, bar1], [foo2, bar2]])

at which point life is much easier for you to operate on each pair in
the order they were passed, instead of you having to crawl through the
two lists to create the pairings yourself.  Changing your calling
conventions in that manner would also make it much easier to write an
O(N) algorithm instead of an O(N^2) one.

-- 
Eric Blake   address@hidden    +1-919-301-3266
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]