(m4.info)Improved m4wrap


Next: Improved cleardivert Prev: Improved copy Up: Answers
Enter node , (file) or (file)node

17.5 Solution for 'm4wrap'
==========================

The replacement 'm4wrap' versions presented above, designed to guarantee
FIFO or LIFO order regardless of the underlying M4 implementation, share
a bug when dealing with wrapped text that looks like parameter
expansion.  Note how the invocation of 'm4wrapN' interprets these
parameters, while using the builtin preserves them for their intended
use.

     $ m4 -I examples
     include(`wraplifo.m4')
     =>
     m4wrap(`define(`foo', ``$0:'-$1-$*-$#-')foo(`a', `b')
     ')
     =>
     builtin(`m4wrap', ``'define(`bar', ``$0:'-$1-$*-$#-')bar(`a', `b')
     ')
     =>
     ^D
     =>bar:-a-a,b-2-
     =>m4wrap0:---0-

   Additionally, the computation of '_m4wrap_level' and creation of
multiple 'm4wrapN' placeholders in the original examples is more
expensive in time and memory than strictly necessary.  Notice how the
improved version grabs the wrapped text via 'defn' to avoid parameter
expansion, then undefines '_m4wrap_text', before stripping a level of
quotes with '_arg1' to expand the text.  That way, each level of
wrapping reuses the single placeholder, which starts each nesting level
in an undefined state.

   Finally, it is worth emulating the GNU M4 extension of saving all
arguments to 'm4wrap', separated by a space, rather than saving just the
first argument.  This is done with the 'join' macro documented
previously (Note: Shift).  The improved LIFO example is shipped as
'm4-1.4.18/examples/wraplifo2.m4', and can easily be converted to a FIFO
solution by swapping the adjacent invocations of 'joinall' and 'defn'.

     $ m4 -I examples
     include(`wraplifo2.m4')
     =>
     undivert(`wraplifo2.m4')dnl
     =>dnl Redefine m4wrap to have LIFO semantics, improved example.
     =>include(`join.m4')dnl
     =>define(`_m4wrap', defn(`m4wrap'))dnl
     =>define(`_arg1', `$1')dnl
     =>define(`m4wrap',
     =>`ifdef(`_$0_text',
     =>       `define(`_$0_text', joinall(` ', $@)defn(`_$0_text'))',
     =>       `_$0(`_arg1(defn(`_$0_text')undefine(`_$0_text'))')dnl
     =>define(`_$0_text', joinall(` ', $@))')')dnl
     m4wrap(`define(`foo', ``$0:'-$1-$*-$#-')foo(`a', `b')
     ')
     =>
     m4wrap(`lifo text
     m4wrap(`nested', `', `$@
     ')')
     =>
     ^D
     =>lifo text
     =>foo:-a-a,b-2-
     =>nested  $@


automatically generated by info2www version 1.2.2.9