|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * @OSF_COPYRIGHT@ ! 24: */ ! 25: /* ! 26: * HISTORY ! 27: * ! 28: * Revision 1.1.1.1 1998/09/22 21:05:48 wsanchez ! 29: * Import of Mac OS X kernel (~semeria) ! 30: * ! 31: * Revision 1.1.1.1 1998/03/07 02:26:09 wsanchez ! 32: * Import of OSF Mach kernel (~mburg) ! 33: * ! 34: * Revision 1.3.10.2 1994/09/23 01:19:37 ezf ! 35: * change marker to not FREE ! 36: * [1994/09/22 21:10:05 ezf] ! 37: * ! 38: * Revision 1.3.10.1 1994/06/11 21:11:48 bolinger ! 39: * Merge up to NMK17.2. ! 40: * [1994/06/11 20:01:41 bolinger] ! 41: * ! 42: * Revision 1.3.8.2 1994/02/11 14:21:41 paire ! 43: * Added string.h header file for strlen declaration. ! 44: * [94/02/09 paire] ! 45: * ! 46: * Revision 1.3.8.1 1994/02/08 10:57:55 bernadat ! 47: * Added db_auto_completion variable. ! 48: * [93/08/17 paire] ! 49: * ! 50: * Added support of symbol completion by typing '\t'. ! 51: * [93/08/14 paire] ! 52: * [94/02/07 bernadat] ! 53: * ! 54: * Revision 1.3.2.4 1993/08/11 20:37:51 elliston ! 55: * Add ANSI Prototypes. CR #9523. ! 56: * [1993/08/11 03:33:21 elliston] ! 57: * ! 58: * Revision 1.3.2.3 1993/07/27 18:27:30 elliston ! 59: * Add ANSI prototypes. CR #9523. ! 60: * [1993/07/27 18:12:01 elliston] ! 61: * ! 62: * Revision 1.3.2.2 1993/06/09 02:20:13 gm ! 63: * CR9176 - ANSI C violations: trailing tokens on CPP ! 64: * directives, extra semicolons after decl_ ..., asm keywords ! 65: * [1993/06/07 18:57:14 jeffc] ! 66: * ! 67: * Added to OSF/1 R1.3 from NMK15.0. ! 68: * [1993/06/02 20:56:26 jeffc] ! 69: * ! 70: * Revision 1.3 1993/04/19 16:02:17 devrcs ! 71: * Replaced ^R (redraw) with ^L [[email protected]] ! 72: * ! 73: * Added ^R and ^S commands for history search commands ! 74: * ^U does not erase end of the line anymore. (only erases ! 75: * from the beginning of the line to current position). ! 76: * [[email protected]] ! 77: * ! 78: * ^C now erases the entire line. [[email protected]] ! 79: * [92/12/03 bernadat] ! 80: * ! 81: * Fixed history management: Do not store repeated typed ! 82: * command. Null terminate current command in case it is a ! 83: * substring of the last command. ! 84: * [92/10/02 bernadat] ! 85: * ! 86: * Revision 1.2 1992/11/25 01:04:24 robert ! 87: * integrate changes for norma_14 below ! 88: * ! 89: * Philippe Bernadat (bernadat) at gr.osf.org 02-Oct-92 ! 90: * Fixed history management: Do not store repeated typed ! 91: * command. Null terminate current command in case it is a ! 92: * substring of the last command. ! 93: * [1992/11/20 00:56:07 robert] ! 94: * ! 95: * integrate changes below for norma_14 ! 96: * [1992/11/13 19:21:34 robert] ! 97: * ! 98: * Revision 1.1 1992/09/30 02:01:08 robert ! 99: * Initial revision ! 100: * ! 101: * $EndLog$ ! 102: */ ! 103: /* CMU_HIST */ ! 104: /* ! 105: * Revision 2.7.3.2 92/09/15 17:14:26 jeffreyh ! 106: * Fixed history code. (Only one char. out of 2 was checked to ! 107: * compare to last command) ! 108: * [[email protected]] ! 109: * ! 110: * Revision 2.7.3.1 92/03/03 16:13:30 jeffreyh ! 111: * Pick up changes from TRUNK ! 112: * [92/02/26 10:59:36 jeffreyh] ! 113: * ! 114: * Revision 2.8 92/02/19 15:07:44 elf ! 115: * Added delete_line (Ctrl-U). ! 116: * [92/02/17 kivinen] ! 117: * ! 118: * Added command line history. Ctrl-P = previous, Ctrl-N = next. If ! 119: * DB_HISTORY_SIZE is 0 then command history is disabled. ! 120: * [92/02/17 kivinen] ! 121: * ! 122: * Revision 2.7 91/10/09 16:00:03 af ! 123: * Revision 2.6.2.1 91/10/05 13:06:12 jeffreyh ! 124: * Fixed incorrect db_lbuf_end setting. ! 125: * [91/08/29 tak] ! 126: * ! 127: * Revision 2.6.2.1 91/10/05 13:06:12 jeffreyh ! 128: * Fixed incorrect db_lbuf_end setting. ! 129: * [91/08/29 tak] ! 130: * ! 131: * Revision 2.6 91/07/09 23:15:49 danner ! 132: * Add include of machine/db_machdep.h to allow machine-specific ! 133: * overrides via defines. ! 134: * [91/07/08 danner] ! 135: * ! 136: * Revision 2.5 91/05/14 15:34:03 mrt ! 137: * Correcting copyright ! 138: * ! 139: * Revision 2.4 91/02/14 14:41:53 mrt ! 140: * Add input line editing. ! 141: * [90/11/11 dbg] ! 142: * ! 143: * Revision 2.3 91/02/05 17:06:32 mrt ! 144: * Changed to new Mach copyright ! 145: * [91/01/31 16:18:13 mrt] ! 146: * ! 147: * Revision 2.2 90/08/27 21:51:03 dbg ! 148: * Reduce lint. ! 149: * [90/08/07 dbg] ! 150: * Created. ! 151: * [90/07/25 dbg] ! 152: * ! 153: */ ! 154: /* CMU_ENDHIST */ ! 155: /* ! 156: * Mach Operating System ! 157: * Copyright (c) 1991,1990 Carnegie Mellon University ! 158: * All Rights Reserved. ! 159: * ! 160: * Permission to use, copy, modify and distribute this software and its ! 161: * documentation is hereby granted, provided that both the copyright ! 162: * notice and this permission notice appear in all copies of the ! 163: * software, derivative works or modified versions, and any portions ! 164: * thereof, and that both notices appear in supporting documentation. ! 165: * ! 166: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 167: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 168: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 169: * ! 170: * Carnegie Mellon requests users of this software to return to ! 171: * ! 172: * Software Distribution Coordinator or [email protected] ! 173: * School of Computer Science ! 174: * Carnegie Mellon University ! 175: * Pittsburgh PA 15213-3890 ! 176: * ! 177: * any improvements or extensions that they make and grant Carnegie Mellon ! 178: * the rights to redistribute these changes. ! 179: */ ! 180: /* ! 181: */ ! 182: /* ! 183: * Author: David B. Golub, Carnegie Mellon University ! 184: * Date: 7/90 ! 185: */ ! 186: ! 187: #include <string.h> ! 188: #include <mach/boolean.h> ! 189: #include <machine/db_machdep.h> ! 190: #include <kern/misc_protos.h> ! 191: #include <ddb/db_output.h> ! 192: #include <ddb/db_lex.h> ! 193: #include <ddb/db_command.h> ! 194: #include <ddb/db_input.h> ! 195: #include <ddb/db_sym.h> ! 196: ! 197: #ifndef DB_HISTORY_SIZE ! 198: #define DB_HISTORY_SIZE 4000 ! 199: #endif /* DB_HISTORY_SIZE */ ! 200: ! 201: /* ! 202: * Character input and editing. ! 203: */ ! 204: ! 205: /* ! 206: * We don't track output position while editing input, ! 207: * since input always ends with a new-line. We just ! 208: * reset the line position at the end. ! 209: */ ! 210: char * db_lbuf_start; /* start of input line buffer */ ! 211: char * db_lbuf_end; /* end of input line buffer */ ! 212: char * db_lc; /* current character */ ! 213: char * db_le; /* one past last character */ ! 214: int db_completion; /* number of incomplete symbols matched */ ! 215: int db_auto_completion = 10; /* number of line to display without asking */ ! 216: #if DB_HISTORY_SIZE != 0 ! 217: char db_history[DB_HISTORY_SIZE]; /* start of history buffer */ ! 218: int db_history_size = DB_HISTORY_SIZE;/* size of history buffer */ ! 219: char * db_history_curr = db_history; /* start of current line */ ! 220: char * db_history_last = db_history; /* start of last line */ ! 221: char * db_history_prev = (char *) 0; /* start of previous line */ ! 222: int db_hist_unmodified = 0; /* unmodified line from history */ ! 223: int db_hist_search = 0; /* are we in hist search mode ? */ ! 224: char db_hist_search_string[DB_LEX_LINE_SIZE];/* the string to look for */ ! 225: int db_hist_ignore_dups = 0; /* don't duplicate commands in hist */ ! 226: #endif ! 227: ! 228: #define CTRL(c) ((c) & 0x1f) ! 229: #define isspace(c) ((c) == ' ' || (c) == '\t') ! 230: #define BLANK ' ' ! 231: #define BACKUP '\b' ! 232: ! 233: ! 234: ! 235: /* Prototypes for functions local to this file. XXX -- should be static! ! 236: */ ! 237: void db_putstring( ! 238: char *s, ! 239: int count); ! 240: ! 241: void db_putnchars( ! 242: int c, ! 243: int count); ! 244: ! 245: void db_delete( ! 246: int n, ! 247: int bwd); ! 248: ! 249: void db_delete_line(void); ! 250: ! 251: boolean_t db_hist_substring( ! 252: char *string, ! 253: char *substring); ! 254: ! 255: boolean_t db_inputchar(int c); ! 256: ! 257: extern jmp_buf_t *db_recover; ! 258: ! 259: void ! 260: db_putstring( ! 261: char *s, ! 262: int count) ! 263: { ! 264: while (--count >= 0) ! 265: cnputc(*s++); ! 266: } ! 267: ! 268: void ! 269: db_putnchars( ! 270: int c, ! 271: int count) ! 272: { ! 273: while (--count >= 0) ! 274: cnputc(c); ! 275: } ! 276: ! 277: /* ! 278: * Delete N characters, forward or backward ! 279: */ ! 280: #define DEL_FWD 0 ! 281: #define DEL_BWD 1 ! 282: void ! 283: db_delete( ! 284: int n, ! 285: int bwd) ! 286: { ! 287: register char *p; ! 288: ! 289: if (bwd) { ! 290: db_lc -= n; ! 291: db_putnchars(BACKUP, n); ! 292: } ! 293: for (p = db_lc; p < db_le-n; p++) { ! 294: *p = *(p+n); ! 295: cnputc(*p); ! 296: } ! 297: db_putnchars(BLANK, n); ! 298: db_putnchars(BACKUP, db_le - db_lc); ! 299: db_le -= n; ! 300: } ! 301: ! 302: void ! 303: db_delete_line(void) ! 304: { ! 305: db_delete(db_le - db_lc, DEL_FWD); ! 306: db_delete(db_lc - db_lbuf_start, DEL_BWD); ! 307: db_le = db_lc = db_lbuf_start; ! 308: } ! 309: ! 310: #if DB_HISTORY_SIZE != 0 ! 311: #define INC_DB_CURR() \ ! 312: do { \ ! 313: db_history_curr++; \ ! 314: if (db_history_curr > \ ! 315: db_history + db_history_size - 1) \ ! 316: db_history_curr = db_history; \ ! 317: } while (0) ! 318: #define DEC_DB_CURR() \ ! 319: do { \ ! 320: db_history_curr--; \ ! 321: if (db_history_curr < db_history) \ ! 322: db_history_curr = db_history + \ ! 323: db_history_size - 1; \ ! 324: } while (0) ! 325: #endif ! 326: ! 327: /* returs TRUE if "substring" is a substring of "string" */ ! 328: boolean_t ! 329: db_hist_substring( ! 330: char *string, ! 331: char *substring) ! 332: { ! 333: register char *cp1, *cp2; ! 334: ! 335: cp1 = string; ! 336: while (*cp1) ! 337: cp1++; ! 338: cp2 = substring; ! 339: while (*cp2) ! 340: cp2++; ! 341: ! 342: while (cp2 > substring) { ! 343: cp1--; cp2--; ! 344: } ! 345: ! 346: while (cp1 >= string) { ! 347: register char *cp3; ! 348: ! 349: cp2 = substring; ! 350: cp3 = cp1; ! 351: while (*cp2 && *cp2 == *cp3) { ! 352: cp2++; cp3++; ! 353: } ! 354: if (*cp2 == '\0') { ! 355: return TRUE; ! 356: } ! 357: cp1--; ! 358: } ! 359: return FALSE; ! 360: } ! 361: ! 362: /* returns TRUE at end-of-line */ ! 363: boolean_t ! 364: db_inputchar(int c) ! 365: { ! 366: char *sym; ! 367: char *start; ! 368: char *restart; ! 369: jmp_buf_t db_jmpbuf; ! 370: jmp_buf_t *db_prev; ! 371: char *p; ! 372: int len; ! 373: ! 374: switch(db_completion) { ! 375: case -1: ! 376: db_putchar('\n'); ! 377: db_prev = db_recover; ! 378: if (_setjmp(db_recover = &db_jmpbuf) == 0 && ! 379: (c == 'y' || c == ' ' || c == '\t')) ! 380: db_print_completion(db_tok_string); ! 381: db_recover = db_prev; ! 382: db_completion = 0; ! 383: db_reset_more(); ! 384: db_output_prompt(); ! 385: if (db_le > db_lbuf_start) { ! 386: for (start = db_lbuf_start; start < db_le; start++) ! 387: db_putchar(*start); ! 388: db_putnchars(BACKUP, db_le - db_lc); ! 389: } ! 390: return(FALSE); ! 391: ! 392: case 0: ! 393: break; ! 394: ! 395: default: ! 396: if (c == '\t') { ! 397: db_printf("\nThere are %d possibilities. ", db_completion); ! 398: db_printf("Do you really wish to see them all [n] ? "); ! 399: db_force_whitespace(); ! 400: db_completion = -1; ! 401: db_reset_more(); ! 402: return(FALSE); ! 403: } ! 404: db_completion = 0; ! 405: break; ! 406: } ! 407: ! 408: switch (c) { ! 409: case '\t': ! 410: /* symbol completion */ ! 411: if (db_lc == db_lbuf_start || db_auto_completion == 0) ! 412: break; ! 413: if (db_le == db_lbuf_end) { ! 414: cnputc('\007'); ! 415: break; ! 416: } ! 417: start = db_lc - 1; ! 418: while (start >= db_lbuf_start && ! 419: ((*start >= 'A' && *start <= 'Z') || ! 420: (*start >= 'a' && *start <= 'z') || ! 421: (*start >= '0' && *start <= '9') || ! 422: *start == '_' || *start == ':')) ! 423: start--; ! 424: if (start == db_lc - 1) ! 425: break; ! 426: if (start > db_lbuf_start && *start == '$') { ! 427: cnputc('\007'); ! 428: break; ! 429: } ! 430: sym = db_tok_string; ! 431: restart = ++start; ! 432: do { ! 433: *sym++ = *start++; ! 434: } while (start != db_lc && ! 435: sym != db_tok_string + sizeof(db_tok_string)); ! 436: if (sym == db_tok_string + sizeof(db_tok_string)) { ! 437: cnputc('\007'); ! 438: break; ! 439: } ! 440: *sym = '\0'; ! 441: db_completion = db_lookup_incomplete(db_tok_string, ! 442: sizeof(db_tok_string)); ! 443: if (db_completion == 0) { ! 444: /* symbol unknown */ ! 445: cnputc('\007'); ! 446: break; ! 447: } ! 448: ! 449: len = strlen(db_tok_string) - (start - restart); ! 450: if (db_completion == 1 && ! 451: (db_le == db_lc || ! 452: (db_le > db_lc) && *db_lc != ' ')) ! 453: len++; ! 454: for (p = db_le - 1; p >= db_lc; p--) ! 455: *(p + len) = *p; ! 456: db_le += len; ! 457: for (sym = &db_tok_string[start - restart]; ! 458: *sym != '\0'; sym++) ! 459: *db_lc++ = *sym; ! 460: ! 461: if (db_completion == 1 || db_completion > db_auto_completion) { ! 462: for (sym = &db_tok_string[start - restart]; ! 463: *sym != '\0'; sym++) ! 464: cnputc(*sym); ! 465: if (db_completion == 1) { ! 466: if (db_le == db_lc || ! 467: (db_le > db_lc) && *db_lc != ' ') { ! 468: cnputc(' '); ! 469: *db_lc++ = ' '; ! 470: } ! 471: db_completion = 0; ! 472: } ! 473: db_putstring(db_lc, db_le - db_lc); ! 474: db_putnchars(BACKUP, db_le - db_lc); ! 475: } ! 476: ! 477: if (db_completion > 1) { ! 478: cnputc('\007'); ! 479: if (db_completion <= db_auto_completion) { ! 480: db_putchar('\n'); ! 481: db_print_completion(db_tok_string); ! 482: db_completion = 0; ! 483: db_reset_more(); ! 484: db_output_prompt(); ! 485: if (db_le > db_lbuf_start) { ! 486: for (start = db_lbuf_start; start < db_le; start++) ! 487: db_putchar(*start); ! 488: db_putnchars(BACKUP, db_le - db_lc); ! 489: } ! 490: } ! 491: } ! 492: break; ! 493: ! 494: case CTRL('b'): ! 495: /* back up one character */ ! 496: if (db_lc > db_lbuf_start) { ! 497: cnputc(BACKUP); ! 498: db_lc--; ! 499: } ! 500: break; ! 501: case CTRL('f'): ! 502: /* forward one character */ ! 503: if (db_lc < db_le) { ! 504: cnputc(*db_lc); ! 505: db_lc++; ! 506: } ! 507: break; ! 508: case CTRL('a'): ! 509: /* beginning of line */ ! 510: while (db_lc > db_lbuf_start) { ! 511: cnputc(BACKUP); ! 512: db_lc--; ! 513: } ! 514: break; ! 515: case CTRL('e'): ! 516: /* end of line */ ! 517: while (db_lc < db_le) { ! 518: cnputc(*db_lc); ! 519: db_lc++; ! 520: } ! 521: break; ! 522: case CTRL('h'): ! 523: case 0177: ! 524: /* erase previous character */ ! 525: if (db_lc > db_lbuf_start) ! 526: db_delete(1, DEL_BWD); ! 527: break; ! 528: case CTRL('d'): ! 529: /* erase next character */ ! 530: if (db_lc < db_le) ! 531: db_delete(1, DEL_FWD); ! 532: break; ! 533: case CTRL('k'): ! 534: /* delete to end of line */ ! 535: if (db_lc < db_le) ! 536: db_delete(db_le - db_lc, DEL_FWD); ! 537: break; ! 538: case CTRL('u'): ! 539: /* delete to beginning of line */ ! 540: if (db_lc > db_lbuf_start) ! 541: db_delete(db_lc - db_lbuf_start, DEL_BWD); ! 542: break; ! 543: case CTRL('t'): ! 544: /* twiddle last 2 characters */ ! 545: if (db_lc >= db_lbuf_start + 2) { ! 546: c = db_lc[-2]; ! 547: db_lc[-2] = db_lc[-1]; ! 548: db_lc[-1] = c; ! 549: cnputc(BACKUP); ! 550: cnputc(BACKUP); ! 551: cnputc(db_lc[-2]); ! 552: cnputc(db_lc[-1]); ! 553: } ! 554: break; ! 555: case CTRL('c'): ! 556: case CTRL('g'): ! 557: db_delete_line(); ! 558: #if DB_HISTORY_SIZE != 0 ! 559: db_history_curr = db_history_last; ! 560: if (c == CTRL('g') && db_hist_search) { ! 561: char *p; ! 562: for (p = db_hist_search_string, db_le = db_lbuf_start; ! 563: *p; ) { ! 564: *db_le++ = *p++; ! 565: } ! 566: db_lc = db_le; ! 567: *db_le = '\0'; ! 568: db_putstring(db_lbuf_start, db_le - db_lbuf_start); ! 569: } ! 570: #endif ! 571: break; ! 572: #if DB_HISTORY_SIZE != 0 ! 573: case CTRL('r'): ! 574: if (db_hist_search++ == 0) { ! 575: /* starting an history lookup */ ! 576: register char *cp1, *cp2; ! 577: for (cp1 = db_lbuf_start, cp2 = db_hist_search_string; ! 578: cp1 < db_le; ! 579: cp1++, cp2++) ! 580: *cp2 = *cp1; ! 581: *cp2 = '\0'; ! 582: db_hist_search++; ! 583: } ! 584: /* FALL THROUGH */ ! 585: case CTRL('p'): ! 586: { ! 587: char * old_history_curr = db_history_curr; ! 588: ! 589: if (db_hist_unmodified++ == 0) ! 590: db_hist_unmodified++; ! 591: DEC_DB_CURR(); ! 592: while (db_history_curr != db_history_last) { ! 593: DEC_DB_CURR(); ! 594: if (*db_history_curr == '\0') { ! 595: INC_DB_CURR(); ! 596: if (db_hist_search <= 1) { ! 597: if (*db_history_curr == '\0') ! 598: cnputc('\007'); ! 599: else ! 600: DEC_DB_CURR(); ! 601: break; ! 602: } ! 603: if (*db_history_curr == '\0') { ! 604: cnputc('\007'); ! 605: db_history_curr = old_history_curr; ! 606: DEC_DB_CURR(); ! 607: break; ! 608: } ! 609: if (db_history_curr != db_history_last && ! 610: db_hist_substring(db_history_curr, ! 611: db_hist_search_string)) { ! 612: DEC_DB_CURR(); ! 613: break; ! 614: } ! 615: DEC_DB_CURR(); ! 616: } ! 617: } ! 618: if (db_history_curr == db_history_last) { ! 619: cnputc('\007'); ! 620: db_history_curr = old_history_curr; ! 621: } else { ! 622: register char *p; ! 623: INC_DB_CURR(); ! 624: db_delete_line(); ! 625: for (p = db_history_curr, db_le = db_lbuf_start; ! 626: *p; ) { ! 627: *db_le++ = *p++; ! 628: if (p == db_history + db_history_size) { ! 629: p = db_history; ! 630: } ! 631: } ! 632: db_lc = db_le; ! 633: *db_le = '\0'; ! 634: db_putstring(db_lbuf_start, db_le - db_lbuf_start); ! 635: } ! 636: break; ! 637: } ! 638: case CTRL('s'): ! 639: if (db_hist_search++ == 0) { ! 640: /* starting an history lookup */ ! 641: register char *cp1, *cp2; ! 642: for (cp1 = db_lbuf_start, cp2 = db_hist_search_string; ! 643: cp1 < db_le; ! 644: cp1++, cp2++) ! 645: *cp2 = *cp1; ! 646: *cp2 = '\0'; ! 647: db_hist_search++; ! 648: } ! 649: /* FALL THROUGH */ ! 650: case CTRL('n'): ! 651: { ! 652: char *old_history_curr = db_history_curr; ! 653: ! 654: if (db_hist_unmodified++ == 0) ! 655: db_hist_unmodified++; ! 656: while (db_history_curr != db_history_last) { ! 657: if (*db_history_curr == '\0') { ! 658: if (db_hist_search <= 1) ! 659: break; ! 660: INC_DB_CURR(); ! 661: if (db_history_curr != db_history_last && ! 662: db_hist_substring(db_history_curr, ! 663: db_hist_search_string)) { ! 664: DEC_DB_CURR(); ! 665: break; ! 666: } ! 667: DEC_DB_CURR(); ! 668: } ! 669: INC_DB_CURR(); ! 670: } ! 671: if (db_history_curr != db_history_last) { ! 672: INC_DB_CURR(); ! 673: if (db_history_curr != db_history_last) { ! 674: register char *p; ! 675: db_delete_line(); ! 676: for (p = db_history_curr, ! 677: db_le = db_lbuf_start; *p;) { ! 678: *db_le++ = *p++; ! 679: if (p == db_history + ! 680: db_history_size) { ! 681: p = db_history; ! 682: } ! 683: } ! 684: db_lc = db_le; ! 685: *db_le = '\0'; ! 686: db_putstring(db_lbuf_start, ! 687: db_le - db_lbuf_start); ! 688: } else { ! 689: cnputc('\007'); ! 690: db_history_curr = old_history_curr; ! 691: } ! 692: } else { ! 693: cnputc('\007'); ! 694: db_history_curr = old_history_curr; ! 695: } ! 696: break; ! 697: } ! 698: #endif ! 699: /* refresh the command line */ ! 700: case CTRL('l'): ! 701: db_putstring("^L\n", 3); ! 702: if (db_le > db_lbuf_start) { ! 703: db_putstring(db_lbuf_start, db_le - db_lbuf_start); ! 704: db_putnchars(BACKUP, db_le - db_lc); ! 705: } ! 706: break; ! 707: case '\n': ! 708: case '\r': ! 709: #if DB_HISTORY_SIZE != 0 ! 710: /* Check if it same than previous line */ ! 711: if (db_history_prev) { ! 712: register char *pp, *pc; ! 713: ! 714: /* Is it unmodified */ ! 715: for (p = db_history_prev, pc = db_lbuf_start; ! 716: pc != db_le && *p;) { ! 717: if (*p != *pc) ! 718: break; ! 719: if (++p == db_history + db_history_size) { ! 720: p = db_history; ! 721: } ! 722: if (++pc == db_history + db_history_size) { ! 723: pc = db_history; ! 724: } ! 725: } ! 726: if (!*p && pc == db_le) { ! 727: /* Repeted previous line, not saved */ ! 728: db_history_curr = db_history_last; ! 729: *db_le++ = c; ! 730: db_hist_search = 0; ! 731: db_hist_unmodified = 0; ! 732: return (TRUE); ! 733: } ! 734: } ! 735: if (db_le != db_lbuf_start && ! 736: (db_hist_unmodified == 0 || !db_hist_ignore_dups)) { ! 737: db_history_prev = db_history_last; ! 738: for (p = db_lbuf_start; p != db_le; p++) { ! 739: *db_history_last++ = *p; ! 740: if (db_history_last == db_history + ! 741: db_history_size) { ! 742: db_history_last = db_history; ! 743: } ! 744: } ! 745: *db_history_last++ = '\0'; ! 746: } ! 747: db_history_curr = db_history_last; ! 748: #endif ! 749: *db_le++ = c; ! 750: db_hist_search = 0; ! 751: db_hist_unmodified = 0; ! 752: return (TRUE); ! 753: default: ! 754: if (db_le == db_lbuf_end) { ! 755: cnputc('\007'); ! 756: } ! 757: else if (c >= ' ' && c <= '~') { ! 758: for (p = db_le; p > db_lc; p--) ! 759: *p = *(p-1); ! 760: *db_lc++ = c; ! 761: db_le++; ! 762: cnputc(c); ! 763: db_putstring(db_lc, db_le - db_lc); ! 764: db_putnchars(BACKUP, db_le - db_lc); ! 765: } ! 766: break; ! 767: } ! 768: if (db_hist_search) ! 769: db_hist_search--; ! 770: if (db_hist_unmodified) ! 771: db_hist_unmodified--; ! 772: return (FALSE); ! 773: } ! 774: ! 775: int ! 776: db_readline( ! 777: char * lstart, ! 778: int lsize) ! 779: { ! 780: db_force_whitespace(); /* synch output position */ ! 781: ! 782: db_lbuf_start = lstart; ! 783: db_lbuf_end = lstart + lsize - 1; ! 784: db_lc = lstart; ! 785: db_le = lstart; ! 786: ! 787: while (!db_inputchar(cngetc())) ! 788: continue; ! 789: ! 790: db_putchar('\n'); /* synch output position */ ! 791: ! 792: *db_le = 0; ! 793: return (db_le - db_lbuf_start); ! 794: } ! 795: ! 796: void ! 797: db_check_interrupt(void) ! 798: { ! 799: register int c; ! 800: ! 801: c = cnmaygetc(); ! 802: switch (c) { ! 803: case -1: /* no character */ ! 804: return; ! 805: ! 806: case CTRL('c'): ! 807: db_error((char *)0); ! 808: /*NOTREACHED*/ ! 809: ! 810: case CTRL('s'): ! 811: do { ! 812: c = cnmaygetc(); ! 813: if (c == CTRL('c')) ! 814: db_error((char *)0); ! 815: } while (c != CTRL('q')); ! 816: break; ! 817: ! 818: default: ! 819: /* drop on floor */ ! 820: break; ! 821: } ! 822: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.