### 17.4 Solution for `copy` ¶

The macro `copy` presented above is unable to handle builtin tokens with M4 1.4.x, because it tries to pass the builtin token through the macro `curry`, where it is silently flattened to an empty string (see Building macros with macros). Rather than using the problematic `curry` to work around the limitation that `stack_foreach` expects to invoke a macro that takes exactly one argument, we can write a new macro that lets us form the exact two-argument `pushdef` call sequence needed, so that we are no longer passing a builtin token through a text macro.

Composite: stack_foreach_sep (macro, pre, post, sep) ¶
Composite: stack_foreach_sep_lifo (macro, pre, post, sep) ¶

  For each of the `pushdef` definitions associated with macro, expand the sequence ‘`pre`'definition`'post`’. Additionally, expand sep between definitions. `stack_foreach_sep` visits the oldest definition first, while `stack_foreach_sep_lifo` visits the current definition first. The expansion may dereference macro, but should not modify it. There are a few special macros, such as `defn`, which cannot be used as the macro parameter.

Note that `stack_foreach(`macro', `action')` is equivalent to `stack_foreach_sep(`macro', `action(', `)')`. By supplying explicit parentheses, split among the pre and post arguments to `stack_foreach_sep`, it is now possible to construct macro calls with more than one argument, without passing builtin tokens through a macro call. It is likewise possible to directly reference the stack definitions without a macro call, by leaving pre and post empty. Thus, in addition to fixing `copy` on builtin tokens, it also executes with fewer macro invocations.

The new macro also adds a separator that is only output after the first iteration of the helper `_stack_reverse_sep`, implemented by prepending the original sep to pre and omitting a sep argument in subsequent iterations. Note that the empty string that separates sep from pre is provided as part of the fourth argument when originally calling `_stack_reverse_sep`, and not by writing `$4`'$3` as the third argument in the recursive call; while the other approach would give the same output, it does so at the expense of increasing the argument size on each iteration of `_stack_reverse_sep`, which results in quadratic instead of linear execution time. The improved stack walking macros are available in `m4-1.4.19/examples/stack_sep.m4`:

    $ m4 -I examples
    include(`stack_sep.m4')
    ⇒
    define(`copy', `ifdef(`$2', `errprint(`$2 already defined
    ')m4exit(`1')',
       `stack_foreach_sep(`$1', `pushdef(`$2',', `)')')')dnl
    pushdef(`a', `1')pushdef(`a', defn(`divnum'))
    ⇒
    copy(`a', `b')
    ⇒
    b
    ⇒0
    popdef(`b')
    ⇒
    b
    ⇒1
    pushdef(`c', `1')pushdef(`c', `2')
    ⇒
    stack_foreach_sep_lifo(`c', `', `', `, ')
    ⇒2, 1
    undivert(`stack_sep.m4')dnl
    ⇒divert(`-1')
    ⇒# stack_foreach_sep(macro, pre, post, sep)
    ⇒# Invoke PRE`'defn`'POST with a single argument of each definition
    ⇒# from the definition stack of MACRO, starting with the oldest, and
    ⇒# separated by SEP between definitions.
    ⇒define(`stack_foreach_sep',
    ⇒`_stack_reverse_sep(`$1', `tmp-$1')'dnl
    ⇒`_stack_reverse_sep(`tmp-$1', `$1', `$2`'defn(`$1')$3', `$4`'')')
    ⇒# stack_foreach_sep_lifo(macro, pre, post, sep)
    ⇒# Like stack_foreach_sep, but starting with the newest definition.
    ⇒define(`stack_foreach_sep_lifo',
    ⇒`_stack_reverse_sep(`$1', `tmp-$1', `$2`'defn(`$1')$3', `$4`'')'dnl
    ⇒`_stack_reverse_sep(`tmp-$1', `$1')')
    ⇒define(`_stack_reverse_sep',
    ⇒`ifdef(`$1', `pushdef(`$2', defn(`$1'))$3`'popdef(`$1')$0(
    ⇒  `$1', `$2', `$4$3')')')
    ⇒divert`'dnl