plan9port

[fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port # fast
git clone https://src.adamsgaard.dk/plan9port.git # slow
Log | Files | Refs | README | LICENSE Back to index

fmtinstall.3 (7881B)


      1 .TH FMTINSTALL 3
      2 .SH NAME
      3 fmtinstall, dofmt, dorfmt, fmtprint, fmtvprint, fmtrune, fmtstrcpy, fmtrunestrcpy, fmtfdinit, fmtfdflush, fmtstrinit, fmtstrflush, runefmtstrinit, runefmtstrflush, errfmt \- support for user-defined print formats and output routines
      4 .SH SYNOPSIS
      5 .B #include <u.h>
      6 .br
      7 .B #include <libc.h>
      8 .PP
      9 .ft L
     10 .nf
     11 .ta \w'    'u +\w'    'u +\w'    'u +\w'    'u +\w'    'u
     12 typedef struct Fmt	Fmt;
     13 struct Fmt{
     14 	uchar	runes;		/* output buffer is runes or chars? */
     15 	void	*start;		/* of buffer */
     16 	void	*to;		/* current place in the buffer */
     17 	void	*stop;		/* end of the buffer; overwritten if flush fails */
     18 	int		(*flush)(Fmt*);	/* called when to == stop */
     19 	void	*farg;		/* to make flush a closure */
     20 	int		nfmt;		/* num chars formatted so far */
     21 	va_list	args;		/* args passed to dofmt */
     22 	int		r;			/* % format Rune */
     23 	int		width;
     24 	int		prec;
     25 	ulong	flags;
     26 };
     27 
     28 enum{
     29 	FmtWidth	= 1,
     30 	FmtLeft		= FmtWidth << 1,
     31 	FmtPrec		= FmtLeft << 1,
     32 	FmtSharp	= FmtPrec << 1,
     33 	FmtSpace	= FmtSharp << 1,
     34 	FmtSign		= FmtSpace << 1,
     35 	FmtZero		= FmtSign << 1,
     36 	FmtUnsigned	= FmtZero << 1,
     37 	FmtShort	= FmtUnsigned << 1,
     38 	FmtLong		= FmtShort << 1,
     39 	FmtVLong	= FmtLong << 1,
     40 	FmtComma	= FmtVLong << 1,
     41 
     42 	FmtFlag		= FmtComma << 1
     43 };
     44 .fi
     45 .PP
     46 .B
     47 .ta \w'\fLchar* 'u
     48 
     49 .PP
     50 .B
     51 int	fmtfdinit(Fmt *f, int fd, char *buf, int nbuf);
     52 .PP
     53 .B
     54 int	fmtfdflush(Fmt *f);
     55 .PP
     56 .B
     57 int	fmtstrinit(Fmt *f);
     58 .PP
     59 .B
     60 char*	fmtstrflush(Fmt *f);
     61 .PP
     62 .B
     63 int	runefmtstrinit(Fmt *f);
     64 .PP
     65 .B
     66 Rune*	runefmtstrflush(Fmt *f);
     67 
     68 .PP
     69 .B
     70 int	fmtinstall(int c, int (*fn)(Fmt*));
     71 .PP
     72 .B
     73 int	dofmt(Fmt *f, char *fmt);
     74 .PP
     75 .B
     76 int	dorfmt(Fmt*, Rune *fmt);
     77 .PP
     78 .B
     79 int	fmtprint(Fmt *f, char *fmt, ...);
     80 .PP
     81 .B
     82 int	fmtvprint(Fmt *f, char *fmt, va_list v);
     83 .PP
     84 .B
     85 int	fmtrune(Fmt *f, int r);
     86 .PP
     87 .B
     88 int	fmtstrcpy(Fmt *f, char *s);
     89 .PP
     90 .B
     91 int	fmtrunestrcpy(Fmt *f, Rune *s);
     92 .PP
     93 .B
     94 int	errfmt(Fmt *f);
     95 .SH DESCRIPTION
     96 The interface described here allows the construction of custom
     97 .MR print (3)
     98 verbs and output routines.
     99 In essence, they provide access to the workings of the formatted print code.
    100 .PP
    101 The
    102 .MR print (3)
    103 suite maintains its state with a data structure called
    104 .BR Fmt .
    105 A typical call to
    106 .MR print (3)
    107 or its relatives initializes a
    108 .B Fmt
    109 structure, passes it to subsidiary routines to process the output,
    110 and finishes by emitting any saved state recorded in the
    111 .BR Fmt .
    112 The details of the
    113 .B Fmt
    114 are unimportant to outside users, except insofar as the general
    115 design influences the interface.
    116 The
    117 .B Fmt
    118 records whether the output is in runes or bytes,
    119 the verb being processed, its precision and width,
    120 and buffering parameters.
    121 Most important, it also records a
    122 .I flush
    123 routine that the library will call if a buffer overflows.
    124 When printing to a file descriptor, the flush routine will
    125 emit saved characters and reset the buffer; when printing
    126 to an allocated string, it will resize the string to receive more output.
    127 The flush routine is nil when printing to fixed-size buffers.
    128 User code need never provide a flush routine; this is done internally
    129 by the library.
    130 .SS Custom output routines
    131 To write a custom output routine, such as an error handler that
    132 formats and prints custom error messages, the output sequence can be run
    133 from outside the library using the routines described here.
    134 There are two main cases: output to an open file descriptor
    135 and output to a string.
    136 .PP
    137 To write to a file descriptor, call
    138 .I fmtfdinit
    139 to initialize the local
    140 .B Fmt
    141 structure
    142 .IR f ,
    143 giving the file descriptor
    144 .IR fd ,
    145 the buffer
    146 .IR buf ,
    147 and its size
    148 .IR nbuf .
    149 Then call
    150 .IR fmtprint
    151 or
    152 .IR fmtvprint
    153 to generate the output.
    154 These behave like
    155 .B fprint
    156 (see
    157 .MR print (3) )
    158 or
    159 .B vfprint
    160 except that the characters are buffered until
    161 .I fmtfdflush
    162 is called and the return value is either 0 or \-1.
    163 A typical example of this sequence appears in the Examples section.
    164 .PP
    165 The same basic sequence applies when outputting to an allocated string:
    166 call
    167 .I fmtstrinit
    168 to initialize the
    169 .BR Fmt ,
    170 then call
    171 .I fmtprint
    172 and
    173 .I fmtvprint
    174 to generate the output.
    175 Finally,
    176 .I fmtstrflush
    177 will return the allocated string, which should be freed after use.
    178 To output to a rune string, use
    179 .I runefmtstrinit
    180 and
    181 .IR runefmtstrflush .
    182 Regardless of the output style or type,
    183 .I fmtprint
    184 or
    185 .I fmtvprint
    186 generates the characters.
    187 .SS Custom format verbs
    188 .I Fmtinstall
    189 is used to install custom verbs and flags labeled by character
    190 .IR c ,
    191 which may be any non-zero Unicode character.
    192 .I Fn
    193 should be declared as
    194 .IP
    195 .EX
    196 int	fn(Fmt*)
    197 .EE
    198 .PP
    199 .IB Fp ->r
    200 is the flag or verb character to cause
    201 .I fn
    202 to be called.
    203 In
    204 .IR fn ,
    205 .IB fp ->width ,
    206 .IB fp ->prec
    207 are the width and precision, and
    208 .IB fp ->flags
    209 the decoded flags for the verb (see
    210 .MR print (3)
    211 for a description of these items).
    212 The standard flag values are:
    213 .B FmtSign
    214 .RB ( + ),
    215 .B FmtLeft
    216 .RB ( - ),
    217 .B FmtSpace
    218 .RB ( '\ ' ),
    219 .B FmtSharp
    220 .RB ( # ),
    221 .B FmtComma
    222 .RB ( , ),
    223 .B FmtLong
    224 .RB ( l ),
    225 .B FmtShort
    226 .RB ( h ),
    227 .B FmtUnsigned
    228 .RB ( u ),
    229 and
    230 .B FmtVLong
    231 .RB ( ll ).
    232 The flag bits
    233 .B FmtWidth
    234 and
    235 .B FmtPrec
    236 identify whether a width and precision were specified.
    237 .PP
    238 .I Fn
    239 is passed a pointer to the
    240 .B Fmt
    241 structure recording the state of the output.
    242 If
    243 .IB fp ->r
    244 is a verb (rather than a flag),
    245 .I fn
    246 should use 
    247 .B Fmt->args
    248 to fetch its argument from the list,
    249 then format it, and return zero.
    250 If
    251 .IB fp ->r
    252 is a flag,
    253 .I fn
    254 should return one.
    255 All interpretation of
    256 .IB fp ->width\f1,
    257 .IB fp ->prec\f1,
    258 and
    259 .IB fp-> flags
    260 is left up to the conversion routine.
    261 .I Fmtinstall
    262 returns 0 if the installation succeeds, \-1 if it fails.
    263 .PP
    264 .IR Fmtprint
    265 and
    266 .IR fmtvprint
    267 may be called to
    268 help prepare output in custom conversion routines.
    269 However, these functions clear the width, precision, and flags.
    270 Both functions return 0 for success and \-1 for failure.
    271 .PP
    272 The functions
    273 .I dofmt
    274 and
    275 .I dorfmt
    276 are the underlying formatters; they
    277 use the existing contents of
    278 .B Fmt
    279 and should be called only by sophisticated conversion routines.
    280 These routines return the number of characters (bytes of UTF or runes)
    281 produced.
    282 .PP
    283 Some internal functions may be useful to format primitive types.
    284 They honor the width, precision and flags as described in
    285 .MR print (3) .
    286 .I Fmtrune
    287 formats a single character
    288 .BR r .
    289 .I Fmtstrcpy
    290 formats a string
    291 .BR s ;
    292 .I fmtrunestrcpy
    293 formats a rune string
    294 .BR s .
    295 .I Errfmt
    296 formats the system error string.
    297 All these routines return zero for successful execution.
    298 Conversion routines that call these functions will work properly
    299 regardless of whether the output is bytes or runes.
    300 .\" .PP
    301 .\" .IR 2c (1)
    302 .\" describes the C directive
    303 .\" .B #pragma
    304 .\" .B varargck
    305 .\" that can be used to provide type-checking for custom print verbs and output routines.
    306 .SH EXAMPLES
    307 This function prints an error message with a variable
    308 number of arguments and then quits.
    309 Compared to the corresponding example in
    310 .MR print (3) ,
    311 this version uses a smaller buffer, will never truncate
    312 the output message, but might generate multiple
    313 .B write
    314 system calls to produce its output.
    315 .IP
    316 .EX
    317 .ta 6n +6n +6n +6n +6n +6n +6n +6n +6n
    318 #pragma	varargck	argpos	error	1
    319 
    320 void fatal(char *fmt, ...)
    321 {
    322 	Fmt f;
    323 	char buf[64];
    324 	va_list arg;
    325 
    326 	fmtfdinit(&f, 1, buf, sizeof buf);
    327 	fmtprint(&f, "fatal: ");
    328 	va_start(arg, fmt);
    329 	fmtvprint(&f, fmt, arg);
    330 	va_end(arg);
    331 	fmtprint(&f, "\en");
    332 	fmtfdflush(&f);
    333 	exits("fatal error");
    334 }
    335 .EE
    336 .PP
    337 This example adds a verb to print complex numbers.
    338 .IP
    339 .EX
    340 typedef
    341 struct {
    342 	double	r, i;
    343 } Complex;
    344 
    345 #pragma	varargck	type	"X"	Complex
    346 
    347 int
    348 Xfmt(Fmt *f)
    349 {
    350 	Complex c;
    351 
    352 	c = va_arg(f->args, Complex);
    353 	return fmtprint(f, "(%g,%g)", c.r, c.i);
    354 }
    355 
    356 main(...)
    357 {
    358 	Complex x = (Complex){ 1.5, -2.3 };
    359 
    360 	fmtinstall('X', Xfmt);
    361 	print("x = %X\en", x);
    362 }
    363 .EE
    364 .SH SOURCE
    365 .B \*9/src/lib9/fmt
    366 .SH SEE ALSO
    367 .MR print (3) ,
    368 .MR utf (7) ,
    369 .MR errstr (3)
    370 .SH DIAGNOSTICS
    371 These routines return negative numbers or nil for errors and set
    372 .IR errstr .