26 static char fmtindex[MAXFMT];
28 static int noconv(va_list*, Fconv*);
29 static int flags(va_list*, Fconv*);
31 static int cconv(va_list*, Fconv*);
32 static int rconv(va_list*, Fconv*);
33 static int sconv(va_list*, Fconv*);
34 static int percent(va_list*, Fconv*);
35 static int column(va_list*, Fconv*);
37 int numbconv(va_list*, Fconv*);
40 int (*fmtconv[MAXCONV])(va_list*, Fconv*) =
64 fmtconv[cc] = numbconv;
85 fmtconv[cc] = percent;
97 fmtinstall(int c, int (*f)(va_list*, Fconv*))
102 if(c < 0 || c >= MAXFMT)
104 if(convcount >= MAXCONV)
106 fmtconv[convcount] = f;
107 fmtindex[c] = convcount;
113 doprint(char *s, char *es, char *fmt, va_list argp)
122 local.eout = es-UTFmax-1;
127 n = chartorune(&rune, fmt);
146 printcol = (printcol+8) & ~7;
150 if(local.out < local.eout)
153 n = runetochar(local.out, &rune);
167 * read one of the following
168 * 1. number, => f1, f2 in order.
169 * 2. '*' same as number (from args)
170 * 3. '.' ignored (separates numbers)
172 * 5. verb and terminate
177 n = chartorune(&rune, fmt);
194 if((c >= '1' && c <= '9') ||
195 (c == '0' && local.f1 != NONE)) { /* '0' is a digit for f2 */
197 while(c >= '0' && c <= '9') {
208 n = va_arg(argp, int);
216 if(c >= 0 && c < MAXFMT)
219 n = (*fmtconv[n])(&argp, &local);
228 numbconv(va_list *arg, Fconv *fp)
231 int i, f, n, b, ucase;
260 switch(fp->f3 & (FVLONG|FLONG|FSHORT|FUNSIGN)) {
262 vl = va_arg(*arg, vlong);
265 case FUNSIGN|FVLONG|FLONG:
266 vl = va_arg(*arg, uvlong);
270 v = va_arg(*arg, long);
274 v = va_arg(*arg, ulong);
278 h = va_arg(*arg, int);
283 h = va_arg(*arg, int);
288 v = va_arg(*arg, int);
292 v = va_arg(*arg, unsigned);
295 if(fp->f3 & FVLONG) {
296 if(!(fp->f3 & FUNSIGN) && vl < 0) {
301 if(!(fp->f3 & FUNSIGN) && v < 0) {
307 for(i = IDIGIT-2;; i--) {
325 if(fp->f2 != NONE && i >= IDIGIT-fp->f2)
327 if(fp->f3 & FVLONG) {
336 if(fp->f3 & FSHARP) {
337 if(b == 8 && s[i] != '0')
355 Strconv(Rune *s, Fconv *fp)
363 if(fp->f1 != NONE && fp->f1 >= 0) {
367 if(fp->out < fp->eout)
378 if(fp->f2 == NONE || fp->f2 > 0) {
379 if(fp->out < fp->eout)
382 i = runetochar(fp->out, &rune);
396 printcol = (printcol+8) & ~7;
401 if(fp->f1 != NONE && fp->f1 < 0) {
404 if(fp->out < fp->eout)
413 strconv(char *s, Fconv *fp)
421 if(fp->f1 != NONE && fp->f1 >= 0) {
424 if(fp->out < fp->eout)
433 i = chartorune(&rune, s);
441 if(fp->f2 == NONE || fp->f2 > 0) {
442 if(fp->out < fp->eout)
445 i = runetochar(fp->out, &rune);
459 printcol = (printcol+8) & ~7;
464 if(fp->f1 != NONE && fp->f1 < 0) {
467 if(fp->out < fp->eout)
477 noconv(va_list *arg, Fconv *fp)
485 if(fp->chr >= 0 && fp->chr < MAXFMT)
486 n = fmtindex[fp->chr];
487 return (*fmtconv[n])(arg, fp);
502 rconv(va_list*, Fconv *fp)
515 cconv(va_list *arg, Fconv *fp)
520 rune = va_arg(*arg, int);
523 s[runetochar(s, &rune)] = 0;
532 sconv(va_list *arg, Fconv *fp)
538 s = va_arg(*arg, char*);
543 r = va_arg(*arg, Rune*);
553 percent(va_list*, Fconv *fp)
556 if(fp->out < fp->eout)
564 column(va_list *arg, Fconv *fp)
568 col = va_arg(*arg, int);
569 while(fp->out < fp->eout && printcol < col) {
570 pc = (printcol+8) & ~7;
584 flags(va_list*, Fconv *fp)