```

     FMTINSTALL(2)					 FMTINSTALL(2)

     NAME
	  fmtinstall, dofmt, dorfmt, fmtprint, fmtvprint, fmtrune,
	  fmtstrcpy, fmtrunestrcpy, fmtfdinit, fmtfdflush, fmtstrinit,
	  fmtstrflush, runefmtstrinit, runefmtstrflush,	errfmt -
	  support for user-defined print formats and output routines

     SYNOPSIS
	  #include <u.h>
	  #include <libc.h>

	  typedef struct Fmt  Fmt;
	  struct Fmt{
	      uchar   runes;  /* output	buffer is runes	or chars? */
	      void    *start; /* of buffer */
	      void    *to;    /* current place in the buffer */
	      void    *stop;  /* end of	the buffer; overwritten	if flush fails */
	      int     (*flush)(Fmt*);/*	called when to == stop */
	      void    *farg;  /* to make flush a closure */
	      int     nfmt;   /* num chars formatted so	far */
	      va_list args;   /* args passed to	dofmt */
	      int     r;      /* % format Rune */
	      int     width;
	      int     prec;
	      ulong   flags;
	  };
	  enum{
	      FmtWidth	  = 1,
	      FmtLeft	  = FmtWidth <<	1,
	      FmtPrec	  = FmtLeft << 1,
	      FmtSharp	  = FmtPrec << 1,
	      FmtSpace	  = FmtSharp <<	1,
	      FmtSign	  = FmtSpace <<	1,
	      FmtZero	  = FmtSign << 1,
	      FmtUnsigned = FmtZero << 1,
	      FmtShort	  = FmtUnsigned	<< 1,
	      FmtLong	  = FmtShort <<	1,
	      FmtVLong	  = FmtLong << 1,
	      FmtComma	  = FmtVLong <<	1,
	      FmtFlag	  = FmtComma <<	1
	  };

	  int	fmtfdinit(Fmt *f, int fd, char *buf, int nbuf);

	  int	fmtfdflush(Fmt *f);

	  int	fmtstrinit(Fmt *f);

	  char*	fmtstrflush(Fmt	*f);

	  int	runefmtstrinit(Fmt *f);

	  Rune*	runefmtstrflush(Fmt *f);

	  int	fmtinstall(int c, int (*fn)(Fmt*));

	  int	dofmt(Fmt *f, char *fmt);

	  int	dorfmt(Fmt*, Rune *fmt);

	  int	fmtprint(Fmt *f, char *fmt, ...);

	  int	fmtvprint(Fmt *f, char *fmt, va_list v);

	  int	fmtrune(Fmt *f,	int r);

	  int	fmtstrcpy(Fmt *f, char *s);

	  int	fmtrunestrcpy(Fmt *f, Rune *s);

	  int	errfmt(Fmt *f);

     DESCRIPTION
	  The interface	described here allows the construction of cus-
	  tom print(2) verbs and output	routines.  In essence, they
	  provide access to the	workings of the	formatted print	code.

	  The print(2) suite maintains its state with a	data structure
	  called Fmt.  A typical call to print(2) or its relatives
	  initializes a	Fmt structure, passes it to subsidiary rou-
	  tines	to process the output, and finishes by emitting	any
	  saved	state recorded in the Fmt.  The	details	of the Fmt are
	  unimportant to outside users,	except insofar as the general
	  design influences the	interface.  The	Fmt records whether
	  the output is	in runes or bytes, the verb being processed,
	  its precision	and width, and buffering parameters.  Most
	  important, it	also records a flush routine that the library
	  will call if a buffer	overflows.  When printing to a file
	  descriptor, the flush	routine	will emit saved	characters and
	  reset	the buffer; when printing to an	allocated string, it
	  will resize the string to receive more output.  The flush
	  routine is nil when printing to fixed-size buffers.  User
	  code need never provide a flush routine; this	is done	inter-
	  nally	by the library.

	Custom output routines
	  To write a custom output routine, such as an error handler
	  that formats and prints custom error messages, the output
	  sequence can be run from outside the library using the rou-
	  tines	described here.	 There are two main cases: output to
	  an open file descriptor and output to	a string.

	  To write to a	file descriptor, call fmtfdinit	to initialize
	  the local Fmt	structure f, giving the	file descriptor	fd,
	  the buffer buf, and its size nbuf. Then call fmtprint	or
	  fmtvprint to generate	the output.  These behave like fprint
	  (see print(2)) or vfprint except that	the characters are
	  buffered until fmtfdflush is called and the return value is
	  either 0 or -1.  A typical example of	this sequence appears
	  in the Examples section.

	  The same basic sequence applies when outputting to an	allo-
	  cated	string:	call fmtstrinit	to initialize the Fmt, then
	  call fmtprint	and fmtvprint to generate the output.
	  Finally, fmtstrflush will return the allocated string, which
	  should be freed after	use.  To output	to a rune string, use
	  runefmtstrinit and runefmtstrflush. Regardless of the	output
	  style	or type, fmtprint or fmtvprint generates the charac-
	  ters.

	Custom format verbs
	  Fmtinstall is	used to	install	custom verbs and flags labeled
	  by character c, which	may be any non-zero Unicode character.
	  Fn should be declared	as

	       int   fn(Fmt*)

	  Fp->r	is the flag or verb character to cause fn to be
	  called.  In fn, fp->width, fp->prec are the width and	preci-
	  sion,	and fp->flags the decoded flags	for the	verb (see
	  print(2) for a description of	these items).  The standard
	  flag values are: FmtSign (+),	FmtLeft	(-), FmtSpace (' '),
	  FmtSharp (#),	FmtComma (,), FmtLong (l), FmtShort (h),
	  FmtUnsigned (u), and FmtVLong	(ll).  The flag	bits FmtWidth
	  and FmtPrec identify whether a width and precision were
	  specified.

	  Fn is	passed a pointer to the	Fmt structure recording	the
	  state	of the output.	If fp->r is a verb (rather than	a
	  flag), fn should use Fmt->args to fetch its argument from
	  the list, then format	it, and	return zero.  If fp->r is a
	  flag,	fn should return one.  All interpretation of
	  fp->width, fp->prec, and fp->flags is	left up	to the conver-
	  sion routine.	 Fmtinstall returns 0 if the installation
	  succeeds, -1 if it fails.

	  Fmtprint and fmtvprint may be	called to help prepare output
	  in custom conversion routines.  However, these functions
	  clear	the width, precision, and flags.  Both functions
	  return 0 for success and -1 for failure.

	  The functions	dofmt and dorfmt are the underlying for-
	  matters; they	use the	existing contents of Fmt and should be
	  called only by sophisticated conversion routines.  These
	  routines return the number of	characters (bytes of UTF or
	  runes) produced.

	  Some internal	functions may be useful	to format primitive
	  types.  They honor the width,	precision and flags as
	  described in print(2). Fmtrune formats a single character r.
	  Fmtstrcpy formats a string s;	fmtrunestrcpy formats a	rune
	  string s.  Errfmt formats the	system error string.  All
	  these	routines return	zero for successful execution.
	  Conversion routines that call	these functions	will work
	  properly regardless of whether the output is bytes or	runes.

	  2c(1)	describes the C	directive #pragma varargck that	can be
	  used to provide type-checking	for custom print verbs and
	  output routines.

     EXAMPLES
	  This function	prints an error	message	with a variable	number
	  of arguments and then	quits.	Compared to the	corresponding
	  example in print(2), this version uses a smaller buffer,
	  will never truncate the output message, but might generate
	  multiple write system	calls to produce its output.

	       #pragma	   varargck    argpos	   fatal 1
	       void
	       fatal(char *fmt,	...)
	       {
		     Fmt f;
		     char buf[64];
		     va_list arg;
		     fmtfdinit(&f, 1, buf, sizeof buf);
		     fmtprint(&f, "fatal: ");
		     va_start(arg, fmt);
		     fmtvprint(&f, fmt,	arg);
		     va_end(arg);
		     fmtprint(&f, "\n");
		     fmtfdflush(&f);
		     exits("fatal error");
	       }

	  This example adds a verb to print complex numbers.

	       typedef struct {
		     double	 r, i;
	       } Complex;
	       #pragma	   varargck    type  "X"   Complex
	       int
	       Xfmt(Fmt	*f)
	       {
		     Complex c;
		     c = va_arg(f->args, Complex);
		     return fmtprint(f,	"(%g,%g)", c.r,	c.i);
	       }
	       main(...)
	       {
		     Complex x = (Complex){ 1.5, -2.3 };
		     fmtinstall('X', Xfmt);
		     print("x =	%X\n", x);
	       }

     SOURCE
	  /sys/src/libc/fmt

     SEE ALSO
	  print(2), utf(6), errstr(2)

     DIAGNOSTICS
	  These	routines return	negative numbers or nil	for errors and
	  set errstr.

```
