blob: 13007d2ad7640b2f976a89af7b2f2a1c5c60aa75 [file] [log] [blame]
rsc78e51a82005-01-14 03:45:44 +00001.TH FMTINSTALL 3
2.SH NAME
3fmtinstall, 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 <utf.h>
6.br
7.B #include <fmt.h>
8.PP
9.ft L
10.nf
11.ta \w' 'u +\w' 'u +\w' 'u +\w' 'u +\w' 'u
12typedef struct Fmt Fmt;
13struct 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
28enum{
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
51int fmtfdinit(Fmt *f, int fd, char *buf, int nbuf);
52.PP
53.B
54int fmtfdflush(Fmt *f);
55.PP
56.B
57int fmtstrinit(Fmt *f);
58.PP
59.B
60char* fmtstrflush(Fmt *f);
61.PP
62.B
63int runefmtstrinit(Fmt *f);
64.PP
65.B
66Rune* runefmtstrflush(Fmt *f);
67
68.PP
69.B
70int fmtinstall(int c, int (*fn)(Fmt*));
71.PP
72.B
73int dofmt(Fmt *f, char *fmt);
74.PP
75.B
76int dorfmt(Fmt*, Rune *fmt);
77.PP
78.B
79int fmtprint(Fmt *f, char *fmt, ...);
80.PP
81.B
82int fmtvprint(Fmt *f, char *fmt, va_list v);
83.PP
84.B
85int fmtrune(Fmt *f, int r);
86.PP
87.B
88int fmtstrcpy(Fmt *f, char *s);
89.PP
90.B
91int fmtrunestrcpy(Fmt *f, Rune *s);
92.PP
93.B
94int errfmt(Fmt *f);
95.SH DESCRIPTION
96The interface described here allows the construction of custom
97.IR print (3)
98verbs and output routines.
99In essence, they provide access to the workings of the formatted print code.
100.PP
101The
102.IR print (3)
103suite maintains its state with a data structure called
104.BR Fmt .
105A typical call to
106.IR print (3)
107or its relatives initializes a
108.B Fmt
109structure, passes it to subsidiary routines to process the output,
110and finishes by emitting any saved state recorded in the
111.BR Fmt .
112The details of the
113.B Fmt
114are unimportant to outside users, except insofar as the general
115design influences the interface.
116The
117.B Fmt
118records whether the output is in runes or bytes,
119the verb being processed, its precision and width,
120and buffering parameters.
121Most important, it also records a
122.I flush
123routine that the library will call if a buffer overflows.
124When printing to a file descriptor, the flush routine will
125emit saved characters and reset the buffer; when printing
126to an allocated string, it will resize the string to receive more output.
127The flush routine is nil when printing to fixed-size buffers.
128User code need never provide a flush routine; this is done internally
129by the library.
130.SS Custom output routines
131To write a custom output routine, such as an error handler that
132formats and prints custom error messages, the output sequence can be run
133from outside the library using the routines described here.
134There are two main cases: output to an open file descriptor
135and output to a string.
136.PP
137To write to a file descriptor, call
138.I fmtfdinit
139to initialize the local
140.B Fmt
141structure
142.IR f ,
143giving the file descriptor
144.IR fd ,
145the buffer
146.IR buf ,
147and its size
148.IR nbuf .
149Then call
150.IR fmtprint
151or
152.IR fmtvprint
153to generate the output.
154These behave like
155.B fprint
156(see
157.IR print (3))
158or
159.B vfprint
160except that the characters are buffered until
161.I fmtfdflush
162is called and the return value is either 0 or \-1.
163A typical example of this sequence appears in the Examples section.
164.PP
165The same basic sequence applies when outputting to an allocated string:
166call
167.I fmtstrinit
168to initialize the
169.BR Fmt ,
170then call
171.I fmtprint
172and
173.I fmtvprint
174to generate the output.
175Finally,
176.I fmtstrflush
177will return the allocated string, which should be freed after use.
178To output to a rune string, use
179.I runefmtstrinit
180and
181.IR runefmtstrflush .
182Regardless of the output style or type,
183.I fmtprint
184or
185.I fmtvprint
186generates the characters.
187.SS Custom format verbs
188.I Fmtinstall
189is used to install custom verbs and flags labeled by character
190.IR c ,
191which may be any non-zero Unicode character.
192.I Fn
193should be declared as
194.IP
195.EX
196int fn(Fmt*)
197.EE
198.PP
199.IB Fp ->r
200is the flag or verb character to cause
201.I fn
202to be called.
203In
204.IR fn ,
205.IB fp ->width ,
206.IB fp ->prec
207are the width and precision, and
208.IB fp ->flags
209the decoded flags for the verb (see
210.IR print (3)
211for a description of these items).
212The 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 ),
229and
230.B FmtVLong
231.RB ( ll ).
232The flag bits
233.B FmtWidth
234and
235.B FmtPrec
236identify whether a width and precision were specified.
237.PP
238.I Fn
239is passed a pointer to the
240.B Fmt
241structure recording the state of the output.
242If
243.IB fp ->r
244is a verb (rather than a flag),
245.I fn
246should use
247.B Fmt->args
248to fetch its argument from the list,
249then format it, and return zero.
250If
251.IB fp ->r
252is a flag,
253.I fn
254should return one.
255All interpretation of
256.IB fp ->width\f1,
257.IB fp ->prec\f1,
258and
259.IB fp-> flags
260is left up to the conversion routine.
261.I Fmtinstall
262returns 0 if the installation succeeds, \-1 if it fails.
263.PP
264.IR Fmtprint
265and
266.IR fmtvprint
267may be called to
268help prepare output in custom conversion routines.
269However, these functions clear the width, precision, and flags.
270Both functions return 0 for success and \-1 for failure.
271.PP
272The functions
273.I dofmt
274and
275.I dorfmt
276are the underlying formatters; they
277use the existing contents of
278.B Fmt
279and should be called only by sophisticated conversion routines.
280These routines return the number of characters (bytes of UTF or runes)
281produced.
282.PP
283Some internal functions may be useful to format primitive types.
284They honor the width, precision and flags as described in
285.IR print (3).
286.I Fmtrune
287formats a single character
288.BR r .
289.I Fmtstrcpy
290formats a string
291.BR s ;
292.I fmtrunestrcpy
293formats a rune string
294.BR s .
295.I Errfmt
296formats the system error string.
297All these routines return zero for successful execution.
298Conversion routines that call these functions will work properly
299regardless 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
307This function prints an error message with a variable
308number of arguments and then quits.
309Compared to the corresponding example in
310.IR print (3),
311this version uses a smaller buffer, will never truncate
312the output message, but might generate multiple
313.B write
314system 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
320void 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
337This example adds a verb to print complex numbers.
338.IP
339.EX
340typedef
341struct {
342 double r, i;
343} Complex;
344
345#pragma varargck type "X" Complex
346
347int
348Xfmt(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
356main(...)
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 http://swtch.com/plan9port/unix
366.SH SEE ALSO
367.IR print (3),
368.IR utf (7)
369.SH DIAGNOSTICS
370These routines return negative numbers or nil for errors and set
371.IR errstr .