1*63277Smckusick /*- 2*63277Smckusick * Copyright (c) 1993 The Regents of the University of California. 3*63277Smckusick * All rights reserved. 4*63277Smckusick * 5*63277Smckusick * %sccs.include.redist.c% 6*63277Smckusick * 7*63277Smckusick * @(#)printf.c 7.1 (Berkeley) 06/11/93 8*63277Smckusick */ 9*63277Smckusick 10*63277Smckusick /* 11*63277Smckusick * Scaled down version of printf(3). 12*63277Smckusick * 13*63277Smckusick * One additional format: 14*63277Smckusick * 15*63277Smckusick * The format %b is supported to decode error registers. 16*63277Smckusick * Its usage is: 17*63277Smckusick * 18*63277Smckusick * printf("reg=%b\n", regval, "<base><arg>*"); 19*63277Smckusick * 20*63277Smckusick * where <base> is the output base expressed as a control character, e.g. 21*63277Smckusick * \10 gives octal; \20 gives hex. Each arg is a sequence of characters, 22*63277Smckusick * the first of which gives the bit number to be inspected (origin 1), and 23*63277Smckusick * the next characters (up to a control character, i.e. a character <= 32), 24*63277Smckusick * give the name of the register. Thus: 25*63277Smckusick * 26*63277Smckusick * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); 27*63277Smckusick * 28*63277Smckusick * would produce output: 29*63277Smckusick * 30*63277Smckusick * reg=3<BITTWO,BITONE> 31*63277Smckusick */ 32*63277Smckusick 33*63277Smckusick #include <sys/cdefs.h> 34*63277Smckusick #include <sys/types.h> 35*63277Smckusick 36*63277Smckusick /* 37*63277Smckusick * Note that stdarg.h and the ANSI style va_start macro is used for both 38*63277Smckusick * ANSI and traditional C compilers. 39*63277Smckusick */ 40*63277Smckusick #define KERNEL 41*63277Smckusick #include <machine/stdarg.h> 42*63277Smckusick #undef KERNEL 43*63277Smckusick 44*63277Smckusick static void kprintn __P((u_long, int)); 45*63277Smckusick 46*63277Smckusick void 47*63277Smckusick #if __STDC__ 48*63277Smckusick printf(const char *fmt, ...) 49*63277Smckusick #else 50*63277Smckusick printf(fmt /* , va_alist */) 51*63277Smckusick char *fmt; 52*63277Smckusick #endif 53*63277Smckusick { 54*63277Smckusick register char *p; 55*63277Smckusick register int ch, n; 56*63277Smckusick unsigned long ul; 57*63277Smckusick int lflag, set; 58*63277Smckusick va_list ap; 59*63277Smckusick 60*63277Smckusick va_start(ap, fmt); 61*63277Smckusick for (;;) { 62*63277Smckusick while ((ch = *fmt++) != '%') { 63*63277Smckusick if (ch == '\0') 64*63277Smckusick return; 65*63277Smckusick putchar(ch); 66*63277Smckusick } 67*63277Smckusick lflag = 0; 68*63277Smckusick reswitch: switch (ch = *fmt++) { 69*63277Smckusick case 'l': 70*63277Smckusick lflag = 1; 71*63277Smckusick goto reswitch; 72*63277Smckusick case 'b': 73*63277Smckusick ul = va_arg(ap, int); 74*63277Smckusick p = va_arg(ap, char *); 75*63277Smckusick kprintn(ul, *p++); 76*63277Smckusick 77*63277Smckusick if (!ul) 78*63277Smckusick break; 79*63277Smckusick 80*63277Smckusick for (set = 0; n = *p++;) { 81*63277Smckusick if (ul & (1 << (n - 1))) { 82*63277Smckusick putchar(set ? ',' : '<'); 83*63277Smckusick for (; (n = *p) > ' '; ++p) 84*63277Smckusick putchar(n); 85*63277Smckusick set = 1; 86*63277Smckusick } else 87*63277Smckusick for (; *p > ' '; ++p); 88*63277Smckusick } 89*63277Smckusick if (set) 90*63277Smckusick putchar('>'); 91*63277Smckusick break; 92*63277Smckusick case 'c': 93*63277Smckusick ch = va_arg(ap, int); 94*63277Smckusick putchar(ch & 0x7f); 95*63277Smckusick break; 96*63277Smckusick case 's': 97*63277Smckusick p = va_arg(ap, char *); 98*63277Smckusick while (ch = *p++) 99*63277Smckusick putchar(ch); 100*63277Smckusick break; 101*63277Smckusick case 'd': 102*63277Smckusick ul = lflag ? 103*63277Smckusick va_arg(ap, long) : va_arg(ap, int); 104*63277Smckusick if ((long)ul < 0) { 105*63277Smckusick putchar('-'); 106*63277Smckusick ul = -(long)ul; 107*63277Smckusick } 108*63277Smckusick kprintn(ul, 10); 109*63277Smckusick break; 110*63277Smckusick case 'o': 111*63277Smckusick ul = lflag ? 112*63277Smckusick va_arg(ap, u_long) : va_arg(ap, u_int); 113*63277Smckusick kprintn(ul, 8); 114*63277Smckusick break; 115*63277Smckusick case 'u': 116*63277Smckusick ul = lflag ? 117*63277Smckusick va_arg(ap, u_long) : va_arg(ap, u_int); 118*63277Smckusick kprintn(ul, 10); 119*63277Smckusick break; 120*63277Smckusick case 'x': 121*63277Smckusick ul = lflag ? 122*63277Smckusick va_arg(ap, u_long) : va_arg(ap, u_int); 123*63277Smckusick kprintn(ul, 16); 124*63277Smckusick break; 125*63277Smckusick default: 126*63277Smckusick putchar('%'); 127*63277Smckusick if (lflag) 128*63277Smckusick putchar('l'); 129*63277Smckusick putchar(ch); 130*63277Smckusick } 131*63277Smckusick } 132*63277Smckusick va_end(ap); 133*63277Smckusick } 134*63277Smckusick 135*63277Smckusick static void 136*63277Smckusick kprintn(ul, base) 137*63277Smckusick unsigned long ul; 138*63277Smckusick int base; 139*63277Smckusick { 140*63277Smckusick /* hold a long in base 8 */ 141*63277Smckusick char *p, buf[(sizeof(long) * NBBY / 3) + 1]; 142*63277Smckusick 143*63277Smckusick p = buf; 144*63277Smckusick do { 145*63277Smckusick *p++ = "0123456789abcdef"[ul % base]; 146*63277Smckusick } while (ul /= base); 147*63277Smckusick do { 148*63277Smckusick putchar(*--p); 149*63277Smckusick } while (p > buf); 150*63277Smckusick } 151