[BACK]Return to fep_edit.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / fep

Annotation of OpenXM_contrib2/fep/fep_edit.c, Revision 1.2

1.1       noro        1: /*     Copyright (c) 1987, 1988 by Software Research Associates, Inc.  */
                      2:
                      3: #ifndef lint
                      4: static char rcsid[]=
                      5: "$Id: fep_edit.c,v 4.10 1995/01/20 08:15:55 utashiro Exp $ (SRA)";
                      6: #endif /* lint */
                      7:
                      8: #include <stdio.h>
                      9: #include <sys/types.h>
                     10: #include <sys/stat.h>
                     11: #include <sys/ioctl.h>
                     12: #ifdef TERMIOS
                     13: #include <termios.h>
                     14: #if defined(__linux__) || defined(__CYGWIN__)
                     15: #ifndef _POSIX_VDISABLE
                     16: #define _POSIX_VDISABLE '\0'
                     17: #endif
                     18: #endif
                     19: #else
                     20: #include <sgtty.h>
                     21: #endif
                     22: #include <sys/time.h>
                     23: #include <ctype.h>
                     24: #if defined(__CYGWIN__)
                     25: #include <sys/dirent.h>
                     26: #define direct dirent
1.2     ! noro       27: #elif defined(sun)
        !            28: #include <dirent.h>
        !            29: #define direct dirent
        !            30: #include <unistd.h>
1.1       noro       31: #else
                     32: #include <sys/dir.h>
                     33: #endif
                     34: #include <sys/file.h>
                     35: #include <setjmp.h>
                     36: #include "fep_defs.h"
                     37: #include "fep_glob.h"
                     38: #include "fep_funcs.h"
                     39:
                     40: CHAR           *CommandLine;           /* pointer to command line buffer */
                     41: CHAR           *KillBuffer;            /* pointer to kill buffer */
                     42: int            CurrentPosition;        /* current cursor position */
                     43: int            MarkPosition = -1;      /* Marked position */
                     44: EDITMODE       editmode = NOTYET;      /* edtimode EMACS, VI */
                     45: EDITSTATUS     editstatus = NOTEDITING;/* EDITING, NOTEDITING */
                     46:
                     47: int    maxline = MAXCMDLEN;            /* maximum length of command line */
                     48: int    NeedNewLine;                    /* add new line flag */
                     49: int    NeedSave;                       /* need to save to history */
                     50: int    Transparency = OFF;             /* transparent flag */
                     51: int    Through = OFF;                  /* through flag */
                     52: int    eof_occured = 0;                /* eof has been occured */
                     53: jmp_buf        jbuf;                           /* jump buffer */
                     54:
                     55: FUNC   *curFuncTab;                    /* current function table */
                     56: FUNC   *altFuncTab;                    /* alternative function table */
                     57:
                     58: /*
                     59:  * Default binding table
                     60:  */
                     61: BINDENT emacsBindings[] = {
                     62:        /* NULL         */      {"\0",          mark},
                     63:        /* ^A           */      {"\\^A",        beginning_of_line},
                     64:        /* ^B           */      {"\\^B",        backward_character},
                     65:        /* ^D           */      {"\\^D",        delete_next_character},
                     66:        /* ^E           */      {"\\^E",        end_of_line},
                     67:        /* ^F           */      {"\\^F",        forward_character},
                     68:        /* ^I           */      {"\\^I",        insert_tab},
                     69:        /* ^J           */      {"\\^J",        new_line},
                     70:        /* ^K           */      {"\\^K",        kill_to_end_of_line},
                     71:        /* ^L           */      {"\\^L",        clear_screen},
                     72:        /* ^M           */      {"\\^M",        new_line},
                     73:        /* ^N           */      {"\\^N",        next_history},
                     74:        /* ^P           */      {"\\^P",        previous_history},
                     75:        /* ^T           */      {"\\^T",        previous_history},
                     76:        /* ^Y           */      {"\\^Y",        yank_from_kill_buffer},
                     77:        /* ^^           */      {"\\^^",        toggle_through},
                     78:        /* esc-b        */      {"\\^[b",       backward_word},
                     79:        /* esc-B        */      {"\\^[B",       backward_Word},
                     80:        /* esc-d        */      {"\\^[d",       delete_next_word},
                     81:        /* esc-D        */      {"\\^[D",       delete_next_Word},
                     82:        /* esc-f        */      {"\\^[f",       forward_word},
                     83:        /* esc-F        */      {"\\^[F",       forward_Word},
                     84:        /* esc-h        */      {"\\^[h",       delete_previous_word},
                     85:        /* esc-H        */      {"\\^[H",       delete_previous_Word},
                     86:        /* esc-l        */      {"\\^[l",       list_file_name},
                     87:        /* esc-L        */      {"\\^[L",       list_file_name},
                     88:        /* esc-n        */      {"\\^[n",       insert_next_history},
                     89:        /* esc-N        */      {"\\^[N",       insert_next_history},
                     90:        /* esc-p        */      {"\\^[p",       insert_previous_history},
                     91:        /* esc-P        */      {"\\^[P",       insert_previous_history},
                     92:        /* esc-.        */      {"\\^[.",       insert_current_history},
                     93:        /* esc-esc      */      {"\\^[\\^[",    expand_file_name},
                     94:        /* esc-"-"      */      {"\\^[-",       toggle_through},
                     95:        /* esc-_        */      {"\\^[_",       invoke_shell},
                     96:        /* esc-<        */      {"\\^[<",       search_reverse},
                     97:        /* esc->        */      {"\\^[>",       search_forward},
                     98:        /* esc-?        */      {"\\^[?",       show_help},
                     99:        /* ^X-^B        */      {"\\^X\\^B",    show_bindings},
                    100:        /* ^X-B         */      {"\\^XB",       show_bindings},
                    101:        /* ^X-b         */      {"\\^Xb",       show_bindings},
                    102:        /* ^X-^H        */      {"\\^X\\^H",    show_history},
                    103:        /* ^X-H         */      {"\\^XH",       show_history},
                    104:        /* ^X-h         */      {"\\^Xh",       show_history},
                    105:        /* ^X-^V        */      {"\\^X\\^V",    view_buffer},
                    106:        /* ^X-^K        */      {"\\^X\\^K",    kill_to_top_of_line},
                    107:        /* ^X-^L        */      {"\\^X\\^L",    fep_repaint},
                    108:        /* ^X-^C        */      {"\\^X\\^C",    (FUNC)terminate},
                    109:        /* ^X-^D        */      {"\\^X\\^D",    send_eof},
                    110:        /* ^X-(         */      {"\\^X(",       fep_start_script},
                    111:        /* ^X-)         */      {"\\^X)",       fep_end_script},
                    112:        /*              */      {NULL,          NULL}
                    113: };
                    114:
                    115: /*
                    116:  * Initialize function table buffer
                    117:  */
                    118: init_bind_table ()
                    119: {
                    120:
                    121:     curFuncTab = (FUNC *) calloc (sizeof (FUNC), 256);
                    122:     altFuncTab = (FUNC *) calloc (sizeof (FUNC), 256);
                    123:     if (curFuncTab == 0 || altFuncTab == 0) {
                    124:        printf ("Can't allocate space for function table\n");
                    125:        exit (1);
                    126:     }
                    127: }
                    128:
                    129: /*
                    130:  * Initialize function table
                    131:  */
                    132: char strspace [256], *strspace_addr = strspace;
                    133:
                    134: init_edit_params ()
                    135: {
                    136:     struct indirect *idp;
                    137:     char *cp, *getenv();
                    138:     char sbuf[2048], *term, *tgetstr();
                    139:
                    140:     if (term = look_var ("term")) {
                    141:        if (tgetent (sbuf, term) == 1) {
                    142:            if (lines == 0)
                    143:                lines = tgetnum ("li");
                    144:            if (columns == 0)
                    145:                columns = tgetnum ("co");
                    146:            term_clear = tgetstr ("cl", &strspace_addr);
                    147:        }
                    148:     }
                    149:
                    150:     if (lines == 0)
                    151:        lines = 24;
                    152:     if (columns == 0)
                    153:        columns = 80;
                    154:
                    155:     sprintf (sbuf, "%d", lines);
                    156:     set_var ("crt", sbuf);
                    157:
                    158:     if (editmode == NOTYET) {
                    159:        if (look_var ("editmode"))
                    160:            set_var ("editmode", look_var ("editmode"));
                    161:        else
                    162:            set_var ("editmode", "emacs");
                    163:     }
                    164:
                    165:     set_var ("showhist", itoa (lines - 1));
                    166:
                    167:     /*
                    168:      * Read startup file
                    169:      */
                    170:     sourceRcFile ();
                    171:
                    172:     /*
                    173:      * Read history if 'history-file' is set
                    174:      */
                    175:     {
                    176:        char *cp, *mk_home_relative ();
                    177:
                    178:        if (look_var ("savehist") && (cp = look_var ("history-file"))) {
                    179:            cp = mk_home_relative (cp);
                    180:
                    181:            if (access (cp, R_OK) == 0)
                    182:                read_history (cp);
                    183:        }
                    184:     }
                    185:
                    186:     /*
                    187:      * Initialize command line buffer
                    188:      */
                    189:     CommandLine = (CHAR *) calloc (maxline, 1);
                    190:     KillBuffer = (CHAR *) calloc (maxline, 1);
                    191:     if (CommandLine == 0 || KillBuffer == 0) {
                    192:        perror ("Edit line buffer");
                    193:        exit (1);
                    194:     }
                    195:     (void) strcpy (CommandLine, "");
                    196:     (void) strcpy (KillBuffer, "");
                    197:     CurrentPosition = 0;
                    198: }
                    199:
                    200: /*
                    201:  * Initialize emacs bindings
                    202:  */
                    203: initEmacsBindings (cft, aft)
                    204:     FUNC cft[], aft[];
                    205: {
                    206:     register int i;
                    207:     BINDENT *ftp;
                    208:
                    209:     for (i = 0; i < 256; i++)
                    210:        cft[i] = self_insert;
                    211:
                    212: #define import(table,key,fn) if((int)key>0)table[(int)key]=fn
                    213:
                    214: #ifdef TERMIOS
                    215:     /* Now, using cbreak mode
                    216:     import (cft, initial_ttymode.c_cc[VSTART], ignore);
                    217:     import (cft, initial_ttymode.c_cc[VSTOP], ignore);
                    218:     */
                    219: #if 0
                    220:     import (cft, initial_ttymode.c_cc[VINTR], insert_and_flush);
                    221: #else
                    222:        /* added by noro */
                    223:     import (cft, initial_ttymode.c_cc[VINTR], send_int_sig);
                    224:        /* XXX : this may not be necessary */
                    225:     import (aft, initial_ttymode.c_cc[VINTR], send_int_sig);
                    226: #endif
                    227:     import (cft, initial_ttymode.c_cc[VQUIT], insert_and_flush);
                    228:     /* Now, EOF will be sent on empty line.
                    229:     import (cft, initial_ttymode.c_cc[VEOF], send_eof);
                    230:     */
                    231: #ifdef VSWTC
                    232:     import (cft, initial_ttymode.c_cc[VSWTC], insert_and_flush);
                    233: #endif
                    234:     import (cft, initial_ttymode.c_cc[VSUSP], insert_and_flush);
                    235:     /* ^Y is used for yank-from-kill-buffer
                    236:     import (cft, initial_ttymode.c_cc[VDSUSP], self_insert);
                    237:     */
                    238:     import (cft, initial_ttymode.c_cc[VREPRINT], reprint);
                    239:     import (cft, initial_ttymode.c_cc[VDISCARD], self_insert);
                    240:     import (cft, initial_ttymode.c_cc[VWERASE], delete_previous_word);
                    241:     import (cft, initial_ttymode.c_cc[VLNEXT], literal_next);
                    242:     import (cft, initial_ttymode.c_cc[VERASE], delete_previous_character);
                    243:     import (cft, initial_ttymode.c_cc[VKILL], delete_line);
                    244: #else
                    245:     /* Now, using cbreak mode
                    246:     import (cft, tchars_buf.t_startc, ignore);
                    247:     import (cft, tchars_buf.t_stopc, ignore);
                    248:     */
                    249: #if 0
                    250:     import (cft, tchars_buf.t_intrc, insert_and_flush);
                    251: #else
                    252:     import (cft, tchars_buf.t_intrc, send_int_sig);
                    253:     import (aft, tchars_buf.t_intrc, send_int_sig);
                    254: #endif
                    255:     import (cft, tchars_buf.t_quitc, insert_and_flush);
                    256:     /* Now, EOF will be sent on empty line.
                    257:     import (cft, tchars_buf.t_eofc, send_eof);
                    258:     */
                    259:     import (cft, tchars_buf.t_brkc, insert_and_flush);
                    260:     import (cft, ltchars_buf.t_suspc, insert_and_flush);
                    261:     /* ^Y is used for yank-from-kill-buffer
                    262:     import (cft, ltchars_buf.t_dsuspc, self_insert);
                    263:     */
                    264:     import (cft, ltchars_buf.t_rprntc, reprint);
                    265:     import (cft, ltchars_buf.t_flushc, self_insert);
                    266:     import (cft, ltchars_buf.t_werasc, delete_previous_word);
                    267:     import (cft, ltchars_buf.t_lnextc, literal_next);
                    268:     import (cft, initial_ttymode.sg_erase, delete_previous_character);
                    269:     import (cft, initial_ttymode.sg_kill, delete_line);
                    270: #endif
                    271:
                    272: #undef import
                    273:
                    274:     /*
                    275:      * Set default bindings
                    276:      */
                    277:     for (ftp = emacsBindings; ftp->bt_s; ftp++) {
                    278:        bind_key (cft, ftp->bt_func, ftp->bt_s, fep_abort);
                    279:     }
                    280: }
                    281:
                    282: /*
                    283:  * Main function of front end program
                    284:  */
                    285: CHAR *
                    286: getline()
                    287: {
                    288:     int c;
                    289:     CHAR *execute_command, *check_alias();
                    290:     char *remained;
                    291:     int processed;
                    292:
                    293:     (void) strcpy (CommandLine, "");
                    294:     CurrentPosition = 0;
                    295:     resetCurrentHistory ();
                    296:
                    297: RETRY:
                    298:     (void) fflush (stdout);
                    299:     NeedNewLine = 0;
                    300:     NeedSave = 0;
                    301:     editstatus = EDITING;
                    302:     processed = 0;
                    303:     (void) setjmp (jbuf);
                    304:
                    305:     /*
                    306:      * If there is file pointer for I/O redirection,
                    307:      * read input from the pointer and return
                    308:      */
                    309:     if (redirect_fp) {
                    310:
                    311:        /*
                    312:         * Check output from sub-process
                    313:         */
                    314:        swallow_output();
                    315:
                    316:        if (fgets (CommandLine, MAXCMDLEN, redirect_fp)) {
                    317:            ++redirect_line;
                    318:            execute_command = CommandLine;
                    319:            goto RETURN;
                    320:        }
                    321:        else {
                    322:            if (look_var ("verbose"))
                    323:                printf ("%d lines redirected\n", redirect_line);
                    324:            errorBell ();
                    325:            if (redirect_pid) {
                    326:                pclose (redirect_fp);
                    327:                redirect_pid = 0;
                    328:            }
                    329:            else
                    330:                fclose (redirect_fp);
                    331:            redirect_fp = NULL;
                    332:        }
                    333:     }
                    334:
                    335:     while ((c = getcharacter ()) >= (CHAR) 0) {
                    336:        int status;
                    337:
                    338:        /*
                    339:         * In transparet mode
                    340:         */
                    341:        if (Through == ON || Transparency == ON) {
                    342:            if (*curFuncTab[(int) c] == toggle_through ||
                    343:                *curFuncTab[(int) c] == fix_transparency) {
                    344:                (*curFuncTab[(int) c])();
                    345:                goto RETRY;
                    346:            }
                    347:            else {
                    348:                CommandLine[CurrentPosition] = c;
                    349:                CommandLine[CurrentPosition + 1] = '\0';
                    350:                return (CommandLine);
                    351:            }
                    352:        }
                    353:
                    354:        /*
                    355:         * If find EOF character on top of empty line
                    356:         * and the variable "send-eof-on-empty-line" is set
                    357:         * call send_eof
                    358:         */
                    359:        if (
                    360: #ifdef TERMIOS
                    361:            c == initial_ttymode.c_cc[VEOF]
                    362: #else
                    363:            c == tchars_buf.t_eofc
                    364: #endif
                    365:            && curFuncTab[c] != send_eof
                    366:            && ! look_var ("ignore-eof")
                    367:            && CommandLine [0] == '\0'
                    368:        ) {
                    369:            if (!eof_occured && look_var ("alarm-on-eof")) {
                    370:                eof_occured = 1;
                    371:                status = alarm_on_eof (c);
                    372:            }
                    373:            else
                    374:                status = send_eof (c);
                    375:        }
                    376:        else {
                    377:            eof_occured = 0;
                    378:            status = callfunc (curFuncTab, c);
                    379:        }
                    380:
                    381:        (void) fflush (stdout);
                    382:        if (status == 1)        /* end of line editing */
                    383:            break;
                    384:        else                    /* continue line editing */
                    385:            continue;
                    386:     }
                    387:     editstatus = NOTEDITING;
                    388:
                    389:  REPROCESS:
                    390:
                    391:     /*
                    392:      * Check command line refer history or not
                    393:      */
                    394:     if (refer_history () == PROCESSED)
                    395:        goto RETRY;
                    396:
                    397:     /*
                    398:      * Check alias list
                    399:      */
                    400:     if (!processed && !look_var ("noalias")
                    401:        && (execute_command = check_alias (CommandLine))
                    402:     ) {
                    403:        if (look_var ("verbose"))
                    404:            printf ("%s\n", execute_command);
                    405:     }
                    406:     else
                    407:        execute_command = CommandLine;
                    408:
                    409:
                    410:     /*
                    411:      * Check builtin function, and execute it.
                    412:      */
                    413:     if (executeBuiltInFunction (execute_command, &remained) == PROCESSED) {
                    414:        if (!processed)
                    415:            addHistory (CommandLine);
                    416:        CommandLine[0] = '\0';
                    417:        CurrentPosition = 0;
                    418:        if (remained && *remained) {
                    419:            strcpy (CommandLine, remained);
                    420:            processed = 1;
                    421:            goto REPROCESS;
                    422:        }
                    423:        if (!redirect_fp)
                    424:            fputs (prompt, stdout);
                    425:        goto RETRY;
                    426:     }
                    427:
                    428:     if (NeedSave) {
                    429:        if (!is_empty_line (CommandLine) || !look_var ("ignore-empty-line"))
                    430:            if (!processed)
                    431:                addHistory (CommandLine);
                    432:        /*
                    433:         * put string to buffer
                    434:         */
                    435:        buf_put (output_buffer, CommandLine);
                    436:        if (NeedNewLine == 1)
                    437:            buf_put (output_buffer, "\n");
                    438:     }
                    439:
                    440:     if (NeedNewLine == 1)
                    441:        (void) strcat (execute_command, "\n");
                    442:
                    443: RETURN:
                    444:     return (execute_command);
                    445: }
                    446:
                    447: /*
                    448:  * Invoke appropliate function according to fucntion table
                    449:  * Return value 1 means exit from line editing
                    450:  */
                    451: callfunc (ft, c)
                    452:     FUNC ft[];
                    453:     int c;
                    454: {
                    455:
                    456:     if (isIndirect(ft[(int) c])) {
                    457:        FUNC *nft = maskIndirect (ft[(int)c]);
                    458:        char nc;
                    459:
                    460:        nc = (CHAR) getcharacter();
                    461:        return (callfunc (nft, nc));
                    462:     }
                    463:     else
                    464:        return ((*ft[(int) c]) (c));
                    465: }
                    466:
                    467: /*
                    468:  * Beep and do nothing
                    469:  */
                    470: fep_abort()
                    471: {
                    472:     (void) errorBell ();
                    473:     return (0);
                    474: }
                    475:
                    476: /*
                    477:  * Insert the character self
                    478:  */
                    479: self_insert(c)
                    480:     CHAR c;
                    481: {
                    482:     register int i, nbyte = 1, currentNull;
                    483: #ifdef KANJI
                    484:     CHAR byte2;
                    485: #endif /* KANJI */
                    486:
                    487:     currentNull = strlen (CommandLine);
                    488:
                    489:     if (currentNull >= maxline) {
                    490:         errorBell();
                    491:        return (0);
                    492:     }
                    493:
                    494:     if (isctlchar(CommandLine[CurrentPosition]))
                    495:        (void) putchar (BS);
                    496: #ifdef KANJI
                    497:     if (iskanji (c)) {
                    498:        byte2 = (CHAR) getcharacter ();
                    499:        putchar (c);
                    500:        putchar (byte2);
                    501:        nbyte = 2;
                    502:     }
                    503:     else
                    504: #endif /* KANJI */
                    505:        putChar (c);
                    506:     reverse_strcpy (
                    507:        &CommandLine[CurrentPosition] + nbyte,
                    508:        &CommandLine[CurrentPosition]
                    509:     );
                    510:     CurrentPosition += nbyte;
                    511:     CommandLine[CurrentPosition - nbyte] = c;
                    512: #ifdef KANJI
                    513:     if (nbyte > 1) {
                    514:        CommandLine[CurrentPosition - 1] = byte2;
                    515:     }
                    516: #endif /* KANJI */
                    517:     printS (&CommandLine [CurrentPosition]);
                    518:
                    519:     if (CommandLine[CurrentPosition] != '\0') {
                    520:        repeat (BS, howlong (&CommandLine[CurrentPosition + 1], 0));
                    521:        (void) putchar (BS);
                    522:     }
                    523:     return (0);
                    524: }
                    525:
                    526: /*
                    527:  * Insert string in current position
                    528:  */
                    529: insert_string (s)
                    530:     CHAR *s;
                    531: {
                    532:     register int i, nbyte = strlen (s), currentNull;
                    533:
                    534:     currentNull = strlen (CommandLine);
                    535:
                    536:     if (currentNull + nbyte >= maxline - 1) {
                    537:         errorBell();
                    538:        return (0);
                    539:     }
                    540:
                    541:     if (isctlchar(CommandLine[CurrentPosition]))
                    542:        (void) putchar (BS);
                    543:     printS (s);
                    544:     reverse_strcpy (
                    545:        &CommandLine[CurrentPosition] + nbyte,  /* to */
                    546:        &CommandLine[CurrentPosition]           /* from */
                    547:     );
                    548:     bcopy (s, &CommandLine[CurrentPosition], nbyte);
                    549:     CurrentPosition += nbyte;
                    550:
                    551:     if (CommandLine[CurrentPosition] != '\0') {
                    552:        printS (&CommandLine[CurrentPosition]);
                    553:        repeat (BS, howlong (&CommandLine[CurrentPosition], 0));
                    554:     }
                    555:     return (0);
                    556: }
                    557:
                    558: /*
                    559:  * Yank string from kill buffer.
                    560:  */
                    561: yank_from_kill_buffer ()
                    562: {
                    563:     insert_string (KillBuffer);
                    564: }
                    565:
                    566: /*
                    567:  * Set mark to current position
                    568:  */
                    569: mark ()
                    570: {
                    571:     set_mark (CurrentPosition);
                    572:     return (0);
                    573: }
                    574:
                    575: /*
                    576:  * Set mark to specified position
                    577:  */
                    578: set_mark (pos)
                    579:     int pos;
                    580: {
                    581:     MarkPosition = pos;
                    582:     return (0);
                    583: }
                    584:
                    585: /*
                    586:  * Delete area from mark to current position to kill buffer
                    587:  */
                    588: delete_to_kill_buffer ()
                    589: {
                    590:     int n = abs (CurrentPosition - MarkPosition);
                    591:
                    592:     if (MarkPosition < 0) {
                    593:        errorBell();
                    594:        return (0);
                    595:     }
                    596:
                    597:     if (CurrentPosition == MarkPosition)
                    598:        return;
                    599:
                    600:     if (CurrentPosition > MarkPosition) {
                    601:        (void) moveto (MarkPosition);
                    602:     }
                    603:
                    604:     return (delete_next_n_character (n));
                    605: }
                    606:
                    607: /*
                    608:  * Move to specified position.
                    609:  */
                    610: moveto (position)
                    611: {
                    612:     if (position < CurrentPosition)
                    613:        while (position < CurrentPosition)
                    614:            (void) backward_n_character (1);
                    615:     else
                    616:        while (position > CurrentPosition
                    617: #ifdef KANJI
                    618:            && !(CurrentPosition + 1 == position
                    619:                    && iskanji (CommandLine[CurrentPosition]))
                    620: #endif /* KANJI */
                    621:        )
                    622:            (void) forward_n_character (1);
                    623: }
                    624:
                    625: /*
                    626:  * Move cursor to top of line
                    627:  */
                    628: beginning_of_line()
                    629: {
                    630:     register int i;
                    631:
                    632:     for (i = CurrentPosition; i > 0; i--) {
                    633:        if (isctlchar (CommandLine[i]))
                    634:            (void) putchar (BS);
                    635:        (void) putchar (BS);
                    636:     }
                    637:     CurrentPosition = 0;
                    638:     return (0);
                    639: }
                    640:
                    641: #ifdef KANJI
                    642: #define INC(i) if(iskanji(CommandLine[i])) i+=2; else i++;
                    643: #define DEC(i) if(i>=2 && iskanji_in_string(CommandLine, i-2)) i-=2; else i--;
                    644: #else /* KANJI */
                    645: #define INC(i) i++
                    646: #define DEC(i) i--
                    647: #endif /* KANJI */
                    648:
                    649: /*
                    650:  * Move cursor to end of line
                    651:  */
                    652: end_of_line()
                    653: {
                    654:     register int    i;
                    655:
                    656:     for (i = CurrentPosition; CommandLine[i]; i++) {
                    657:        if (isctlchar (CommandLine[i]))
                    658:            (void) putchar (unctl(CommandLine[i]));
                    659:        else
                    660:            (void) putchar (CommandLine[i]);
                    661:        if (isctlchar(CommandLine[i+1]))
                    662:            (void) putchar ('^');
                    663:     }
                    664:     CurrentPosition = i;
                    665:     return (0);
                    666: }
                    667:
                    668: /*
                    669:  * Move cursor left one space
                    670:  */
                    671: backward_character()
                    672: {
                    673:
                    674:     return (backward_n_character (1));
                    675: }
                    676:
                    677: /*
                    678:  * Move cursor left "n" space
                    679:  */
                    680: backward_n_character(n)
                    681:     int n;
                    682: {
                    683:     int space;
                    684:     int i = CurrentPosition;
                    685:
                    686:     if (n == 0)
                    687:        return (0);
                    688:     else if (n < 0)
                    689:        return (forward_n_character (-n));
                    690:     else if (n > CurrentPosition) {
                    691:        errorBell ();
                    692:        return (0);
                    693:     }
                    694:
                    695:     while (n-- && i >= 0) {
                    696:        if (isctlchar (CommandLine[i]))
                    697:            putchar (BS);
                    698: #ifdef KANJI
                    699:        if (i > 0 && iskanji_in_string (CommandLine, i-2)) {
                    700:            (void) putchar (BS);
                    701:            (void) putchar (BS);
                    702:            i--;
                    703:        }
                    704:        else
                    705: #endif /* KANJI */
                    706:        putchar (BS);
                    707:        i--;
                    708:     }
                    709:     CurrentPosition = i;
                    710:     return (0);
                    711: }
                    712:
                    713: /*
                    714:  * Move cursor backward one word
                    715:  */
                    716: backward_word ()
                    717: {
                    718:
                    719:     return (backward_n_word (1));
                    720: }
                    721:
                    722: /*
                    723:  * Move cursor backward n word
                    724:  */
                    725: backward_n_word (n)
                    726:     int n;
                    727: {
                    728:     register int i = CurrentPosition, nchars = 0;
                    729:
                    730:     if (i == 0) {
                    731:        errorBell ();
                    732:        return (0);
                    733:     }
                    734:
                    735: #ifdef KANJI
                    736:     while (n--) {
                    737:        DEC(i);
                    738:        nchars++;
                    739:
                    740:        while (1) {
                    741:            if (i >= 2 && iskanji_in_string (CommandLine, i-2))
                    742:                break;
                    743:            else if (i > 0 && !iswordchar (CommandLine[i]))
                    744:                i -= 1;
                    745:            else
                    746:                break;
                    747:
                    748:            nchars++;
                    749:        }
                    750:        while (1) {
                    751:            if (i >= 2 && iskanji_in_string (CommandLine, i - 2))
                    752:                i -= 2;
                    753:            else if (i > 0 && iswordchar (CommandLine [i -1]))
                    754:                i -= 1;
                    755:            else
                    756:                break;
                    757:            nchars++;
                    758:        }
                    759:     }
                    760: #else /* KANJI */
                    761:     while (n--) {
                    762:        i--, nchars++;
                    763:        while (i > 0 && !iswordchar (CommandLine [i])) {
                    764:            i--, nchars++;
                    765:        }
                    766:        while (i > 0 && iswordchar (CommandLine [i - 1])) {
                    767:            i--, nchars++;
                    768:        }
                    769:     }
                    770: #endif /* KANJI */
                    771:     return (backward_n_character (nchars));
                    772: }
                    773:
                    774: /*
                    775:  * Move cursor backward one Word
                    776:  */
                    777: backward_Word ()
                    778: {
                    779:
                    780:     return (backward_n_Word (1));
                    781: }
                    782:
                    783: /*
                    784:  * Move cursor backward n Word
                    785:  */
                    786: backward_n_Word (n)
                    787:     int n;
                    788: {
                    789:     register int i = CurrentPosition, nchars = 0;
                    790:
                    791:     if (i == 0) {
                    792:        errorBell ();
                    793:        return (0);
                    794:     }
                    795:
                    796: #ifdef KANJI
                    797:     while (n--) {
                    798:        DEC(i);
                    799:        nchars++;
                    800:
                    801:        while (1) {
                    802:            if (i > 1 && iskanji_in_string (CommandLine, i - 2))
                    803:                break;
                    804:            else if (i > 0 && !iswordchar (CommandLine[i]))
                    805:                i -= 1;
                    806:            else
                    807:                break;
                    808:
                    809:            nchars++;
                    810:        }
                    811:        while (1) {
                    812:            if (i > 2 && iskanji_in_string (CommandLine, i - 2))
                    813:                i -= 2;
                    814:            else if (i > 0 && iswordchar (CommandLine [i - 1]))
                    815:                i -= 1;
                    816:            else
                    817:                break;
                    818:            nchars++;
                    819:        }
                    820:     }
                    821: #else /* KANJI */
                    822:     while (n--) {
                    823:        i--, nchars++;
                    824:        while (i > 0 && !isWordchar (CommandLine [i]))
                    825:            i--, nchars++;
                    826:        while (i > 0 && isWordchar (CommandLine [i - 1]))
                    827:            i--, nchars++;
                    828:     }
                    829: #endif /* KANJI */
                    830:     return (backward_n_character (nchars));
                    831: }
                    832:
                    833: /*
                    834:  * Move cursor forward one character
                    835:  */
                    836: forward_character()
                    837: {
                    838:
                    839:     return (forward_n_character (1));
                    840: }
                    841:
                    842: /*
                    843:  * Move cursor forward n character
                    844:  */
                    845: forward_n_character(n)
                    846:     int n;
                    847: {
                    848:     int space;
                    849:     register int i = CurrentPosition;
                    850:
                    851:     if (n == 0)
                    852:        return (0);
                    853:     else if (n < 0)
                    854:        return (backward_n_character (-n));
                    855:
                    856:     if (CommandLine [CurrentPosition] == '\0') {
                    857:        errorBell ();
                    858:        return (0);
                    859:     }
                    860:
                    861: #ifdef KANJI
                    862:     if (iskanji (CommandLine[i])) {
                    863:        (void) putchar (CommandLine[i++]);
                    864:        (void) putchar (CommandLine[i++]);
                    865:     }
                    866:     else
                    867: #endif /* KANJI */
                    868:     if (isctlchar(CommandLine[i])) {
                    869:        (void) putchar (unctl (CommandLine [i]));
                    870:        i++;
                    871:     }
                    872:     else
                    873:        (void) putchar (CommandLine[i++]);
                    874:
                    875:     while (--n && CommandLine [i]) {
                    876: #ifdef KANJI
                    877:        if (iskanji (CommandLine[i])) {
                    878:            (void) putchar (CommandLine[i++]);
                    879:            (void) putchar (CommandLine[i++]);
                    880:        }
                    881:        else
                    882: #endif /* KANJI */
                    883:        putChar (CommandLine [i++]);
                    884:     }
                    885:
                    886:     if (isctlchar (CommandLine [i]))
                    887:        putchar ('^');
                    888:
                    889:     CurrentPosition = i;
                    890:
                    891:     return (0);
                    892: }
                    893:
                    894: /*
                    895:  * Move cursor forward one word
                    896:  */
                    897: forward_word ()
                    898: {
                    899:     return (forward_n_word (1));
                    900: }
                    901:
                    902: /*
                    903:  * Move cursor forward n word
                    904:  */
                    905: forward_n_word (n)
                    906:     int n;
                    907: {
                    908:     register int i = CurrentPosition, nchars = 0;
                    909:
                    910:     if (CommandLine [i] == '\0') {
                    911:        errorBell ();
                    912:        return (0);
                    913:     }
                    914:
                    915:     while (n--) {
                    916:        while (CommandLine [i] && iswordchar (CommandLine [i])) {
                    917:            INC(i);
                    918:            nchars++;
                    919:        }
                    920:        while (CommandLine [i] && !iswordchar (CommandLine [i])) {
                    921:            INC(i);
                    922:            nchars++;
                    923:        }
                    924:     }
                    925:     return (forward_n_character (nchars));
                    926: }
                    927:
                    928: /*
                    929:  * Move cursor forward one word
                    930:  */
                    931: forward_Word ()
                    932: {
                    933:     return (forward_n_Word (1));
                    934: }
                    935:
                    936: /*
                    937:  * Move cursor forward n word
                    938:  */
                    939: forward_n_Word (n)
                    940:     int n;
                    941: {
                    942:     register int i = CurrentPosition, nchars = 0;
                    943:
                    944:     if (CommandLine [i] == '\0') {
                    945:        errorBell ();
                    946:        return (0);
                    947:     }
                    948:
                    949:     while (n--) {
                    950:        while (CommandLine [i] && isWordchar (CommandLine [i])) {
                    951:            INC(i);
                    952:             nchars++;
                    953:        }
                    954:        while (CommandLine [i] && !isWordchar (CommandLine [i])) {
                    955:            INC(i);
                    956:             nchars++;
                    957:        }
                    958:     }
                    959:     return (forward_n_character (nchars));
                    960: }
                    961:
                    962: /*
                    963:  * Forward to end of word
                    964:  */
                    965: forward_to_end_of_word ()
                    966: {
                    967:
                    968:     return (forward_to_end_of_n_word (1));
                    969: }
                    970:
                    971: /*
                    972:  * Forward to end of n word
                    973:  */
                    974: forward_to_end_of_n_word (n)
                    975: {
                    976:     register int i = CurrentPosition, nchars = 0;
                    977:
                    978:     if (CommandLine [i] == '\0') {
                    979:        errorBell ();
                    980:        return (0);
                    981:     }
                    982:
                    983:     INC(i);
                    984:     while (n--) {
                    985:        while (CommandLine [i] && !iswordchar (CommandLine [i])) {
                    986:            INC(i);
                    987:            nchars++;
                    988:        }
                    989:        while (CommandLine [i] && iswordchar (CommandLine [i])) {
                    990:            INC(i);
                    991:            nchars++;
                    992:        }
                    993:     }
                    994:     DEC(i);
                    995:     return (forward_n_character (nchars));
                    996: }
                    997:
                    998: /*
                    999:  * Forward to end of word
                   1000:  */
                   1001: forward_to_end_of_Word ()
                   1002: {
                   1003:
                   1004:     return (forward_to_end_of_n_Word (1));
                   1005: }
                   1006:
                   1007: /*
                   1008:  * Forward to end of n word
                   1009:  */
                   1010: forward_to_end_of_n_Word (n)
                   1011: {
                   1012:     register int i = CurrentPosition, nchars = 0;
                   1013:
                   1014:     if (CommandLine [i] == '\0') {
                   1015:        errorBell ();
                   1016:        return (0);
                   1017:     }
                   1018:
                   1019:     INC(i);
                   1020:     while (n--) {
                   1021:        while (CommandLine [i] && !isWordchar (CommandLine [i])) {
                   1022:            INC(i);
                   1023:            nchars++;
                   1024:        }
                   1025:        while (CommandLine [i] && isWordchar (CommandLine [i])) {
                   1026:            INC(i);
                   1027:            nchars++;
                   1028:        }
                   1029:     }
                   1030:     DEC(i);
                   1031:     return (forward_n_character (nchars));
                   1032: }
                   1033:
                   1034: /*
                   1035:  * Delete previous one character
                   1036:  */
                   1037: delete_previous_character()
                   1038: {
                   1039:
                   1040:     return (delete_previous_n_character (1));
                   1041: }
                   1042:
                   1043: /*
                   1044:  * Delete previous n characters
                   1045:  */
                   1046: delete_previous_n_character(n)
                   1047:     int n;
                   1048: {
                   1049:     register int i, nbyte;
                   1050:     int deleteArea, restArea;
                   1051:
                   1052:     if (CurrentPosition < n) {
                   1053:        errorBell ();
                   1054:        return (0);
                   1055:     }
                   1056:
                   1057: #ifdef KANJI
                   1058:     for (nbyte = 0, i = CurrentPosition; n-- > 0 && i;)
                   1059:        if (i > 1 && iskanji_in_string (CommandLine, i - 2))
                   1060:            i -= 2, nbyte += 2;
                   1061:        else
                   1062:            i -= 1, nbyte += 1;
                   1063: #else /* KANJI */
                   1064:     nbyte = n;
                   1065: #endif /* KANJI */
                   1066:
                   1067:     deleteArea = howlong (&CommandLine[CurrentPosition - nbyte], nbyte);
                   1068:     restArea = howlong (&CommandLine[CurrentPosition], 0);
                   1069:     if (isctlchar(CommandLine[CurrentPosition]))
                   1070:        (void) putchar (BS);
                   1071:     repeat(BS, deleteArea);
                   1072:     CurrentPosition -= nbyte;
                   1073:     strcpy (KillBuffer, &CommandLine [CurrentPosition]);
                   1074:     KillBuffer [nbyte] = '\0';
                   1075:     for (i = CurrentPosition; CommandLine[i + nbyte]; i++) {
                   1076:        CommandLine[i] = CommandLine[i + nbyte];
                   1077:        putChar (CommandLine[i]);
                   1078:     }
                   1079:     CommandLine[i] = '\0';
                   1080:     repeat(SP, deleteArea);
                   1081:     repeat(BS, deleteArea);
                   1082:     if (isctlchar (CommandLine[CurrentPosition]))
                   1083:        repeat(BS, restArea - 1);
                   1084:     else
                   1085:        repeat(BS, restArea);
                   1086:
                   1087:     return (0);
                   1088: }
                   1089:
                   1090: /*
                   1091:  * Delete previous one word
                   1092:  */
                   1093: delete_previous_word()
                   1094: {
                   1095:
                   1096:     return (delete_previous_n_word (1));
                   1097: }
                   1098:
                   1099: /*
                   1100:  * Delete previous n word
                   1101:  */
                   1102: delete_previous_n_word(n)
                   1103:     int n;
                   1104: {
                   1105:     register int i = CurrentPosition, nchars = 0;
                   1106:
                   1107:     if (i == 0) {
                   1108:        errorBell();
                   1109:        return (0);
                   1110:     }
                   1111:
                   1112: #ifdef KANJI
                   1113:     while (n--) {
                   1114:        if (i>1 && iskanji_in_string (CommandLine, i-2))
                   1115:            i--;
                   1116:        i--, nchars++;
                   1117:
                   1118:        while (1) {
                   1119:            if (i > 1 && iskanji_in_string (CommandLine, i-2))
                   1120:                break;
                   1121:            else if (i > 0 && !iswordchar (CommandLine[i]))
                   1122:                i -= 1;
                   1123:            else
                   1124:                break;
                   1125:
                   1126:            nchars++;
                   1127:        }
                   1128:        while (1) {
                   1129:            if (i > 2 && iskanji_in_string (CommandLine, i - 2))
                   1130:                i -= 2;
                   1131:            else if (i > 0 && iswordchar (CommandLine [i -1]))
                   1132:                i -= 1;
                   1133:            else
                   1134:                break;
                   1135:            nchars++;
                   1136:        }
                   1137:     }
                   1138: #else /* KANJI */
                   1139:     while (n--) {
                   1140:        i--, nchars++;
                   1141:        while (i > 0 && !iswordchar (CommandLine [i]))
                   1142:            i--, nchars++;
                   1143:        while (i > 0 && iswordchar (CommandLine [i - 1]))
                   1144:            i--, nchars++;
                   1145:     }
                   1146: #endif /* KANJI */
                   1147:
                   1148:     return (delete_previous_n_character (nchars));
                   1149: }
                   1150:
                   1151: /*
                   1152:  * Delete previous one word
                   1153:  */
                   1154: delete_previous_Word()
                   1155: {
                   1156:
                   1157:     return (delete_previous_n_Word (1));
                   1158: }
                   1159:
                   1160: /*
                   1161:  * Delete previous n word
                   1162:  */
                   1163: delete_previous_n_Word(n)
                   1164:     int n;
                   1165: {
                   1166:     register int i = CurrentPosition, nchars = 0;
                   1167:
                   1168:     if (i == 0) {
                   1169:        errorBell();
                   1170:        return (0);
                   1171:     }
                   1172:
                   1173: #ifdef KANJI
                   1174:     while (n--) {
                   1175:        if (i>1 && iskanji_in_string (CommandLine, i-2))
                   1176:            i--;
                   1177:        i--, nchars++;
                   1178:
                   1179:        while (1) {
                   1180:            if (i > 1 && iskanji_in_string (CommandLine, i-2))
                   1181:                break;
                   1182:            else if (i > 0 && !isWordchar (CommandLine[i]))
                   1183:                i -= 1;
                   1184:            else
                   1185:                break;
                   1186:
                   1187:            nchars++;
                   1188:        }
                   1189:        while (1) {
                   1190:            if (i > 2 && iskanji_in_string (CommandLine, i - 2))
                   1191:                i -= 2;
                   1192:            else if (i > 0 && isWordchar (CommandLine [i -1]))
                   1193:                i -= 1;
                   1194:            else
                   1195:                break;
                   1196:            nchars++;
                   1197:        }
                   1198:     }
                   1199: #else /* KANJI */
                   1200:     while (n--) {
                   1201:        i--, nchars++;
                   1202:        while (i > 0 && !isWordchar (CommandLine [i]))
                   1203:            i--, nchars++;
                   1204:        while (i > 0 && isWordchar (CommandLine [i - 1]))
                   1205:            i--, nchars++;
                   1206:     }
                   1207: #endif /* KANJI */
                   1208:
                   1209:     return (delete_previous_n_character (nchars));
                   1210: }
                   1211:
                   1212: /*
                   1213:  * Delete next one character
                   1214:  */
                   1215: delete_next_character ()
                   1216: {
                   1217:
                   1218:     return (delete_next_n_character (1));
                   1219: }
                   1220:
                   1221: /*
                   1222:  * Delete next n character
                   1223:  */
                   1224: delete_next_n_character (n)
                   1225:     int n;
                   1226: {
                   1227:     register int i, nbyte;
                   1228:     int deleteArea, restArea;
                   1229:
                   1230:     if (strlen (&CommandLine [CurrentPosition]) < n) {
                   1231:        errorBell ();
                   1232:        return (0);
                   1233:     }
                   1234:
                   1235: #ifdef KANJI
                   1236:     {
                   1237:        register CHAR *cp = &CommandLine[CurrentPosition];
                   1238:
                   1239:        nbyte = 0;
                   1240:        while (n-- > 0 && *cp)
                   1241:            if (iskanji (*cp))
                   1242:                cp += 2, nbyte += 2;
                   1243:            else
                   1244:                cp++, nbyte++;
                   1245:     }
                   1246: #else /* KANJI */
                   1247:     nbyte = n;
                   1248: #endif /* KANJI */
                   1249:
                   1250:     deleteArea = howlong (&CommandLine[CurrentPosition], nbyte);
                   1251:     restArea = howlong (&CommandLine[CurrentPosition + nbyte], 0);
                   1252:     if (isctlchar(CommandLine[CurrentPosition]))
                   1253:        (void) putchar (BS);
                   1254:     strcpy (KillBuffer, CommandLine + CurrentPosition);
                   1255:     KillBuffer [nbyte] = '\0';
                   1256:     for (i = CurrentPosition; CommandLine[i + nbyte]; i++) {
                   1257:        CommandLine[i] = CommandLine[i + nbyte];
                   1258:        putChar (CommandLine[i]);
                   1259:     }
                   1260:     CommandLine[i] = '\0';
                   1261:     repeat(SP, deleteArea);
                   1262:     repeat(BS, deleteArea);
                   1263:     if (isctlchar (CommandLine[CurrentPosition]))
                   1264:        repeat(BS, restArea - 1);
                   1265:     else
                   1266:        repeat(BS, restArea);
                   1267:
                   1268:     return (0);
                   1269: }
                   1270:
                   1271: /*
                   1272:  * Delete next one word
                   1273:  */
                   1274: delete_next_word ()
                   1275: {
                   1276:     return (delete_next_n_word (1));
                   1277: }
                   1278:
                   1279: /*
                   1280:  * Delete next n word
                   1281:  */
                   1282: delete_next_n_word (n)
                   1283:     int n;
                   1284: {
                   1285:     register int i = CurrentPosition, nchars = 0;
                   1286:
                   1287:     if (CommandLine [i] == '\0') {
                   1288:        errorBell ();
                   1289:        return (0);
                   1290:     }
                   1291:
                   1292:     while (n--) {
                   1293:        while (CommandLine [i] && iswordchar (CommandLine [i])) {
                   1294:            INC(i);
                   1295:            nchars++;
                   1296:        }
                   1297:        while (CommandLine [i] && !iswordchar (CommandLine [i])) {
                   1298:            INC(i);
                   1299:            nchars++;
                   1300:        }
                   1301:     }
                   1302:     return (delete_next_n_character (nchars));
                   1303: }
                   1304:
                   1305: /*
                   1306:  * Delete next one word
                   1307:  */
                   1308: delete_next_Word ()
                   1309: {
                   1310:     return (delete_next_n_Word (1));
                   1311: }
                   1312:
                   1313: /*
                   1314:  * Delete next n word
                   1315:  */
                   1316: delete_next_n_Word (n)
                   1317:     int n;
                   1318: {
                   1319:     register int i = CurrentPosition, nchars = 0;
                   1320:
                   1321:     if (CommandLine [i] == '\0') {
                   1322:        errorBell ();
                   1323:        return (0);
                   1324:     }
                   1325:
                   1326:     while (n--) {
                   1327:        while (CommandLine [i] && isWordchar (CommandLine [i])) {
                   1328:            INC(i);
                   1329:            nchars++;
                   1330:        }
                   1331:        while (CommandLine [i] && !isWordchar (CommandLine [i])) {
                   1332:            INC(i);
                   1333:            nchars++;
                   1334:        }
                   1335:     }
                   1336:     return (delete_next_n_character (nchars));
                   1337: }
                   1338:
                   1339: /*
                   1340:  * Erase whole line
                   1341:  */
                   1342: delete_line()
                   1343: {
                   1344:     register int i = CurrentPosition;
                   1345:     register int len;
                   1346:
                   1347:     len = howlong (CommandLine, 0);
                   1348:
                   1349:     /*
                   1350:      * If cursor is there right part of line, move it to end of line
                   1351:      * and erase character by character from end
                   1352:      */
                   1353:     if (howlong (CommandLine, CurrentPosition + 1) > len / 2) {
                   1354:        (void) end_of_line ();
                   1355:        repeat_string ("\b \b", len);
                   1356:     }
                   1357:     /*
                   1358:      * If cursor is there on left part of line, move it to top of line
                   1359:      * and erase line at once
                   1360:      */
                   1361:     else {
                   1362:        (void) beginning_of_line ();
                   1363:        if (isctlchar (CommandLine[0]))
                   1364:            putchar (BS);
                   1365:        repeat (SP, len);
                   1366:        repeat (BS, len);
                   1367:     }
                   1368:     strcpy (KillBuffer, CommandLine);
                   1369:     CurrentPosition = 0;
                   1370:     CommandLine [0] = '\0';
                   1371:     return (0);
                   1372: }
                   1373:
                   1374: /*
                   1375:  * Delete characters from current position to top of line
                   1376:  */
                   1377: kill_to_top_of_line()
                   1378: {
                   1379:     int i = CurrentPosition;
                   1380:
                   1381:     (void) beginning_of_line();
                   1382:     return (delete_next_n_character (i));
                   1383: }
                   1384:
                   1385: /*
                   1386:  * Delete characters from current position to end of line
                   1387:  */
                   1388: kill_to_end_of_line()
                   1389: {
                   1390:     register int    i, backCnt = 0;
                   1391:
                   1392:     if (isctlchar(CommandLine[CurrentPosition])) {
                   1393:         (void) putchar(BS);
                   1394:     }
                   1395:     for (i = CurrentPosition; CommandLine[i]; i++) {
                   1396:        if (isctlchar(CommandLine[i])) {
                   1397:            fputs("  ", stdout);
                   1398:            backCnt++;
                   1399:        }
                   1400:        else
                   1401:            (void) putchar (SP);
                   1402:        backCnt++;
                   1403:     }
                   1404:     for (; backCnt; backCnt--)
                   1405:        (void) putchar (BS);
                   1406:     strcpy (KillBuffer, CommandLine + CurrentPosition);
                   1407:     CommandLine[CurrentPosition] = '\0';
                   1408:     return (0);
                   1409: }
                   1410:
                   1411: /*
                   1412:  * Insert tab to current cursor position
                   1413:  */
                   1414: insert_tab()
                   1415: {
                   1416:
                   1417:     /* sorry, not implemented */
                   1418:     return (self_insert ('\t'));
                   1419: }
                   1420:
                   1421: /*
                   1422:  * Process new line
                   1423:  */
                   1424: new_line()
                   1425: {
                   1426:
                   1427:     (void) end_of_line;
                   1428:     fputs ("\r\n", stdout);
                   1429:     NeedNewLine = 1;
                   1430:     NeedSave = 1;
                   1431:
                   1432:     return (1);
                   1433: }
                   1434:
                   1435: /*
                   1436:  * Check current position is top-of-line
                   1437:  */
                   1438: is_tol()
                   1439: {
                   1440:     return (CurrentPosition == 0);
                   1441: }
                   1442:
                   1443: /*
                   1444:  * Check current position is end-of-line
                   1445:  */
                   1446: is_eol()
                   1447: {
                   1448:     return (CommandLine [CurrentPosition] == '\0');
                   1449: }
                   1450:
                   1451: /*
                   1452:  * Check command line if it refer history or not
                   1453:  */
                   1454: refer_history()
                   1455: {
                   1456:     char   *historyExtract ();
                   1457:     char   *his;
                   1458:
                   1459:     if (CommandLine[0] != '!')
                   1460:        return (NOT_PROCESSED);
                   1461:
                   1462:     if (his = historyExtract (CommandLine)) {
                   1463:        (void) strcpy (CommandLine, his);
                   1464:        CurrentPosition = strlen (CommandLine);
                   1465:     }
                   1466:     else {
                   1467:        fputs (CommandLine, stdout);
                   1468:        fputs (" : Event not found.\r\n", stdout);
                   1469:        (void) strcpy (CommandLine, "");
                   1470:        CurrentPosition = 0;
                   1471:     }
                   1472:     fputs (prompt, stdout);
                   1473:     print_com_line ();
                   1474:     return (PROCESSED);
                   1475: }
                   1476:
                   1477: #define FORWARD            1
                   1478: #define REVERSE            2
                   1479:
                   1480: search_reverse ()
                   1481: {
                   1482:     return (search_history (REVERSE));
                   1483: }
                   1484:
                   1485: search_forward ()
                   1486: {
                   1487:     return (search_history (FORWARD));
                   1488: }
                   1489:
                   1490: search_history (direct)
                   1491:     int direct;
                   1492: {
                   1493:     char *his, *search_reverse_history(), *search_forward_history();
                   1494:     char *(*func)();
                   1495:
                   1496:     if (direct == FORWARD)
                   1497:        func = search_forward_history;
                   1498:     else
                   1499:        func = search_reverse_history;
                   1500:
                   1501: AGAIN:
                   1502:     if (his = (*func) (0)) {
                   1503:        if (eq (his, CommandLine))
                   1504:            goto AGAIN;
                   1505:
                   1506:        (void) delete_line ();
                   1507:        (void) insert_string (his);
                   1508:        CurrentPosition = strlen (CommandLine);
                   1509:     }
                   1510:     else {
                   1511:        (void) errorBell ();
                   1512:
                   1513:        if (look_var ("verbose")) {
                   1514:            char *cp;
                   1515:
                   1516:            if ((cp = look_var ("search-string")) == NULL)
                   1517:                cp = "";
                   1518:            (void) clear_edit_line ();
                   1519:            fprintf (stdout, "\"%s\": No match.\r\n", cp);
                   1520:            (void) recover_edit_line (1);
                   1521:        }
                   1522:     }
                   1523:
                   1524:     return 0;
                   1525: }
                   1526:
                   1527:
                   1528: /*
                   1529:  * Insert the character and flush buffer
                   1530:  */
                   1531: insert_and_flush(c)
                   1532:     char c;
                   1533: {
                   1534:     (void) self_insert (c);
                   1535:     return (1);
                   1536: }
                   1537:
                   1538: /*
                   1539:  * Insert the character, but it means EOL. Therefore move cursor backward and
                   1540:  * flush buffer
                   1541:  */
                   1542: send_eof()
                   1543: {
                   1544: #ifdef TERMIOS
                   1545:     char c = initial_ttymode.c_cc[VEOF];
                   1546: #else
                   1547:     char c = tchars_buf.t_eofc;
                   1548: #endif
                   1549:
                   1550:     (void) self_insert (c);
                   1551:     if (isctlchar (c))
                   1552:        fputs ("\b\b", stdout);
                   1553:     else
                   1554:        fputs ("\b", stdout);
                   1555:     return (1);
                   1556: }
                   1557:
                   1558: /*
                   1559:  * Alarm for EOF on only the first time finding eof character
                   1560:  */
                   1561: alarm_on_eof ()
                   1562: {
                   1563:
                   1564:     errorBell ();
                   1565:     (void) clear_edit_line ();
                   1566:     printf ("EOF -- one more eof character to send eof to the process.\n");
                   1567:     (void) recover_edit_line (1);
                   1568: }
                   1569:
                   1570: /*
                   1571:  * Clear screen
                   1572:  */
                   1573: clear_screen()
                   1574: {
                   1575:
                   1576:     if (term_clear) {
                   1577:        (void) clear_edit_line ();
                   1578:        fputs (term_clear, stdout);
                   1579:        (void) recover_edit_line (1);
                   1580:     }
                   1581:     else
                   1582:        errorBell ();
                   1583:
                   1584:     return (0);
                   1585: }
                   1586:
                   1587: typedef enum {HOP_INSERT, HOP_REPLACE} HISTOP;
                   1588: typedef enum {HDIR_PREV, HDIR_CURRENT, HDIR_NEXT} HISTDIR;
                   1589:
                   1590: /*
                   1591:  * Get next history entry
                   1592:  */
                   1593: next_history()
                   1594: {
                   1595:     return (serv_history (HOP_REPLACE, HDIR_NEXT));
                   1596: }
                   1597:
                   1598: /*
                   1599:  * Get next history entry
                   1600:  */
                   1601: previous_history()
                   1602: {
                   1603:     return (serv_history (HOP_REPLACE, HDIR_PREV));
                   1604: }
                   1605:
                   1606: /*
                   1607:  * Insert next history entry
                   1608:  */
                   1609: insert_current_history()
                   1610: {
                   1611:     return (serv_history (HOP_INSERT, HDIR_CURRENT));
                   1612: }
                   1613:
                   1614: /*
                   1615:  * Insert next history entry
                   1616:  */
                   1617: insert_next_history()
                   1618: {
                   1619:     return (serv_history (HOP_INSERT, HDIR_NEXT));
                   1620: }
                   1621:
                   1622: /*
                   1623:  * Insert next history entry
                   1624:  */
                   1625: insert_previous_history()
                   1626: {
                   1627:     return (serv_history (HOP_INSERT, HDIR_PREV));
                   1628: }
                   1629:
                   1630: /*
                   1631:  * Get previous history
                   1632:  */
                   1633: serv_history(op, dir)
                   1634:     HISTOP op;
                   1635:     HISTDIR dir;
                   1636: {
                   1637:     register char *cp;
                   1638:     char *getPreviousHistory (), *getNextHistory (), *getCurrentHistory ();
                   1639:     int diff;
                   1640:
                   1641:     switch (dir) {
                   1642:     case HDIR_PREV: cp = getPreviousHistory (); break;
                   1643:     case HDIR_NEXT: cp = getNextHistory (); break;
                   1644:     case HDIR_CURRENT: cp = getCurrentHistory (); break;
                   1645:     default: cp = (char*)0;
                   1646:     }
                   1647:
                   1648:     if (cp == (char *)0) {
                   1649:        errorBell ();
                   1650:        return (0);
                   1651:     }
                   1652:
                   1653:     if (op == HOP_REPLACE)
                   1654:        (void) delete_line ();
                   1655:     (void) insert_string (cp);
                   1656:     return (0);
                   1657: }
                   1658:
                   1659: /*
                   1660:  * Show history
                   1661:  */
                   1662: show_history()
                   1663: {
                   1664:
                   1665:     (void) clear_edit_line ();
                   1666:     hist_showHistory (lookd_var ("showhist"));
                   1667:     (void) recover_edit_line (1);
                   1668: }
                   1669:
                   1670: /*
                   1671:  * Do nothing
                   1672:  */
                   1673: ignore()
                   1674: {
                   1675:     return(0);
                   1676: }
                   1677:
                   1678: /*
                   1679:  * Next character is literal
                   1680:  */
                   1681: literal_next()
                   1682: {
                   1683:
                   1684:     return (self_insert (getcharacter ()));
                   1685: }
                   1686:
                   1687: /*
                   1688:  * Reprint command line
                   1689:  */
                   1690: reprint()
                   1691: {
                   1692:
                   1693:     (void) clear_edit_line ();
                   1694:     (void) recover_edit_line (1);
                   1695:     return (0);
                   1696: }
                   1697:
                   1698: /*
                   1699:  * Print whole command line and move cursor to the current position
                   1700:  */
                   1701: print_com_line()
                   1702: {
                   1703:
                   1704:     printS (CommandLine);
                   1705:     if (CommandLine[CurrentPosition] != '\0') {
                   1706:        repeat (BS, howlong(&CommandLine[CurrentPosition + 1], 0));
                   1707:        (void) putchar (BS);
                   1708:     }
                   1709: }
                   1710:
                   1711: /*
                   1712:  * Calcurate space of string using "^" for control character
                   1713:  */
                   1714: howlong(s, n)
                   1715:     char *s;
                   1716:     int n;
                   1717: {
                   1718:     register char *sp;
                   1719:     register int area = 0;
                   1720:
                   1721:     if (n == 0)
                   1722:        n = -1;
                   1723:     for (sp = s; *sp && n; sp++, n--) {
                   1724:        if (isctlchar(*sp))
                   1725:            area += 2;
                   1726:        else
                   1727:            area += 1;
                   1728:     }
                   1729:     return (area);
                   1730: }
                   1731:
                   1732: /*
                   1733:  * Repeat puting character n times
                   1734:  */
                   1735: repeat(c, n)
                   1736:     char c;
                   1737:     register int n;
                   1738: {
                   1739:     for (n = n; n; n--)
                   1740:        (void) putchar(c);
                   1741: }
                   1742:
                   1743: /*
                   1744:  * Repeat putting string n times
                   1745:  */
                   1746: repeat_string(s, n)
                   1747:     char *s;
                   1748:     register int n;
                   1749: {
                   1750:     for (n = n; n; n--)
                   1751:        fputs(s, stdout);
                   1752: }
                   1753:
                   1754: /*
                   1755:  * Expand file name
                   1756:  */
                   1757: expand_file_name ()
                   1758: {
                   1759:     CHAR *cp, *start_expand;
                   1760:     char *x_dirname();
                   1761:     char dir[256];
                   1762:     char *fileList[256];
                   1763:     CHAR line[256];
                   1764:     DIR *dirp, *x_opendir();
                   1765:     struct direct *dp;
                   1766:     int found = 0;
                   1767:     int i;
                   1768:     int tilde_expanded = 0;
                   1769:     CHAR *index(), *rindex();
                   1770:
                   1771:     if (delimiters == NULL)
                   1772:         delimiters = DEFAULT_DELIMITERS;
                   1773:     strcpy (line, CommandLine);
                   1774:     for (cp = &line[CurrentPosition] - 1; cp > line ; --cp) {
                   1775:         if (index (delimiters, *(cp - 1)))
                   1776:            break;
                   1777:     }
                   1778:     start_expand = cp;
                   1779:     if (any ('/', cp)) {
                   1780:        (void) strcpy (dir, cp);
                   1781:        *(rindex (dir, '/') + 1) = '\0';
                   1782:        cp = (CHAR *) (rindex (cp, '/') + 1);
                   1783:     }
                   1784:     else
                   1785:        strcpy (dir, ".");
                   1786:
                   1787:     if ((dirp = x_opendir (dir)) == NULL) {
                   1788:        errorBell ();
                   1789:        return (0);
                   1790:     }
                   1791:
                   1792:     for (dp = readdir(dirp), i = 0; dp != NULL; dp = readdir(dirp)) {
                   1793:
                   1794:        if (*cp == '\0')
                   1795:            break;
                   1796:
                   1797:        if (*cp != '.' && *(dp->d_name) == '.')
                   1798:            continue;
                   1799:
                   1800:        if (prefix (cp, dp->d_name)) {
                   1801:            char *fcp;
                   1802:
                   1803: # ifdef ALLOCA
                   1804:            fcp = (char *) alloca (strlen (dp->d_name) + 1);
                   1805: # else /* ALLOCA */
                   1806:            fcp = (char *) malloc (strlen (dp->d_name) + 1);
                   1807: # endif /* ALLOCA */
                   1808:            if (fcp == 0) {
                   1809:                fputs ("\r\n", stdout);
                   1810:                perror ("alloca:");
                   1811:                reprint ();
                   1812:                longjmp (jbuf, 1);
                   1813:            }
                   1814:            strcpy (fcp, dp->d_name);
                   1815:            fileList [i++] = fcp;
                   1816:        }
                   1817:     }
                   1818:     fileList [i] = (char *) 0;
                   1819:
                   1820:     if (*start_expand == '~' && look_var ("expand-tilde")) {
                   1821:        char buf [256], *p;
                   1822:
                   1823:        strcpy (buf, start_expand);
                   1824:        p = x_dirname (buf);
                   1825:        if (!eq (p, buf)) {
                   1826:            (void) moveto (start_expand - line);
                   1827:            (void) kill_to_end_of_line ();
                   1828:            (void) insert_string (x_dirname (buf));
                   1829:            tilde_expanded = 1;
                   1830:        }
                   1831:     }
                   1832:
                   1833:     switch (i) {
                   1834:
                   1835:        case 0:
                   1836:            if (tilde_expanded == 0)
                   1837:                errorBell ();
                   1838:            break;
                   1839:
                   1840:        case 1:
                   1841:            (void) end_of_line ();
                   1842:            (void) insert_string (fileList[0] + strlen (cp));
                   1843:            break;
                   1844:
                   1845:        default:
                   1846:            {
                   1847:                char *one, *other;
                   1848:                char *c1, *c2;
                   1849:                int i;
                   1850:
                   1851:                one = fileList [0];
                   1852:                for (i = 1; other = fileList [i]; i++) {
                   1853:                    for (c1 = one, c2 = other; *c1 && *c2; c1++, c2++)
                   1854:                        if (*c1 != *c2)
                   1855:                            break;
                   1856:                    *c1 = '\0';
                   1857:                }
                   1858:                errorBell ();
                   1859:                (void) end_of_line ();
                   1860:                (void) insert_string (fileList[0] + strlen (cp));
                   1861:            }
                   1862:            break;
                   1863:     }
                   1864:
                   1865: # ifndef ALLOCA
                   1866:     for (i = 0; fileList [i]; i++)
                   1867:        free (fileList [i]);
                   1868: # endif /* ALLOCA */
                   1869:
                   1870:     closedir(dirp);
                   1871:     return (0);
                   1872: }
                   1873:
                   1874: /*
                   1875:  * List file name
                   1876:  */
                   1877: list_file_name ()
                   1878: {
                   1879:     CHAR *cp;
                   1880:     char dir[256];
                   1881:     DIR *dirp, *x_opendir();
                   1882:     CHAR *index(), *rindex();
                   1883:
                   1884:     if (delimiters == NULL)
                   1885:         delimiters = DEFAULT_DELIMITERS;
                   1886:     for (cp = (CHAR *) index (CommandLine, '\0'); cp > CommandLine ; --cp) {
                   1887:         if (index (delimiters, *(cp - 1))) {
                   1888:            break;
                   1889:        }
                   1890:     }
                   1891: #ifdef RINFO
                   1892:     /*
                   1893:      * This is an experimental code for rinfod, which serves remote
                   1894:      * information about file, process, etc.
                   1895:      */
                   1896:     if (any (':', cp)) {
                   1897:        char *host, *pattern;
                   1898:
                   1899:        (void) strcpy (dir, cp);
                   1900:        host = dir;
                   1901:        *(index (host, ':')) = '\0';
                   1902:        pattern = (index (cp, ':') + 1);;
                   1903:
                   1904:        (void) clear_edit_line();
                   1905:        list_remote_file (host, pattern);
                   1906:        (void) recover_edit_line (1);
                   1907:        return;
                   1908:     }
                   1909: #endif
                   1910:     if (any ('/', cp)) {
                   1911:        (void) strcpy (dir, cp);
                   1912:        *(rindex (dir, '/') + 1) = '\0';
                   1913:        cp = (CHAR *) (rindex (cp, '/') + 1);
                   1914:     }
                   1915:     else
                   1916:        strcpy (dir, ".");
                   1917:
                   1918:
                   1919:     if ((dirp = x_opendir (dir)) == NULL) {
                   1920:        errorBell ();
                   1921:        return (0);
                   1922:     }
                   1923:
                   1924:     (void) clear_edit_line();
                   1925:     ls (dirp, cp);
                   1926:     closedir(dirp);
                   1927:     (void) recover_edit_line (1);
                   1928:
                   1929:     return (0);
                   1930: }
                   1931:
                   1932: int    rememberPosition;
                   1933:
                   1934: clear_edit_line ()
                   1935: {
                   1936:
                   1937:     if (editstatus == NOTEDITING)
                   1938:        return;
                   1939:
                   1940:     rememberPosition = CurrentPosition;
                   1941:     (void) end_of_line ();
                   1942:     (void) fputs ("\r\n", stdout);
                   1943: }
                   1944:
                   1945: recover_edit_line (put_prompt)
                   1946:     int put_prompt;
                   1947: {
                   1948:
                   1949:     if (editstatus == NOTEDITING)
                   1950:        return;
                   1951:
                   1952:     if (rememberPosition < 0)
                   1953:        return;
                   1954:     CurrentPosition = rememberPosition;
                   1955:     rememberPosition = -1;
                   1956:     if (put_prompt && prompt)
                   1957:        fputs (prompt, stdout);
                   1958:     (void) print_com_line();
                   1959: }
                   1960:
                   1961: #define MAXFILES 256
                   1962:
                   1963: /*
                   1964:  * Do ls
                   1965:  */
                   1966: ls (dirp, prefixstring)
                   1967:     DIR *dirp;
                   1968:     char *prefixstring;
                   1969: {
                   1970:     struct direct *dp;
                   1971:     char *fileList[MAXFILES + 1];
                   1972:     int i, j;
                   1973:     int maxlen = 0;
                   1974:     int files;         /* number of file */
                   1975:     int fpl;           /* file par line */
                   1976:     int cpf;           /* column par file */
                   1977:     int fpc;           /* file par column */
                   1978:     int COL = 80;
                   1979:     char format[10];
                   1980:     int scmp();
                   1981:
                   1982:     for (dp = readdir(dirp), i = 0; dp != NULL; dp = readdir(dirp)) {
                   1983:        char *fcp;
                   1984:
                   1985:        if (i >= MAXFILES) {
                   1986:            printf ("Too many files\n");
                   1987:            break;
                   1988:        }
                   1989:
                   1990:        if (dp->d_ino == (unsigned long) 0
                   1991:                || (prefixstring[0] != '.' && dp->d_name[0] == '.'))
                   1992:            continue;
                   1993:        if (prefix (prefixstring, dp->d_name)) {
                   1994: # ifdef ALLOCA
                   1995:            fcp = (char *) alloca (strlen (dp->d_name) + 1);
                   1996: # else /* ALLOCA */
                   1997:            fcp = (char *) malloc (strlen (dp->d_name) + 1);
                   1998: # endif /* ALLOCA */
                   1999:            if (fcp == 0) {
                   2000:                fputs ("\r\n", stdout);
                   2001:                perror ("alloca:");
                   2002:                reprint ();
                   2003:                longjmp (jbuf, 1);
                   2004:            }
                   2005:            strcpy (fcp, dp->d_name);
                   2006:            fileList [i++] = fcp;
                   2007:            maxlen = max (maxlen, strlen (dp->d_name));
                   2008:        }
                   2009:     }
                   2010:     fileList [i] = (char *) 0;
                   2011:
                   2012:     if (i == 0)
                   2013:        goto BACK;
                   2014:
                   2015:     files = i;
                   2016:
                   2017:     qsort (fileList, i, sizeof (char *), scmp);
                   2018:
                   2019:     if (debug)
                   2020:        printf ("%d files\n", files);
                   2021:
                   2022:     cpf = maxlen + 1;
                   2023:     fpl = COL / cpf;
                   2024:     if (fpl == 0) fpl = 1;
                   2025:     fpc = (files + fpl - 1) / fpl;
                   2026:
                   2027:     sprintf (format, "%%-%ds", cpf);
                   2028:     for (i = 0; i < fpc; i++) {
                   2029:        for (j = 0; j < fpl - 1; j++)
                   2030:            if (i + j * fpc < files)
                   2031:                printf (format, fileList[i + (j * fpc)]);
                   2032:        if (i + (fpc * (fpl - 1)) < files)
                   2033:            printf ("%s", fileList[i + (fpc * (fpl - 1))]);
                   2034:        fputs ("\n", stdout);
                   2035:     }
                   2036:
                   2037: BACK:
                   2038:
                   2039: # ifndef ALLOCA
                   2040:     for (i = 0; fileList [i]; i++)
                   2041:        free (fileList [i]);
                   2042: # endif /* ALLOCA */
                   2043:     return;
                   2044: }
                   2045:
                   2046: #ifdef RINFO
                   2047:
                   2048: #include "../rinfo/rinfo.h"
                   2049:
                   2050: list_remote_file (host, pattern)
                   2051:     char *host, *pattern;
                   2052: {
                   2053:     struct slist *slp, *getfilelist();
                   2054:     int i, j;
                   2055:     char format [64];
                   2056:     int COL = 80;
                   2057:     int  maxlen, cpf, fpl, fpc;
                   2058:     int files;
                   2059:
                   2060:     slp = getfilelist (host, pattern);
                   2061:     files = slp->s_cnt;
                   2062:
                   2063:     COL = 80;
                   2064:     maxlen = 0;
                   2065:     for (i = 0; i < files; i++) {
                   2066:        int len;
                   2067:
                   2068:        if ((len = strlen (*(slp->s_list + i))) > maxlen)
                   2069:            maxlen = len;
                   2070:     }
                   2071:
                   2072:     cpf = maxlen + 1;
                   2073:     fpl = COL / cpf;
                   2074:     if (fpl == 0)
                   2075:        fpl = 1;
                   2076:     fpc = (files + fpl - 1) / fpl;
                   2077:
                   2078:     sprintf (format, "%%-%ds", cpf);
                   2079:     for (i = 0; i < fpc; i++) {
                   2080:        for (j = 0; j < fpl - 1; j++) {
                   2081:            if (i + j * fpc < slp->s_cnt)
                   2082:                printf (format, *(slp->s_list + (i + (j * fpc))));
                   2083:        }
                   2084:        if (i + (fpc * (fpl - 1)) < files)
                   2085:            printf ("%s", slp->s_list[i + (fpc * (fpl - 1))]);
                   2086:        fputs ("\n", stdout);
                   2087:     }
                   2088: }
                   2089: #endif /* RINFO */
                   2090:
                   2091: bind_key (ft, func, s, dfunc)
                   2092:     FUNC ft[];         /* Function table */
                   2093:     FUNC func;         /* Function to be binded */
                   2094:     char *s;           /* String to bind */
                   2095:     FUNC dfunc;                /* Default function for table allocating */
                   2096: {
                   2097:     char tmps[16];
                   2098:
                   2099:     if (s[0] == '\\' && s[1] == '^' && s[2] != '\0') {
                   2100:        tmps[0] = toctrl (s[2]);
                   2101:        strcpy (&tmps[1], &s[3]);
                   2102:        s = tmps;
                   2103:     }
                   2104:
                   2105:     /*
                   2106:      * If the string contain only one character, put the function to
                   2107:      * appropriate position in the table.
                   2108:      */
                   2109:     if (*(s+1) == '\0') {
                   2110:        if (isIndirect (ft[(int) *s]))
                   2111:            free (maskIndirect (ft[(int) *s]));
                   2112:
                   2113:        ft[(int) *s] = func;
                   2114:        return (1);
                   2115:     }
                   2116:     else {
                   2117:        FUNC *nft = (FUNC *) 0;
                   2118:        int status;
                   2119:
                   2120:        /*
                   2121:         * If the entry doesn't have indirect function table, allocate it.
                   2122:         */
                   2123:        if (! (isIndirect (ft[(int) *s]))) {
                   2124:            register int i;
                   2125:
                   2126:            nft = (FUNC *) calloc (sizeof (FUNC), 256);
                   2127:            /*
                   2128:             * If failed in allocating, return 0.
                   2129:             */
                   2130:            if (nft == 0)
                   2131:                return (0);
                   2132:
                   2133:            /*
                   2134:             * Initialize the table with default function
                   2135:             */
                   2136:            for (i = 0; i < 256; i++)
                   2137:                nft [i] = dfunc;
                   2138:            ft[(int) *s] = setIndirect (nft);
                   2139:        }
                   2140:
                   2141:        status = bind_key (maskIndirect (ft[(int) *s]), func, s+1, dfunc);
                   2142:        /*
                   2143:         * If the binding failed and the table was allocated in this function
                   2144:         * free the table and return with same status.
                   2145:         */
                   2146:        if (status == 0 && nft)
                   2147:            free (nft);
                   2148:        return (status);
                   2149:     }
                   2150: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>