Annotation of XNU/osfmk/ddb/db_input.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.