372 lines · 7.8 KB · Text
RawDownload
.TH FMTINSTALL 2.SH NAMEfmtinstall, dofmt, dorfmt, fmtprint, fmtvprint, fmtrune, fmtstrcpy, fmtrunestrcpy, fmtfdinit, fmtfdflush, fmtstrinit, fmtstrflush, runefmtstrinit, runefmtstrflush, errfmt \- support for user-defined print formats and output routines.SH SYNOPSIS.B #include <u.h>.br.B #include <libc.h>.PP.ft L.nf.ta \w'    'u +\w'    'u +\w'    'u +\w'    'u +\w'    'utypedef 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;};.sp 0.3venum{	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,.sp 0.3v	FmtFlag		= FmtComma << 1};.fi.PP.B.ta \w'\fLchar* 'u.sp 0.3v.PP.Bint	fmtfdinit(Fmt *f, int fd, char *buf, int nbuf);.PP.Bint	fmtfdflush(Fmt *f);.PP.Bint	fmtstrinit(Fmt *f);.PP.Bchar*	fmtstrflush(Fmt *f);.PP.Bint	runefmtstrinit(Fmt *f);.PP.BRune*	runefmtstrflush(Fmt *f);.sp 0.3v.PP.Bint	fmtinstall(int c, int (*fn)(Fmt*));.PP.Bint	dofmt(Fmt *f, char *fmt);.PP.Bint	dorfmt(Fmt*, Rune *fmt);.PP.Bint	fmtprint(Fmt *f, char *fmt, ...);.PP.Bint	fmtvprint(Fmt *f, char *fmt, va_list v);.PP.Bint	fmtrune(Fmt *f, int r);.PP.Bint	fmtstrcpy(Fmt *f, char *s);.PP.Bint	fmtrunestrcpy(Fmt *f, Rune *s);.PP.Bint	errfmt(Fmt *f);.SH DESCRIPTIONThe interface described here allows the construction of custom.IR print (2)verbs and output routines.In essence, they provide access to the workings of the formatted print code..PPThe.IR print (2)suite maintains its state with a data structure called.BR Fmt .A typical call to.IR print (2)or its relatives initializes a.B Fmtstructure, passes it to subsidiary routines to process the output,and finishes by emitting any saved state recorded in the.BR Fmt .The details of the.B Fmtare unimportant to outside users, except insofar as the generaldesign influences the interface.The.B Fmtrecords 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.I flushroutine that the library will call if a buffer overflows.When printing to a file descriptor, the flush routine willemit saved characters and reset the buffer; when printingto 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 internallyby the library..SS Custom output routinesTo write a custom output routine, such as an error handler thatformats and prints custom error messages, the output sequence can be runfrom outside the library using the routines described here.There are two main cases: output to an open file descriptorand output to a string..PPTo write to a file descriptor, call.I fmtfdinitto initialize the local.B Fmtstructure.IR f ,giving the file descriptor.IR fd ,the buffer.IR buf ,and its size.IR nbuf .Then call.IR fmtprintor.IR fmtvprintto generate the output.These behave like.B fprint(see.IR print (2))or.B vfprintexcept that the characters are buffered until.I fmtfdflushis called and the return value is either 0 or \-1.A typical example of this sequence appears in the Examples section..PPThe same basic sequence applies when outputting to an allocated string:call.I fmtstrinitto initialize the.BR Fmt ,then call.I fmtprintand.I fmtvprintto generate the output.Finally,.I fmtstrflushwill return the allocated string, which should be freed after use.To output to a rune string, use.I runefmtstrinitand.IR runefmtstrflush .Regardless of the output style or type,.I fmtprintor.I fmtvprintgenerates the characters..SS Custom format verbs.I Fmtinstallis used to install custom verbs and flags labeled by character.IR c ,which may be any non-zero Unicode character..I Fnshould be declared as.IP.EXint	fn(Fmt*).EE.PP.IB Fp ->ris the flag or verb character to cause.I fnto be called.In.IR fn ,.IB fp ->width ,.IB fp ->precare the width and precision, and.IB fp ->flagsthe decoded flags for the verb (see.IR print (2)for a description of these items).The standard flag values are:.B FmtSign.RB ( + ),.B FmtLeft.RB ( - ),.B FmtSpace.RB ( '\ ' ),.B FmtSharp.RB ( # ),.B FmtComma.RB ( , ),.B FmtLong.RB ( l ),.B FmtShort.RB ( h ),.B FmtUnsigned.RB ( u ),and.B FmtVLong.RB ( ll ).The flag bits.B FmtWidthand.B FmtPrecidentify whether a width and precision were specified..PP.I Fnis passed a pointer to the.B Fmtstructure recording the state of the output.If.IB fp ->ris a verb (rather than a flag),.I fnshould use .B Fmt->argsto fetch its argument from the list,then format it, and return zero.If.IB fp ->ris a flag,.I fnshould return one.All interpretation of.IB fp ->width\f1,.IB fp ->prec\f1,and.IB fp-> flagsis left up to the conversion routine..I Fmtinstallreturns 0 if the installation succeeds, \-1 if it fails..PP.IR Fmtprintand.IR fmtvprintmay be called tohelp 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..PPThe functions.I dofmtand.I dorfmtare the underlying formatters; theyuse the existing contents of.B Fmtand should be called only by sophisticated conversion routines.These routines return the number of characters (bytes of UTF or runes)produced..PPSome internal functions may be useful to format primitive types.They honor the width, precision and flags as described in.IR print (2)..I Fmtruneformats a single character.BR r ..I Fmtstrcpyformats a string.BR s ;.I fmtrunestrcpyformats a rune string.BR s ..I Errfmtformats the system error string.All these routines return zero for successful execution.Conversion routines that call these functions will work properlyregardless of whether the output is bytes or runes..PP.IR 2c (1)describes the C directive.B #pragma.B varargckthat can be used to provide type-checking for custom print verbs and output routines..SH EXAMPLESThis function prints an error message with a variablenumber of arguments and then quits.Compared to the corresponding example in.IR print (2),this version uses a smaller buffer, will never truncatethe output message, but might generate multiple.B writesystem calls to produce its output..IP.EX.ta 6n +6n +6n +6n +6n +6n +6n +6n +6n#pragma	varargck	argpos	fatal	1.sp 0.3vvoidfatal(char *fmt, ...){	Fmt f;	char buf[64];	va_list arg;.sp 0.3v	fmtfdinit(&f, 1, buf, sizeof buf);	fmtprint(&f, "fatal: ");	va_start(arg, fmt);	fmtvprint(&f, fmt, arg);	va_end(arg);	fmtprint(&f, "\en");	fmtfdflush(&f);	exits("fatal error");}.EE.PPThis example adds a verb to print complex numbers..IP.EXtypedef struct {	double	r, i;} Complex;.sp 0.3v#pragma	varargck	type	"X"	Complex.sp 0.3vintXfmt(Fmt *f){	Complex c;.sp 0.3v	c = va_arg(f->args, Complex);	return fmtprint(f, "(%g,%g)", c.r, c.i);}.sp 0.3vmain(...){	Complex x = (Complex){ 1.5, -2.3 };.sp 0.3v	fmtinstall('X', Xfmt);	print("x = %X\en", x);}.EE.SH SOURCE.B /sys/src/libc/fmt.SH SEE ALSO.IR print (2),.IR utf (6),.IR errstr (2).SH DIAGNOSTICSThese routines return negative numbers or nil for errors and set.IR errstr .