xref: /freebsd/sys/ddb/db_output.c (revision 7f3dea244c40159a41ab22da77a434d7c5b5e85a)
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  *	$Id: db_output.c,v 1.24 1998/07/08 09:11:36 bde Exp $
27  */
28 
29 /*
30  * 	Author: David B. Golub, Carnegie Mellon University
31  *	Date:	7/90
32  */
33 
34 /*
35  * Printf and character output for debugger.
36  */
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 
66 static void db_putchar __P((int c, void *arg));
67 
68 /*
69  * Force pending whitespace.
70  */
71 void
72 db_force_whitespace()
73 {
74 	register int last_print, next_tab;
75 
76 	last_print = db_last_non_space;
77 	while (last_print < db_output_position) {
78 	    next_tab = NEXT_TAB(last_print);
79 	    if (next_tab <= db_output_position) {
80 		while (last_print < next_tab) { /* DON'T send a tab!!! */
81 			cnputc(' ');
82 			last_print++;
83 		}
84 	    }
85 	    else {
86 		cnputc(' ');
87 		last_print++;
88 	    }
89 	}
90 	db_last_non_space = db_output_position;
91 }
92 
93 /*
94  * Output character.  Buffer whitespace.
95  */
96 static void
97 db_putchar(c, arg)
98 	int	c;		/* character to output */
99 	void *	arg;
100 {
101 	if (c > ' ' && c <= '~') {
102 	    /*
103 	     * Printing character.
104 	     * If we have spaces to print, print them first.
105 	     * Use tabs if possible.
106 	     */
107 	    db_force_whitespace();
108 	    cnputc(c);
109 	    db_output_position++;
110 	    db_last_non_space = db_output_position;
111 	}
112 	else if (c == '\n') {
113 	    /* Newline */
114 	    cnputc(c);
115 	    db_output_position = 0;
116 	    db_last_non_space = 0;
117 	    db_check_interrupt();
118 	}
119 	else if (c == '\r') {
120 	    /* Return */
121 	    cnputc(c);
122 	    db_output_position = 0;
123 	    db_last_non_space = 0;
124 	    db_check_interrupt();
125 	}
126 	else if (c == '\t') {
127 	    /* assume tabs every 8 positions */
128 	    db_output_position = NEXT_TAB(db_output_position);
129 	}
130 	else if (c == ' ') {
131 	    /* space */
132 	    db_output_position++;
133 	}
134 	else if (c == '\007') {
135 	    /* bell */
136 	    cnputc(c);
137 	}
138 	/* other characters are assumed non-printing */
139 }
140 
141 /*
142  * Return output position
143  */
144 int
145 db_print_position()
146 {
147 	return (db_output_position);
148 }
149 
150 /*
151  * Printing
152  */
153 void
154 #if __STDC__
155 db_printf(const char *fmt, ...)
156 #else
157 db_printf(fmt)
158 	const char *fmt;
159 #endif
160 {
161 	va_list	listp;
162 
163 	va_start(listp, fmt);
164 	kvprintf (fmt, db_putchar, NULL, db_radix, listp);
165 	va_end(listp);
166 }
167 
168 int db_indent;
169 
170 void
171 #if __STDC__
172 db_iprintf(const char *fmt,...)
173 #else
174 db_iprintf(fmt)
175 	const char *fmt;
176 #endif
177 {
178 	register int i;
179 	va_list listp;
180 
181 	for (i = db_indent; i >= 8; i -= 8)
182 		db_printf("\t");
183 	while (--i >= 0)
184 		db_printf(" ");
185 	va_start(listp, fmt);
186 	kvprintf (fmt, db_putchar, NULL, db_radix, listp);
187 	va_end(listp);
188 }
189 
190 /*
191  * End line if too long.
192  */
193 void
194 db_end_line()
195 {
196 	if (db_output_position >= db_max_width)
197 	    db_printf("\n");
198 }
199