db_output.c revision 13446
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.15 1995/12/10 19:08:03 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 41#include <machine/cons.h> 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 */ 59static int db_output_position = 0; /* output column */ 60static int db_last_non_space = 0; /* last non-space character */ 61int 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) 64int db_max_width = 80; /* output line width */ 65 66static char *db_ksprintn __P((u_long ul, int base, int *lenp)); 67static void db_printf_guts __P((const char *, va_list)); 68 69/* 70 * Force pending whitespace. 71 */ 72void 73db_force_whitespace() 74{ 75 register int last_print, next_tab; 76 77 last_print = db_last_non_space; 78 while (last_print < db_output_position) { 79 next_tab = NEXT_TAB(last_print); 80 if (next_tab <= db_output_position) { 81 while (last_print < next_tab) { /* DON'T send a tab!!! */ 82 cnputc(' '); 83 last_print++; 84 } 85 } 86 else { 87 cnputc(' '); 88 last_print++; 89 } 90 } 91 db_last_non_space = db_output_position; 92} 93 94/* 95 * Output character. Buffer whitespace. 96 */ 97void 98db_putchar(c) 99 int c; /* character to output */ 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 */ 144int 145db_print_position() 146{ 147 return (db_output_position); 148} 149 150/* 151 * Printing 152 */ 153void 154db_printf(const char *fmt, ...) 155{ 156 va_list listp; 157 va_start(listp, fmt); 158 kvprintf (fmt, db_putchar, NULL, db_radix, listp); 159 va_end(listp); 160} 161 162/* 163 * End line if too long. 164 */ 165void 166db_end_line() 167{ 168 if (db_output_position >= db_max_width) 169 db_printf("\n"); 170} 171 172/* 173 * Put a number (base <= 16) in a buffer in reverse order; return an 174 * optional length and a pointer to the NULL terminated (preceded?) 175 * buffer. 176 */ 177static char * 178db_ksprintn(ul, base, lenp) 179 register u_long ul; 180 register int base, *lenp; 181{ /* A long in base 8, plus NULL. */ 182 static char buf[sizeof(long) * NBBY / 3 + 2]; 183 register char *p; 184 185 p = buf; 186 do { 187 *++p = "0123456789abcdef"[ul % base]; 188 } while (ul /= base); 189 if (lenp) 190 *lenp = p - buf; 191 return (p); 192} 193