Initial import from FreeBSD RELENG_4:
[dragonfly.git] / 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  * $FreeBSD: src/sys/ddb/db_output.c,v 1.26 1999/08/28 00:41:09 peter 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 }