Formatted I/O
pkg std =
/* output to file descriptors */
const put : (fmt : byte[:], args : ... -> size)
const fput : (fd : fd, fmt : byte[:], args : ... -> size)
const putv : (fmt : byte[:], ap : valist# -> size)
const fputv : (fd : fd, fmt : byte[:], ap : valist# -> size)
/* formatting values */
const fmt : (fmt : byte[:], args : ... -> byte[:])
const fmtv : (fmt : byte[:], ap : valist# -> byte[:])
const bfmt : (buf : byte[:], fmt : byte[:], args : ... -> byte[:])
const bfmtv : (buf : byte[:], fmt : byte[:], ap : valist# -> byte[:])
const sbfmt : (buf : strbuf#, fmt : byte[:], args : ... -> size)
const sbfmtv : (buf : strbuf#, fmt : byte[:], ap : valist# -> size)
/* custom formatting */
const fmtinstall : (ty : byte[:], \
fn : (sb : strbuf#, \
ap : valist#, \
opts : (byte[:],byte[:])[:] \
-> void), \
optdesc : (byte[:], bool)[:] \
-> void)
;;
Overview
Formatting in Myrddin is done with format strings. These are effectively dynamically typed at runtime, using introspection to decide the best way to format a type. Custom formatters are allowed and encouraged.
Formatting is specified with a {}
pair, with any specifiers describing the
formatting passed in as a comma separated set of key value pairs. For example,
an integer can be padded with zeros and formatted in hex with the following
format specifier: {p=0,x}
. If you want a literal '{' character, it can
be escaped by doubling it.
None of the format specifiers print a newline character by default.
Format Specifiers
The set of specifiers for the default types is sparse, and is fully specified below.
- w=WIDTH
Fill out to at least width WIDTH, filling with pad characters.
- p=PAD
-
Fill spare width with this character. Defaults to a space character.
- x
-
Format in hex. This is only valid for integer types.
- j=joiner
-
Join slices with the joiner string. This leaves off the square brackets from the ends, and replaces the default joiner string ", ".
- s=significant figure
-
Specify the number of significant digits (base 10) for floating point types. These digits may be zero.
- e
-
Format in scientific notation. This is only valid for floating point types.
Specifiers can be installed by custom specifiers, and can be any arbitrary set of strings.
Functions
All the format functions come in two variants: A variadic one, and one that takes a variadic argument list. The latter is present for ease of chaining from within a variadic function.
const put : (fmt : byte[:], args : ... -> size)
const fput : (fd : fd, fmt : byte[:], args : ... -> size)
const putv : (fmt : byte[:], ap : valist# -> size)
const fputv : (fd : fd, fmt : byte[:], ap : valist# -> size)
The put
set of functions will format and output to a file descriptor. For
put
and putv
, the file descriptor is stdout. For fput
and fputv
, the
file descriptor is the one that is provided.
These functions write immediately, and do not buffer, although they do attempt to do their writing in a single system call, and will only split the call if the kernel indicates short writes.
The v
variants will take a variadic argument list for printing.
Returns: the number of bytes written to the file descriptor.
const sbfmt : (buf : strbuf#, fmt : byte[:], args : ... -> size)
const sbfmtv : (buf : strbuf#, fmt : byte[:], ap : valist# -> size)
The sbfmt functions will append to a string buffer, instead of writing to an
output stream, but are otherwise similar to the fmt
functions. These
functions will return the number of bytes formatted. If the string buffer is
statically sized, and gets filled, the truncated size will be returned.
const fmt : (fmt : byte[:], args : ... -> byte[:])
const fmtv : (fmt : byte[:], ap : valist# -> byte[:])
These functions will format according to the format string, and return a
freshly allocated string containing the formatted string. This string should
be freed with slfree
.
const bfmt : (buf : byte[:], fmt : byte[:], args : ... -> byte[:])
const bfmtv : (buf : byte[:], fmt : byte[:], ap : valist# -> byte[:])
These functions will format according to the format string, putting the result
into buf
. They return a slice into the buffer array.
const fmtinstall : (ty : byte[:], \
fn : (sb : strbuf#,
ap : valist#, \
opts : (byte[:],byte[:])[:] \
-> void), \
optdesc : (byte[:], bool)[:] \
-> void)
Fmtinstall installs a custom formatter for a type. The type ty
is a type
description that you would want to format. It can be obtained
using std.typeof(var)
, fn
is a function that handles custom formatting,
and optdesc
is a list of options that this custom formater takes. It is
in the form a list of strings -- the argument names -- and booleans that
define whether these arguments take values.
The custom formatter takes a string buffer sb
which you are expected to
format the custom input into, as well as a valist that you are expected to
pull the value from. Finally, it takes an option list.
If a formatter is already installed for a type, it is replaced.
Examples
This example demonstrates a bunch of formatting using the std.format API. It covers all of the various format specifiers, escaping, as well as showing the formatting of complex types.
This example shows how you would set up a