1 /* 2 * Copyright (c) 1982, 1986, 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)prf.c 7.3 (Berkeley) 12/16/90 8 */ 9 10 #include "sys/param.h" 11 12 /* 13 * Scaled down version of C Library printf. 14 * Used to print diagnostic information directly on console tty. 15 * Since it is not interrupt driven, all system activities are 16 * suspended. Printf should not be used for chit-chat. 17 * 18 * One additional format: %b is supported to decode error registers. 19 * Usage is: 20 * printf("reg=%b\n", regval, "<base><arg>*"); 21 * Where <base> is the output base expressed as a control character, 22 * e.g. \10 gives octal; \20 gives hex. Each arg is a sequence of 23 * characters, the first of which gives the bit number to be inspected 24 * (origin 1), and the next characters (up to a control character, i.e. 25 * a character <= 32), give the name of the register. Thus 26 * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); 27 * would produce output: 28 * reg=2<BITTWO,BITONE> 29 */ 30 /*VARARGS1*/ 31 printf(fmt, x1) 32 char *fmt; 33 unsigned x1; 34 { 35 36 prf(0, fmt, &x1); 37 } 38 39 /*VARARGS1*/ 40 romprintf(fmt, x1) 41 char *fmt; 42 unsigned x1; 43 { 44 45 prf(1, fmt, &x1); 46 } 47 48 prf(userom, fmt, adx) 49 register char *fmt; 50 register u_int *adx; 51 { 52 register int b, c, i; 53 char *s; 54 int any; 55 56 loop: 57 while ((c = *fmt++) != '%') { 58 if(c == '\0') 59 return; 60 putchar(userom, c); 61 } 62 again: 63 c = *fmt++; 64 /* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */ 65 switch (c) { 66 67 case 'l': 68 goto again; 69 case 'x': case 'X': 70 b = 16; 71 goto number; 72 case 'd': case 'D': 73 case 'u': /* what a joke */ 74 b = 10; 75 goto number; 76 case 'o': case 'O': 77 b = 8; 78 number: 79 printn(userom, (u_long)*adx, b); 80 break; 81 case 'c': 82 b = *adx; 83 for (i = 24; i >= 0; i -= 8) 84 if (c = (b >> i) & 0x7f) 85 putchar(userom, c); 86 break; 87 case 'b': 88 b = *adx++; 89 s = (char *)*adx; 90 printn(userom, (u_long)b, *s++); 91 any = 0; 92 if (b) { 93 while (i = *s++) { 94 if (b & (1 << (i-1))) { 95 putchar(userom, any? ',' : '<'); 96 any = 1; 97 for (; (c = *s) > 32; s++) 98 putchar(userom, c); 99 } else 100 for (; *s > 32; s++) 101 ; 102 } 103 if (any) 104 putchar(userom, '>'); 105 } 106 break; 107 108 case 's': 109 s = (char *)*adx; 110 while (c = *s++) 111 putchar(userom, c); 112 break; 113 } 114 adx++; 115 goto loop; 116 } 117 118 /* 119 * Printn prints a number n in base b. 120 * We don't use recursion to avoid deep kernel stacks. 121 */ 122 printn(userom, n, b) 123 u_long n; 124 { 125 char prbuf[11]; 126 register char *cp; 127 128 if (b == 10 && (int)n < 0) { 129 putchar(userom, '-'); 130 n = (unsigned)(-(int)n); 131 } 132 cp = prbuf; 133 do { 134 *cp++ = "0123456789abcdef"[n%b]; 135 n /= b; 136 } while (n); 137 do 138 putchar(userom, *--cp); 139 while (cp > prbuf); 140 } 141 142 /* 143 * Print a character on console. 144 */ 145 putchar(userom, c) 146 register c; 147 { 148 #ifdef ROMPRF 149 if (userom) { 150 romputchar(c); 151 return; 152 } 153 #endif 154 cnputc(c); 155 if(c == '\n') 156 cnputc('\r'); 157 } 158 159 peekchar() 160 { 161 register c; 162 163 c = cngetc(); 164 if (c == ('c'&037)) { 165 printf("^C"); 166 _stop(""); 167 /* NOTREACHED */ 168 } 169 return(c); 170 } 171 172 getchar() 173 { 174 register c; 175 176 while((c = cngetc()) == 0) 177 ; 178 if (c == '\r') 179 c = '\n'; 180 else if (c == ('c'&037)) { 181 printf("^C"); 182 _stop(""); 183 /* NOTREACHED */ 184 } 185 putchar(0, c); 186 return(c); 187 } 188 189 gets(buf) 190 char *buf; 191 { 192 register char *lp; 193 register c; 194 195 lp = buf; 196 for (;;) { 197 c = getchar() & 0177; 198 switch(c) { 199 case '\n': 200 case '\r': 201 c = '\n'; 202 *lp++ = '\0'; 203 return; 204 case '\b': 205 if (lp > buf) { 206 lp--; 207 putchar(0, ' '); 208 putchar(0, '\b'); 209 } 210 continue; 211 case '#': 212 case '\177': 213 lp--; 214 if (lp < buf) 215 lp = buf; 216 continue; 217 case '@': 218 case 'u'&037: 219 lp = buf; 220 putchar(0, '\n'); 221 continue; 222 default: 223 *lp++ = c; 224 } 225 } 226 } 227 228