* Scaled down version of printf(3). * * Two additional formats: * * The format %b is supported to decode error registers. * Its usage is: * * printf("reg=%b\n", regval, " *"); * * where is the output base expressed as a control character, e.g. * \10 gives octal; \20 gives hex. Each arg is a sequence of characters, * the first of which gives the bit number to be inspect
| 645 | * ("%*D", len, ptr, " " -> XX XX XX XX ... |
| 646 | */ |
| 647 | int |
| 648 | kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap) |
| 649 | { |
| 650 | #define PCHAR(c) {int cc=(c); if (func) (*func)(cc,arg); else *d++ = cc; retval++; } |
| 651 | char nbuf[MAXNBUF]; |
| 652 | char *d; |
| 653 | const char *p, *percent, *q; |
| 654 | u_char *up; |
| 655 | int ch, n; |
| 656 | uintmax_t num; |
| 657 | int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot; |
| 658 | int cflag, hflag, jflag, tflag, zflag; |
| 659 | int bconv, dwidth, upper; |
| 660 | char padc; |
| 661 | int stop = 0, retval = 0; |
| 662 | |
| 663 | num = 0; |
| 664 | q = NULL; |
| 665 | if (!func) |
| 666 | d = (char *) arg; |
| 667 | else |
| 668 | d = NULL; |
| 669 | |
| 670 | if (fmt == NULL) |
| 671 | fmt = "(fmt null)\n"; |
| 672 | |
| 673 | if (radix < 2 || radix > 36) |
| 674 | radix = 10; |
| 675 | |
| 676 | for (;;) { |
| 677 | padc = ' '; |
| 678 | width = 0; |
| 679 | while ((ch = (u_char)*fmt++) != '%' || stop) { |
| 680 | if (ch == '\0') |
| 681 | return (retval); |
| 682 | PCHAR(ch); |
| 683 | } |
| 684 | percent = fmt - 1; |
| 685 | qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0; |
| 686 | sign = 0; dot = 0; bconv = 0; dwidth = 0; upper = 0; |
| 687 | cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0; |
| 688 | reswitch: switch (ch = (u_char)*fmt++) { |
| 689 | case '.': |
| 690 | dot = 1; |
| 691 | goto reswitch; |
| 692 | case '#': |
| 693 | sharpflag = 1; |
| 694 | goto reswitch; |
| 695 | case '+': |
| 696 | sign = 1; |
| 697 | goto reswitch; |
| 698 | case '-': |
| 699 | ladjust = 1; |
| 700 | goto reswitch; |
| 701 | case '%': |
| 702 | PCHAR(ch); |
| 703 | break; |
| 704 | case '*': |
no test coverage detected