|
|
1.1 ! root 1: /* ! 2: * Mach Operating System ! 3: * Copyright (c) 1992,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: #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 ! 41: #endif DB_HISTORY_SIZE ! 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 ! 63: ! 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 ! 136: ! 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: ! 378: #endif MACH_KDB
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.