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