m4: Ifelse

 
 6.2 If-else construct, or multibranch
 =====================================
 
 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:
 
  -- Builtin: ifelse (COMMENT)
  -- Builtin: ifelse (STRING-1, STRING-2, EQUAL, [NOT-EQUAL])
  -- Builtin: ifelse (STRING-1, STRING-2, EQUAL-1, STRING-3, STRING-4,
           EQUAL-2, ..., [NOT-EQUAL])
      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 blind 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
 
    For an example of a way to make defining blind macros easier, see
 ⇒Composition.
 
    The macro '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.