|
|
1.1.1.2 ! root 1: /* 1.1 root 2: * Mach Operating System 3: * Copyright (c) 1992,1991,1990 Carnegie Mellon University 4: * All Rights Reserved. 1.1.1.2 ! root 5: * 1.1 root 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. 1.1.1.2 ! root 11: * 1.1 root 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. 1.1.1.2 ! root 15: * 1.1 root 16: * Carnegie Mellon requests users of this software to return to 1.1.1.2 ! root 17: * 1.1 root 18: * Software Distribution Coordinator or [email protected] 19: * School of Computer Science 20: * Carnegie Mellon University 21: * Pittsburgh PA 15213-3890 1.1.1.2 ! root 22: * 1.1 root 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: #include "mach_kdb.h" 31: #if MACH_KDB 32: 33: #include <mach/boolean.h> 34: #include <machine/db_machdep.h> 35: #include <ddb/db_output.h> 36: 37: 38: 39: #ifndef DB_HISTORY_SIZE 40: #define DB_HISTORY_SIZE 4000 1.1.1.2 ! root 41: #endif /* DB_HISTORY_SIZE */ 1.1 root 42: 43: /* 44: * Character input and editing. 45: */ 46: 47: /* 48: * We don't track output position while editing input, 49: * since input always ends with a new-line. We just 50: * reset the line position at the end. 51: */ 52: char * db_lbuf_start; /* start of input line buffer */ 53: char * db_lbuf_end; /* end of input line buffer */ 54: char * db_lc; /* current character */ 55: char * db_le; /* one past last character */ 56: #if DB_HISTORY_SIZE != 0 57: char db_history[DB_HISTORY_SIZE]; /* start of history buffer */ 58: int db_history_size = DB_HISTORY_SIZE;/* size of history buffer */ 59: char * db_history_curr = db_history; /* start of current line */ 60: char * db_history_last = db_history; /* start of last line */ 61: char * db_history_prev = (char *) 0; /* start of previous line */ 62: #endif 1.1.1.2 ! root 63: 1.1 root 64: #define CTRL(c) ((c) & 0x1f) 65: #define isspace(c) ((c) == ' ' || (c) == '\t') 66: #define BLANK ' ' 67: #define BACKUP '\b' 68: 69: void 70: db_putstring(s, count) 71: char *s; 72: int count; 73: { 74: while (--count >= 0) 75: cnputc(*s++); 76: } 77: 78: void 79: db_putnchars(c, count) 80: int c; 81: int count; 82: { 83: while (--count >= 0) 84: cnputc(c); 85: } 86: 87: /* 88: * Delete N characters, forward or backward 89: */ 90: #define DEL_FWD 0 91: #define DEL_BWD 1 92: void 93: db_delete(n, bwd) 94: int n; 95: int bwd; 96: { 97: register char *p; 98: 99: if (bwd) { 100: db_lc -= n; 101: db_putnchars(BACKUP, n); 102: } 103: for (p = db_lc; p < db_le-n; p++) { 104: *p = *(p+n); 105: cnputc(*p); 106: } 107: db_putnchars(BLANK, n); 108: db_putnchars(BACKUP, db_le - db_lc); 109: db_le -= n; 110: } 111: 112: void 113: db_delete_line() 114: { 115: db_delete(db_le - db_lc, DEL_FWD); 116: db_delete(db_lc - db_lbuf_start, DEL_BWD); 117: db_le = db_lc = db_lbuf_start; 118: } 119: 120: #if DB_HISTORY_SIZE != 0 121: #define INC_DB_CURR() \ 122: do { \ 123: db_history_curr++; \ 124: if (db_history_curr > \ 125: db_history + db_history_size - 1) \ 126: db_history_curr = db_history; \ 127: } while (0) 128: #define DEC_DB_CURR() \ 129: do { \ 130: db_history_curr--; \ 131: if (db_history_curr < db_history) \ 132: db_history_curr = db_history + \ 133: db_history_size - 1; \ 134: } while (0) 135: #endif 1.1.1.2 ! root 136: 1.1 root 137: /* returns TRUE at end-of-line */ 138: boolean_t 139: db_inputchar(c) 140: int c; 141: { 142: switch (c) { 143: case CTRL('b'): 144: /* back up one character */ 145: if (db_lc > db_lbuf_start) { 146: cnputc(BACKUP); 147: db_lc--; 148: } 149: break; 150: case CTRL('f'): 151: /* forward one character */ 152: if (db_lc < db_le) { 153: cnputc(*db_lc); 154: db_lc++; 155: } 156: break; 157: case CTRL('a'): 158: /* beginning of line */ 159: while (db_lc > db_lbuf_start) { 160: cnputc(BACKUP); 161: db_lc--; 162: } 163: break; 164: case CTRL('e'): 165: /* end of line */ 166: while (db_lc < db_le) { 167: cnputc(*db_lc); 168: db_lc++; 169: } 170: break; 171: case CTRL('h'): 172: case 0177: 173: /* erase previous character */ 174: if (db_lc > db_lbuf_start) 175: db_delete(1, DEL_BWD); 176: break; 177: case CTRL('d'): 178: /* erase next character */ 179: if (db_lc < db_le) 180: db_delete(1, DEL_FWD); 181: break; 182: case CTRL('k'): 183: /* delete to end of line */ 184: if (db_lc < db_le) 185: db_delete(db_le - db_lc, DEL_FWD); 186: break; 187: case CTRL('u'): 188: /* delete line */ 189: db_delete_line(); 190: break; 191: case CTRL('t'): 192: /* twiddle last 2 characters */ 193: if (db_lc >= db_lbuf_start + 2) { 194: c = db_lc[-2]; 195: db_lc[-2] = db_lc[-1]; 196: db_lc[-1] = c; 197: cnputc(BACKUP); 198: cnputc(BACKUP); 199: cnputc(db_lc[-2]); 200: cnputc(db_lc[-1]); 201: } 202: break; 203: #if DB_HISTORY_SIZE != 0 204: case CTRL('p'): 205: DEC_DB_CURR(); 206: while (db_history_curr != db_history_last) { 207: DEC_DB_CURR(); 208: if (*db_history_curr == '\0') 209: break; 210: } 211: db_delete_line(); 212: if (db_history_curr == db_history_last) { 213: INC_DB_CURR(); 214: db_le = db_lc = db_lbuf_start; 215: } else { 216: register char *p; 217: INC_DB_CURR(); 218: for (p = db_history_curr, db_le = db_lbuf_start; 219: *p; ) { 220: *db_le++ = *p++; 221: if (p == db_history + db_history_size) { 222: p = db_history; 223: } 224: } 225: db_lc = db_le; 226: } 227: db_putstring(db_lbuf_start, db_le - db_lbuf_start); 228: break; 229: case CTRL('n'): 230: while (db_history_curr != db_history_last) { 231: if (*db_history_curr == '\0') 232: break; 233: INC_DB_CURR(); 234: } 235: if (db_history_curr != db_history_last) { 236: INC_DB_CURR(); 237: db_delete_line(); 238: if (db_history_curr != db_history_last) { 239: register char *p; 240: for (p = db_history_curr, 241: db_le = db_lbuf_start; *p;) { 242: *db_le++ = *p++; 243: if (p == db_history + 244: db_history_size) { 245: p = db_history; 246: } 247: } 248: db_lc = db_le; 249: } 250: db_putstring(db_lbuf_start, db_le - db_lbuf_start); 251: } 252: break; 253: #endif 254: case CTRL('r'): 255: db_putstring("^R\n", 3); 256: if (db_le > db_lbuf_start) { 257: db_putstring(db_lbuf_start, db_le - db_lbuf_start); 258: db_putnchars(BACKUP, db_le - db_lc); 259: } 260: break; 261: case '\n': 262: case '\r': 263: #if DB_HISTORY_SIZE != 0 264: /* 265: * Check whether current line is the same 266: * as previous saved line. If it is, don`t 267: * save it. 268: */ 269: if (db_history_curr == db_history_prev) { 270: register char *pp, *pc; 271: 272: /* 273: * Is it the same? 274: */ 275: for (pp = db_history_prev, pc = db_lbuf_start; 276: pc != db_le && *pp; ) { 277: if (*pp != *pc) 278: break; 279: if (++pp == db_history + db_history_size) { 280: pp = db_history; 281: } 282: pc++; 283: } 284: if (!*pp && pc == db_le) { 285: /* 286: * Repeated previous line. Don`t save. 287: */ 288: db_history_curr = db_history_last; 289: *db_le++ = c; 290: return (TRUE); 291: } 292: } 293: if (db_le != db_lbuf_start) { 294: register char *p; 295: db_history_prev = db_history_last; 296: for (p = db_lbuf_start; p != db_le; p++) { 297: *db_history_last++ = *p; 298: if (db_history_last == db_history + 299: db_history_size) { 300: db_history_last = db_history; 301: } 302: } 303: *db_history_last++ = '\0'; 304: } 305: db_history_curr = db_history_last; 306: #endif 307: *db_le++ = c; 308: return (TRUE); 309: default: 310: if (db_le == db_lbuf_end) { 311: cnputc('\007'); 312: } 313: else if (c >= ' ' && c <= '~') { 314: register char *p; 315: 316: for (p = db_le; p > db_lc; p--) 317: *p = *(p-1); 318: *db_lc++ = c; 319: db_le++; 320: cnputc(c); 321: db_putstring(db_lc, db_le - db_lc); 322: db_putnchars(BACKUP, db_le - db_lc); 323: } 324: break; 325: } 326: return (FALSE); 327: } 328: 329: int 330: db_readline(lstart, lsize) 331: char * lstart; 332: int lsize; 333: { 334: db_force_whitespace(); /* synch output position */ 335: 336: db_lbuf_start = lstart; 337: db_lbuf_end = lstart + lsize - 1; 338: db_lc = lstart; 339: db_le = lstart; 340: 341: while (!db_inputchar(cngetc())) 342: continue; 343: 344: db_putchar('\n'); /* synch output position */ 345: 346: *db_le = 0; 347: return (db_le - db_lbuf_start); 348: } 349: 350: void 351: db_check_interrupt() 352: { 353: register int c; 354: 355: c = cnmaygetc(); 356: switch (c) { 357: case -1: /* no character */ 358: return; 359: 360: case CTRL('c'): 361: db_error((char *)0); 362: /*NOTREACHED*/ 363: 364: case CTRL('s'): 365: do { 366: c = cnmaygetc(); 367: if (c == CTRL('c')) 368: db_error((char *)0); 369: } while (c != CTRL('q')); 370: break; 371: 372: default: 373: /* drop on floor */ 374: break; 375: } 376: } 377: 1.1.1.2 ! root 378: #endif /* MACH_KDB */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.