Blob


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