m4: Pushdef

 
 5.6 Temporarily redefining macros
 =================================
 
 It is possible to redefine a macro temporarily, reverting to the
 previous definition at a later time.  This is done with the builtins
 'pushdef' and 'popdef':
 
  -- Builtin: pushdef (NAME, [EXPANSION])
  -- Builtin: popdef (NAME...)
      Analogous to 'define' and 'undefine'.
 
      These macros work in a stack-like fashion.  A macro is temporarily
      redefined with 'pushdef', which replaces an existing definition of
      NAME, while saving the previous definition, before the new one is
      installed.  If there is no previous definition, 'pushdef' behaves
      exactly like 'define'.
 
      If a macro has several definitions (of which only one is
      accessible), the topmost definition can be removed with 'popdef'.
      If there is no previous definition, 'popdef' behaves like
      'undefine'.
 
      The expansion of both 'pushdef' and 'popdef' is void.  The macros
      'pushdef' and 'popdef' are recognized only with parameters.
 
      define(`foo', `Expansion one.')
      =>
      foo
      =>Expansion one.
      pushdef(`foo', `Expansion two.')
      =>
      foo
      =>Expansion two.
      pushdef(`foo', `Expansion three.')
      =>
      pushdef(`foo', `Expansion four.')
      =>
      popdef(`foo')
      =>
      foo
      =>Expansion three.
      popdef(`foo', `foo')
      =>
      foo
      =>Expansion one.
      popdef(`foo')
      =>
      foo
      =>foo
 
    If a macro with several definitions is redefined with 'define', the
 topmost definition is _replaced_ with the new definition.  If it is
 removed with 'undefine', _all_ the definitions are removed, and not only
 the topmost one.  However, POSIX allows other implementations that treat
 'define' as replacing an entire stack of definitions with a single new
 definition, so to be portable to other implementations, it may be worth
 explicitly using 'popdef' and 'pushdef' rather than relying on the GNU
 behavior of 'define'.
 
      define(`foo', `Expansion one.')
      =>
      foo
      =>Expansion one.
      pushdef(`foo', `Expansion two.')
      =>
      foo
      =>Expansion two.
      define(`foo', `Second expansion two.')
      =>
      foo
      =>Second expansion two.
      undefine(`foo')
      =>
      foo
      =>foo
 
    Local variables within macros are made with 'pushdef' and 'popdef'.
 At the start of the macro a new definition is pushed, within the macro
 it is manipulated and at the end it is popped, revealing the former
 definition.
 
    It is possible to temporarily redefine a builtin with 'pushdef' and
 'defn'.