386BSD 0.1 development
[unix-history] / usr / src / sys.386bsd / ddb / db_output.c
CommitLineData
c1cfdb7a
WJ
1/*
2 * Mach Operating System
3 * Copyright (c) 1991,1990 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie the
24 * rights to redistribute these changes.
25 */
26/*
27 * HISTORY
28 * $Log: db_output.c,v $
29 * Revision 1.1 1992/03/25 21:45:18 pace
30 * Initial revision
31 *
32 * Revision 2.3 91/02/05 17:06:45 mrt
33 * Changed to new Mach copyright
34 * [91/01/31 16:18:41 mrt]
35 *
36 * Revision 2.2 90/08/27 21:51:25 dbg
37 * Put extra features of db_doprnt in _doprnt.
38 * [90/08/20 dbg]
39 * Reduce lint.
40 * [90/08/07 dbg]
41 * Created.
42 * [90/07/25 dbg]
43 *
44 */
45/*
46 * Author: David B. Golub, Carnegie Mellon University
47 * Date: 7/90
48 */
49
50/*
51 * Printf and character output for debugger.
52 */
53
54#include "param.h"
55#include <machine/stdarg.h>
56
57/*
58 * Character output - tracks position in line.
59 * To do this correctly, we should know how wide
60 * the output device is - then we could zero
61 * the line position when the output device wraps
62 * around to the start of the next line.
63 *
64 * Instead, we count the number of spaces printed
65 * since the last printing character so that we
66 * don't print trailing spaces. This avoids most
67 * of the wraparounds.
68 */
69int db_output_position = 0; /* output column */
70int db_last_non_space = 0; /* last non-space character */
71int db_tab_stop_width = 8; /* how wide are tab stops? */
72#define NEXT_TAB(i) \
73 ((((i) + db_tab_stop_width) / db_tab_stop_width) * db_tab_stop_width)
74int db_max_width = 80; /* output line width */
75
76extern void db_check_interrupt();
77
78/*
79 * Force pending whitespace.
80 */
81void
82db_force_whitespace()
83{
84 register int last_print, next_tab;
85
86 last_print = db_last_non_space;
87 while (last_print < db_output_position) {
88 next_tab = NEXT_TAB(last_print);
89 if (next_tab <= db_output_position) {
90 cnputc('\t');
91 last_print = next_tab;
92 }
93 else {
94 cnputc(' ');
95 last_print++;
96 }
97 }
98 db_last_non_space = db_output_position;
99}
100
101/*
102 * Output character. Buffer whitespace.
103 */
104db_putchar(c)
105 int c; /* character to output */
106{
107 if (c > ' ' && c <= '~') {
108 /*
109 * Printing character.
110 * If we have spaces to print, print them first.
111 * Use tabs if possible.
112 */
113 db_force_whitespace();
114 cnputc(c);
115 db_output_position++;
116 db_last_non_space = db_output_position;
117 }
118 else if (c == '\n') {
119 /* Return */
120 cnputc(c);
121 db_output_position = 0;
122 db_last_non_space = 0;
123 db_check_interrupt();
124 }
125 else if (c == '\t') {
126 /* assume tabs every 8 positions */
127 db_output_position = NEXT_TAB(db_output_position);
128 }
129 else if (c == ' ') {
130 /* space */
131 db_output_position++;
132 }
133 else if (c == '\007') {
134 /* bell */
135 cnputc(c);
136 }
137 /* other characters are assumed non-printing */
138}
139
140/*
141 * Return output position
142 */
143int
144db_print_position()
145{
146 return (db_output_position);
147}
148
149/*
150 * End line if too long.
151 */
152void
153db_end_line()
154{
155 if (db_output_position >= db_max_width)
156 db_printf("\n");
157}
158
159/*
160 * Printing
161 */
162extern int db_radix;
163
164/*VARARGS1*/
165db_printf(char *fmt, ...)
166{
167 va_list listp;
168 va_start(listp, fmt);
169 db_printf_guts (fmt, listp);
170 va_end(listp);
171}
172
173/* alternate name */
174
175/*VARARGS1*/
176kdbprintf(char *fmt, ...)
177{
178 va_list listp;
179 va_start(listp, fmt);
180 db_printf_guts (fmt, listp);
181 va_end(listp);
182}
183
184/*
185 * Put a number (base <= 16) in a buffer in reverse order; return an
186 * optional length and a pointer to the NULL terminated (preceded?)
187 * buffer.
188 */
189static char *
190db_ksprintn(ul, base, lenp)
191 register u_long ul;
192 register int base, *lenp;
193{ /* A long in base 8, plus NULL. */
194 static char buf[sizeof(long) * NBBY / 3 + 2];
195 register char *p;
196
197 p = buf;
198 do {
199 *++p = "0123456789abcdef"[ul % base];
200 } while (ul /= base);
201 if (lenp)
202 *lenp = p - buf;
203 return (p);
204}
205
206db_printf_guts(fmt, ap)
207 register const char *fmt;
208 va_list ap;
209{
210 register char *p;
211 register int ch, n;
212 u_long ul;
213 int base, lflag, tmp, width;
214 char padc;
215 int ladjust;
216 int sharpflag;
217 int neg;
218
219 for (;;) {
220 padc = ' ';
221 width = 0;
222 while ((ch = *(u_char *)fmt++) != '%') {
223 if (ch == '\0')
224 return;
225 db_putchar(ch);
226 }
227 lflag = 0;
228 ladjust = 0;
229 sharpflag = 0;
230 neg = 0;
231reswitch: switch (ch = *(u_char *)fmt++) {
232 case '0':
233 padc = '0';
234 goto reswitch;
235 case '1': case '2': case '3': case '4':
236 case '5': case '6': case '7': case '8': case '9':
237 for (width = 0;; ++fmt) {
238 width = width * 10 + ch - '0';
239 ch = *fmt;
240 if (ch < '0' || ch > '9')
241 break;
242 }
243 goto reswitch;
244 case 'l':
245 lflag = 1;
246 goto reswitch;
247 case '-':
248 ladjust = 1;
249 goto reswitch;
250 case '#':
251 sharpflag = 1;
252 goto reswitch;
253 case 'b':
254 ul = va_arg(ap, int);
255 p = va_arg(ap, char *);
256 for (p = db_ksprintn(ul, *p++, NULL); ch = *p--;)
257 db_putchar(ch);
258
259 if (!ul)
260 break;
261
262 for (tmp = 0; n = *p++;) {
263 if (ul & (1 << (n - 1))) {
264 db_putchar(tmp ? ',' : '<');
265 for (; (n = *p) > ' '; ++p)
266 db_putchar(n);
267 tmp = 1;
268 } else
269 for (; *p > ' '; ++p);
270 }
271 if (tmp)
272 db_putchar('>');
273 break;
274 case '*':
275 width = va_arg (ap, int);
276 if (width < 0) {
277 ladjust = !ladjust;
278 width = -width;
279 }
280 goto reswitch;
281 case 'c':
282 db_putchar(va_arg(ap, int));
283 break;
284 case 's':
285 p = va_arg(ap, char *);
286 width -= strlen (p);
287 if (!ladjust && width > 0)
288 while (width--)
289 db_putchar (padc);
290 while (ch = *p++)
291 db_putchar(ch);
292 if (ladjust && width > 0)
293 while (width--)
294 db_putchar (padc);
295 break;
296 case 'r':
297 ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
298 if ((long)ul < 0) {
299 neg = 1;
300 ul = -(long)ul;
301 }
302 base = db_radix;
303 if (base < 8 || base > 16)
304 base = 10;
305 goto number;
306 case 'n':
307 ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
308 base = db_radix;
309 if (base < 8 || base > 16)
310 base = 10;
311 goto number;
312 case 'd':
313 ul = lflag ? va_arg(ap, long) : va_arg(ap, int);
314 if ((long)ul < 0) {
315 neg = 1;
316 ul = -(long)ul;
317 }
318 base = 10;
319 goto number;
320 case 'o':
321 ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
322 base = 8;
323 goto number;
324 case 'u':
325 ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
326 base = 10;
327 goto number;
328 case 'z':
329 ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
330 if ((long)ul < 0) {
331 neg = 1;
332 ul = -(long)ul;
333 }
334 base = 16;
335 goto number;
336 case 'x':
337 ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
338 base = 16;
339number: p = (char *)db_ksprintn(ul, base, &tmp);
340 if (sharpflag && ul != 0) {
341 if (base == 8)
342 tmp++;
343 else if (base == 16)
344 tmp += 2;
345 }
346 if (neg)
347 tmp++;
348
349 if (!ladjust && width && (width -= tmp) > 0)
350 while (width--)
351 db_putchar(padc);
352 if (neg)
353 db_putchar ('-');
354 if (sharpflag && ul != 0) {
355 if (base == 8) {
356 db_putchar ('0');
357 } else if (base == 16) {
358 db_putchar ('0');
359 db_putchar ('x');
360 }
361 }
362 if (ladjust && width && (width -= tmp) > 0)
363 while (width--)
364 db_putchar(padc);
365
366 while (ch = *p--)
367 db_putchar(ch);
368 break;
369 default:
370 db_putchar('%');
371 if (lflag)
372 db_putchar('l');
373 /* FALLTHROUGH */
374 case '%':
375 db_putchar(ch);
376 }
377 }
378}
379