www.digitalmars.com

D Programming Language 2.0

Last update Sun Mar 11 21:56:06 2012

std.format

This module implements the formatting functionality for strings and I/O. It's comparable to C99's vsprintf() and uses a similar format encoding scheme.

License:
Boost License 1.0.

Authors:
Walter Bright, Andrei Alexandrescu, and Kenji Hara

Source:
std/format.d

class FormatException: object.Exception;
Signals a mismatch between a format and its corresponding argument.

alias FormatError;
Scheduled for deprecation. Please use FormatException instead.

void formattedWrite(Writer, Char, A...)(Writer w, in Char[] fmt, A args);
Interprets variadic argument list args, formats them according to fmt, and sends the resulting characters to w. The encoding of the output is the same as Char. type Writer must satisfy std.range.isOutputRange!(Writer, Char).

The variadic arguments are normally consumed in order. POSIX-style positional parameter syntax is also supported. Each argument is formatted into a sequence of chars according to the format specification, and the characters are passed to w. As many arguments as specified in the format string are consumed and formatted. If there are fewer arguments than format specifiers, a FormatException is thrown. If there are more remaining arguments than needed by the format specification, they are ignored but only if at least one argument was formatted.

Parameters:
w Output is sent do this writer. Typical output writers include std.array.Appender!string and std.stdio.BlockingTextWriter.
fmt Format string.
args Variadic argument list.

Throws:
Mismatched arguments and formats result in a FormatException being thrown.

Format String:
Format strings consist of characters interspersed with format specifications. Characters are simply copied to the output (such as putc) after any necessary conversion to the corresponding UTF-8 sequence.

The format string has the following grammar:

FormatString:
    FormatStringItem*
FormatStringItem:
    '%%'
    '%C' ColorSpec ( FormatString '%)'
    '%' Position Flags Width Precision FormatChar
    '%(' FormatString '%)'
    OtherCharacterExceptPercent
Position:
    empty
    Integer '$'
Flags:
    empty
    '-' Flags
    '+' Flags
    '#' Flags
    '0' Flags
    ' ' Flags
Width:
    empty
    Integer
    '*'
Precision:
    empty
    '.'
    '.' Integer
    '.*'
ColorSpec:
    ColorFlags ColorID
    ColorFlags 'F' ColorID 'B' ColorID
ColorFlags:
    empty
    ColorFlag ColorFlags
ColorFlag:
    'N'|'L'|'D'|'U'|'S'|'R'|'B'
ColorID:
    'd' Integer
    'x' HexDigit HexDigit
    'blk'|'wht'|'grn'|'red'|'blu'|'yel'|'mag'|'cyn'
HexDigit:
    Digit|'a'|'A'|'b'|'B'|'c'|'C'|'d'|'D'|'e'|'E'|'f'|'F'
Integer:
    Digit
    Digit Integer
Digit:
    '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'
FormatChar:
    's'|'c'|'b'|'d'|'o'|'x'|'X'|'e'|'E'|'f'|'F'|'g'|'G'|'a'|'A'

Flags affect formatting depending on the specifier as follows.
Flag Types affected Semantics
'-' numeric Left justify the result in the field. It overrides any 0 flag.
'+' numeric Prefix positive numbers in a signed conversion with a +. It overrides any space flag.
'#' integral ('o') Add to precision as necessary so that the first digit of the octal formatting is a '0', even if both the argument and the Precision are zero.
'#' integral ('x', 'X') If non-zero, prefix result with 0x (0X).
'#' floating Always insert the decimal point and print trailing zeros.
'#' numeric ('0') Use leading zeros to pad rather than spaces (except for the floating point values nan and infinity). Ignore if there's a Precision.
' ' integral ('d') Prefix positive numbers in a signed conversion with a space.

Width
Specifies the minimum field width. If the width is a *, the next argument, which must be of type int, is taken as the width. If the width is negative, it is as if the - was given as a Flags character.

Precision
Gives the precision for numeric conversions. If the precision is a *, the next argument, which must be of type int, is taken as the precision. If it is negative, it is as if there was no Precision.

FormatChar
's'
The corresponding argument is formatted in a manner consistent with its type:
bool
The result is 'true' or 'false'.
integral types
The %d format is used.
floating point types
The %g format is used.
string types
The result is the string converted to UTF-8. A Precision specifies the maximum number of characters to use in the result.
classes derived from Object
The result is the string returned from the class instance's .toString() method. A Precision specifies the maximum number of characters to use in the result.
non-string static and dynamic arrays
The result is [s0, s1, ...] where sk is the kth element formatted with the default format.

'c'
The corresponding argument must be a character type.

'b','d','o','x','X'
The corresponding argument must be an integral type and is formatted as an integer. If the argument is a signed type and the FormatChar is d it is converted to a signed string of characters, otherwise it is treated as unsigned. An argument of type bool is formatted as '1' or '0'. The base used is binary for b, octal for o, decimal for d, and hexadecimal for x or X. x formats using lower case letters, X uppercase. If there are fewer resulting digits than the Precision, leading zeros are used as necessary. If the Precision is 0 and the number is 0, no digits result.

'e','E'
A floating point number is formatted as one digit before the decimal point, Precision digits after, the FormatChar, ±, followed by at least a two digit exponent: d.dddddde±dd. If there is no Precision, six digits are generated after the decimal point. If the Precision is 0, no decimal point is generated.

'f','F'
A floating point number is formatted in decimal notation. The Precision specifies the number of digits generated after the decimal point. It defaults to six. At least one digit is generated before the decimal point. If the Precision is zero, no decimal point is generated.

'g','G'
A floating point number is formatted in either e or f format for g; E or F format for G. The f format is used if the exponent for an e format is greater than -5 and less than the Precision. The Precision specifies the number of significant digits, and defaults to six. Trailing zeros are elided after the decimal point, if the fractional part is zero then no decimal point is generated.

'a','A'
A floating point number is formatted in hexadecimal exponential notation 0xh.hhhhhhp±d. There is one hexadecimal digit before the decimal point, and as many after as specified by the Precision. If the Precision is zero, no decimal point is generated. If there is no Precision, as many hexadecimal digits as necessary to exactly represent the mantissa are generated. The exponent is written in as few digits as possible, but at least one, is in decimal, and represents a power of 2 as in h.hhhhhh*2±d. The exponent for zero is zero. The hexadecimal digits, x and p are in upper case if the FormatChar is upper case.

Floating point NaN's are formatted as nan if the FormatChar is lower case, or NAN if upper. Floating point infinities are formatted as inf or infinity if the FormatChar is lower case, or INF or INFINITY if upper.

ColorSpec
Describes what graphics effects and coloring should be applied to the text enclosed in the parentheses. This assumes the formatted text will eventually make its way onto the screen of a terminal or terminal emulator. Escape sequences will be inserted into the formatted string that will be interpreted by the terminal as coloring commands. ColorID is how the color itself is defined. This can be either a 256-color palette index given with the 'd' or 'x' prefixes, or a 16-color mnemonic. A combination of foreground and background colors can be described with the F ColorID B ColorID syntax, where the F ColorID will be the Foreground color, and the B ColorID will be the Background color.

ColorFlags are available to describe common terminal graphics commands:
Flag Name Meaning
'N' Neutral This resets any graphics properties or coloration present outside of the text enclosed in the parentheses. This will not negate other flags in the same format specifier, so it can be used to have fine-grained control of the graphics flags when nesting format specifiers within each other.
'L' Light Lighter colored text. This will cause the text to render as "bright" or "bold".
'D' Dark Darker colored text. This will use the terminal's "dim" text setting.
'U' Underline Underline the text.
'S' Strikethrough Puts a line through the middle of the text.
'R' Reverse Video Swaps the foreground and background colors of the text.
'B' Blink Makes the text blink on and off.

TODO: Colors are only supported on Linux for the time being, and will only emit 16-color escape sequences until better feature detection is implemented. Color formats on other systems will be ignored and the text will be displayed in a plain manner.

Example:
import std.c.stdio;
import std.format;

void main()
{
    auto writer = appender!string();
    formattedWrite(writer, "%s is the ultimate %s.", 42, "answer");
    assert(writer.data == "42 is the ultimate answer.");
    // Clear the writer
    writer = appender!string();
    formattedWrite(writer, "Date: %2$s %1$s", "October", 5);
    assert(writer.data == "Date: 5 October");

    writer = appender!string();
    formattedWrite(writer, "Normal text. %CLgrn(Light green.%) Normal.");

    writer = appender!string();
    formattedWrite(writer, "%CFx00Bd17(256 colors, black on blue.%)");
}
The positional and non-positional styles can be mixed in the same format string. (POSIX leaves this behavior undefined.) The internal counter for non-positional parameters tracks the next parameter after the largest positional parameter already used.

uint formattedRead(R, Char, S...)(ref R r, const(Char)[] fmt, S args);
Reads characters from input range r, converts them according to fmt, and writes them to args.

Example:
string s = "hello!124:34.5";
string a;
int b;
double c;
formattedRead(s, "%s!%s:%s", &a, &b, &c);
assert(a == "hello" && b == 124 && c == 34.5);

struct FormatSpec(Char) if (is(Unqual!(Char) == Char));
A compiled version of an individual format specifier, backwards compatible with printf specifiers.

int width;
Minimum width, default 0.

int precision;
Precision. Its semantics depends on the argument type. For floating point numbers, precision dictates the number of decimals printed.

int DYNAMIC;
Special value for width and precision. DYNAMIC width or precision means that they were specified with '*' in the format string and are passed at runtime through the varargs.

int UNSPECIFIED;
Special value for precision, meaning the format specifier contained no explicit precision.

char spec;
The actual format specifier, 's' by default.

ubyte indexStart;
Index of the argument for positional parameters, from 1 to ubyte.max. (0 means not used).

ubyte indexEnd;
Index of the last argument for positional parameter range, from 1 to ubyte.max. (0 means not used).

bool flDash;
The format specifier contained a '-' (printf compatibility).

bool flZero;
The format specifier contained a '0' (printf compatibility).

bool flSpace;
The format specifier contained a ' ' (printf compatibility).

bool flPlus;
The format specifier contained a '+' (printf compatibility).

bool flHash;
The format specifier contained a '#' (printf compatibility).

const(Char)[] nested;
In case of a compound format specifier starting with "%(" and ending with "%)", nested contains the string contained within the two separators.

const(Char)[] sep;
In case of a compound format specifier, sep contains the string positioning after "%|".

const(Char)[] trailing;
trailing contains the rest of the format string.

this(in Char[] fmt);
Given a string format specification fmt, parses a format specifier. The string is assumed to start with the character immediately following the '%'. The string is advanced to right after the end of the format specifier.

void formatValue(Writer, T, Char)(Writer w, T val, ref FormatSpec!(Char) f);
bools are formatted as "true" or "false" with %s and as "1" or "0" with integral-specific format specs.

void formatValue(Writer, T, Char)(Writer w, T val, ref FormatSpec!(Char) f);
Integrals are formatted like printf does.

void formatValue(Writer, D, Char)(Writer w, D obj, ref FormatSpec!(Char) f);
Floating-point values are formatted like printf does.

void formatValue(Writer, T, Char)(Writer w, T val, ref FormatSpec!(Char) f);
Individual characters (char, wchar, or dchar) are formatted as Unicode characters with %s and as integers with integral-specific format specs.

void formatValue(Writer, T, Char)(Writer w, T val, ref FormatSpec!(Char) f);
Strings are formatted like printf does.

void formatValue(Writer, T, Char)(Writer w, ref T val, ref FormatSpec!(Char) f);
Static-size arrays are formatted as dynamic arrays.

void formatValue(Writer, T, Char)(Writer w, T val, ref FormatSpec!(Char) f);
Dynamic arrays are formatted as input ranges.

Specializations:

void formatValue(Writer, T, Char)(Writer w, T val, ref FormatSpec!(Char) f);
Associative arrays are formatted by using ':' and ', ' as separators, and enclosed by '[' and ']'.

void formatValue(Writer, T, Char)(Writer w, T val, ref FormatSpec!(Char) f);
void formatValue(Writer, T, Char)(Writer w, T val, ref FormatSpec!(Char) f);
void formatValue(Writer, T, Char)(Writer w, auto ref T val, ref FormatSpec!(Char) f);
Aggregates (struct, union, class, and interface) are basically formatted by calling toString. toString should have one of the following signatures:

const void toString(scope void delegate(const(char)[]) sink, FormatSpec fmt);
const void toString(scope void delegate(const(char)[]) sink, string fmt);
const void toString(scope void delegate(const(char)[]) sink);
const string toString();
For the class objects which have input range interface,

For the struct and union objects which does not have toString,

Otherwise, are formatted just as their type name.

void formatValue(Writer, T, Char)(Writer w, T val, ref FormatSpec!(Char) f);
enum is formatted like its base value.

void formatValue(Writer, T, Char)(Writer w, T val, ref FormatSpec!(Char) f);
Pointers are formatted as hex integers.

void formatValue(Writer, T, Char)(Writer w, T val, ref FormatSpec!(Char) f);
Delegates are formatted by 'Attributes ReturnType delegate(Parameters)'

T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!(Char) spec);
Reads a boolean value and returns it.

T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!(Char) spec);
Reads an integral value and returns it.

T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!(Char) spec);
Reads a floating-point value and returns it.

T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!(Char) spec);
Reads one character and returns it.

T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!(Char) spec);
Reads a string and returns it.

T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!(Char) spec);
Reads an array (except for string types) and returns it.

T unformatValue(T, Range, Char)(ref Range input, ref FormatSpec!(Char) spec);
Reads an associative array and returns it.