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 */
74 int (*fmtdoquote)(int);
77 * __fmtlock() must be set
80 __fmtinstall(int c, Fmts f)
89 ep = &fmtalloc.fmt[fmtalloc.nfmt];
90 for(p=fmtalloc.fmt; p<ep; p++)
94 if(p == &fmtalloc.fmt[Maxfmt])
98 if(p == ep){ /* installing a new format character */
107 fmtinstall(int c, Fmts f)
112 ret = __fmtinstall(c, f);
122 ep = &fmtalloc.fmt[fmtalloc.nfmt];
123 for(p=fmtalloc.fmt; p<ep; p++)
125 while(p->fmt == nil) /* loop until value is updated */
130 /* is this a predefined format char? */
132 for(p=knownfmt; p->c; p++)
134 __fmtinstall(p->c, p->fmt);
144 __fmtdispatch(Fmt *f, void *fmt, int isrunes)
150 f->width = f->prec = 0;
155 fmt = (Rune*)fmt + 1;
157 fmt = (char*)fmt + chartorune(&rune, (char*)fmt);
165 f->flags |= FmtWidth|FmtPrec;
168 if(!(f->flags & FmtWidth)){
173 case '1': case '2': case '3': case '4':
174 case '5': case '6': case '7': case '8': case '9':
176 while(r >= '0' && r <= '9'){
177 i = i * 10 + r - '0';
180 fmt = (Rune*)fmt + 1;
183 fmt = (char*)fmt + 1;
187 fmt = (Rune*)fmt - 1;
189 fmt = (char*)fmt - 1;
191 if(f->flags & FmtWidth){
195 f->flags |= FmtWidth;
200 i = va_arg(f->args, int);
203 * negative precision =>
204 * ignore the precision.
206 if(f->flags & FmtPrec){
207 f->flags &= ~FmtPrec;