Annotation of XNU/osfmk/ddb/db_input.c, revision 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.