xref: /original-bsd/sys/hp300/stand/prf.c (revision f43fc9d7)
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.2 (Berkeley) 06/24/90
8  */
9 
10 #include "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