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$"); 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 } 265