|
|
1.1.1.2 root 1: /*
1.1 root 2: * Mach Operating System
3: * Copyright (c) 1991,1990 Carnegie Mellon University
4: * All Rights Reserved.
1.1.1.2 root 5: *
1.1 root 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.
1.1.1.2 root 11: *
1.1 root 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.
1.1.1.2 root 15: *
1.1 root 16: * Carnegie Mellon requests users of this software to return to
1.1.1.2 root 17: *
1.1 root 18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
1.1.1.2 root 22: *
1.1 root 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: #if MACH_KDB
32:
33: /*
34: * Printf and character output for debugger.
35: */
36:
1.1.1.3 root 37: #include <kern/printf.h>
1.1.1.2 root 38: #include <stdarg.h>
1.1 root 39: #include <mach/boolean.h>
40: #include <machine/db_machdep.h>
1.1.1.3 root 41: #include <device/cons.h>
42: #include <ddb/db_command.h>
1.1 root 43: #include <ddb/db_lex.h>
44: #include <ddb/db_output.h>
1.1.1.4 root 45: #include <ddb/db_input.h>
1.1 root 46:
47: /*
48: * Character output - tracks position in line.
49: * To do this correctly, we should know how wide
50: * the output device is - then we could zero
51: * the line position when the output device wraps
52: * around to the start of the next line.
53: *
54: * Instead, we count the number of spaces printed
55: * since the last printing character so that we
56: * don't print trailing spaces. This avoids most
57: * of the wraparounds.
58: */
59:
60: #ifndef DB_MAX_LINE
61: #define DB_MAX_LINE 24 /* maximum line */
62: #define DB_MAX_WIDTH 80 /* maximum width */
1.1.1.2 root 63: #endif /* DB_MAX_LINE */
1.1 root 64:
65: #define DB_MIN_MAX_WIDTH 20 /* minimum max width */
66: #define DB_MIN_MAX_LINE 3 /* minimum max line */
67: #define CTRL(c) ((c) & 0xff)
68:
69: int db_output_position = 0; /* output column */
70: int db_output_line = 0; /* output line number */
71: int db_last_non_space = 0; /* last non-space character */
72: int db_tab_stop_width = 8; /* how wide are tab stops? */
73: #define NEXT_TAB(i) \
74: ((((i) + db_tab_stop_width) / db_tab_stop_width) * db_tab_stop_width)
75: int db_max_line = DB_MAX_LINE; /* output max lines */
76: int db_max_width = DB_MAX_WIDTH; /* output line width */
77:
78: /*
79: * Force pending whitespace.
80: */
81: void
1.1.1.3 root 82: db_force_whitespace(void)
1.1 root 83: {
1.1.1.4 root 84: int last_print, next_tab;
1.1 root 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: static void
1.1.1.4 root 102: db_more(void)
1.1 root 103: {
1.1.1.4 root 104: char *p;
1.1 root 105: boolean_t quit_output = FALSE;
106:
107: for (p = "--db_more--"; *p; p++)
108: cnputc(*p);
109: switch(cngetc()) {
110: case ' ':
111: db_output_line = 0;
112: break;
113: case 'q':
114: case CTRL('c'):
115: db_output_line = 0;
116: quit_output = TRUE;
117: break;
118: default:
119: db_output_line--;
120: break;
121: }
122: p = "\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b";
123: while (*p)
124: cnputc(*p++);
125: if (quit_output) {
126: db_error(0);
127: /* NOTREACHED */
128: }
129: }
130:
131: /*
132: * Output character. Buffer whitespace.
133: */
134: void
1.1.1.4 root 135: db_putchar(int c) /* character to output */
1.1 root 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
1.1.1.5 root 149: && db_output_position >= db_max_width) {
1.1 root 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: */
1.1.1.4 root 190: int __attribute__ ((pure))
1.1.1.3 root 191: db_print_position(void)
1.1 root 192: {
193: return (db_output_position);
194: }
195:
196: /*
197: * End line if too long.
198: */
1.1.1.3 root 199: void db_end_line(void)
1.1 root 200: {
201: if (db_output_position >= db_max_width-1)
202: db_printf("\n");
203: }
204:
205: /*VARARGS1*/
1.1.1.6 ! root 206: int
1.1.1.2 root 207: db_printf(const char *fmt, ...)
1.1 root 208: {
209: va_list listp;
210:
1.1.1.2 root 211: va_start(listp, fmt);
1.1.1.3 root 212: _doprnt(fmt, listp, db_id_putc, db_radix, 0);
1.1 root 213: va_end(listp);
1.1.1.6 ! root 214: return 0;
1.1 root 215: }
216:
1.1.1.2 root 217: #endif /* MACH_KDB */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.