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