[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.8

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

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