2 * The authors of this software are Rob Pike and Ken Thompson.
3 * Copyright (c) 2002 by Lucent Technologies.
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose without fee is hereby granted, provided that this entire notice
6 * is included in all copies of any software which is or includes a copy
7 * or modification of this software and in all copies of the supporting
8 * documentation for such software.
9 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
10 * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
11 * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
12 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
25 typedef struct Convfmt Convfmt;
29 volatile Fmts fmt; /* for spin lock in fmtfmt; avoids race due to write order */
34 /* lock by calling __fmtlock, __fmtunlock */
39 static Convfmt knownfmt[] = {
46 'C', __runefmt, /* Plan 9 addition */
49 'F', __efgfmt, /* ANSI only */
53 'L', __flagfmt, /* ANSI only */
55 'S', __runesfmt, /* Plan 9 addition */
57 'b', __ifmt, /* Plan 9 addition */
65 'i', __ifmt, /* ANSI only */
83 int (*fmtdoquote)(int);
86 * __fmtlock() must be set
89 __fmtinstall(int c, Fmts f)
98 ep = &fmtalloc.fmt[fmtalloc.nfmt];
99 for(p=fmtalloc.fmt; p<ep; p++)
103 if(p == &fmtalloc.fmt[Maxfmt])
107 if(p == ep){ /* installing a new format character */
116 fmtinstall(int c, int (*f)(Fmt*))
121 ret = __fmtinstall(c, f);
131 ep = &fmtalloc.fmt[fmtalloc.nfmt];
132 for(p=fmtalloc.fmt; p<ep; p++)
134 while(p->fmt == nil) /* loop until value is updated */
139 /* is this a predefined format char? */
141 for(p=knownfmt; p->c; p++)
143 __fmtinstall(p->c, p->fmt);
153 __fmtdispatch(Fmt *f, void *fmt, int isrunes)
159 f->width = f->prec = 0;
164 fmt = (Rune*)fmt + 1;
166 fmt = (char*)fmt + chartorune(&rune, (char*)fmt);
174 f->flags |= FmtWidth|FmtPrec;
177 if(!(f->flags & FmtWidth)){
182 case '1': case '2': case '3': case '4':
183 case '5': case '6': case '7': case '8': case '9':
185 while(r >= '0' && r <= '9'){
186 i = i * 10 + r - '0';
189 fmt = (Rune*)fmt + 1;
192 fmt = (char*)fmt + 1;
196 fmt = (Rune*)fmt - 1;
198 fmt = (char*)fmt - 1;
200 if(f->flags & FmtWidth){
204 f->flags |= FmtWidth;
209 i = va_arg(f->args, int);
212 * negative precision =>
213 * ignore the precision.
215 if(f->flags & FmtPrec){
216 f->flags &= ~FmtPrec;