Home > Mobile >  GNU M4 seems to access unnecessary value in ifelse
GNU M4 seems to access unnecessary value in ifelse

Time:09-26

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
  • Related