|
|
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 "AS IS"
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 Mellon
24: * the rights to redistribute these changes.
25: */
26: /*
27: * Author: David B. Golub, Carnegie Mellon University
28: * Date: 7/90
29: */
30:
31: #include "mach_kdb.h"
32: #if MACH_KDB
33:
34: /*
35: * Printf and character output for debugger.
36: */
37:
38: #include <mach/boolean.h>
39: #include <sys/varargs.h>
40: #include <machine/db_machdep.h>
41: #include <ddb/db_lex.h>
42: #include <ddb/db_output.h>
43:
44: /*
45: * Character output - tracks position in line.
46: * To do this correctly, we should know how wide
47: * the output device is - then we could zero
48: * the line position when the output device wraps
49: * around to the start of the next line.
50: *
51: * Instead, we count the number of spaces printed
52: * since the last printing character so that we
53: * don't print trailing spaces. This avoids most
54: * of the wraparounds.
55: */
56:
57: #ifndef DB_MAX_LINE
58: #define DB_MAX_LINE 24 /* maximum line */
59: #define DB_MAX_WIDTH 80 /* maximum width */
60: #endif DB_MAX_LINE
61:
62: #define DB_MIN_MAX_WIDTH 20 /* minimum max width */
63: #define DB_MIN_MAX_LINE 3 /* minimum max line */
64: #define CTRL(c) ((c) & 0xff)
65:
66: int db_output_position = 0; /* output column */
67: int db_output_line = 0; /* output line number */
68: int db_last_non_space = 0; /* last non-space character */
69: int db_tab_stop_width = 8; /* how wide are tab stops? */
70: #define NEXT_TAB(i) \
71: ((((i) + db_tab_stop_width) / db_tab_stop_width) * db_tab_stop_width)
72: int db_max_line = DB_MAX_LINE; /* output max lines */
73: int db_max_width = DB_MAX_WIDTH; /* output line width */
74:
75: extern void db_check_interrupt();
76:
77: /*
78: * Force pending whitespace.
79: */
80: void
81: db_force_whitespace()
82: {
83: register int last_print, next_tab;
84:
85: last_print = db_last_non_space;
86: while (last_print < db_output_position) {
87: next_tab = NEXT_TAB(last_print);
88: if (next_tab <= db_output_position) {
89: cnputc('\t');
90: last_print = next_tab;
91: }
92: else {
93: cnputc(' ');
94: last_print++;
95: }
96: }
97: db_last_non_space = db_output_position;
98: }
99:
100: static void
101: db_more()
102: {
103: register char *p;
104: boolean_t quit_output = FALSE;
105:
106: for (p = "--db_more--"; *p; p++)
107: cnputc(*p);
108: switch(cngetc()) {
109: case ' ':
110: db_output_line = 0;
111: break;
112: case 'q':
113: case CTRL('c'):
114: db_output_line = 0;
115: quit_output = TRUE;
116: break;
117: default:
118: db_output_line--;
119: break;
120: }
121: p = "\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b";
122: while (*p)
123: cnputc(*p++);
124: if (quit_output) {
125: db_error(0);
126: /* NOTREACHED */
127: }
128: }
129:
130: /*
131: * Output character. Buffer whitespace.
132: */
133: void
134: db_putchar(c)
135: int c; /* character to output */
136: {
137: if (db_max_line >= DB_MIN_MAX_LINE && db_output_line >= db_max_line-1)
138: db_more();
139: if (c > ' ' && c <= '~') {
140: /*
141: * Printing character.
142: * If we have spaces to print, print them first.
143: * Use tabs if possible.
144: */
145: db_force_whitespace();
146: cnputc(c);
147: db_output_position++;
148: if (db_max_width >= DB_MIN_MAX_WIDTH
149: && db_output_position >= db_max_width-1) {
150: /* auto new line */
151: cnputc('\n');
152: db_output_position = 0;
153: db_last_non_space = 0;
154: db_output_line++;
155: }
156: db_last_non_space = db_output_position;
157: }
158: else if (c == '\n') {
159: /* Return */
160: cnputc(c);
161: db_output_position = 0;
162: db_last_non_space = 0;
163: db_output_line++;
164: db_check_interrupt();
165: }
166: else if (c == '\t') {
167: /* assume tabs every 8 positions */
168: db_output_position = NEXT_TAB(db_output_position);
169: }
170: else if (c == ' ') {
171: /* space */
172: db_output_position++;
173: }
174: else if (c == '\007') {
175: /* bell */
176: cnputc(c);
177: }
178: /* other characters are assumed non-printing */
179: }
180:
181: void
182: db_id_putc(char c, vm_offset_t dummy)
183: {
184: db_putchar(c);
185: }
186:
187: /*
188: * Return output position
189: */
190: int
191: db_print_position()
192: {
193: return (db_output_position);
194: }
195:
196: /*
197: * End line if too long.
198: */
199: void db_end_line()
200: {
201: if (db_output_position >= db_max_width-1)
202: db_printf("\n");
203: }
204:
205: /*
206: * Printing
207: */
208: extern void _doprnt();
209:
210: /*VARARGS1*/
211: void
212: db_printf( fmt, va_alist)
213: char * fmt;
214: va_dcl
215: {
216: va_list listp;
217:
218: #ifdef db_printf_enter
219: db_printf_enter(); /* optional multiP serialization */
220: #endif
221: va_start(listp);
222: _doprnt(fmt, &listp, db_id_putc, db_radix, 0);
223: va_end(listp);
224: }
225:
226: /* alternate name */
227:
228: /*VARARGS1*/
229: void
230: kdbprintf(fmt, va_alist)
231: char * fmt;
232: va_dcl
233: {
234: va_list listp;
235: va_start(listp);
236: _doprnt(fmt, &listp, db_id_putc, db_radix, 0);
237: va_end(listp);
238: }
239:
240: #endif MACH_KDB
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.