5 /* format the output into f->to and return the number of characters fmted */
7 dofmt(Fmt *f, char *fmt)
19 while((r = *(uchar*)fmt) && r != '%'){
23 fmt += chartorune(&rune, fmt);
26 FMTRCHAR(f, rt, rs, r);
29 f->nfmt += rt - (Rune *)f->to;
32 return f->nfmt - nfmt;
37 while((r = *(uchar*)fmt) && r != '%'){
42 n = chartorune(&rune, fmt);
44 t = _fmtflush(f, t, n);
55 f->nfmt += t - (char *)f->to;
58 return f->nfmt - nfmt;
62 fmt = _fmtdispatch(f, fmt, 0);
69 _fmtflush(Fmt *f, void *t, int len)
72 f->nfmt += (Rune*)t - (Rune*)f->to;
74 f->nfmt += (char*)t - (char *)f->to;
76 if(f->flush == 0 || (*f->flush)(f) == 0 || (char*)f->to + len > (char*)f->stop){
84 * put a formatted block of memory sz bytes long of n runes into the output buffer,
85 * left/right justified in a field of at least f->width charactes
88 _fmtpad(Fmt *f, int n)
95 for(i = 0; i < n; i++)
96 FMTCHAR(f, t, s, ' ');
97 f->nfmt += t - (char *)f->to;
103 _rfmtpad(Fmt *f, int n)
110 for(i = 0; i < n; i++)
111 FMTRCHAR(f, t, s, ' ');
112 f->nfmt += t - (Rune *)f->to;
118 _fmtcpy(Fmt *f, void *vm, int n, int sz)
121 char *t, *s, *m, *me;
129 if((fl & FmtPrec) && n > f->prec)
132 if(!(fl & FmtLeft) && _rfmtpad(f, w - n) < 0)
136 for(nc = n; nc > 0; nc--){
140 else if((me - m) >= UTFmax || fullrune(m, me-m))
141 m += chartorune(&r, m);
144 FMTRCHAR(f, rt, rs, r);
146 f->nfmt += rt - (Rune *)f->to;
148 if(fl & FmtLeft && _rfmtpad(f, w - n) < 0)
151 if(!(fl & FmtLeft) && _fmtpad(f, w - n) < 0)
155 for(nc = n; nc > 0; nc--){
159 else if((me - m) >= UTFmax || fullrune(m, me-m))
160 m += chartorune(&r, m);
165 f->nfmt += t - (char *)f->to;
167 if(fl & FmtLeft && _fmtpad(f, w - n) < 0)
174 _fmtrcpy(Fmt *f, void *vm, int n)
176 Rune r, *m, *me, *rt, *rs;
184 if((fl & FmtPrec) && n > f->prec)
187 if(!(fl & FmtLeft) && _rfmtpad(f, w - n) < 0)
191 for(me = m + n; m < me; m++)
192 FMTRCHAR(f, rt, rs, *m);
193 f->nfmt += rt - (Rune *)f->to;
195 if(fl & FmtLeft && _rfmtpad(f, w - n) < 0)
198 if(!(fl & FmtLeft) && _fmtpad(f, w - n) < 0)
202 for(me = m + n; m < me; m++){
206 f->nfmt += t - (char *)f->to;
208 if(fl & FmtLeft && _fmtpad(f, w - n) < 0)
214 /* fmt out one character */
220 x[0] = va_arg(f->args, int);
222 return _fmtcpy(f, x, 1, 1);
225 /* fmt out one rune */
231 x[0] = va_arg(f->args, int);
232 return _fmtrcpy(f, x, 1);
235 /* public helper routine: fmt out a null terminated string already in hand */
237 fmtstrcpy(Fmt *f, char *s)
243 return _fmtcpy(f, "<nil>", 5, 5);
244 /* if precision is specified, make sure we don't wander off the end */
245 if(f->flags & FmtPrec){
247 for(j=0; j<f->prec && s[i]; j++)
248 i += chartorune(&r, s+i);
249 return _fmtcpy(f, s, j, i);
251 return _fmtcpy(f, s, utflen(s), strlen(s));
254 /* fmt out a null terminated utf string */
260 s = va_arg(f->args, char *);
261 return fmtstrcpy(f, s);
264 /* public helper routine: fmt out a null terminated rune string already in hand */
266 fmtrunestrcpy(Fmt *f, Rune *s)
272 return _fmtcpy(f, "<nil>", 5, 5);
273 /* if precision is specified, make sure we don't wander off the end */
274 if(f->flags & FmtPrec){
276 for(n = 0; n < p; n++)
284 return _fmtrcpy(f, s, n);
287 /* fmt out a null terminated rune string */
293 s = va_arg(f->args, Rune *);
294 return fmtrunestrcpy(f, s);
305 return _fmtrcpy(f, x, 1);
312 char buf[70], *p, *conv;
316 int neg, base, i, n, fl, w, isv;
324 pu = va_arg(f->args, uintptr);
325 if(sizeof(uintptr) == sizeof(uvlong)){
332 }else if(fl & FmtVLong){
335 vu = va_arg(f->args, uvlong);
337 vu = va_arg(f->args, vlong);
338 }else if(fl & FmtLong){
340 u = va_arg(f->args, ulong);
342 u = va_arg(f->args, long);
343 }else if(fl & FmtByte){
345 u = (uchar)va_arg(f->args, int);
347 u = (char)va_arg(f->args, int);
348 }else if(fl & FmtShort){
350 u = (ushort)va_arg(f->args, int);
352 u = (short)va_arg(f->args, int);
355 u = va_arg(f->args, uint);
357 u = va_arg(f->args, int);
359 conv = "0123456789abcdef";
369 conv = "0123456789ABCDEF";
380 if(!(fl & FmtUnsigned)){
381 if(isv && (vlong)vu < 0){
384 }else if(!isv && (long)u < 0){
389 p = buf + sizeof buf - 1;
395 if((fl & FmtComma) && n % 4 == 3){
406 if((fl & FmtComma) && n % 4 == 3){
418 for(w = f->prec; n < w && p > buf+3; n++)
420 if(neg || (fl & (FmtSign|FmtSpace)))
432 if((fl & FmtZero) && !(fl & (FmtLeft|FmtPrec))){
433 for(w = f->width; n < w && p > buf+3; n++)
440 if(base == 16 || base == 8)
445 else if(fl & FmtSign)
447 else if(fl & FmtSpace)
449 f->flags &= ~FmtPrec;
450 return _fmtcpy(f, p + 1, n, n);
460 p = va_arg(f->args, void*);
462 *(vlong*)p = f->nfmt;
463 }else if(fl & FmtLong){
465 }else if(fl & FmtByte){
467 }else if(fl & FmtShort){
468 *(short*)p = f->nfmt;
480 f->flags |= FmtComma;
489 f->flags |= FmtSharp;
492 f->flags |= FmtSpace;
495 f->flags |= FmtUnsigned;
498 if(f->flags & FmtShort)
500 f->flags |= FmtShort;
503 if(f->flags & FmtLong)
504 f->flags |= FmtVLong;
511 /* default error format */
521 n = 1+runetochar(x+1, &r);