FreeBSD/Linux Kernel Cross Reference
sys/ddb/db_output.c
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 * Author: David B. Golub, Carnegie Mellon University
28 * Date: 7/90
29 */
30
31 /*
32 * Printf and character output for debugger.
33 */
34
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD: releng/5.2/sys/ddb/db_output.c 118268 2003-07-31 17:27:52Z jhb $");
37
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/cons.h>
41
42 #include <machine/stdarg.h>
43
44 #include <ddb/ddb.h>
45 #include <ddb/db_output.h>
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 static int db_output_position = 0; /* output column */
60 static int db_last_non_space = 0; /* last non-space character */
61 db_expr_t db_tab_stop_width = 8; /* how wide are tab stops? */
62 #define NEXT_TAB(i) \
63 ((((i) + db_tab_stop_width) / db_tab_stop_width) * db_tab_stop_width)
64 db_expr_t db_max_width = 79; /* output line width */
65 static int db_newlines; /* # lines this page */
66 static int db_maxlines = -1; /* max lines per page */
67 static db_page_calloutfcn_t *db_page_callout = NULL;
68 static void *db_page_callout_arg = NULL;
69
70 static void db_putchar(int c, void *arg);
71
72 /*
73 * Force pending whitespace.
74 */
75 void
76 db_force_whitespace()
77 {
78 register int last_print, next_tab;
79
80 last_print = db_last_non_space;
81 while (last_print < db_output_position) {
82 next_tab = NEXT_TAB(last_print);
83 if (next_tab <= db_output_position) {
84 while (last_print < next_tab) { /* DON'T send a tab!!! */
85 cnputc(' ');
86 last_print++;
87 }
88 }
89 else {
90 cnputc(' ');
91 last_print++;
92 }
93 }
94 db_last_non_space = db_output_position;
95 }
96
97 /*
98 * Output character. Buffer whitespace.
99 */
100 static void
101 db_putchar(c, arg)
102 int c; /* character to output */
103 void * arg;
104 {
105
106 if (c > ' ' && c <= '~') {
107 /*
108 * Printing character.
109 * If we have spaces to print, print them first.
110 * Use tabs if possible.
111 */
112 db_force_whitespace();
113 cnputc(c);
114 db_output_position++;
115 db_last_non_space = db_output_position;
116 }
117 else if (c == '\n') {
118 /* Newline */
119 cnputc(c);
120 db_output_position = 0;
121 db_last_non_space = 0;
122 db_check_interrupt();
123 if (db_maxlines > 0 && db_page_callout != NULL) {
124 db_newlines++;
125 if (db_newlines >= db_maxlines) {
126 db_maxlines = -1;
127 db_page_callout(db_page_callout_arg);
128 }
129 }
130 }
131 else if (c == '\r') {
132 /* Return */
133 cnputc(c);
134 db_output_position = 0;
135 db_last_non_space = 0;
136 db_check_interrupt();
137 }
138 else if (c == '\t') {
139 /* assume tabs every 8 positions */
140 db_output_position = NEXT_TAB(db_output_position);
141 }
142 else if (c == ' ') {
143 /* space */
144 db_output_position++;
145 }
146 else if (c == '\007') {
147 /* bell */
148 cnputc(c);
149 }
150 /* other characters are assumed non-printing */
151 }
152
153 /*
154 * Register callout for providing a pager for output.
155 */
156 void
157 db_setup_paging(db_page_calloutfcn_t *callout, void *arg, int maxlines)
158 {
159
160 db_page_callout = callout;
161 db_page_callout_arg = arg;
162 db_maxlines = maxlines;
163 db_newlines = 0;
164 }
165
166 /*
167 * A simple paging callout function. If the argument is not null, it
168 * points to an integer that will be set to 1 if the user asks to quit.
169 */
170 void
171 db_simple_pager(void *arg)
172 {
173 int c;
174
175 db_printf("--More--\r");
176 for (;;) {
177 c = cngetc();
178 switch (c) {
179 case '\n':
180 /* Just one more line. */
181 db_setup_paging(db_simple_pager, arg, 1);
182 return;
183 case ' ':
184 /* Another page. */
185 db_setup_paging(db_simple_pager, arg,
186 DB_LINES_PER_PAGE);
187 return;
188 case 'q':
189 case 'Q':
190 case 'x':
191 case 'X':
192 /* Quit */
193 if (arg != NULL) {
194 *(int *)arg = 1;
195 db_printf("\n");
196 return;
197 }
198 #if 0
199 /* FALLTHROUGH */
200 default:
201 cnputc('\007');
202 #endif
203 }
204 }
205 }
206
207 /*
208 * Return output position
209 */
210 int
211 db_print_position()
212 {
213 return (db_output_position);
214 }
215
216 /*
217 * Printing
218 */
219 void
220 #if __STDC__
221 db_printf(const char *fmt, ...)
222 #else
223 db_printf(fmt)
224 const char *fmt;
225 #endif
226 {
227 va_list listp;
228
229 va_start(listp, fmt);
230 kvprintf (fmt, db_putchar, NULL, db_radix, listp);
231 va_end(listp);
232 }
233
234 int db_indent;
235
236 void
237 #if __STDC__
238 db_iprintf(const char *fmt,...)
239 #else
240 db_iprintf(fmt)
241 const char *fmt;
242 #endif
243 {
244 register int i;
245 va_list listp;
246
247 for (i = db_indent; i >= 8; i -= 8)
248 db_printf("\t");
249 while (--i >= 0)
250 db_printf(" ");
251 va_start(listp, fmt);
252 kvprintf (fmt, db_putchar, NULL, db_radix, listp);
253 va_end(listp);
254 }
255
256 /*
257 * End line if too long.
258 */
259 void
260 db_end_line()
261 {
262 if (db_output_position >= db_max_width)
263 db_printf("\n");
264 }
Cache object: 5eea88efe53d18995c8b2ec7180ba807
|