|
|
1.1 ! root 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 "AS IS" ! 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 [email protected] ! 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 Mellon ! 24: * the rights to redistribute these changes. ! 25: */ ! 26: /* ! 27: * Author: David B. Golub, Carnegie Mellon University ! 28: * Date: 7/90 ! 29: */ ! 30: ! 31: #include "mach_kdb.h" ! 32: #if MACH_KDB ! 33: ! 34: /* ! 35: * Printf and character output for debugger. ! 36: */ ! 37: ! 38: #include <mach/boolean.h> ! 39: #include <sys/varargs.h> ! 40: #include <machine/db_machdep.h> ! 41: #include <ddb/db_lex.h> ! 42: #include <ddb/db_output.h> ! 43: ! 44: /* ! 45: * Character output - tracks position in line. ! 46: * To do this correctly, we should know how wide ! 47: * the output device is - then we could zero ! 48: * the line position when the output device wraps ! 49: * around to the start of the next line. ! 50: * ! 51: * Instead, we count the number of spaces printed ! 52: * since the last printing character so that we ! 53: * don't print trailing spaces. This avoids most ! 54: * of the wraparounds. ! 55: */ ! 56: ! 57: #ifndef DB_MAX_LINE ! 58: #define DB_MAX_LINE 24 /* maximum line */ ! 59: #define DB_MAX_WIDTH 80 /* maximum width */ ! 60: #endif DB_MAX_LINE ! 61: ! 62: #define DB_MIN_MAX_WIDTH 20 /* minimum max width */ ! 63: #define DB_MIN_MAX_LINE 3 /* minimum max line */ ! 64: #define CTRL(c) ((c) & 0xff) ! 65: ! 66: int db_output_position = 0; /* output column */ ! 67: int db_output_line = 0; /* output line number */ ! 68: int db_last_non_space = 0; /* last non-space character */ ! 69: int db_tab_stop_width = 8; /* how wide are tab stops? */ ! 70: #define NEXT_TAB(i) \ ! 71: ((((i) + db_tab_stop_width) / db_tab_stop_width) * db_tab_stop_width) ! 72: int db_max_line = DB_MAX_LINE; /* output max lines */ ! 73: int db_max_width = DB_MAX_WIDTH; /* output line width */ ! 74: ! 75: extern void db_check_interrupt(); ! 76: ! 77: /* ! 78: * Force pending whitespace. ! 79: */ ! 80: void ! 81: db_force_whitespace() ! 82: { ! 83: register int last_print, next_tab; ! 84: ! 85: last_print = db_last_non_space; ! 86: while (last_print < db_output_position) { ! 87: next_tab = NEXT_TAB(last_print); ! 88: if (next_tab <= db_output_position) { ! 89: cnputc('\t'); ! 90: last_print = next_tab; ! 91: } ! 92: else { ! 93: cnputc(' '); ! 94: last_print++; ! 95: } ! 96: } ! 97: db_last_non_space = db_output_position; ! 98: } ! 99: ! 100: static void ! 101: db_more() ! 102: { ! 103: register char *p; ! 104: boolean_t quit_output = FALSE; ! 105: ! 106: for (p = "--db_more--"; *p; p++) ! 107: cnputc(*p); ! 108: switch(cngetc()) { ! 109: case ' ': ! 110: db_output_line = 0; ! 111: break; ! 112: case 'q': ! 113: case CTRL('c'): ! 114: db_output_line = 0; ! 115: quit_output = TRUE; ! 116: break; ! 117: default: ! 118: db_output_line--; ! 119: break; ! 120: } ! 121: p = "\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b"; ! 122: while (*p) ! 123: cnputc(*p++); ! 124: if (quit_output) { ! 125: db_error(0); ! 126: /* NOTREACHED */ ! 127: } ! 128: } ! 129: ! 130: /* ! 131: * Output character. Buffer whitespace. ! 132: */ ! 133: void ! 134: db_putchar(c) ! 135: int c; /* character to output */ ! 136: { ! 137: if (db_max_line >= DB_MIN_MAX_LINE && db_output_line >= db_max_line-1) ! 138: db_more(); ! 139: if (c > ' ' && c <= '~') { ! 140: /* ! 141: * Printing character. ! 142: * If we have spaces to print, print them first. ! 143: * Use tabs if possible. ! 144: */ ! 145: db_force_whitespace(); ! 146: cnputc(c); ! 147: db_output_position++; ! 148: if (db_max_width >= DB_MIN_MAX_WIDTH ! 149: && db_output_position >= db_max_width-1) { ! 150: /* auto new line */ ! 151: cnputc('\n'); ! 152: db_output_position = 0; ! 153: db_last_non_space = 0; ! 154: db_output_line++; ! 155: } ! 156: db_last_non_space = db_output_position; ! 157: } ! 158: else if (c == '\n') { ! 159: /* Return */ ! 160: cnputc(c); ! 161: db_output_position = 0; ! 162: db_last_non_space = 0; ! 163: db_output_line++; ! 164: db_check_interrupt(); ! 165: } ! 166: else if (c == '\t') { ! 167: /* assume tabs every 8 positions */ ! 168: db_output_position = NEXT_TAB(db_output_position); ! 169: } ! 170: else if (c == ' ') { ! 171: /* space */ ! 172: db_output_position++; ! 173: } ! 174: else if (c == '\007') { ! 175: /* bell */ ! 176: cnputc(c); ! 177: } ! 178: /* other characters are assumed non-printing */ ! 179: } ! 180: ! 181: void ! 182: db_id_putc(char c, vm_offset_t dummy) ! 183: { ! 184: db_putchar(c); ! 185: } ! 186: ! 187: /* ! 188: * Return output position ! 189: */ ! 190: int ! 191: db_print_position() ! 192: { ! 193: return (db_output_position); ! 194: } ! 195: ! 196: /* ! 197: * End line if too long. ! 198: */ ! 199: void db_end_line() ! 200: { ! 201: if (db_output_position >= db_max_width-1) ! 202: db_printf("\n"); ! 203: } ! 204: ! 205: /* ! 206: * Printing ! 207: */ ! 208: extern void _doprnt(); ! 209: ! 210: /*VARARGS1*/ ! 211: void ! 212: db_printf( fmt, va_alist) ! 213: char * fmt; ! 214: va_dcl ! 215: { ! 216: va_list listp; ! 217: ! 218: #ifdef db_printf_enter ! 219: db_printf_enter(); /* optional multiP serialization */ ! 220: #endif ! 221: va_start(listp); ! 222: _doprnt(fmt, &listp, db_id_putc, db_radix, 0); ! 223: va_end(listp); ! 224: } ! 225: ! 226: /* alternate name */ ! 227: ! 228: /*VARARGS1*/ ! 229: void ! 230: kdbprintf(fmt, va_alist) ! 231: char * fmt; ! 232: va_dcl ! 233: { ! 234: va_list listp; ! 235: va_start(listp); ! 236: _doprnt(fmt, &listp, db_id_putc, db_radix, 0); ! 237: va_end(listp); ! 238: } ! 239: ! 240: #endif MACH_KDB
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.