|
|
1.1 root 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 [email protected]
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.
1.1.1.2 root 25: *
26: * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
27: * -------------------- ----- ----------------------
28: * CURRENT PATCH LEVEL: 4 00083
29: * -------------------- ----- ----------------------
30: *
31: * 14 Mar 93 Chris G. Demetriou Fixed so that tab is not output,
32: * use spaces instead.
1.1 root 33: */
34: /*
1.1.1.3 ! root 35: * db_output.c,v 1.3 1993/05/20 03:39:21 cgd Exp
! 36: *
1.1 root 37: * HISTORY
1.1.1.3 ! root 38: * db_output.c,v
! 39: * Revision 1.3 1993/05/20 03:39:21 cgd
! 40: * add explicit rcs id
! 41: *
! 42: * Revision 1.2 1993/03/21 18:08:08 cgd
1.1.1.2 root 43: * after 0.2.2 "stable" patches applied
44: *
45: * Revision 1.1.1.1 93/03/21 09:46:26 cgd
46: * initial import of 386bsd-0.1 sources
47: *
1.1 root 48: * Revision 1.1 1992/03/25 21:45:18 pace
49: * Initial revision
50: *
51: * Revision 2.3 91/02/05 17:06:45 mrt
52: * Changed to new Mach copyright
53: * [91/01/31 16:18:41 mrt]
54: *
55: * Revision 2.2 90/08/27 21:51:25 dbg
56: * Put extra features of db_doprnt in _doprnt.
57: * [90/08/20 dbg]
58: * Reduce lint.
59: * [90/08/07 dbg]
60: * Created.
61: * [90/07/25 dbg]
62: *
63: */
64: /*
65: * Author: David B. Golub, Carnegie Mellon University
66: * Date: 7/90
67: */
68:
69: /*
70: * Printf and character output for debugger.
71: */
72:
73: #include "param.h"
74: #include <machine/stdarg.h>
75:
76: /*
77: * Character output - tracks position in line.
78: * To do this correctly, we should know how wide
79: * the output device is - then we could zero
80: * the line position when the output device wraps
81: * around to the start of the next line.
82: *
83: * Instead, we count the number of spaces printed
84: * since the last printing character so that we
85: * don't print trailing spaces. This avoids most
86: * of the wraparounds.
87: */
1.1.1.3 ! root 88:
! 89: #ifndef DB_MAX_LINE
! 90: #define DB_MAX_LINE 24 /* maximum line */
! 91: #define DB_MAX_WIDTH 80 /* maximum width */
! 92: #endif DB_MAX_LINE
! 93:
! 94: #define DB_MIN_MAX_WIDTH 20 /* minimum max width */
! 95: #define DB_MIN_MAX_LINE 3 /* minimum max line */
! 96: #define CTRL(c) ((c) & 0xff)
! 97:
1.1 root 98: int db_output_position = 0; /* output column */
1.1.1.3 ! root 99: int db_output_line = 0; /* output line number */
1.1 root 100: int db_last_non_space = 0; /* last non-space character */
101: int db_tab_stop_width = 8; /* how wide are tab stops? */
102: #define NEXT_TAB(i) \
103: ((((i) + db_tab_stop_width) / db_tab_stop_width) * db_tab_stop_width)
1.1.1.3 ! root 104: int db_max_line = DB_MAX_LINE; /* output max lines */
! 105: int db_max_width = DB_MAX_WIDTH; /* output line width */
1.1 root 106:
107: extern void db_check_interrupt();
108:
109: /*
110: * Force pending whitespace.
111: */
112: void
113: db_force_whitespace()
114: {
115: register int last_print, next_tab;
116:
117: last_print = db_last_non_space;
118: while (last_print < db_output_position) {
119: next_tab = NEXT_TAB(last_print);
120: if (next_tab <= db_output_position) {
1.1.1.2 root 121: while (last_print < next_tab) { /* DON'T send a tab!!! */
122: cnputc(' ');
123: last_print++;
124: }
1.1 root 125: }
126: else {
127: cnputc(' ');
128: last_print++;
129: }
130: }
131: db_last_non_space = db_output_position;
132: }
133:
1.1.1.3 ! root 134: static void
! 135: db_more()
! 136: {
! 137: register char *p;
! 138: int quit_output = 0;
! 139:
! 140: for (p = "--db_more--"; *p; p++)
! 141: cnputc(*p);
! 142: switch(cngetc()) {
! 143: case ' ':
! 144: db_output_line = 0;
! 145: break;
! 146: case 'q':
! 147: case CTRL('c'):
! 148: db_output_line = 0;
! 149: quit_output = 1;
! 150: break;
! 151: default:
! 152: db_output_line--;
! 153: break;
! 154: }
! 155: p = "\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b";
! 156: while (*p)
! 157: cnputc(*p++);
! 158: if (quit_output) {
! 159: db_error(0);
! 160: /* NOTREACHED */
! 161: }
! 162: }
! 163:
1.1 root 164: /*
165: * Output character. Buffer whitespace.
166: */
167: db_putchar(c)
168: int c; /* character to output */
169: {
1.1.1.3 ! root 170: if (db_max_line >= DB_MIN_MAX_LINE && db_output_line >= db_max_line-1)
! 171: db_more();
1.1 root 172: if (c > ' ' && c <= '~') {
173: /*
174: * Printing character.
175: * If we have spaces to print, print them first.
176: * Use tabs if possible.
177: */
178: db_force_whitespace();
179: cnputc(c);
180: db_output_position++;
1.1.1.3 ! root 181: if (db_max_width >= DB_MIN_MAX_WIDTH
! 182: && db_output_position >= db_max_width-1) {
! 183: /* auto new line */
! 184: cnputc('\n');
! 185: db_output_position = 0;
! 186: db_last_non_space = 0;
! 187: db_output_line++;
! 188: }
1.1 root 189: db_last_non_space = db_output_position;
190: }
191: else if (c == '\n') {
192: /* Return */
193: cnputc(c);
194: db_output_position = 0;
195: db_last_non_space = 0;
1.1.1.3 ! root 196: db_output_line++;
1.1 root 197: db_check_interrupt();
198: }
199: else if (c == '\t') {
200: /* assume tabs every 8 positions */
201: db_output_position = NEXT_TAB(db_output_position);
202: }
203: else if (c == ' ') {
204: /* space */
205: db_output_position++;
206: }
207: else if (c == '\007') {
208: /* bell */
209: cnputc(c);
210: }
211: /* other characters are assumed non-printing */
212: }
213:
214: /*
215: * Return output position
216: */
217: int
218: db_print_position()
219: {
220: return (db_output_position);
221: }
222:
223: /*
224: * Printing
225: */
226: extern int db_radix;
227:
228: /*VARARGS1*/
229: db_printf(char *fmt, ...)
230: {
231: va_list listp;
232: va_start(listp, fmt);
233: db_printf_guts (fmt, listp);
234: va_end(listp);
235: }
236:
237: /* alternate name */
238:
239: /*VARARGS1*/
240: kdbprintf(char *fmt, ...)
241: {
242: va_list listp;
243: va_start(listp, fmt);
244: db_printf_guts (fmt, listp);
245: va_end(listp);
246: }
247:
248: /*
1.1.1.3 ! root 249: * End line if too long.
! 250: */
! 251: void
! 252: db_end_line()
! 253: {
! 254: if (db_output_position >= db_max_width)
! 255: db_printf("\n");
! 256: }
! 257:
! 258: /*
1.1 root 259: * Put a number (base <= 16) in a buffer in reverse order; return an
260: * optional length and a pointer to the NULL terminated (preceded?)
261: * buffer.
262: */
263: static char *
264: db_ksprintn(ul, base, lenp)
265: register u_long ul;
266: register int base, *lenp;
267: { /* A long in base 8, plus NULL. */
268: static char buf[sizeof(long) * NBBY / 3 + 2];
269: register char *p;
270:
271: p = buf;
272: do {
273: *++p = "0123456789abcdef"[ul % base];
274: } while (ul /= base);
275: if (lenp)
276: *lenp = p - buf;
277: return (p);
278: }
279:
280: db_printf_guts(fmt, ap)
281: register const char *fmt;
282: va_list ap;
283: {
284: register char *p;
285: register int ch, n;
286: u_long ul;
287: int base, lflag, tmp, width;
288: char padc;
289: int ladjust;
290: int sharpflag;
291: int neg;
292:
293: for (;;) {
294: padc = ' ';
295: width = 0;
296: while ((ch = *(u_char *)fmt++) != '%') {
297: if (ch == '\0')
298: return;
299: db_putchar(ch);
300: }
301: lflag = 0;
302: ladjust = 0;
303: sharpflag = 0;
304: neg = 0;
305: reswitch: switch (ch = *(u_char *)fmt++) {
306: case '0':
307: padc = '0';
308: goto reswitch;
309: case '1': case '2': case '3': case '4':
310: case '5': case '6': case '7': case '8': case '9':
311: for (width = 0;; ++fmt) {
312: width = width * 10 + ch - '0';
313: ch = *fmt;
314: if (ch < '0' || ch > '9')
315: break;
316: }
317: goto reswitch;
318: case 'l':
319: lflag = 1;
320: goto reswitch;
321: case '-':
322: ladjust = 1;
323: goto reswitch;
324: case '#':
325: sharpflag = 1;
326: goto reswitch;
327: case 'b':
328: ul = va_arg(ap, int);
329: p = va_arg(ap, char *);
330: for (p = db_ksprintn(ul, *p++, NULL); ch = *p--;)
331: db_putchar(ch);
332:
333: if (!ul)
334: break;
335:
336: for (tmp = 0; n = *p++;) {
337: if (ul & (1 << (n - 1))) {
338: db_putchar(tmp ? ',' : '<');
339: for (; (n = *p) > ' '; ++p)
340: db_putchar(n);
341: tmp = 1;
342: } else
343: for (; *p > ' '; ++p);
344: }
345: if (tmp)
346: db_putchar('>');
347: break;
348: case '*':
349: width = va_arg (ap, int);
350: if (width < 0) {
351: ladjust = !ladjust;
352: width = -width;
353: }
354: goto reswitch;
355: case 'c':
356: db_putchar(va_arg(ap, int));
357: break;
358: case 's':
359: p = va_arg(ap, char *);
360: width -= strlen (p);
361: if (!ladjust && width > 0)
362: while (width--)
363: db_putchar (padc);
364: while (ch = *p++)
365: db_putchar(ch);
366: if (ladjust && width > 0)
367: while (width--)
368: db_putchar (padc);
369: break;
370: case 'r':
371: ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
372: if ((long)ul < 0) {
373: neg = 1;
374: ul = -(long)ul;
375: }
376: base = db_radix;
377: if (base < 8 || base > 16)
378: base = 10;
379: goto number;
380: case 'n':
381: ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
382: base = db_radix;
383: if (base < 8 || base > 16)
384: base = 10;
385: goto number;
386: case 'd':
387: ul = lflag ? va_arg(ap, long) : va_arg(ap, int);
388: if ((long)ul < 0) {
389: neg = 1;
390: ul = -(long)ul;
391: }
392: base = 10;
393: goto number;
394: case 'o':
395: ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
396: base = 8;
397: goto number;
398: case 'u':
399: ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
400: base = 10;
401: goto number;
402: case 'z':
403: ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
404: if ((long)ul < 0) {
405: neg = 1;
406: ul = -(long)ul;
407: }
408: base = 16;
409: goto number;
410: case 'x':
411: ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
412: base = 16;
413: number: p = (char *)db_ksprintn(ul, base, &tmp);
414: if (sharpflag && ul != 0) {
415: if (base == 8)
416: tmp++;
417: else if (base == 16)
418: tmp += 2;
419: }
420: if (neg)
421: tmp++;
422:
423: if (!ladjust && width && (width -= tmp) > 0)
424: while (width--)
425: db_putchar(padc);
426: if (neg)
427: db_putchar ('-');
428: if (sharpflag && ul != 0) {
429: if (base == 8) {
430: db_putchar ('0');
431: } else if (base == 16) {
432: db_putchar ('0');
433: db_putchar ('x');
434: }
435: }
436: if (ladjust && width && (width -= tmp) > 0)
437: while (width--)
438: db_putchar(padc);
439:
440: while (ch = *p--)
441: db_putchar(ch);
442: break;
443: default:
444: db_putchar('%');
445: if (lflag)
446: db_putchar('l');
447: /* FALLTHROUGH */
448: case '%':
449: db_putchar(ch);
450: }
451: }
452: }
453:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.