Next: Loops, Previous: Ifdef, Up: Conditionals
The other conditional, ifelse
, is much more powerful. It can be
used as a way to introduce a long comment, as an if-else construct, or
as a multibranch, depending on the number of arguments supplied:
Used with only one argument, the
ifelse
simply discards it and produces no output.If called with three or four arguments,
ifelse
expands into equal, if string-1 and string-2 are equal (character for character), otherwise it expands to not-equal. A final fifth argument is ignored, after triggering a warning.If called with six or more arguments, and string-1 and string-2 are equal,
ifelse
expands into equal-1, otherwise the first three arguments are discarded and the processing starts again.The macro
ifelse
is recognized only with parameters.
Using only one argument is a common m4
idiom for introducing a
block comment, as an alternative to repeatedly using dnl
. This
special usage is recognized by GNU m4
, so that in this
case, the warning about missing arguments is never triggered.
ifelse(`some comments') => ifelse(`foo', `bar') error-->m4:stdin:2: Warning: too few arguments to builtin `ifelse' =>
Using three or four arguments provides decision points.
ifelse(`foo', `bar', `true') => ifelse(`foo', `foo', `true') =>true define(`foo', `bar') => ifelse(foo, `bar', `true', `false') =>true ifelse(foo, `foo', `true', `false') =>false
Notice how the first argument was used unquoted; it is common to compare the expansion of a macro with a string. With this macro, you can now reproduce the behavior of many of the builtins, where the macro is recognized only with arguments.
define(`foo', `ifelse(`$#', `0', ``$0'', `arguments:$#')') => foo =>foo foo() =>arguments:1 foo(`a', `b', `c') =>arguments:3
However, ifelse
can take more than four arguments. If given more
than four arguments, ifelse
works like a case
or switch
statement in traditional programming languages. If string-1 and
string-2 are equal, ifelse
expands into equal-1, otherwise
the procedure is repeated with the first three arguments discarded. This
calls for an example:
ifelse(`foo', `bar', `third', `gnu', `gnats') error-->m4:stdin:1: Warning: excess arguments to builtin `ifelse' ignored =>gnu ifelse(`foo', `bar', `third', `gnu', `gnats', `sixth') => ifelse(`foo', `bar', `third', `gnu', `gnats', `sixth', `seventh') =>seventh ifelse(`foo', `bar', `3', `gnu', `gnats', `6', `7', `8') error-->m4:stdin:4: Warning: excess arguments to builtin `ifelse' ignored =>7
Naturally, the normal case will be slightly more advanced than these
examples. A common use of ifelse
is in macros implementing loops
of various kinds.