2 b2cfc4e2 2003-09-30 devnull * The authors of this software are Rob Pike and Ken Thompson.
3 b2cfc4e2 2003-09-30 devnull * Copyright (c) 2002 by Lucent Technologies.
4 b2cfc4e2 2003-09-30 devnull * Permission to use, copy, modify, and distribute this software for any
5 b2cfc4e2 2003-09-30 devnull * purpose without fee is hereby granted, provided that this entire notice
6 b2cfc4e2 2003-09-30 devnull * is included in all copies of any software which is or includes a copy
7 b2cfc4e2 2003-09-30 devnull * or modification of this software and in all copies of the supporting
8 b2cfc4e2 2003-09-30 devnull * documentation for such software.
9 b2cfc4e2 2003-09-30 devnull * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
10 b2cfc4e2 2003-09-30 devnull * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
11 b2cfc4e2 2003-09-30 devnull * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
12 b2cfc4e2 2003-09-30 devnull * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
14 b2cfc4e2 2003-09-30 devnull #include <stdarg.h>
15 b2cfc4e2 2003-09-30 devnull #include <string.h>
16 b2cfc4e2 2003-09-30 devnull #include "utf.h"
17 b2cfc4e2 2003-09-30 devnull #include "fmt.h"
18 b2cfc4e2 2003-09-30 devnull #include "fmtdef.h"
20 b2cfc4e2 2003-09-30 devnull /* format the output into f->to and return the number of characters fmted */
22 b2cfc4e2 2003-09-30 devnull dofmt(Fmt *f, char *fmt)
24 b2cfc4e2 2003-09-30 devnull Rune rune, *rt, *rs;
26 b2cfc4e2 2003-09-30 devnull char *t, *s;
27 b2cfc4e2 2003-09-30 devnull int n, nfmt;
29 b2cfc4e2 2003-09-30 devnull nfmt = f->nfmt;
31 b2cfc4e2 2003-09-30 devnull if(f->runes){
32 b2cfc4e2 2003-09-30 devnull rt = (Rune*)f->to;
33 b2cfc4e2 2003-09-30 devnull rs = (Rune*)f->stop;
34 b2cfc4e2 2003-09-30 devnull while((r = *(uchar*)fmt) && r != '%'){
35 b2cfc4e2 2003-09-30 devnull if(r < Runeself)
38 b2cfc4e2 2003-09-30 devnull fmt += chartorune(&rune, fmt);
39 b2cfc4e2 2003-09-30 devnull r = rune;
41 b2cfc4e2 2003-09-30 devnull FMTRCHAR(f, rt, rs, r);
44 b2cfc4e2 2003-09-30 devnull f->nfmt += rt - (Rune *)f->to;
45 b2cfc4e2 2003-09-30 devnull f->to = rt;
47 b2cfc4e2 2003-09-30 devnull return f->nfmt - nfmt;
48 b2cfc4e2 2003-09-30 devnull f->stop = rs;
50 b2cfc4e2 2003-09-30 devnull t = (char*)f->to;
51 b2cfc4e2 2003-09-30 devnull s = (char*)f->stop;
52 b2cfc4e2 2003-09-30 devnull while((r = *(uchar*)fmt) && r != '%'){
53 b2cfc4e2 2003-09-30 devnull if(r < Runeself){
54 b2cfc4e2 2003-09-30 devnull FMTCHAR(f, t, s, r);
57 b2cfc4e2 2003-09-30 devnull n = chartorune(&rune, fmt);
58 b2cfc4e2 2003-09-30 devnull if(t + n > s){
59 b2cfc4e2 2003-09-30 devnull t = (char*)__fmtflush(f, t, n);
60 b2cfc4e2 2003-09-30 devnull if(t != nil)
61 b2cfc4e2 2003-09-30 devnull s = (char*)f->stop;
63 b2cfc4e2 2003-09-30 devnull return -1;
65 b2cfc4e2 2003-09-30 devnull while(n--)
66 b2cfc4e2 2003-09-30 devnull *t++ = *fmt++;
70 b2cfc4e2 2003-09-30 devnull f->nfmt += t - (char *)f->to;
71 b2cfc4e2 2003-09-30 devnull f->to = t;
73 b2cfc4e2 2003-09-30 devnull return f->nfmt - nfmt;
74 b2cfc4e2 2003-09-30 devnull f->stop = s;
77 b2cfc4e2 2003-09-30 devnull fmt = (char*)__fmtdispatch(f, fmt, 0);
78 b2cfc4e2 2003-09-30 devnull if(fmt == nil)
79 b2cfc4e2 2003-09-30 devnull return -1;
81 b2cfc4e2 2003-09-30 devnull return 0; /* not reached */
85 b2cfc4e2 2003-09-30 devnull __fmtflush(Fmt *f, void *t, int len)
87 b2cfc4e2 2003-09-30 devnull if(f->runes)
88 b2cfc4e2 2003-09-30 devnull f->nfmt += (Rune*)t - (Rune*)f->to;
90 b2cfc4e2 2003-09-30 devnull f->nfmt += (char*)t - (char *)f->to;
91 b2cfc4e2 2003-09-30 devnull f->to = t;
92 b2cfc4e2 2003-09-30 devnull if(f->flush == 0 || (*f->flush)(f) == 0 || (char*)f->to + len > (char*)f->stop){
93 b2cfc4e2 2003-09-30 devnull f->stop = f->to;
94 b2cfc4e2 2003-09-30 devnull return nil;
96 b2cfc4e2 2003-09-30 devnull return f->to;
100 b2cfc4e2 2003-09-30 devnull * put a formatted block of memory sz bytes long of n runes into the output buffer,
101 b2cfc4e2 2003-09-30 devnull * left/right justified in a field of at least f->width charactes
104 b2cfc4e2 2003-09-30 devnull __fmtpad(Fmt *f, int n)
106 b2cfc4e2 2003-09-30 devnull char *t, *s;
109 b2cfc4e2 2003-09-30 devnull t = (char*)f->to;
110 b2cfc4e2 2003-09-30 devnull s = (char*)f->stop;
111 b2cfc4e2 2003-09-30 devnull for(i = 0; i < n; i++)
112 b2cfc4e2 2003-09-30 devnull FMTCHAR(f, t, s, ' ');
113 b2cfc4e2 2003-09-30 devnull f->nfmt += t - (char *)f->to;
114 b2cfc4e2 2003-09-30 devnull f->to = t;
115 b2cfc4e2 2003-09-30 devnull return 0;
119 b2cfc4e2 2003-09-30 devnull __rfmtpad(Fmt *f, int n)
121 b2cfc4e2 2003-09-30 devnull Rune *t, *s;
124 b2cfc4e2 2003-09-30 devnull t = (Rune*)f->to;
125 b2cfc4e2 2003-09-30 devnull s = (Rune*)f->stop;
126 b2cfc4e2 2003-09-30 devnull for(i = 0; i < n; i++)
127 b2cfc4e2 2003-09-30 devnull FMTRCHAR(f, t, s, ' ');
128 b2cfc4e2 2003-09-30 devnull f->nfmt += t - (Rune *)f->to;
129 b2cfc4e2 2003-09-30 devnull f->to = t;
130 b2cfc4e2 2003-09-30 devnull return 0;
134 b2cfc4e2 2003-09-30 devnull __fmtcpy(Fmt *f, const void *vm, int n, int sz)
136 b2cfc4e2 2003-09-30 devnull Rune *rt, *rs, r;
137 b2cfc4e2 2003-09-30 devnull char *t, *s, *m, *me;
138 b2cfc4e2 2003-09-30 devnull ulong fl;
139 b2cfc4e2 2003-09-30 devnull int nc, w;
141 b2cfc4e2 2003-09-30 devnull m = (char*)vm;
142 b2cfc4e2 2003-09-30 devnull me = m + sz;
143 b2cfc4e2 2003-09-30 devnull w = f->width;
144 b2cfc4e2 2003-09-30 devnull fl = f->flags;
145 b2cfc4e2 2003-09-30 devnull if((fl & FmtPrec) && n > f->prec)
146 b2cfc4e2 2003-09-30 devnull n = f->prec;
147 b2cfc4e2 2003-09-30 devnull if(f->runes){
148 b2cfc4e2 2003-09-30 devnull if(!(fl & FmtLeft) && __rfmtpad(f, w - n) < 0)
149 b2cfc4e2 2003-09-30 devnull return -1;
150 b2cfc4e2 2003-09-30 devnull rt = (Rune*)f->to;
151 b2cfc4e2 2003-09-30 devnull rs = (Rune*)f->stop;
152 b2cfc4e2 2003-09-30 devnull for(nc = n; nc > 0; nc--){
153 b2cfc4e2 2003-09-30 devnull r = *(uchar*)m;
154 b2cfc4e2 2003-09-30 devnull if(r < Runeself)
156 b2cfc4e2 2003-09-30 devnull else if((me - m) >= UTFmax || fullrune(m, me-m))
157 b2cfc4e2 2003-09-30 devnull m += chartorune(&r, m);
160 b2cfc4e2 2003-09-30 devnull FMTRCHAR(f, rt, rs, r);
162 b2cfc4e2 2003-09-30 devnull f->nfmt += rt - (Rune *)f->to;
163 b2cfc4e2 2003-09-30 devnull f->to = rt;
164 b2cfc4e2 2003-09-30 devnull if(m < me)
165 b2cfc4e2 2003-09-30 devnull return -1;
166 b2cfc4e2 2003-09-30 devnull if(fl & FmtLeft && __rfmtpad(f, w - n) < 0)
167 b2cfc4e2 2003-09-30 devnull return -1;
169 b2cfc4e2 2003-09-30 devnull if(!(fl & FmtLeft) && __fmtpad(f, w - n) < 0)
170 b2cfc4e2 2003-09-30 devnull return -1;
171 b2cfc4e2 2003-09-30 devnull t = (char*)f->to;
172 b2cfc4e2 2003-09-30 devnull s = (char*)f->stop;
173 b2cfc4e2 2003-09-30 devnull for(nc = n; nc > 0; nc--){
174 b2cfc4e2 2003-09-30 devnull r = *(uchar*)m;
175 b2cfc4e2 2003-09-30 devnull if(r < Runeself)
177 b2cfc4e2 2003-09-30 devnull else if((me - m) >= UTFmax || fullrune(m, me-m))
178 b2cfc4e2 2003-09-30 devnull m += chartorune(&r, m);
181 b2cfc4e2 2003-09-30 devnull FMTRUNE(f, t, s, r);
183 b2cfc4e2 2003-09-30 devnull f->nfmt += t - (char *)f->to;
184 b2cfc4e2 2003-09-30 devnull f->to = t;
185 b2cfc4e2 2003-09-30 devnull if(fl & FmtLeft && __fmtpad(f, w - n) < 0)
186 b2cfc4e2 2003-09-30 devnull return -1;
188 b2cfc4e2 2003-09-30 devnull return 0;
192 b2cfc4e2 2003-09-30 devnull __fmtrcpy(Fmt *f, const void *vm, int n)
194 b2cfc4e2 2003-09-30 devnull Rune r, *m, *me, *rt, *rs;
195 b2cfc4e2 2003-09-30 devnull char *t, *s;
196 b2cfc4e2 2003-09-30 devnull ulong fl;
199 b2cfc4e2 2003-09-30 devnull m = (Rune*)vm;
200 b2cfc4e2 2003-09-30 devnull w = f->width;
201 b2cfc4e2 2003-09-30 devnull fl = f->flags;
202 b2cfc4e2 2003-09-30 devnull if((fl & FmtPrec) && n > f->prec)
203 b2cfc4e2 2003-09-30 devnull n = f->prec;
204 b2cfc4e2 2003-09-30 devnull if(f->runes){
205 b2cfc4e2 2003-09-30 devnull if(!(fl & FmtLeft) && __rfmtpad(f, w - n) < 0)
206 b2cfc4e2 2003-09-30 devnull return -1;
207 b2cfc4e2 2003-09-30 devnull rt = (Rune*)f->to;
208 b2cfc4e2 2003-09-30 devnull rs = (Rune*)f->stop;
209 b2cfc4e2 2003-09-30 devnull for(me = m + n; m < me; m++)
210 b2cfc4e2 2003-09-30 devnull FMTRCHAR(f, rt, rs, *m);
211 b2cfc4e2 2003-09-30 devnull f->nfmt += rt - (Rune *)f->to;
212 b2cfc4e2 2003-09-30 devnull f->to = rt;
213 b2cfc4e2 2003-09-30 devnull if(fl & FmtLeft && __rfmtpad(f, w - n) < 0)
214 b2cfc4e2 2003-09-30 devnull return -1;
216 b2cfc4e2 2003-09-30 devnull if(!(fl & FmtLeft) && __fmtpad(f, w - n) < 0)
217 b2cfc4e2 2003-09-30 devnull return -1;
218 b2cfc4e2 2003-09-30 devnull t = (char*)f->to;
219 b2cfc4e2 2003-09-30 devnull s = (char*)f->stop;
220 b2cfc4e2 2003-09-30 devnull for(me = m + n; m < me; m++){
222 b2cfc4e2 2003-09-30 devnull FMTRUNE(f, t, s, r);
224 b2cfc4e2 2003-09-30 devnull f->nfmt += t - (char *)f->to;
225 b2cfc4e2 2003-09-30 devnull f->to = t;
226 b2cfc4e2 2003-09-30 devnull if(fl & FmtLeft && __fmtpad(f, w - n) < 0)
227 b2cfc4e2 2003-09-30 devnull return -1;
229 b2cfc4e2 2003-09-30 devnull return 0;
232 b2cfc4e2 2003-09-30 devnull /* fmt out one character */
234 b2cfc4e2 2003-09-30 devnull __charfmt(Fmt *f)
236 b2cfc4e2 2003-09-30 devnull char x[1];
238 b2cfc4e2 2003-09-30 devnull x[0] = va_arg(f->args, int);
239 b2cfc4e2 2003-09-30 devnull f->prec = 1;
240 b2cfc4e2 2003-09-30 devnull return __fmtcpy(f, (const char*)x, 1, 1);
243 b2cfc4e2 2003-09-30 devnull /* fmt out one rune */
245 b2cfc4e2 2003-09-30 devnull __runefmt(Fmt *f)
247 b2cfc4e2 2003-09-30 devnull Rune x[1];
249 b2cfc4e2 2003-09-30 devnull x[0] = va_arg(f->args, int);
250 b2cfc4e2 2003-09-30 devnull return __fmtrcpy(f, (const void*)x, 1);
253 b2cfc4e2 2003-09-30 devnull /* public helper routine: fmt out a null terminated string already in hand */
255 b2cfc4e2 2003-09-30 devnull fmtstrcpy(Fmt *f, char *s)
257 b2cfc4e2 2003-09-30 devnull int p, i;
259 b2cfc4e2 2003-09-30 devnull return __fmtcpy(f, "<nil>", 5, 5);
260 b2cfc4e2 2003-09-30 devnull /* if precision is specified, make sure we don't wander off the end */
261 b2cfc4e2 2003-09-30 devnull if(f->flags & FmtPrec){
262 b2cfc4e2 2003-09-30 devnull p = f->prec;
263 b2cfc4e2 2003-09-30 devnull for(i = 0; i < p; i++)
264 b2cfc4e2 2003-09-30 devnull if(s[i] == 0)
266 b2cfc4e2 2003-09-30 devnull return __fmtcpy(f, s, utfnlen(s, i), i); /* BUG?: won't print a partial rune at end */
269 b2cfc4e2 2003-09-30 devnull return __fmtcpy(f, s, utflen(s), strlen(s));
272 b2cfc4e2 2003-09-30 devnull /* fmt out a null terminated utf string */
274 b2cfc4e2 2003-09-30 devnull __strfmt(Fmt *f)
276 b2cfc4e2 2003-09-30 devnull char *s;
278 b2cfc4e2 2003-09-30 devnull s = va_arg(f->args, char *);
279 b2cfc4e2 2003-09-30 devnull return fmtstrcpy(f, s);
282 b2cfc4e2 2003-09-30 devnull /* public helper routine: fmt out a null terminated rune string already in hand */
284 b2cfc4e2 2003-09-30 devnull fmtrunestrcpy(Fmt *f, Rune *s)
286 b2cfc4e2 2003-09-30 devnull Rune *e;
287 b2cfc4e2 2003-09-30 devnull int n, p;
290 b2cfc4e2 2003-09-30 devnull return __fmtcpy(f, "<nil>", 5, 5);
291 b2cfc4e2 2003-09-30 devnull /* if precision is specified, make sure we don't wander off the end */
292 b2cfc4e2 2003-09-30 devnull if(f->flags & FmtPrec){
293 b2cfc4e2 2003-09-30 devnull p = f->prec;
294 b2cfc4e2 2003-09-30 devnull for(n = 0; n < p; n++)
295 b2cfc4e2 2003-09-30 devnull if(s[n] == 0)
298 b2cfc4e2 2003-09-30 devnull for(e = s; *e; e++)
300 b2cfc4e2 2003-09-30 devnull n = e - s;
302 b2cfc4e2 2003-09-30 devnull return __fmtrcpy(f, s, n);
305 b2cfc4e2 2003-09-30 devnull /* fmt out a null terminated rune string */
307 b2cfc4e2 2003-09-30 devnull __runesfmt(Fmt *f)
309 b2cfc4e2 2003-09-30 devnull Rune *s;
311 b2cfc4e2 2003-09-30 devnull s = va_arg(f->args, Rune *);
312 b2cfc4e2 2003-09-30 devnull return fmtrunestrcpy(f, s);
315 b2cfc4e2 2003-09-30 devnull /* fmt a % */
317 b2cfc4e2 2003-09-30 devnull __percentfmt(Fmt *f)
319 b2cfc4e2 2003-09-30 devnull Rune x[1];
321 b2cfc4e2 2003-09-30 devnull x[0] = f->r;
322 b2cfc4e2 2003-09-30 devnull f->prec = 1;
323 b2cfc4e2 2003-09-30 devnull return __fmtrcpy(f, (const void*)x, 1);
326 b2cfc4e2 2003-09-30 devnull /* fmt an integer */
328 b2cfc4e2 2003-09-30 devnull __ifmt(Fmt *f)
330 b2cfc4e2 2003-09-30 devnull char buf[70], *p, *conv;
331 b2cfc4e2 2003-09-30 devnull uvlong vu;
332 b2cfc4e2 2003-09-30 devnull ulong u;
333 b2cfc4e2 2003-09-30 devnull int neg, base, i, n, fl, w, isv;
335 b2cfc4e2 2003-09-30 devnull neg = 0;
336 b2cfc4e2 2003-09-30 devnull fl = f->flags;
337 b2cfc4e2 2003-09-30 devnull isv = 0;
341 b2cfc4e2 2003-09-30 devnull * Unsigned verbs
343 b2cfc4e2 2003-09-30 devnull switch(f->r){
344 b2cfc4e2 2003-09-30 devnull case 'o':
345 b2cfc4e2 2003-09-30 devnull case 'u':
346 b2cfc4e2 2003-09-30 devnull case 'x':
347 b2cfc4e2 2003-09-30 devnull case 'X':
348 b2cfc4e2 2003-09-30 devnull fl |= FmtUnsigned;
351 b2cfc4e2 2003-09-30 devnull if(f->r == 'p'){
352 b2cfc4e2 2003-09-30 devnull u = (ulong)va_arg(f->args, void*);
353 b2cfc4e2 2003-09-30 devnull f->r = 'x';
354 b2cfc4e2 2003-09-30 devnull fl |= FmtUnsigned;
355 b2cfc4e2 2003-09-30 devnull }else if(fl & FmtVLong){
356 b2cfc4e2 2003-09-30 devnull isv = 1;
357 b2cfc4e2 2003-09-30 devnull if(fl & FmtUnsigned)
358 b2cfc4e2 2003-09-30 devnull vu = va_arg(f->args, uvlong);
360 b2cfc4e2 2003-09-30 devnull vu = va_arg(f->args, vlong);
361 b2cfc4e2 2003-09-30 devnull }else if(fl & FmtLong){
362 b2cfc4e2 2003-09-30 devnull if(fl & FmtUnsigned)
363 b2cfc4e2 2003-09-30 devnull u = va_arg(f->args, ulong);
365 b2cfc4e2 2003-09-30 devnull u = va_arg(f->args, long);
366 b2cfc4e2 2003-09-30 devnull }else if(fl & FmtByte){
367 b2cfc4e2 2003-09-30 devnull if(fl & FmtUnsigned)
368 b2cfc4e2 2003-09-30 devnull u = (uchar)va_arg(f->args, int);
370 b2cfc4e2 2003-09-30 devnull u = (char)va_arg(f->args, int);
371 b2cfc4e2 2003-09-30 devnull }else if(fl & FmtShort){
372 b2cfc4e2 2003-09-30 devnull if(fl & FmtUnsigned)
373 b2cfc4e2 2003-09-30 devnull u = (ushort)va_arg(f->args, int);
375 b2cfc4e2 2003-09-30 devnull u = (short)va_arg(f->args, int);
377 b2cfc4e2 2003-09-30 devnull if(fl & FmtUnsigned)
378 b2cfc4e2 2003-09-30 devnull u = va_arg(f->args, uint);
380 b2cfc4e2 2003-09-30 devnull u = va_arg(f->args, int);
382 b2cfc4e2 2003-09-30 devnull conv = "0123456789abcdef";
383 b2cfc4e2 2003-09-30 devnull switch(f->r){
384 b2cfc4e2 2003-09-30 devnull case 'd':
385 b2cfc4e2 2003-09-30 devnull case 'i':
386 b2cfc4e2 2003-09-30 devnull base = 10;
388 b2cfc4e2 2003-09-30 devnull case 'u':
389 b2cfc4e2 2003-09-30 devnull base = 10;
391 b2cfc4e2 2003-09-30 devnull case 'x':
392 b2cfc4e2 2003-09-30 devnull base = 16;
394 b2cfc4e2 2003-09-30 devnull case 'X':
395 b2cfc4e2 2003-09-30 devnull base = 16;
396 b2cfc4e2 2003-09-30 devnull conv = "0123456789ABCDEF";
398 b2cfc4e2 2003-09-30 devnull case 'b':
399 b2cfc4e2 2003-09-30 devnull base = 2;
401 b2cfc4e2 2003-09-30 devnull case 'o':
402 b2cfc4e2 2003-09-30 devnull base = 8;
404 b2cfc4e2 2003-09-30 devnull default:
405 b2cfc4e2 2003-09-30 devnull return -1;
407 b2cfc4e2 2003-09-30 devnull if(!(fl & FmtUnsigned)){
408 b2cfc4e2 2003-09-30 devnull if(isv && (vlong)vu < 0){
409 b2cfc4e2 2003-09-30 devnull vu = -(vlong)vu;
410 b2cfc4e2 2003-09-30 devnull neg = 1;
411 b2cfc4e2 2003-09-30 devnull }else if(!isv && (long)u < 0){
412 b2cfc4e2 2003-09-30 devnull u = -(long)u;
413 b2cfc4e2 2003-09-30 devnull neg = 1;
416 b2cfc4e2 2003-09-30 devnull fl &= ~(FmtSign|FmtSpace); /* no + for unsigned conversions */
418 b2cfc4e2 2003-09-30 devnull p = buf + sizeof buf - 1;
420 b2cfc4e2 2003-09-30 devnull if(isv){
421 b2cfc4e2 2003-09-30 devnull while(vu){
422 b2cfc4e2 2003-09-30 devnull i = vu % base;
423 b2cfc4e2 2003-09-30 devnull vu /= base;
424 b2cfc4e2 2003-09-30 devnull if((fl & FmtComma) && n % 4 == 3){
425 b2cfc4e2 2003-09-30 devnull *p-- = ',';
428 b2cfc4e2 2003-09-30 devnull *p-- = conv[i];
432 b2cfc4e2 2003-09-30 devnull while(u){
433 b2cfc4e2 2003-09-30 devnull i = u % base;
434 b2cfc4e2 2003-09-30 devnull u /= base;
435 b2cfc4e2 2003-09-30 devnull if((fl & FmtComma) && n % 4 == 3){
436 b2cfc4e2 2003-09-30 devnull *p-- = ',';
439 b2cfc4e2 2003-09-30 devnull *p-- = conv[i];
443 b2cfc4e2 2003-09-30 devnull if(n == 0){
444 b2cfc4e2 2003-09-30 devnull if(!(fl & FmtPrec) || f->prec != 0){
445 b2cfc4e2 2003-09-30 devnull *p-- = '0';
448 b2cfc4e2 2003-09-30 devnull fl &= ~FmtSharp;
450 b2cfc4e2 2003-09-30 devnull for(w = f->prec; n < w && p > buf+3; n++)
451 b2cfc4e2 2003-09-30 devnull *p-- = '0';
452 b2cfc4e2 2003-09-30 devnull if(neg || (fl & (FmtSign|FmtSpace)))
454 b2cfc4e2 2003-09-30 devnull if(fl & FmtSharp){
455 b2cfc4e2 2003-09-30 devnull if(base == 16)
457 b2cfc4e2 2003-09-30 devnull else if(base == 8){
458 b2cfc4e2 2003-09-30 devnull if(p[1] == '0')
459 b2cfc4e2 2003-09-30 devnull fl &= ~FmtSharp;
464 b2cfc4e2 2003-09-30 devnull if((fl & FmtZero) && !(fl & (FmtLeft|FmtPrec))){
465 b2cfc4e2 2003-09-30 devnull for(w = f->width; n < w && p > buf+3; n++)
466 b2cfc4e2 2003-09-30 devnull *p-- = '0';
467 b2cfc4e2 2003-09-30 devnull f->width = 0;
469 b2cfc4e2 2003-09-30 devnull if(fl & FmtSharp){
470 b2cfc4e2 2003-09-30 devnull if(base == 16)
471 b2cfc4e2 2003-09-30 devnull *p-- = f->r;
472 b2cfc4e2 2003-09-30 devnull if(base == 16 || base == 8)
473 b2cfc4e2 2003-09-30 devnull *p-- = '0';
476 b2cfc4e2 2003-09-30 devnull *p-- = '-';
477 b2cfc4e2 2003-09-30 devnull else if(fl & FmtSign)
478 b2cfc4e2 2003-09-30 devnull *p-- = '+';
479 b2cfc4e2 2003-09-30 devnull else if(fl & FmtSpace)
480 b2cfc4e2 2003-09-30 devnull *p-- = ' ';
481 b2cfc4e2 2003-09-30 devnull f->flags &= ~FmtPrec;
482 b2cfc4e2 2003-09-30 devnull return __fmtcpy(f, p + 1, n, n);
486 b2cfc4e2 2003-09-30 devnull __countfmt(Fmt *f)
488 b2cfc4e2 2003-09-30 devnull void *p;
489 b2cfc4e2 2003-09-30 devnull ulong fl;
491 b2cfc4e2 2003-09-30 devnull fl = f->flags;
492 b2cfc4e2 2003-09-30 devnull p = va_arg(f->args, void*);
493 b2cfc4e2 2003-09-30 devnull if(fl & FmtVLong){
494 b2cfc4e2 2003-09-30 devnull *(vlong*)p = f->nfmt;
495 b2cfc4e2 2003-09-30 devnull }else if(fl & FmtLong){
496 b2cfc4e2 2003-09-30 devnull *(long*)p = f->nfmt;
497 b2cfc4e2 2003-09-30 devnull }else if(fl & FmtByte){
498 b2cfc4e2 2003-09-30 devnull *(char*)p = f->nfmt;
499 b2cfc4e2 2003-09-30 devnull }else if(fl & FmtShort){
500 b2cfc4e2 2003-09-30 devnull *(short*)p = f->nfmt;
502 b2cfc4e2 2003-09-30 devnull *(int*)p = f->nfmt;
504 b2cfc4e2 2003-09-30 devnull return 0;
508 b2cfc4e2 2003-09-30 devnull __flagfmt(Fmt *f)
510 b2cfc4e2 2003-09-30 devnull switch(f->r){
511 b2cfc4e2 2003-09-30 devnull case ',':
512 b2cfc4e2 2003-09-30 devnull f->flags |= FmtComma;
514 b2cfc4e2 2003-09-30 devnull case '-':
515 b2cfc4e2 2003-09-30 devnull f->flags |= FmtLeft;
517 b2cfc4e2 2003-09-30 devnull case '+':
518 b2cfc4e2 2003-09-30 devnull f->flags |= FmtSign;
520 b2cfc4e2 2003-09-30 devnull case '#':
521 b2cfc4e2 2003-09-30 devnull f->flags |= FmtSharp;
523 b2cfc4e2 2003-09-30 devnull case ' ':
524 b2cfc4e2 2003-09-30 devnull f->flags |= FmtSpace;
526 b2cfc4e2 2003-09-30 devnull case 'u':
527 b2cfc4e2 2003-09-30 devnull f->flags |= FmtUnsigned;
529 b2cfc4e2 2003-09-30 devnull case 'h':
530 b2cfc4e2 2003-09-30 devnull if(f->flags & FmtShort)
531 b2cfc4e2 2003-09-30 devnull f->flags |= FmtByte;
532 b2cfc4e2 2003-09-30 devnull f->flags |= FmtShort;
534 b2cfc4e2 2003-09-30 devnull case 'L':
535 b2cfc4e2 2003-09-30 devnull f->flags |= FmtLDouble;
537 b2cfc4e2 2003-09-30 devnull case 'l':
538 b2cfc4e2 2003-09-30 devnull if(f->flags & FmtLong)
539 b2cfc4e2 2003-09-30 devnull f->flags |= FmtVLong;
540 b2cfc4e2 2003-09-30 devnull f->flags |= FmtLong;
543 b2cfc4e2 2003-09-30 devnull return 1;
546 b2cfc4e2 2003-09-30 devnull /* default error format */
548 b2cfc4e2 2003-09-30 devnull __badfmt(Fmt *f)
550 b2cfc4e2 2003-09-30 devnull char x[3];
552 b2cfc4e2 2003-09-30 devnull x[0] = '%';
553 b2cfc4e2 2003-09-30 devnull x[1] = f->r;
554 b2cfc4e2 2003-09-30 devnull x[2] = '%';
555 b2cfc4e2 2003-09-30 devnull f->prec = 3;
556 b2cfc4e2 2003-09-30 devnull __fmtcpy(f, (const void*)x, 3, 3);
557 b2cfc4e2 2003-09-30 devnull return 0;