Blame


1 91c13e54 2004-02-29 devnull /*
2 91c13e54 2004-02-29 devnull * The authors of this software are Rob Pike and Ken Thompson.
3 91c13e54 2004-02-29 devnull * Copyright (c) 2002 by Lucent Technologies.
4 91c13e54 2004-02-29 devnull * Permission to use, copy, modify, and distribute this software for any
5 91c13e54 2004-02-29 devnull * purpose without fee is hereby granted, provided that this entire notice
6 91c13e54 2004-02-29 devnull * is included in all copies of any software which is or includes a copy
7 91c13e54 2004-02-29 devnull * or modification of this software and in all copies of the supporting
8 91c13e54 2004-02-29 devnull * documentation for such software.
9 91c13e54 2004-02-29 devnull * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
10 c90dd38f 2004-12-29 devnull * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
11 c90dd38f 2004-12-29 devnull * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
12 91c13e54 2004-02-29 devnull * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
13 91c13e54 2004-02-29 devnull */
14 91c13e54 2004-02-29 devnull #include <stdarg.h>
15 91c13e54 2004-02-29 devnull #include <string.h>
16 e5aa96ac 2004-12-26 devnull #include "plan9.h"
17 91c13e54 2004-02-29 devnull #include "fmt.h"
18 91c13e54 2004-02-29 devnull #include "fmtdef.h"
19 91c13e54 2004-02-29 devnull
20 91c13e54 2004-02-29 devnull /* format the output into f->to and return the number of characters fmted */
21 91c13e54 2004-02-29 devnull int
22 91c13e54 2004-02-29 devnull dofmt(Fmt *f, char *fmt)
23 91c13e54 2004-02-29 devnull {
24 91c13e54 2004-02-29 devnull Rune rune, *rt, *rs;
25 91c13e54 2004-02-29 devnull int r;
26 91c13e54 2004-02-29 devnull char *t, *s;
27 91c13e54 2004-02-29 devnull int n, nfmt;
28 91c13e54 2004-02-29 devnull
29 91c13e54 2004-02-29 devnull nfmt = f->nfmt;
30 91c13e54 2004-02-29 devnull for(;;){
31 91c13e54 2004-02-29 devnull if(f->runes){
32 91c13e54 2004-02-29 devnull rt = (Rune*)f->to;
33 91c13e54 2004-02-29 devnull rs = (Rune*)f->stop;
34 91c13e54 2004-02-29 devnull while((r = *(uchar*)fmt) && r != '%'){
35 91c13e54 2004-02-29 devnull if(r < Runeself)
36 91c13e54 2004-02-29 devnull fmt++;
37 91c13e54 2004-02-29 devnull else{
38 91c13e54 2004-02-29 devnull fmt += chartorune(&rune, fmt);
39 91c13e54 2004-02-29 devnull r = rune;
40 91c13e54 2004-02-29 devnull }
41 91c13e54 2004-02-29 devnull FMTRCHAR(f, rt, rs, r);
42 91c13e54 2004-02-29 devnull }
43 91c13e54 2004-02-29 devnull fmt++;
44 91c13e54 2004-02-29 devnull f->nfmt += rt - (Rune *)f->to;
45 91c13e54 2004-02-29 devnull f->to = rt;
46 91c13e54 2004-02-29 devnull if(!r)
47 91c13e54 2004-02-29 devnull return f->nfmt - nfmt;
48 91c13e54 2004-02-29 devnull f->stop = rs;
49 91c13e54 2004-02-29 devnull }else{
50 91c13e54 2004-02-29 devnull t = (char*)f->to;
51 91c13e54 2004-02-29 devnull s = (char*)f->stop;
52 91c13e54 2004-02-29 devnull while((r = *(uchar*)fmt) && r != '%'){
53 91c13e54 2004-02-29 devnull if(r < Runeself){
54 91c13e54 2004-02-29 devnull FMTCHAR(f, t, s, r);
55 91c13e54 2004-02-29 devnull fmt++;
56 91c13e54 2004-02-29 devnull }else{
57 91c13e54 2004-02-29 devnull n = chartorune(&rune, fmt);
58 91c13e54 2004-02-29 devnull if(t + n > s){
59 91c13e54 2004-02-29 devnull t = (char*)__fmtflush(f, t, n);
60 91c13e54 2004-02-29 devnull if(t != nil)
61 91c13e54 2004-02-29 devnull s = (char*)f->stop;
62 91c13e54 2004-02-29 devnull else
63 91c13e54 2004-02-29 devnull return -1;
64 91c13e54 2004-02-29 devnull }
65 91c13e54 2004-02-29 devnull while(n--)
66 91c13e54 2004-02-29 devnull *t++ = *fmt++;
67 91c13e54 2004-02-29 devnull }
68 91c13e54 2004-02-29 devnull }
69 91c13e54 2004-02-29 devnull fmt++;
70 91c13e54 2004-02-29 devnull f->nfmt += t - (char *)f->to;
71 91c13e54 2004-02-29 devnull f->to = t;
72 91c13e54 2004-02-29 devnull if(!r)
73 91c13e54 2004-02-29 devnull return f->nfmt - nfmt;
74 91c13e54 2004-02-29 devnull f->stop = s;
75 91c13e54 2004-02-29 devnull }
76 91c13e54 2004-02-29 devnull
77 91c13e54 2004-02-29 devnull fmt = (char*)__fmtdispatch(f, fmt, 0);
78 91c13e54 2004-02-29 devnull if(fmt == nil)
79 91c13e54 2004-02-29 devnull return -1;
80 91c13e54 2004-02-29 devnull }
81 91c13e54 2004-02-29 devnull return 0; /* not reached */
82 91c13e54 2004-02-29 devnull }
83 91c13e54 2004-02-29 devnull
84 91c13e54 2004-02-29 devnull void *
85 91c13e54 2004-02-29 devnull __fmtflush(Fmt *f, void *t, int len)
86 91c13e54 2004-02-29 devnull {
87 91c13e54 2004-02-29 devnull if(f->runes)
88 91c13e54 2004-02-29 devnull f->nfmt += (Rune*)t - (Rune*)f->to;
89 91c13e54 2004-02-29 devnull else
90 91c13e54 2004-02-29 devnull f->nfmt += (char*)t - (char *)f->to;
91 91c13e54 2004-02-29 devnull f->to = t;
92 91c13e54 2004-02-29 devnull if(f->flush == 0 || (*f->flush)(f) == 0 || (char*)f->to + len > (char*)f->stop){
93 91c13e54 2004-02-29 devnull f->stop = f->to;
94 91c13e54 2004-02-29 devnull return nil;
95 91c13e54 2004-02-29 devnull }
96 91c13e54 2004-02-29 devnull return f->to;
97 91c13e54 2004-02-29 devnull }
98 91c13e54 2004-02-29 devnull
99 91c13e54 2004-02-29 devnull /*
100 91c13e54 2004-02-29 devnull * put a formatted block of memory sz bytes long of n runes into the output buffer,
101 91c13e54 2004-02-29 devnull * left/right justified in a field of at least f->width charactes
102 91c13e54 2004-02-29 devnull */
103 91c13e54 2004-02-29 devnull int
104 91c13e54 2004-02-29 devnull __fmtpad(Fmt *f, int n)
105 91c13e54 2004-02-29 devnull {
106 91c13e54 2004-02-29 devnull char *t, *s;
107 91c13e54 2004-02-29 devnull int i;
108 91c13e54 2004-02-29 devnull
109 91c13e54 2004-02-29 devnull t = (char*)f->to;
110 91c13e54 2004-02-29 devnull s = (char*)f->stop;
111 91c13e54 2004-02-29 devnull for(i = 0; i < n; i++)
112 91c13e54 2004-02-29 devnull FMTCHAR(f, t, s, ' ');
113 91c13e54 2004-02-29 devnull f->nfmt += t - (char *)f->to;
114 91c13e54 2004-02-29 devnull f->to = t;
115 91c13e54 2004-02-29 devnull return 0;
116 91c13e54 2004-02-29 devnull }
117 91c13e54 2004-02-29 devnull
118 91c13e54 2004-02-29 devnull int
119 91c13e54 2004-02-29 devnull __rfmtpad(Fmt *f, int n)
120 91c13e54 2004-02-29 devnull {
121 91c13e54 2004-02-29 devnull Rune *t, *s;
122 91c13e54 2004-02-29 devnull int i;
123 91c13e54 2004-02-29 devnull
124 91c13e54 2004-02-29 devnull t = (Rune*)f->to;
125 91c13e54 2004-02-29 devnull s = (Rune*)f->stop;
126 91c13e54 2004-02-29 devnull for(i = 0; i < n; i++)
127 91c13e54 2004-02-29 devnull FMTRCHAR(f, t, s, ' ');
128 91c13e54 2004-02-29 devnull f->nfmt += t - (Rune *)f->to;
129 91c13e54 2004-02-29 devnull f->to = t;
130 91c13e54 2004-02-29 devnull return 0;
131 91c13e54 2004-02-29 devnull }
132 91c13e54 2004-02-29 devnull
133 91c13e54 2004-02-29 devnull int
134 91c13e54 2004-02-29 devnull __fmtcpy(Fmt *f, const void *vm, int n, int sz)
135 91c13e54 2004-02-29 devnull {
136 91c13e54 2004-02-29 devnull Rune *rt, *rs, r;
137 91c13e54 2004-02-29 devnull char *t, *s, *m, *me;
138 91c13e54 2004-02-29 devnull ulong fl;
139 91c13e54 2004-02-29 devnull int nc, w;
140 91c13e54 2004-02-29 devnull
141 91c13e54 2004-02-29 devnull m = (char*)vm;
142 91c13e54 2004-02-29 devnull me = m + sz;
143 91c13e54 2004-02-29 devnull w = f->width;
144 91c13e54 2004-02-29 devnull fl = f->flags;
145 91c13e54 2004-02-29 devnull if((fl & FmtPrec) && n > f->prec)
146 91c13e54 2004-02-29 devnull n = f->prec;
147 91c13e54 2004-02-29 devnull if(f->runes){
148 91c13e54 2004-02-29 devnull if(!(fl & FmtLeft) && __rfmtpad(f, w - n) < 0)
149 91c13e54 2004-02-29 devnull return -1;
150 91c13e54 2004-02-29 devnull rt = (Rune*)f->to;
151 91c13e54 2004-02-29 devnull rs = (Rune*)f->stop;
152 91c13e54 2004-02-29 devnull for(nc = n; nc > 0; nc--){
153 91c13e54 2004-02-29 devnull r = *(uchar*)m;
154 91c13e54 2004-02-29 devnull if(r < Runeself)
155 91c13e54 2004-02-29 devnull m++;
156 91c13e54 2004-02-29 devnull else if((me - m) >= UTFmax || fullrune(m, me-m))
157 91c13e54 2004-02-29 devnull m += chartorune(&r, m);
158 91c13e54 2004-02-29 devnull else
159 91c13e54 2004-02-29 devnull break;
160 91c13e54 2004-02-29 devnull FMTRCHAR(f, rt, rs, r);
161 91c13e54 2004-02-29 devnull }
162 91c13e54 2004-02-29 devnull f->nfmt += rt - (Rune *)f->to;
163 91c13e54 2004-02-29 devnull f->to = rt;
164 91c13e54 2004-02-29 devnull if(fl & FmtLeft && __rfmtpad(f, w - n) < 0)
165 91c13e54 2004-02-29 devnull return -1;
166 91c13e54 2004-02-29 devnull }else{
167 91c13e54 2004-02-29 devnull if(!(fl & FmtLeft) && __fmtpad(f, w - n) < 0)
168 91c13e54 2004-02-29 devnull return -1;
169 91c13e54 2004-02-29 devnull t = (char*)f->to;
170 91c13e54 2004-02-29 devnull s = (char*)f->stop;
171 91c13e54 2004-02-29 devnull for(nc = n; nc > 0; nc--){
172 91c13e54 2004-02-29 devnull r = *(uchar*)m;
173 91c13e54 2004-02-29 devnull if(r < Runeself)
174 91c13e54 2004-02-29 devnull m++;
175 91c13e54 2004-02-29 devnull else if((me - m) >= UTFmax || fullrune(m, me-m))
176 91c13e54 2004-02-29 devnull m += chartorune(&r, m);
177 91c13e54 2004-02-29 devnull else
178 91c13e54 2004-02-29 devnull break;
179 91c13e54 2004-02-29 devnull FMTRUNE(f, t, s, r);
180 91c13e54 2004-02-29 devnull }
181 91c13e54 2004-02-29 devnull f->nfmt += t - (char *)f->to;
182 91c13e54 2004-02-29 devnull f->to = t;
183 91c13e54 2004-02-29 devnull if(fl & FmtLeft && __fmtpad(f, w - n) < 0)
184 91c13e54 2004-02-29 devnull return -1;
185 91c13e54 2004-02-29 devnull }
186 91c13e54 2004-02-29 devnull return 0;
187 91c13e54 2004-02-29 devnull }
188 91c13e54 2004-02-29 devnull
189 91c13e54 2004-02-29 devnull int
190 91c13e54 2004-02-29 devnull __fmtrcpy(Fmt *f, const void *vm, int n)
191 91c13e54 2004-02-29 devnull {
192 91c13e54 2004-02-29 devnull Rune r, *m, *me, *rt, *rs;
193 91c13e54 2004-02-29 devnull char *t, *s;
194 91c13e54 2004-02-29 devnull ulong fl;
195 91c13e54 2004-02-29 devnull int w;
196 91c13e54 2004-02-29 devnull
197 91c13e54 2004-02-29 devnull m = (Rune*)vm;
198 91c13e54 2004-02-29 devnull w = f->width;
199 91c13e54 2004-02-29 devnull fl = f->flags;
200 91c13e54 2004-02-29 devnull if((fl & FmtPrec) && n > f->prec)
201 91c13e54 2004-02-29 devnull n = f->prec;
202 91c13e54 2004-02-29 devnull if(f->runes){
203 91c13e54 2004-02-29 devnull if(!(fl & FmtLeft) && __rfmtpad(f, w - n) < 0)
204 91c13e54 2004-02-29 devnull return -1;
205 91c13e54 2004-02-29 devnull rt = (Rune*)f->to;
206 91c13e54 2004-02-29 devnull rs = (Rune*)f->stop;
207 91c13e54 2004-02-29 devnull for(me = m + n; m < me; m++)
208 91c13e54 2004-02-29 devnull FMTRCHAR(f, rt, rs, *m);
209 91c13e54 2004-02-29 devnull f->nfmt += rt - (Rune *)f->to;
210 91c13e54 2004-02-29 devnull f->to = rt;
211 91c13e54 2004-02-29 devnull if(fl & FmtLeft && __rfmtpad(f, w - n) < 0)
212 91c13e54 2004-02-29 devnull return -1;
213 91c13e54 2004-02-29 devnull }else{
214 91c13e54 2004-02-29 devnull if(!(fl & FmtLeft) && __fmtpad(f, w - n) < 0)
215 91c13e54 2004-02-29 devnull return -1;
216 91c13e54 2004-02-29 devnull t = (char*)f->to;
217 91c13e54 2004-02-29 devnull s = (char*)f->stop;
218 91c13e54 2004-02-29 devnull for(me = m + n; m < me; m++){
219 91c13e54 2004-02-29 devnull r = *m;
220 91c13e54 2004-02-29 devnull FMTRUNE(f, t, s, r);
221 91c13e54 2004-02-29 devnull }
222 91c13e54 2004-02-29 devnull f->nfmt += t - (char *)f->to;
223 91c13e54 2004-02-29 devnull f->to = t;
224 91c13e54 2004-02-29 devnull if(fl & FmtLeft && __fmtpad(f, w - n) < 0)
225 91c13e54 2004-02-29 devnull return -1;
226 91c13e54 2004-02-29 devnull }
227 91c13e54 2004-02-29 devnull return 0;
228 91c13e54 2004-02-29 devnull }
229 91c13e54 2004-02-29 devnull
230 91c13e54 2004-02-29 devnull /* fmt out one character */
231 91c13e54 2004-02-29 devnull int
232 91c13e54 2004-02-29 devnull __charfmt(Fmt *f)
233 91c13e54 2004-02-29 devnull {
234 91c13e54 2004-02-29 devnull char x[1];
235 91c13e54 2004-02-29 devnull
236 91c13e54 2004-02-29 devnull x[0] = va_arg(f->args, int);
237 91c13e54 2004-02-29 devnull f->prec = 1;
238 91c13e54 2004-02-29 devnull return __fmtcpy(f, (const char*)x, 1, 1);
239 91c13e54 2004-02-29 devnull }
240 91c13e54 2004-02-29 devnull
241 91c13e54 2004-02-29 devnull /* fmt out one rune */
242 91c13e54 2004-02-29 devnull int
243 91c13e54 2004-02-29 devnull __runefmt(Fmt *f)
244 91c13e54 2004-02-29 devnull {
245 91c13e54 2004-02-29 devnull Rune x[1];
246 91c13e54 2004-02-29 devnull
247 91c13e54 2004-02-29 devnull x[0] = va_arg(f->args, int);
248 91c13e54 2004-02-29 devnull return __fmtrcpy(f, (const void*)x, 1);
249 91c13e54 2004-02-29 devnull }
250 91c13e54 2004-02-29 devnull
251 91c13e54 2004-02-29 devnull /* public helper routine: fmt out a null terminated string already in hand */
252 91c13e54 2004-02-29 devnull int
253 91c13e54 2004-02-29 devnull fmtstrcpy(Fmt *f, char *s)
254 91c13e54 2004-02-29 devnull {
255 3f1a2197 2004-12-26 devnull int i, j;
256 3f1a2197 2004-12-26 devnull Rune r;
257 3f1a2197 2004-12-26 devnull
258 91c13e54 2004-02-29 devnull if(!s)
259 91c13e54 2004-02-29 devnull return __fmtcpy(f, "<nil>", 5, 5);
260 91c13e54 2004-02-29 devnull /* if precision is specified, make sure we don't wander off the end */
261 91c13e54 2004-02-29 devnull if(f->flags & FmtPrec){
262 3f1a2197 2004-12-26 devnull i = 0;
263 3f1a2197 2004-12-26 devnull for(j=0; j<f->prec && s[i]; j++)
264 3f1a2197 2004-12-26 devnull i += chartorune(&r, s+i);
265 3f1a2197 2004-12-26 devnull return __fmtcpy(f, s, j, i);
266 91c13e54 2004-02-29 devnull }
267 91c13e54 2004-02-29 devnull return __fmtcpy(f, s, utflen(s), strlen(s));
268 91c13e54 2004-02-29 devnull }
269 91c13e54 2004-02-29 devnull
270 91c13e54 2004-02-29 devnull /* fmt out a null terminated utf string */
271 91c13e54 2004-02-29 devnull int
272 91c13e54 2004-02-29 devnull __strfmt(Fmt *f)
273 91c13e54 2004-02-29 devnull {
274 91c13e54 2004-02-29 devnull char *s;
275 91c13e54 2004-02-29 devnull
276 91c13e54 2004-02-29 devnull s = va_arg(f->args, char *);
277 91c13e54 2004-02-29 devnull return fmtstrcpy(f, s);
278 91c13e54 2004-02-29 devnull }
279 91c13e54 2004-02-29 devnull
280 91c13e54 2004-02-29 devnull /* public helper routine: fmt out a null terminated rune string already in hand */
281 91c13e54 2004-02-29 devnull int
282 91c13e54 2004-02-29 devnull fmtrunestrcpy(Fmt *f, Rune *s)
283 91c13e54 2004-02-29 devnull {
284 91c13e54 2004-02-29 devnull Rune *e;
285 91c13e54 2004-02-29 devnull int n, p;
286 91c13e54 2004-02-29 devnull
287 91c13e54 2004-02-29 devnull if(!s)
288 91c13e54 2004-02-29 devnull return __fmtcpy(f, "<nil>", 5, 5);
289 91c13e54 2004-02-29 devnull /* if precision is specified, make sure we don't wander off the end */
290 91c13e54 2004-02-29 devnull if(f->flags & FmtPrec){
291 91c13e54 2004-02-29 devnull p = f->prec;
292 91c13e54 2004-02-29 devnull for(n = 0; n < p; n++)
293 91c13e54 2004-02-29 devnull if(s[n] == 0)
294 91c13e54 2004-02-29 devnull break;
295 91c13e54 2004-02-29 devnull }else{
296 91c13e54 2004-02-29 devnull for(e = s; *e; e++)
297 91c13e54 2004-02-29 devnull ;
298 91c13e54 2004-02-29 devnull n = e - s;
299 91c13e54 2004-02-29 devnull }
300 91c13e54 2004-02-29 devnull return __fmtrcpy(f, s, n);
301 91c13e54 2004-02-29 devnull }
302 91c13e54 2004-02-29 devnull
303 91c13e54 2004-02-29 devnull /* fmt out a null terminated rune string */
304 91c13e54 2004-02-29 devnull int
305 91c13e54 2004-02-29 devnull __runesfmt(Fmt *f)
306 91c13e54 2004-02-29 devnull {
307 91c13e54 2004-02-29 devnull Rune *s;
308 91c13e54 2004-02-29 devnull
309 91c13e54 2004-02-29 devnull s = va_arg(f->args, Rune *);
310 91c13e54 2004-02-29 devnull return fmtrunestrcpy(f, s);
311 91c13e54 2004-02-29 devnull }
312 91c13e54 2004-02-29 devnull
313 91c13e54 2004-02-29 devnull /* fmt a % */
314 91c13e54 2004-02-29 devnull int
315 91c13e54 2004-02-29 devnull __percentfmt(Fmt *f)
316 91c13e54 2004-02-29 devnull {
317 91c13e54 2004-02-29 devnull Rune x[1];
318 91c13e54 2004-02-29 devnull
319 91c13e54 2004-02-29 devnull x[0] = f->r;
320 91c13e54 2004-02-29 devnull f->prec = 1;
321 91c13e54 2004-02-29 devnull return __fmtrcpy(f, (const void*)x, 1);
322 91c13e54 2004-02-29 devnull }
323 91c13e54 2004-02-29 devnull
324 91c13e54 2004-02-29 devnull /* fmt an integer */
325 91c13e54 2004-02-29 devnull int
326 91c13e54 2004-02-29 devnull __ifmt(Fmt *f)
327 91c13e54 2004-02-29 devnull {
328 91c13e54 2004-02-29 devnull char buf[70], *p, *conv;
329 91c13e54 2004-02-29 devnull uvlong vu;
330 91c13e54 2004-02-29 devnull ulong u;
331 91c13e54 2004-02-29 devnull int neg, base, i, n, fl, w, isv;
332 91c13e54 2004-02-29 devnull
333 91c13e54 2004-02-29 devnull neg = 0;
334 91c13e54 2004-02-29 devnull fl = f->flags;
335 91c13e54 2004-02-29 devnull isv = 0;
336 91c13e54 2004-02-29 devnull vu = 0;
337 91c13e54 2004-02-29 devnull u = 0;
338 3f1a2197 2004-12-26 devnull #ifndef PLAN9PORT
339 91c13e54 2004-02-29 devnull /*
340 3f1a2197 2004-12-26 devnull * Unsigned verbs for ANSI C
341 91c13e54 2004-02-29 devnull */
342 91c13e54 2004-02-29 devnull switch(f->r){
343 91c13e54 2004-02-29 devnull case 'x':
344 91c13e54 2004-02-29 devnull case 'X':
345 e5aa96ac 2004-12-26 devnull case 'o':
346 e5aa96ac 2004-12-26 devnull case 'u':
347 3f1a2197 2004-12-26 devnull case 'p':
348 91c13e54 2004-02-29 devnull fl |= FmtUnsigned;
349 3f1a2197 2004-12-26 devnull fl &= ~(FmtSign|FmtSpace);
350 91c13e54 2004-02-29 devnull break;
351 91c13e54 2004-02-29 devnull }
352 3f1a2197 2004-12-26 devnull #endif
353 91c13e54 2004-02-29 devnull if(f->r == 'p'){
354 91c13e54 2004-02-29 devnull u = (ulong)va_arg(f->args, void*);
355 91c13e54 2004-02-29 devnull f->r = 'x';
356 91c13e54 2004-02-29 devnull fl |= FmtUnsigned;
357 91c13e54 2004-02-29 devnull }else if(fl & FmtVLong){
358 91c13e54 2004-02-29 devnull isv = 1;
359 91c13e54 2004-02-29 devnull if(fl & FmtUnsigned)
360 91c13e54 2004-02-29 devnull vu = va_arg(f->args, uvlong);
361 91c13e54 2004-02-29 devnull else
362 91c13e54 2004-02-29 devnull vu = va_arg(f->args, vlong);
363 91c13e54 2004-02-29 devnull }else if(fl & FmtLong){
364 91c13e54 2004-02-29 devnull if(fl & FmtUnsigned)
365 91c13e54 2004-02-29 devnull u = va_arg(f->args, ulong);
366 91c13e54 2004-02-29 devnull else
367 91c13e54 2004-02-29 devnull u = va_arg(f->args, long);
368 91c13e54 2004-02-29 devnull }else if(fl & FmtByte){
369 91c13e54 2004-02-29 devnull if(fl & FmtUnsigned)
370 91c13e54 2004-02-29 devnull u = (uchar)va_arg(f->args, int);
371 91c13e54 2004-02-29 devnull else
372 91c13e54 2004-02-29 devnull u = (char)va_arg(f->args, int);
373 91c13e54 2004-02-29 devnull }else if(fl & FmtShort){
374 91c13e54 2004-02-29 devnull if(fl & FmtUnsigned)
375 91c13e54 2004-02-29 devnull u = (ushort)va_arg(f->args, int);
376 91c13e54 2004-02-29 devnull else
377 91c13e54 2004-02-29 devnull u = (short)va_arg(f->args, int);
378 91c13e54 2004-02-29 devnull }else{
379 91c13e54 2004-02-29 devnull if(fl & FmtUnsigned)
380 91c13e54 2004-02-29 devnull u = va_arg(f->args, uint);
381 91c13e54 2004-02-29 devnull else
382 91c13e54 2004-02-29 devnull u = va_arg(f->args, int);
383 91c13e54 2004-02-29 devnull }
384 91c13e54 2004-02-29 devnull conv = "0123456789abcdef";
385 91c13e54 2004-02-29 devnull switch(f->r){
386 91c13e54 2004-02-29 devnull case 'd':
387 91c13e54 2004-02-29 devnull case 'i':
388 91c13e54 2004-02-29 devnull case 'u':
389 91c13e54 2004-02-29 devnull base = 10;
390 91c13e54 2004-02-29 devnull break;
391 91c13e54 2004-02-29 devnull case 'x':
392 91c13e54 2004-02-29 devnull base = 16;
393 91c13e54 2004-02-29 devnull break;
394 91c13e54 2004-02-29 devnull case 'X':
395 91c13e54 2004-02-29 devnull base = 16;
396 91c13e54 2004-02-29 devnull conv = "0123456789ABCDEF";
397 91c13e54 2004-02-29 devnull break;
398 91c13e54 2004-02-29 devnull case 'b':
399 91c13e54 2004-02-29 devnull base = 2;
400 91c13e54 2004-02-29 devnull break;
401 91c13e54 2004-02-29 devnull case 'o':
402 91c13e54 2004-02-29 devnull base = 8;
403 91c13e54 2004-02-29 devnull break;
404 91c13e54 2004-02-29 devnull default:
405 91c13e54 2004-02-29 devnull return -1;
406 91c13e54 2004-02-29 devnull }
407 3f1a2197 2004-12-26 devnull if(!(fl & FmtUnsigned)){
408 91c13e54 2004-02-29 devnull if(isv && (vlong)vu < 0){
409 91c13e54 2004-02-29 devnull vu = -(vlong)vu;
410 91c13e54 2004-02-29 devnull neg = 1;
411 91c13e54 2004-02-29 devnull }else if(!isv && (long)u < 0){
412 91c13e54 2004-02-29 devnull u = -(long)u;
413 91c13e54 2004-02-29 devnull neg = 1;
414 91c13e54 2004-02-29 devnull }
415 91c13e54 2004-02-29 devnull }
416 91c13e54 2004-02-29 devnull p = buf + sizeof buf - 1;
417 91c13e54 2004-02-29 devnull n = 0;
418 91c13e54 2004-02-29 devnull if(isv){
419 91c13e54 2004-02-29 devnull while(vu){
420 91c13e54 2004-02-29 devnull i = vu % base;
421 91c13e54 2004-02-29 devnull vu /= base;
422 91c13e54 2004-02-29 devnull if((fl & FmtComma) && n % 4 == 3){
423 91c13e54 2004-02-29 devnull *p-- = ',';
424 91c13e54 2004-02-29 devnull n++;
425 91c13e54 2004-02-29 devnull }
426 91c13e54 2004-02-29 devnull *p-- = conv[i];
427 91c13e54 2004-02-29 devnull n++;
428 91c13e54 2004-02-29 devnull }
429 91c13e54 2004-02-29 devnull }else{
430 91c13e54 2004-02-29 devnull while(u){
431 91c13e54 2004-02-29 devnull i = u % base;
432 91c13e54 2004-02-29 devnull u /= base;
433 91c13e54 2004-02-29 devnull if((fl & FmtComma) && n % 4 == 3){
434 91c13e54 2004-02-29 devnull *p-- = ',';
435 91c13e54 2004-02-29 devnull n++;
436 91c13e54 2004-02-29 devnull }
437 91c13e54 2004-02-29 devnull *p-- = conv[i];
438 91c13e54 2004-02-29 devnull n++;
439 91c13e54 2004-02-29 devnull }
440 91c13e54 2004-02-29 devnull }
441 91c13e54 2004-02-29 devnull if(n == 0){
442 3f1a2197 2004-12-26 devnull *p-- = '0';
443 3f1a2197 2004-12-26 devnull n = 1;
444 91c13e54 2004-02-29 devnull }
445 91c13e54 2004-02-29 devnull for(w = f->prec; n < w && p > buf+3; n++)
446 91c13e54 2004-02-29 devnull *p-- = '0';
447 91c13e54 2004-02-29 devnull if(neg || (fl & (FmtSign|FmtSpace)))
448 91c13e54 2004-02-29 devnull n++;
449 91c13e54 2004-02-29 devnull if(fl & FmtSharp){
450 91c13e54 2004-02-29 devnull if(base == 16)
451 91c13e54 2004-02-29 devnull n += 2;
452 91c13e54 2004-02-29 devnull else if(base == 8){
453 91c13e54 2004-02-29 devnull if(p[1] == '0')
454 91c13e54 2004-02-29 devnull fl &= ~FmtSharp;
455 91c13e54 2004-02-29 devnull else
456 91c13e54 2004-02-29 devnull n++;
457 91c13e54 2004-02-29 devnull }
458 91c13e54 2004-02-29 devnull }
459 91c13e54 2004-02-29 devnull if((fl & FmtZero) && !(fl & (FmtLeft|FmtPrec))){
460 91c13e54 2004-02-29 devnull for(w = f->width; n < w && p > buf+3; n++)
461 91c13e54 2004-02-29 devnull *p-- = '0';
462 91c13e54 2004-02-29 devnull f->width = 0;
463 91c13e54 2004-02-29 devnull }
464 91c13e54 2004-02-29 devnull if(fl & FmtSharp){
465 91c13e54 2004-02-29 devnull if(base == 16)
466 91c13e54 2004-02-29 devnull *p-- = f->r;
467 91c13e54 2004-02-29 devnull if(base == 16 || base == 8)
468 91c13e54 2004-02-29 devnull *p-- = '0';
469 91c13e54 2004-02-29 devnull }
470 91c13e54 2004-02-29 devnull if(neg)
471 91c13e54 2004-02-29 devnull *p-- = '-';
472 91c13e54 2004-02-29 devnull else if(fl & FmtSign)
473 91c13e54 2004-02-29 devnull *p-- = '+';
474 91c13e54 2004-02-29 devnull else if(fl & FmtSpace)
475 91c13e54 2004-02-29 devnull *p-- = ' ';
476 91c13e54 2004-02-29 devnull f->flags &= ~FmtPrec;
477 91c13e54 2004-02-29 devnull return __fmtcpy(f, p + 1, n, n);
478 91c13e54 2004-02-29 devnull }
479 91c13e54 2004-02-29 devnull
480 91c13e54 2004-02-29 devnull int
481 91c13e54 2004-02-29 devnull __countfmt(Fmt *f)
482 91c13e54 2004-02-29 devnull {
483 91c13e54 2004-02-29 devnull void *p;
484 91c13e54 2004-02-29 devnull ulong fl;
485 91c13e54 2004-02-29 devnull
486 91c13e54 2004-02-29 devnull fl = f->flags;
487 91c13e54 2004-02-29 devnull p = va_arg(f->args, void*);
488 91c13e54 2004-02-29 devnull if(fl & FmtVLong){
489 91c13e54 2004-02-29 devnull *(vlong*)p = f->nfmt;
490 91c13e54 2004-02-29 devnull }else if(fl & FmtLong){
491 91c13e54 2004-02-29 devnull *(long*)p = f->nfmt;
492 91c13e54 2004-02-29 devnull }else if(fl & FmtByte){
493 91c13e54 2004-02-29 devnull *(char*)p = f->nfmt;
494 91c13e54 2004-02-29 devnull }else if(fl & FmtShort){
495 91c13e54 2004-02-29 devnull *(short*)p = f->nfmt;
496 91c13e54 2004-02-29 devnull }else{
497 91c13e54 2004-02-29 devnull *(int*)p = f->nfmt;
498 91c13e54 2004-02-29 devnull }
499 91c13e54 2004-02-29 devnull return 0;
500 91c13e54 2004-02-29 devnull }
501 91c13e54 2004-02-29 devnull
502 91c13e54 2004-02-29 devnull int
503 91c13e54 2004-02-29 devnull __flagfmt(Fmt *f)
504 91c13e54 2004-02-29 devnull {
505 91c13e54 2004-02-29 devnull switch(f->r){
506 91c13e54 2004-02-29 devnull case ',':
507 91c13e54 2004-02-29 devnull f->flags |= FmtComma;
508 91c13e54 2004-02-29 devnull break;
509 91c13e54 2004-02-29 devnull case '-':
510 91c13e54 2004-02-29 devnull f->flags |= FmtLeft;
511 91c13e54 2004-02-29 devnull break;
512 91c13e54 2004-02-29 devnull case '+':
513 91c13e54 2004-02-29 devnull f->flags |= FmtSign;
514 91c13e54 2004-02-29 devnull break;
515 91c13e54 2004-02-29 devnull case '#':
516 91c13e54 2004-02-29 devnull f->flags |= FmtSharp;
517 91c13e54 2004-02-29 devnull break;
518 91c13e54 2004-02-29 devnull case ' ':
519 91c13e54 2004-02-29 devnull f->flags |= FmtSpace;
520 91c13e54 2004-02-29 devnull break;
521 91c13e54 2004-02-29 devnull case 'u':
522 91c13e54 2004-02-29 devnull f->flags |= FmtUnsigned;
523 91c13e54 2004-02-29 devnull break;
524 91c13e54 2004-02-29 devnull case 'h':
525 91c13e54 2004-02-29 devnull if(f->flags & FmtShort)
526 91c13e54 2004-02-29 devnull f->flags |= FmtByte;
527 91c13e54 2004-02-29 devnull f->flags |= FmtShort;
528 91c13e54 2004-02-29 devnull break;
529 91c13e54 2004-02-29 devnull case 'L':
530 91c13e54 2004-02-29 devnull f->flags |= FmtLDouble;
531 91c13e54 2004-02-29 devnull break;
532 91c13e54 2004-02-29 devnull case 'l':
533 91c13e54 2004-02-29 devnull if(f->flags & FmtLong)
534 91c13e54 2004-02-29 devnull f->flags |= FmtVLong;
535 91c13e54 2004-02-29 devnull f->flags |= FmtLong;
536 91c13e54 2004-02-29 devnull break;
537 91c13e54 2004-02-29 devnull }
538 91c13e54 2004-02-29 devnull return 1;
539 91c13e54 2004-02-29 devnull }
540 91c13e54 2004-02-29 devnull
541 91c13e54 2004-02-29 devnull /* default error format */
542 91c13e54 2004-02-29 devnull int
543 91c13e54 2004-02-29 devnull __badfmt(Fmt *f)
544 91c13e54 2004-02-29 devnull {
545 91c13e54 2004-02-29 devnull char x[3];
546 91c13e54 2004-02-29 devnull
547 91c13e54 2004-02-29 devnull x[0] = '%';
548 91c13e54 2004-02-29 devnull x[1] = f->r;
549 91c13e54 2004-02-29 devnull x[2] = '%';
550 91c13e54 2004-02-29 devnull f->prec = 3;
551 91c13e54 2004-02-29 devnull __fmtcpy(f, (const void*)x, 3, 3);
552 91c13e54 2004-02-29 devnull return 0;
553 91c13e54 2004-02-29 devnull }