I'm trying out the m4 CLI on linux and trying to create a for(begin, end, step) macro that will print out a comma separated list of numbers in the given range. I also want it to support a default step of 1. I tried the following
[tom@sp4 ~]$ m4
define(`for',`ifelse($#,2,`for($1,$2,1)',eval($1 $3>$2),1,$1,`$1, for(eval($1 $3),$2,$3)')')
for(3,9)
m4:stdin:3: bad expression in eval: 3 >9
3, 4, 5, 6, 7, 8, 9
While it works OK I can't understand why I get the error message as $3 is only blank on first pass. Why is it even bothering to read the eval($1 $3>$2) when $#==2?
CodePudding user response:
When m4
encounters foo(3,9)
, it expands that to the text of the ifelse
as defined in the macro. In order to invoke ifelse
, it has to pass arguments to it. To determine those arguments, it has to expand eval
. Hence the error message.
You can avoid the error message with:
define(`for',
`ifelse(
`$#', `2', `for(`$1', `$2', `1')',
eval(`$1' ifelse(`$3', `', `0', `1') > `$2'), `1', `$1',
`$1, for(eval(`$1' `$3'), `$2', `$3')'dnl
)')dnl