Previous: Patsubst, Up: Text handling


11.7 Formatting strings (printf-like)

Formatted output can be made with format:

— Builtin: format (format-string, ...)

Works much like the C function printf. The first argument format-string can contain `%' specifications which are satisfied by additional arguments, and the expansion of format is the formatted string.

The macro format is recognized only with parameters.

Its use is best described by a few examples:

     define(`foo', `The brown fox jumped over the lazy dog')
     =>
     format(`The string "%s" uses %d characters', foo, len(foo))
     =>The string "The brown fox jumped over the lazy dog" uses 38 characters
     format(`%*.*d', `-1', `-1', `1')
     =>1
     format(`%.0f', `56789.9876')
     =>56790
     len(format(`%-*X', `5000', `1'))
     =>5000
     ifelse(format(`%010F', `infinity'), `       INF', `success',
            format(`%010F', `infinity'), `  INFINITY', `success',
            format(`%010F', `infinity'))
     =>success
     ifelse(format(`%.1A', `1.999'), `0X1.0P+1', `success',
            format(`%.1A', `1.999'), `0X2.0P+0', `success',
            format(`%.1A', `1.999'))
     =>success
     format(`%g', `0xa.P+1')
     =>20

Using the forloop macro defined earlier (see Forloop), this example shows how format can be used to produce tabular output.

     $ m4 -I examples
     include(`forloop.m4')
     =>
     forloop(`i', `1', `10', `format(`%6d squared is %10d
     ', i, eval(i**2))')
     =>     1 squared is          1
     =>     2 squared is          4
     =>     3 squared is          9
     =>     4 squared is         16
     =>     5 squared is         25
     =>     6 squared is         36
     =>     7 squared is         49
     =>     8 squared is         64
     =>     9 squared is         81
     =>    10 squared is        100
     =>

The builtin format is modeled after the ANSI C `printf' function, and supports these `%' specifiers: `c', `s', `d', `o', `x', `X', `u', `a', `A', `e', `E', `f', `F', `g', `G', and `%'; it supports field widths and precisions, and the flags `+', `-', ` ', `0', `#', and `''. For integer specifiers, the width modifiers `hh', `h', and `l' are recognized, and for floating point specifiers, the width modifier `l' is recognized. Items not yet supported include positional arguments, the `n', `p', `S', and `C' specifiers, the `z', `t', `j', `L' and `ll' modifiers, and any platform extensions available in the native printf. For more details on the functioning of printf, see the C Library Manual, or the POSIX specification (for example, `%a' is supported even on platforms that haven't yet implemented C99 hexadecimal floating point output natively).

Unrecognized specifiers result in a warning. It is anticipated that a future release of GNU m4 will support more specifiers, and give better warnings when various problems such as overflow are encountered. Likewise, escape sequences are not yet recognized.

     format(`%p', `0')
     error-->m4:stdin:1: Warning: unrecognized specifier in `%p'
     =>