m4-question

T. J. Thompson tj at mks.com
Thu Nov 9 11:21:34 AEST 1989


In <720 at Aragorn.dde.dk> Claus Tondering says:
>I am trying to write an m4-macro that can do for-loop evaluation.
>I want to be able to say something like:
>
>	for(x,`alpha,beta,gamma,delta',This is x )
>
>and this should output:
>
>	This is alpha This is beta This is gamma This is delta
>
>However, I have not been able to write this macro. I think I
>get the quotes wrong. This is my best attempt:
>
>define(for,`ifelse(`$2',,,`define(`$1',$2) $3 for(`$1',shift($2),`$3')')')
>
>But it doesn't work. It just produces:
>	
>	This is alpha  gamma
>
>Could somebody please help me?

The problem is not simply a matter of getting the quotes right.
What is happening is that the result of `shift' is the arguments
(less the first) individually quoted, separated by unquoted commas.
Therefore the `for' macro is called the second time with the body
defined as the 3rd element of the iteration list.

This behaviour of shift is what one generally wants: for example
it means that shift(shift(`a',`b',`c')) is `c'.
It also means, however, that there is no way to get exactly the
effect you expected (quoted commas).

If you can accept a slight modification of the calling sequence
of your macro, so that it does not try to use quoted commas, then
your solution is not far off the mark. The following has the desired
effect on my system. (I changed the name to `for_in' to avoid
conflict with my m4 library of C-style control macros).

8<-----------8<-----------
# for_in(`control', `body with control', `instance', ...)
define(`for_in',
`ifelse(`$3',,
	,
	`define(`$1',`$3')$2 $0(`$1', `$2', shift(shift(shift($@))))')')dnl
8<-----------8<-----------
for_in(`x', `This is x.', `alpha', `beta', `gamma', `delta')
 This is alpha. This is beta. This is gamma. This is delta.
-- 
     ||  // // ,'/~~\'   T. J. Thompson                        tj at mks.com
    /||/// //|' `\\\     Mortice Kern Systems Inc.         (519) 884-2251
   / | //_// ||\___/     35 King St. N., Waterloo, Ont., Can. N2J 2W9
O_/                                long time(); /* know C */



More information about the Comp.unix.wizards mailing list