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 ANY
11 * 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 */
48 'F', __efgfmt, /* ANSI only */
50 'L', __flagfmt, /* ANSI only */
51 'S', __runesfmt, /* Plan 9 addition */
53 'b', __ifmt, /* Plan 9 addition */
60 'i', __ifmt, /* ANSI only */
67 'u', __flagfmt, /* in Unix, __ifmt */
73 int (*fmtdoquote)(int);
76 * __fmtlock() must be set
79 __fmtinstall(int c, Fmts f)
88 ep = &fmtalloc.fmt[fmtalloc.nfmt];
89 for(p=fmtalloc.fmt; p<ep; p++)
93 if(p == &fmtalloc.fmt[Maxfmt])
97 if(p == ep){ /* installing a new format character */
106 fmtinstall(int c, Fmts f)
111 ret = __fmtinstall(c, f);
121 ep = &fmtalloc.fmt[fmtalloc.nfmt];
122 for(p=fmtalloc.fmt; p<ep; p++)
124 while(p->fmt == nil) /* loop until value is updated */
129 /* is this a predefined format char? */
131 for(p=knownfmt; p->c; p++)
133 __fmtinstall(p->c, p->fmt);
143 __fmtdispatch(Fmt *f, void *fmt, int isrunes)
149 f->width = f->prec = 0;
154 fmt = (Rune*)fmt + 1;
156 fmt = (char*)fmt + chartorune(&rune, (char*)fmt);
164 f->flags |= FmtWidth|FmtPrec;
167 if(!(f->flags & FmtWidth)){
172 case '1': case '2': case '3': case '4':
173 case '5': case '6': case '7': case '8': case '9':
175 while(r >= '0' && r <= '9'){
176 i = i * 10 + r - '0';
179 fmt = (Rune*)fmt + 1;
182 fmt = (char*)fmt + 1;
186 fmt = (Rune*)fmt - 1;
188 fmt = (char*)fmt - 1;
190 if(f->flags & FmtWidth){
194 f->flags |= FmtWidth;
199 i = va_arg(f->args, int);
202 * negative precision =>
203 * ignore the precision.
205 if(f->flags & FmtPrec){
206 f->flags &= ~FmtPrec;