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]])