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