Blame


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