1 /*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * William Jolitz. 7 * 8 * %sccs.include.noredist.c% 9 * 10 * @(#)prf.c 7.1 (Berkeley) 04/24/90 11 */ 12 13 #include <sys/types.h> 14 15 /* 16 * Scaled down version of C Library printf. 17 * Used to print diagnostic information directly on console tty. 18 * 19 * One additional format: %b is supported to decode error registers. 20 * Usage is: 21 * printf("reg=%b\n", regval, "<base><arg>*"); 22 * Where <base> is the output base expressed as a control character, 23 * e.g. \10 gives octal; \20 gives hex. Each arg is a sequence of 24 * characters, the first of which gives the bit number to be inspected 25 * (origin 1), and the next characters (up to a control character, i.e. 26 * a character <= 32), give the name of the register. Thus 27 * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); 28 * would produce output: 29 * reg=3<BITTWO,BITONE> 30 */ 31 /*VARARGS1*/ 32 printf(fmt, x1) 33 char *fmt; 34 unsigned x1; 35 { 36 37 prf(fmt, &x1); 38 } 39 40 prf(fmt, adx) 41 register char *fmt; 42 register *adx; 43 { 44 register int b, c, i; 45 char *s, sep; 46 47 loop: 48 while ((c = *fmt++) != '%') { 49 if(c == '\0') 50 return; 51 putchar(c); 52 } 53 again: 54 c = *fmt++; 55 /* 56 * THIS CODE IS BYTE-ORDER DEPENDENT IN HANDLING %c 57 * AND IGNORES SHORT/LONG DISTINCTIONS. 58 */ 59 switch (c) { 60 61 case 'l': 62 goto again; 63 case 'x': case 'X': 64 b = 16; 65 goto number; 66 case 'd': case 'D': 67 case 'u': /* what a joke */ 68 b = 10; 69 goto number; 70 case 'o': case 'O': 71 b = 8; 72 number: 73 printn((u_long)*adx, b); 74 break; 75 case 'c': 76 b = *adx; 77 for (i = 24; i >= 0; i -= 8) 78 if (c = (b >> i) & 0x7f) 79 putchar(c); 80 break; 81 #ifndef notyet 82 case 'b': 83 b = *adx++; 84 s = (char *)*adx; 85 printn((u_long)b, *s++); 86 if (b) { 87 sep = '<'; 88 while (i = *s++) { 89 if (b & (1 << (i-1))) { 90 putchar(sep); 91 sep = ','; 92 for (; (c = *s) > 32; s++) 93 putchar(c); 94 } else 95 for (; *s > 32; s++) 96 ; 97 } 98 if (sep != '<') 99 putchar('>'); 100 } 101 break; 102 #endif 103 104 case 's': 105 s = (char *)*adx; 106 while (c = *s++) 107 putchar(c); 108 break; 109 } 110 adx++; 111 goto loop; 112 } 113 114 /* 115 * Printn prints a number n in base b. 116 * We don't use recursion to avoid deep kernel stacks. 117 */ 118 printn(n, b) 119 u_long n; 120 { 121 char prbuf[11]; 122 register char *cp; 123 124 if (b == 10 && (int)n < 0) { 125 putchar('-'); 126 n = (unsigned)(-(int)n); 127 } 128 cp = prbuf; 129 do { 130 *cp++ = "0123456789abcdef"[n%b]; 131 n /= b; 132 } while (n); 133 do 134 putchar(*--cp); 135 while (cp > prbuf); 136 } 137 138 #define lf 10 139 #define cr 13 140 141 putchar(c) 142 char c; 143 { 144 if (c == lf) 145 { 146 sput(cr); 147 wait(60000); 148 } 149 sput(c); 150 return(0); 151 } 152 153 wait(n) { while(n--) ; } 154