* 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 insp
| 219 | * ("%*D", len, ptr, " " -> XX XX XX XX ... |
| 220 | */ |
| 221 | int |
| 222 | kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap) |
| 223 | { |
| 224 | #define PCHAR(c) {int cc=(c); if (func) (*func)(cc,arg); else *d++ = cc; retval++; } |
| 225 | char nbuf[MAXNBUF]; |
| 226 | char *d; |
| 227 | const char *p, *percent, *q; |
| 228 | u_char *up; |
| 229 | int ch, n; |
| 230 | uintmax_t num; |
| 231 | int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot; |
| 232 | int cflag, hflag, jflag, tflag, zflag; |
| 233 | int dwidth, upper; |
| 234 | char padc; |
| 235 | int stop = 0, retval = 0; |
| 236 | |
| 237 | num = 0; |
| 238 | if (!func) |
| 239 | d = (char *) arg; |
| 240 | else |
| 241 | d = NULL; |
| 242 | |
| 243 | if (fmt == NULL) |
| 244 | fmt = "(fmt null)\n"; |
| 245 | |
| 246 | if (radix < 2 || radix > 36) |
| 247 | radix = 10; |
| 248 | |
| 249 | for (;;) { |
| 250 | padc = ' '; |
| 251 | width = 0; |
| 252 | while ((ch = (u_char)*fmt++) != '%' || stop) { |
| 253 | if (ch == '\0') |
| 254 | return (retval); |
| 255 | PCHAR(ch); |
| 256 | } |
| 257 | percent = fmt - 1; |
| 258 | qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0; |
| 259 | sign = 0; dot = 0; dwidth = 0; upper = 0; |
| 260 | cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0; |
| 261 | reswitch: switch (ch = (u_char)*fmt++) { |
| 262 | case '.': |
| 263 | dot = 1; |
| 264 | goto reswitch; |
| 265 | case '#': |
| 266 | sharpflag = 1; |
| 267 | goto reswitch; |
| 268 | case '+': |
| 269 | sign = 1; |
| 270 | goto reswitch; |
| 271 | case '-': |
| 272 | ladjust = 1; |
| 273 | goto reswitch; |
| 274 | case '%': |
| 275 | PCHAR(ch); |
| 276 | break; |
| 277 | case '*': |
| 278 | if (!dot) { |