db_output.c revision 4
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 * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE 27 * -------------------- ----- ---------------------- 28 * CURRENT PATCH LEVEL: 4 00083 29 * -------------------- ----- ---------------------- 30 * 31 * 14 Mar 93 Chris G. Demetriou Fixed so that tab is not output, 32 * use spaces instead. 33 */ 34/* 35 * HISTORY 36 * $Log: db_output.c,v $ 37 * Revision 1.1 1992/03/25 21:45:18 pace 38 * Initial revision 39 * 40 * Revision 2.3 91/02/05 17:06:45 mrt 41 * Changed to new Mach copyright 42 * [91/01/31 16:18:41 mrt] 43 * 44 * Revision 2.2 90/08/27 21:51:25 dbg 45 * Put extra features of db_doprnt in _doprnt. 46 * [90/08/20 dbg] 47 * Reduce lint. 48 * [90/08/07 dbg] 49 * Created. 50 * [90/07/25 dbg] 51 * 52 */ 53/* 54 * Author: David B. Golub, Carnegie Mellon University 55 * Date: 7/90 56 */ 57 58/* 59 * Printf and character output for debugger. 60 */ 61 62#include "param.h" 63#include <machine/stdarg.h> 64 65/* 66 * Character output - tracks position in line. 67 * To do this correctly, we should know how wide 68 * the output device is - then we could zero 69 * the line position when the output device wraps 70 * around to the start of the next line. 71 * 72 * Instead, we count the number of spaces printed 73 * since the last printing character so that we 74 * don't print trailing spaces. This avoids most 75 * of the wraparounds. 76 */ 77int db_output_position = 0; /* output column */ 78int db_last_non_space = 0; /* last non-space character */ 79int db_tab_stop_width = 8; /* how wide are tab stops? */ 80#define NEXT_TAB(i) \ 81 ((((i) + db_tab_stop_width) / db_tab_stop_width) * db_tab_stop_width) 82int db_max_width = 80; /* output line width */ 83 84extern void db_check_interrupt(); 85 86/* 87 * Force pending whitespace. 88 */ 89void 90db_force_whitespace() 91{ 92 register int last_print, next_tab; 93 94 last_print = db_last_non_space; 95 while (last_print < db_output_position) { 96 next_tab = NEXT_TAB(last_print); 97 if (next_tab <= db_output_position) { 98 while (last_print < next_tab) { /* DON'T send a tab!!! */ 99 cnputc(' '); 100 last_print++; 101 } 102 } 103 else { 104 cnputc(' '); 105 last_print++; 106 } 107 } 108 db_last_non_space = db_output_position; 109} 110 111/* 112 * Output character. Buffer whitespace. 113 */ 114db_putchar(c) 115 int c; /* character to output */ 116{ 117 if (c > ' ' && c <= '~') { 118 /* 119 * Printing character. 120 * If we have spaces to print, print them first. 121 * Use tabs if possible. 122 */ 123 db_force_whitespace(); 124 cnputc(c); 125 db_output_position++; 126 db_last_non_space = db_output_position; 127 } 128 else if (c == '\n') { 129 /* Return */ 130 cnputc(c); 131 db_output_position = 0; 132 db_last_non_space = 0; 133 db_check_interrupt(); 134 } 135 else if (c == '\t') { 136 /* assume tabs every 8 positions */ 137 db_output_position = NEXT_TAB(db_output_position); 138 } 139 else if (c == ' ') { 140 /* space */ 141 db_output_position++; 142 } 143 else if (c == '\007') { 144 /* bell */ 145 cnputc(c); 146 } 147 /* other characters are assumed non-printing */ 148} 149 150/* 151 * Return output position 152 */ 153int 154db_print_position() 155{ 156 return (db_output_position); 157} 158 159/* 160 * End line if too long. 161 */ 162void 163db_end_line() 164{ 165 if (db_output_position >= db_max_width) 166 db_printf("\n"); 167} 168 169/* 170 * Printing 171 */ 172extern int db_radix; 173 174/*VARARGS1*/ 175db_printf(char *fmt, ...) 176{ 177 va_list listp; 178 va_start(listp, fmt); 179 db_printf_guts (fmt, listp); 180 va_end(listp); 181} 182 183/* alternate name */ 184 185/*VARARGS1*/ 186kdbprintf(char *fmt, ...) 187{ 188 va_list listp; 189 va_start(listp, fmt); 190 db_printf_guts (fmt, listp); 191 va_end(listp); 192} 193 194/* 195 * Put a number (base <= 16) in a buffer in reverse order; return an 196 * optional length and a pointer to the NULL terminated (preceded?) 197 * buffer. 198 */ 199static char * 200db_ksprintn(ul, base, lenp) 201 register u_long ul; 202 register int base, *lenp; 203{ /* A long in base 8, plus NULL. */ 204 static char buf[sizeof(long) * NBBY / 3 + 2]; 205 register char *p; 206 207 p = buf; 208 do { 209 *++p = "0123456789abcdef"[ul % base]; 210 } while (ul /= base); 211 if (lenp) 212 *lenp = p - buf; 213 return (p); 214} 215 216db_printf_guts(fmt, ap) 217 register const char *fmt; 218 va_list ap; 219{ 220 register char *p; 221 register int ch, n; 222 u_long ul; 223 int base, lflag, tmp, width; 224 char padc; 225 int ladjust; 226 int sharpflag; 227 int neg; 228 229 for (;;) { 230 padc = ' '; 231 width = 0; 232 while ((ch = *(u_char *)fmt++) != '%') { 233 if (ch == '\0') 234 return; 235 db_putchar(ch); 236 } 237 lflag = 0; 238 ladjust = 0; 239 sharpflag = 0; 240 neg = 0; 241reswitch: switch (ch = *(u_char *)fmt++) { 242 case '0': 243 padc = '0'; 244 goto reswitch; 245 case '1': case '2': case '3': case '4': 246 case '5': case '6': case '7': case '8': case '9': 247 for (width = 0;; ++fmt) { 248 width = width * 10 + ch - '0'; 249 ch = *fmt; 250 if (ch < '0' || ch > '9') 251 break; 252 } 253 goto reswitch; 254 case 'l': 255 lflag = 1; 256 goto reswitch; 257 case '-': 258 ladjust = 1; 259 goto reswitch; 260 case '#': 261 sharpflag = 1; 262 goto reswitch; 263 case 'b': 264 ul = va_arg(ap, int); 265 p = va_arg(ap, char *); 266 for (p = db_ksprintn(ul, *p++, NULL); ch = *p--;) 267 db_putchar(ch); 268 269 if (!ul) 270 break; 271 272 for (tmp = 0; n = *p++;) { 273 if (ul & (1 << (n - 1))) { 274 db_putchar(tmp ? ',' : '<'); 275 for (; (n = *p) > ' '; ++p) 276 db_putchar(n); 277 tmp = 1; 278 } else 279 for (; *p > ' '; ++p); 280 } 281 if (tmp) 282 db_putchar('>'); 283 break; 284 case '*': 285 width = va_arg (ap, int); 286 if (width < 0) { 287 ladjust = !ladjust; 288 width = -width; 289 } 290 goto reswitch; 291 case 'c': 292 db_putchar(va_arg(ap, int)); 293 break; 294 case 's': 295 p = va_arg(ap, char *); 296 width -= strlen (p); 297 if (!ladjust && width > 0) 298 while (width--) 299 db_putchar (padc); 300 while (ch = *p++) 301 db_putchar(ch); 302 if (ladjust && width > 0) 303 while (width--) 304 db_putchar (padc); 305 break; 306 case 'r': 307 ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 308 if ((long)ul < 0) { 309 neg = 1; 310 ul = -(long)ul; 311 } 312 base = db_radix; 313 if (base < 8 || base > 16) 314 base = 10; 315 goto number; 316 case 'n': 317 ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 318 base = db_radix; 319 if (base < 8 || base > 16) 320 base = 10; 321 goto number; 322 case 'd': 323 ul = lflag ? va_arg(ap, long) : va_arg(ap, int); 324 if ((long)ul < 0) { 325 neg = 1; 326 ul = -(long)ul; 327 } 328 base = 10; 329 goto number; 330 case 'o': 331 ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 332 base = 8; 333 goto number; 334 case 'u': 335 ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 336 base = 10; 337 goto number; 338 case 'z': 339 ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 340 if ((long)ul < 0) { 341 neg = 1; 342 ul = -(long)ul; 343 } 344 base = 16; 345 goto number; 346 case 'x': 347 ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 348 base = 16; 349number: p = (char *)db_ksprintn(ul, base, &tmp); 350 if (sharpflag && ul != 0) { 351 if (base == 8) 352 tmp++; 353 else if (base == 16) 354 tmp += 2; 355 } 356 if (neg) 357 tmp++; 358 359 if (!ladjust && width && (width -= tmp) > 0) 360 while (width--) 361 db_putchar(padc); 362 if (neg) 363 db_putchar ('-'); 364 if (sharpflag && ul != 0) { 365 if (base == 8) { 366 db_putchar ('0'); 367 } else if (base == 16) { 368 db_putchar ('0'); 369 db_putchar ('x'); 370 } 371 } 372 if (ladjust && width && (width -= tmp) > 0) 373 while (width--) 374 db_putchar(padc); 375 376 while (ch = *p--) 377 db_putchar(ch); 378 break; 379 default: 380 db_putchar('%'); 381 if (lflag) 382 db_putchar('l'); 383 /* FALLTHROUGH */ 384 case '%': 385 db_putchar(ch); 386 } 387 } 388} 389 390