xref: /original-bsd/sys/kern/subr_prf.c (revision d25e1985)
1 /*	subr_prf.c	3.3	06/22/80	*/
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
5 #include "../h/seg.h"
6 #include "../h/buf.h"
7 #include "../h/conf.h"
8 #include "../h/mtpr.h"
9 
10 #ifdef TRACE
11 #define	TRCBUFS	4096
12 char	trcbuf[TRCBUFS];
13 char	*trcbufp = trcbuf;
14 int	trcwrap;
15 int	trcprt = TRCBUFS;
16 #endif
17 
18 /*
19  * In case console is off,
20  * panicstr contains argument to last
21  * call to panic.
22  */
23 
24 char	*panicstr;
25 
26 /*
27  * Scaled down version of C Library printf.
28  * Only %s %u %d (==%u) %o %x %D are recognized.
29  * Used to print diagnostic information
30  * directly on console tty.
31  * Since it is not interrupt driven,
32  * all system activities are pretty much
33  * suspended.
34  * Printf should not be used for chit-chat.
35  */
36 /*VARARGS1*/
37 printf(fmt, x1)
38 register char *fmt;
39 unsigned x1;
40 {
41 
42 	prf(fmt, &x1, 0);
43 }
44 
45 #ifdef TRACE
46 trace(fmt, x1)
47 register char *fmt;
48 unsigned x1;
49 {
50 
51 	prf(fmt, &x1, 1);
52 }
53 
54 #endif
55 
56 prf(fmt, adx, trace)
57 register char *fmt;
58 register unsigned int *adx;
59 {
60 	register c;
61 	char *s;
62 
63 loop:
64 	while((c = *fmt++) != '%') {
65 		if(c == '\0')
66 			return;
67 		putchar(c, trace);
68 	}
69 	c = *fmt++;
70 	if (c == 'X')
71 		printx((long)*adx, trace);
72 	else if (c == 'd' || c == 'u' || c == 'o' || c == 'x')
73 		printn((long)*adx, c=='o'? 8: (c=='x'? 16:10), trace);
74 	else if (c == 's') {
75 		s = (char *)*adx;
76 		while (c = *s++)
77 #ifdef TRACE
78 			if (trace) {
79 				*trcbufp++ = c;
80 				if (trcbufp >= &trcbuf[TRCBUFS]) {
81 					trcbufp = trcbuf;
82 					trcwrap = 1;
83 				}
84 			} else
85 #endif
86 				putchar(c, trace);
87 	} else if (c == 'D') {
88 		printn(*(long *)adx, 10, trace);
89 		adx += (sizeof(long) / sizeof(int)) - 1;
90 	}
91 	adx++;
92 	goto loop;
93 }
94 
95 printx(x, trace)
96 long x;
97 {
98 	int i;
99 
100 	for (i = 0; i < 8; i++)
101 		putchar("0123456789ABCDEF"[(x>>((7-i)*4))&0xf], trace);
102 }
103 
104 /*
105  * Print an unsigned integer in base b.
106  */
107 printn(n, b, trace)
108 long n;
109 {
110 	register long a;
111 
112 	if (n<0) {	/* shouldn't happen */
113 		putchar('-', trace);
114 		n = -n;
115 	}
116 	if(a = n/b)
117 		printn(a, b, trace);
118 	putchar("0123456789ABCDEF"[(int)(n%b)], trace);
119 }
120 
121 /*
122  * Panic is called on unresolvable
123  * fatal errors.
124  * It syncs, prints "panic: mesg" and
125  * then loops.
126  */
127 panic(s)
128 char *s;
129 {
130 	panicstr = s;
131 	update();
132 	printf("panic: %s\n", s);
133 	spl0();
134 	for(;;)
135 		;
136 }
137 
138 /*
139  * prdev prints a warning message of the
140  * form "mesg on dev x/y".
141  * x and y are the major and minor parts of
142  * the device argument.
143  */
144 prdev(str, dev)
145 char *str;
146 dev_t dev;
147 {
148 
149 	printf("%s on dev %u/%u\n", str, major(dev), minor(dev));
150 }
151 
152 /*
153  * deverr prints a diagnostic from
154  * a device driver.
155  * It prints the device, block number,
156  * and an octal word (usually some error
157  * status register) passed as argument.
158  */
159 deverror(bp, o1, o2)
160 register struct buf *bp;
161 {
162 
163 	prdev("err", bp->b_dev);
164 	printf("bn=%d er=%x,%x\n", bp->b_blkno, o1,o2);
165 }
166 
167 #ifdef TRACE
168 dumptrc()
169 {
170 	register char *cp;
171 	register int pos, nch;
172 
173 	nch = trcprt;
174 	if (nch < 0 || nch > TRCBUFS)
175 		nch = TRCBUFS;
176 	pos = (trcbufp - trcbuf) - nch;
177 	if (pos < 0)
178 		if (trcwrap)
179 			pos += TRCBUFS;
180 		else {
181 			nch += pos;
182 			pos = 0;
183 		}
184 	for (cp = &trcbuf[pos]; nch > 0; nch--) {
185 		putchar(*cp++, 0);
186 		if (cp >= &trcbuf[TRCBUFS])
187 			cp = trcbuf;
188 	}
189 }
190 #else
191 /*ARGSUSED*/
192 dumptrc(nch)
193 	int nch;
194 {
195 
196 }
197 #endif
198 
199 char	*msgbufp = msgbuf;	/* Next saved printf character */
200 /*
201  * Print a character on console or in internal trace buffer.
202  * If destination is console then the last MSGBUFS characters
203  * are saved in msgbuf for inspection later.
204  */
205 putchar(c, trace)
206 register c;
207 {
208 	register s, timo;
209 
210 #ifdef TRACE
211 	if (trace) {
212 		*trcbufp++ = c;
213 		if (trcbufp >= &trcbuf[TRCBUFS]) {
214 			trcbufp = trcbuf;
215 			trcwrap = 1;
216 		}
217 		return;
218 	}
219 #endif
220 	if (c != '\0' && c != '\r' && c != 0177) {
221 		*msgbufp++ = c;
222 		if (msgbufp >= &msgbuf[MSGBUFS])
223 			msgbufp = msgbuf;
224 	}
225 	if (c == 0)
226 		return;
227 	cnputc(c);
228 }
229