Next: , Previous: , Up: Answers   [Contents][Index]


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 (see Shift). The improved LIFO example is shipped as m4-1.4.19/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  $@

Next: , Previous: , Up: Answers   [Contents][Index]