summaryrefslogtreecommitdiff
path: root/doc/api/libstd/fmt.txt
diff options
context:
space:
mode:
Diffstat (limited to 'doc/api/libstd/fmt.txt')
-rw-r--r--doc/api/libstd/fmt.txt201
1 files changed, 201 insertions, 0 deletions
diff --git a/doc/api/libstd/fmt.txt b/doc/api/libstd/fmt.txt
new file mode 100644
index 0000000..40f1b3f
--- /dev/null
+++ b/doc/api/libstd/fmt.txt
@@ -0,0 +1,201 @@
+{
+ title: Formatted I/O
+ description: libstd: Formatted I/O
+}
+
+
+
+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.
+
+<dl>
+ <dt>w=WIDTH</dt>
+ <dd><p>Fill out to at least width WIDTH, filling with pad
+ characters.</p></dd>
+
+ <dt>p=PAD</dt>
+ <dd>
+ <p>Fill spare width with this character. Defaults to a space
+ character.</p> </dd>
+
+ <dt>x</dt>
+ <dd>
+ <p>Format in hex. This is only valid for integer types.</p>
+ </dd>
+
+ <dt>j=joiner</dt>
+ <dd>
+ <p>Join slices with the joiner string. This leaves off the square
+ brackets from the ends, and replaces the default joiner string ", ".
+ </p>
+ </dd>
+</dl>
+
+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.
+
+```{runmyr fmtsimple}
+use std
+
+const main = {
+ /* default formats */
+ std.put("{} {}\n", "abcd", 123)
+ std.put("{}\n", [1,2,3][:])
+ std.put("{}\n", (1,"foo"))
+
+ /* mix in some format options */
+ std.put("{w=10}\n", "abcd")
+ std.put("{p=0,w=10}\n", "abcdefghijkl")
+ std.put("{w=10,x}\n", 10)
+ std.put("{p=0,w=10}\n", 10)
+
+ /* and now some escaping */
+ std.put("{}bar{}\n", "foo\n", "baz")
+ std.put("{{}}bar{}\n", "baz")
+ std.put("{{bar{}}}\n", "baz")
+}
+```
+
+This example shows how you would set up a
+
+```{runmyr customfmt}
+use std
+
+const main = {
+ var x : int = 0 /* dummy: used for typeof */
+
+ std.fmtinstall(std.typeof(x), goaway, [][:])
+ std.put("custom format: {}\n", 0x41)
+}
+
+const goaway = {sb, ap, opts
+ var i : int64
+
+ i = std.vanext(ap)
+ std.sbfmt(sb, "go away! char val={}\n", i castto(char))
+}
+```
+
+
+