m4: Ifelse

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