Blame


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