[BACK]Return to chared.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libedit

Annotation of src/lib/libedit/chared.c, Revision 1.17

1.17    ! christos    1: /*     $NetBSD: chared.c,v 1.16 2002/10/27 21:41:50 christos Exp $     */
1.2       lukem       2:
1.1       cgd         3: /*-
                      4:  * Copyright (c) 1992, 1993
                      5:  *     The Regents of the University of California.  All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to Berkeley by
                      8:  * Christos Zoulas of Cornell University.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
                     20:  *     This product includes software developed by the University of
                     21:  *     California, Berkeley and its contributors.
                     22:  * 4. Neither the name of the University nor the names of its contributors
                     23:  *    may be used to endorse or promote products derived from this software
                     24:  *    without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     27:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     28:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     29:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     30:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     31:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     32:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     33:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     34:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     35:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     36:  * SUCH DAMAGE.
                     37:  */
                     38:
1.15      christos   39: #include "config.h"
1.1       cgd        40: #if !defined(lint) && !defined(SCCSID)
1.2       lukem      41: #if 0
1.1       cgd        42: static char sccsid[] = "@(#)chared.c   8.1 (Berkeley) 6/4/93";
1.2       lukem      43: #else
1.17    ! christos   44: __RCSID("$NetBSD: chared.c,v 1.16 2002/10/27 21:41:50 christos Exp $");
1.2       lukem      45: #endif
1.1       cgd        46: #endif /* not lint && not SCCSID */
                     47:
1.7       simonb     48: /*
1.1       cgd        49:  * chared.c: Character editor utilities
                     50:  */
                     51: #include <stdlib.h>
                     52: #include "el.h"
                     53:
1.12      jdolecek   54: /* value to leave unused in line buffer */
                     55: #define        EL_LEAVE        2
                     56:
1.1       cgd        57: /* cv_undo():
                     58:  *     Handle state for the vi undo command
                     59:  */
                     60: protected void
1.17    ! christos   61: cv_undo(EditLine *el)
1.9       lukem      62: {
                     63:        c_undo_t *vu = &el->el_chared.c_undo;
1.17    ! christos   64:        c_redo_t *r = &el->el_chared.c_redo;
        !            65:        uint size;
1.16      christos   66:
1.17    ! christos   67:        /* Save entire line for undo */
        !            68:        size = el->el_line.lastchar - el->el_line.buffer;
        !            69:        vu->len = size;
1.16      christos   70:        vu->cursor = el->el_line.cursor - el->el_line.buffer;
1.17    ! christos   71:        memcpy(vu->buf, el->el_line.buffer, size);
1.16      christos   72:
1.17    ! christos   73:        /* save command info for redo */
        !            74:        r->count = el->el_state.doingarg ? el->el_state.argument : 0;
        !            75:        r->action = el->el_chared.c_vcmd.action;
        !            76:        r->pos = r->buf;
        !            77:        r->cmd = el->el_state.thiscmd;
        !            78:        r->ch = el->el_state.thisch;
        !            79: }
        !            80:
        !            81: /* cv_yank():
        !            82:  *     Save yank/delete data for paste
        !            83:  */
        !            84: protected void
        !            85: cv_yank(EditLine *el, const char *ptr, int size)
        !            86: {
        !            87:        c_kill_t *k = &el->el_chared.c_kill;
        !            88:
        !            89:        memcpy(k->buf, ptr, size +0u);
        !            90:        k->last = k->buf + size;
1.1       cgd        91: }
                     92:
                     93:
1.7       simonb     94: /* c_insert():
1.1       cgd        95:  *     Insert num characters
                     96:  */
                     97: protected void
1.9       lukem      98: c_insert(EditLine *el, int num)
                     99: {
                    100:        char *cp;
                    101:
1.17    ! christos  102:        if (el->el_line.lastchar + num >= el->el_line.limit) {
        !           103:                if (!ch_enlargebufs(el, num +0u))
        !           104:                        return;         /* can't go past end of buffer */
        !           105:        }
1.9       lukem     106:
                    107:        if (el->el_line.cursor < el->el_line.lastchar) {
                    108:                /* if I must move chars */
                    109:                for (cp = el->el_line.lastchar; cp >= el->el_line.cursor; cp--)
                    110:                        cp[num] = *cp;
                    111:        }
                    112:        el->el_line.lastchar += num;
                    113: }
1.1       cgd       114:
                    115:
                    116: /* c_delafter():
                    117:  *     Delete num characters after the cursor
                    118:  */
                    119: protected void
1.9       lukem     120: c_delafter(EditLine *el, int num)
1.1       cgd       121: {
                    122:
1.9       lukem     123:        if (el->el_line.cursor + num > el->el_line.lastchar)
                    124:                num = el->el_line.lastchar - el->el_line.cursor;
1.1       cgd       125:
1.17    ! christos  126:        if (el->el_map.current != el->el_map.emacs) {
        !           127:                cv_undo(el);
        !           128:                cv_yank(el, el->el_line.cursor, num);
        !           129:        }
1.16      christos  130:
1.9       lukem     131:        if (num > 0) {
                    132:                char *cp;
1.1       cgd       133:
1.9       lukem     134:                for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
                    135:                        *cp = cp[num];
1.1       cgd       136:
1.9       lukem     137:                el->el_line.lastchar -= num;
                    138:        }
1.1       cgd       139: }
                    140:
                    141:
                    142: /* c_delbefore():
                    143:  *     Delete num characters before the cursor
                    144:  */
                    145: protected void
1.9       lukem     146: c_delbefore(EditLine *el, int num)
1.1       cgd       147: {
                    148:
1.9       lukem     149:        if (el->el_line.cursor - num < el->el_line.buffer)
                    150:                num = el->el_line.cursor - el->el_line.buffer;
1.1       cgd       151:
1.17    ! christos  152:        if (el->el_map.current != el->el_map.emacs) {
        !           153:                cv_undo(el);
        !           154:                cv_yank(el, el->el_line.cursor - num, num);
        !           155:        }
1.16      christos  156:
1.9       lukem     157:        if (num > 0) {
                    158:                char *cp;
1.1       cgd       159:
1.9       lukem     160:                for (cp = el->el_line.cursor - num;
                    161:                    cp <= el->el_line.lastchar;
                    162:                    cp++)
                    163:                        *cp = cp[num];
1.1       cgd       164:
1.9       lukem     165:                el->el_line.lastchar -= num;
                    166:        }
1.1       cgd       167: }
                    168:
                    169:
                    170: /* ce__isword():
                    171:  *     Return if p is part of a word according to emacs
                    172:  */
                    173: protected int
1.9       lukem     174: ce__isword(int p)
1.1       cgd       175: {
1.16      christos  176:        return (isalnum(p) || strchr("*?_-.[]~=", p) != NULL);
1.1       cgd       177: }
                    178:
                    179:
                    180: /* cv__isword():
                    181:  *     Return if p is part of a word according to vi
                    182:  */
                    183: protected int
1.9       lukem     184: cv__isword(int p)
1.1       cgd       185: {
1.17    ! christos  186:        if (isalnum(p) || p == '_')
        !           187:                return 1;
        !           188:        if (isgraph(p))
        !           189:                return 2;
        !           190:        return 0;
1.16      christos  191: }
                    192:
                    193:
                    194: /* cv__isWord():
                    195:  *     Return if p is part of a big word according to vi
                    196:  */
                    197: protected int
                    198: cv__isWord(int p)
                    199: {
1.9       lukem     200:        return (!isspace(p));
1.1       cgd       201: }
                    202:
                    203:
                    204: /* c__prev_word():
                    205:  *     Find the previous word
                    206:  */
                    207: protected char *
1.9       lukem     208: c__prev_word(char *p, char *low, int n, int (*wtest)(int))
                    209: {
                    210:        p--;
                    211:
                    212:        while (n--) {
                    213:                while ((p >= low) && !(*wtest)((unsigned char) *p))
                    214:                        p--;
                    215:                while ((p >= low) && (*wtest)((unsigned char) *p))
                    216:                        p--;
                    217:        }
                    218:
                    219:        /* cp now points to one character before the word */
                    220:        p++;
                    221:        if (p < low)
                    222:                p = low;
                    223:        /* cp now points where we want it */
                    224:        return (p);
1.1       cgd       225: }
                    226:
                    227:
                    228: /* c__next_word():
                    229:  *     Find the next word
                    230:  */
                    231: protected char *
1.9       lukem     232: c__next_word(char *p, char *high, int n, int (*wtest)(int))
                    233: {
                    234:        while (n--) {
                    235:                while ((p < high) && !(*wtest)((unsigned char) *p))
                    236:                        p++;
                    237:                while ((p < high) && (*wtest)((unsigned char) *p))
                    238:                        p++;
                    239:        }
                    240:        if (p > high)
                    241:                p = high;
                    242:        /* p now points where we want it */
                    243:        return (p);
1.1       cgd       244: }
                    245:
                    246: /* cv_next_word():
                    247:  *     Find the next word vi style
                    248:  */
                    249: protected char *
1.9       lukem     250: cv_next_word(EditLine *el, char *p, char *high, int n, int (*wtest)(int))
                    251: {
                    252:        int test;
                    253:
                    254:        while (n--) {
                    255:                test = (*wtest)((unsigned char) *p);
                    256:                while ((p < high) && (*wtest)((unsigned char) *p) == test)
                    257:                        p++;
                    258:                /*
                    259:                 * vi historically deletes with cw only the word preserving the
                    260:                 * trailing whitespace! This is not what 'w' does..
                    261:                 */
1.16      christos  262:                if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT))
1.9       lukem     263:                        while ((p < high) && isspace((unsigned char) *p))
                    264:                                p++;
                    265:        }
1.1       cgd       266:
1.9       lukem     267:        /* p now points where we want it */
                    268:        if (p > high)
                    269:                return (high);
                    270:        else
                    271:                return (p);
1.1       cgd       272: }
                    273:
                    274:
                    275: /* cv_prev_word():
                    276:  *     Find the previous word vi style
                    277:  */
                    278: protected char *
1.16      christos  279: cv_prev_word(char *p, char *low, int n, int (*wtest)(int))
1.1       cgd       280: {
1.9       lukem     281:        int test;
1.1       cgd       282:
1.16      christos  283:        p--;
1.9       lukem     284:        while (n--) {
1.16      christos  285:                while ((p > low) && isspace((unsigned char) *p))
                    286:                        p--;
1.9       lukem     287:                test = (*wtest)((unsigned char) *p);
                    288:                while ((p >= low) && (*wtest)((unsigned char) *p) == test)
                    289:                        p--;
                    290:        }
1.16      christos  291:        p++;
1.1       cgd       292:
1.9       lukem     293:        /* p now points where we want it */
                    294:        if (p < low)
                    295:                return (low);
                    296:        else
                    297:                return (p);
1.1       cgd       298: }
                    299:
                    300:
                    301: #ifdef notdef
                    302: /* c__number():
                    303:  *     Ignore character p points to, return number appearing after that.
                    304:  *     A '$' by itself means a big number; "$-" is for negative; '^' means 1.
                    305:  *     Return p pointing to last char used.
                    306:  */
                    307: protected char *
1.9       lukem     308: c__number(
                    309:     char *p,   /* character position */
                    310:     int *num,  /* Return value */
                    311:     int dval)  /* dval is the number to subtract from like $-3 */
                    312: {
                    313:        int i;
                    314:        int sign = 1;
                    315:
                    316:        if (*++p == '^') {
                    317:                *num = 1;
                    318:                return (p);
                    319:        }
                    320:        if (*p == '$') {
                    321:                if (*++p != '-') {
                    322:                        *num = 0x7fffffff;      /* Handle $ */
                    323:                        return (--p);
                    324:                }
                    325:                sign = -1;                      /* Handle $- */
                    326:                ++p;
                    327:        }
                    328:        for (i = 0; isdigit((unsigned char) *p); i = 10 * i + *p++ - '0')
                    329:                continue;
                    330:        *num = (sign < 0 ? dval - i : i);
                    331:        return (--p);
1.1       cgd       332: }
                    333: #endif
                    334:
                    335: /* cv_delfini():
                    336:  *     Finish vi delete action
                    337:  */
                    338: protected void
1.9       lukem     339: cv_delfini(EditLine *el)
1.1       cgd       340: {
1.9       lukem     341:        int size;
1.17    ! christos  342:        int action = el->el_chared.c_vcmd.action;
1.1       cgd       343:
1.17    ! christos  344:        if (action & INSERT)
1.9       lukem     345:                el->el_map.current = el->el_map.key;
1.1       cgd       346:
1.9       lukem     347:        if (el->el_chared.c_vcmd.pos == 0)
1.17    ! christos  348:                /* sanity */
1.9       lukem     349:                return;
                    350:
1.17    ! christos  351:        size = el->el_line.cursor - el->el_chared.c_vcmd.pos;
        !           352:        if (size == 0)
        !           353:                size = 1;
1.16      christos  354:        el->el_line.cursor = el->el_chared.c_vcmd.pos;
1.17    ! christos  355:        if (action & YANK) {
        !           356:                if (size > 0)
        !           357:                        cv_yank(el, el->el_line.cursor, size);
        !           358:                else
        !           359:                        cv_yank(el, el->el_line.cursor + size, -size);
1.9       lukem     360:        } else {
1.17    ! christos  361:                if (size > 0) {
        !           362:                        c_delafter(el, size);
        !           363:                        re_refresh_cursor(el);
        !           364:                } else  {
        !           365:                        c_delbefore(el, -size);
        !           366:                        el->el_line.cursor += size;
        !           367:                }
1.9       lukem     368:        }
1.17    ! christos  369:        el->el_chared.c_vcmd.action = NOP;
1.1       cgd       370: }
                    371:
                    372:
                    373: #ifdef notdef
                    374: /* ce__endword():
                    375:  *     Go to the end of this word according to emacs
                    376:  */
                    377: protected char *
1.9       lukem     378: ce__endword(char *p, char *high, int n)
                    379: {
                    380:        p++;
1.1       cgd       381:
1.9       lukem     382:        while (n--) {
                    383:                while ((p < high) && isspace((unsigned char) *p))
                    384:                        p++;
                    385:                while ((p < high) && !isspace((unsigned char) *p))
                    386:                        p++;
                    387:        }
                    388:
                    389:        p--;
                    390:        return (p);
1.1       cgd       391: }
                    392: #endif
                    393:
                    394:
                    395: /* cv__endword():
                    396:  *     Go to the end of this word according to vi
                    397:  */
                    398: protected char *
1.16      christos  399: cv__endword(char *p, char *high, int n, int (*wtest)(int))
1.9       lukem     400: {
1.16      christos  401:        int test;
                    402:
1.9       lukem     403:        p++;
1.1       cgd       404:
1.9       lukem     405:        while (n--) {
                    406:                while ((p < high) && isspace((unsigned char) *p))
                    407:                        p++;
                    408:
1.16      christos  409:                test = (*wtest)((unsigned char) *p);
                    410:                while ((p < high) && (*wtest)((unsigned char) *p) == test)
                    411:                        p++;
1.9       lukem     412:        }
                    413:        p--;
                    414:        return (p);
1.1       cgd       415: }
                    416:
                    417: /* ch_init():
                    418:  *     Initialize the character editor
                    419:  */
                    420: protected int
1.9       lukem     421: ch_init(EditLine *el)
1.1       cgd       422: {
1.11      christos  423:        el->el_line.buffer              = (char *) el_malloc(EL_BUFSIZ);
                    424:        if (el->el_line.buffer == NULL)
                    425:                return (-1);
                    426:
1.9       lukem     427:        (void) memset(el->el_line.buffer, 0, EL_BUFSIZ);
                    428:        el->el_line.cursor              = el->el_line.buffer;
                    429:        el->el_line.lastchar            = el->el_line.buffer;
1.16      christos  430:        el->el_line.limit               = &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE];
1.9       lukem     431:
1.11      christos  432:        el->el_chared.c_undo.buf        = (char *) el_malloc(EL_BUFSIZ);
                    433:        if (el->el_chared.c_undo.buf == NULL)
                    434:                return (-1);
1.9       lukem     435:        (void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ);
1.16      christos  436:        el->el_chared.c_undo.len        = -1;
                    437:        el->el_chared.c_undo.cursor     = 0;
1.17    ! christos  438:        el->el_chared.c_redo.buf        = (char *) el_malloc(EL_BUFSIZ);
        !           439:        if (el->el_chared.c_redo.buf == NULL)
1.16      christos  440:                return (-1);
1.17    ! christos  441:        el->el_chared.c_redo.pos        = el->el_chared.c_redo.buf;
        !           442:        el->el_chared.c_redo.lim        = el->el_chared.c_redo.buf + EL_BUFSIZ;
        !           443:        el->el_chared.c_redo.cmd        = ED_UNASSIGNED;
1.9       lukem     444:
                    445:        el->el_chared.c_vcmd.action     = NOP;
                    446:        el->el_chared.c_vcmd.pos        = el->el_line.buffer;
                    447:
                    448:        el->el_chared.c_kill.buf        = (char *) el_malloc(EL_BUFSIZ);
1.11      christos  449:        if (el->el_chared.c_kill.buf == NULL)
                    450:                return (-1);
1.9       lukem     451:        (void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ);
                    452:        el->el_chared.c_kill.mark       = el->el_line.buffer;
                    453:        el->el_chared.c_kill.last       = el->el_chared.c_kill.buf;
                    454:
                    455:        el->el_map.current              = el->el_map.key;
                    456:
                    457:        el->el_state.inputmode          = MODE_INSERT; /* XXX: save a default */
                    458:        el->el_state.doingarg           = 0;
                    459:        el->el_state.metanext           = 0;
                    460:        el->el_state.argument           = 1;
                    461:        el->el_state.lastcmd            = ED_UNASSIGNED;
                    462:
                    463:        el->el_chared.c_macro.nline     = NULL;
                    464:        el->el_chared.c_macro.level     = -1;
                    465:        el->el_chared.c_macro.macro     = (char **) el_malloc(EL_MAXMACRO *
1.11      christos  466:            sizeof(char *));
                    467:        if (el->el_chared.c_macro.macro == NULL)
                    468:                return (-1);
1.9       lukem     469:        return (0);
1.1       cgd       470: }
                    471:
                    472: /* ch_reset():
                    473:  *     Reset the character editor
                    474:  */
                    475: protected void
1.9       lukem     476: ch_reset(EditLine *el)
1.1       cgd       477: {
1.9       lukem     478:        el->el_line.cursor              = el->el_line.buffer;
                    479:        el->el_line.lastchar            = el->el_line.buffer;
1.1       cgd       480:
1.16      christos  481:        el->el_chared.c_undo.len        = -1;
                    482:        el->el_chared.c_undo.cursor     = 0;
1.1       cgd       483:
1.9       lukem     484:        el->el_chared.c_vcmd.action     = NOP;
                    485:        el->el_chared.c_vcmd.pos        = el->el_line.buffer;
1.1       cgd       486:
1.9       lukem     487:        el->el_chared.c_kill.mark       = el->el_line.buffer;
1.1       cgd       488:
1.9       lukem     489:        el->el_map.current              = el->el_map.key;
1.1       cgd       490:
1.9       lukem     491:        el->el_state.inputmode          = MODE_INSERT; /* XXX: save a default */
                    492:        el->el_state.doingarg           = 0;
                    493:        el->el_state.metanext           = 0;
                    494:        el->el_state.argument           = 1;
                    495:        el->el_state.lastcmd            = ED_UNASSIGNED;
1.1       cgd       496:
1.9       lukem     497:        el->el_chared.c_macro.level     = -1;
1.1       cgd       498:
1.9       lukem     499:        el->el_history.eventno          = 0;
1.1       cgd       500: }
                    501:
1.12      jdolecek  502: /* ch_enlargebufs():
                    503:  *     Enlarge line buffer to be able to hold twice as much characters.
                    504:  *     Returns 1 if successful, 0 if not.
                    505:  */
                    506: protected int
                    507: ch_enlargebufs(el, addlen)
1.13      lukem     508:        EditLine *el;
                    509:        size_t addlen;
1.12      jdolecek  510: {
1.13      lukem     511:        size_t sz, newsz;
                    512:        char *newbuffer, *oldbuf, *oldkbuf;
1.12      jdolecek  513:
1.13      lukem     514:        sz = el->el_line.limit - el->el_line.buffer + EL_LEAVE;
                    515:        newsz = sz * 2;
                    516:        /*
                    517:         * If newly required length is longer than current buffer, we need
                    518:         * to make the buffer big enough to hold both old and new stuff.
                    519:         */
                    520:        if (addlen > sz) {
                    521:                while(newsz - sz < addlen)
                    522:                        newsz *= 2;
                    523:        }
                    524:
                    525:        /*
                    526:         * Reallocate line buffer.
                    527:         */
                    528:        newbuffer = el_realloc(el->el_line.buffer, newsz);
                    529:        if (!newbuffer)
                    530:                return 0;
                    531:
                    532:        /* zero the newly added memory, leave old data in */
                    533:        (void) memset(&newbuffer[sz], 0, newsz - sz);
                    534:
                    535:        oldbuf = el->el_line.buffer;
                    536:
                    537:        el->el_line.buffer = newbuffer;
                    538:        el->el_line.cursor = newbuffer + (el->el_line.cursor - oldbuf);
                    539:        el->el_line.lastchar = newbuffer + (el->el_line.lastchar - oldbuf);
1.16      christos  540:        /* don't set new size until all buffers are enlarged */
                    541:        el->el_line.limit  = &newbuffer[sz - EL_LEAVE];
1.13      lukem     542:
                    543:        /*
                    544:         * Reallocate kill buffer.
                    545:         */
                    546:        newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz);
                    547:        if (!newbuffer)
                    548:                return 0;
1.12      jdolecek  549:
1.13      lukem     550:        /* zero the newly added memory, leave old data in */
                    551:        (void) memset(&newbuffer[sz], 0, newsz - sz);
1.12      jdolecek  552:
1.13      lukem     553:        oldkbuf = el->el_chared.c_kill.buf;
1.12      jdolecek  554:
1.13      lukem     555:        el->el_chared.c_kill.buf = newbuffer;
                    556:        el->el_chared.c_kill.last = newbuffer +
1.12      jdolecek  557:                                        (el->el_chared.c_kill.last - oldkbuf);
1.13      lukem     558:        el->el_chared.c_kill.mark = el->el_line.buffer +
1.12      jdolecek  559:                                        (el->el_chared.c_kill.mark - oldbuf);
                    560:
1.13      lukem     561:        /*
                    562:         * Reallocate undo buffer.
                    563:         */
                    564:        newbuffer = el_realloc(el->el_chared.c_undo.buf, newsz);
                    565:        if (!newbuffer)
                    566:                return 0;
                    567:
                    568:        /* zero the newly added memory, leave old data in */
                    569:        (void) memset(&newbuffer[sz], 0, newsz - sz);
1.16      christos  570:        el->el_chared.c_undo.buf = newbuffer;
1.13      lukem     571:
1.17    ! christos  572:        newbuffer = el_realloc(el->el_chared.c_redo.buf, newsz);
1.16      christos  573:        if (!newbuffer)
                    574:                return 0;
1.17    ! christos  575:        el->el_chared.c_redo.pos = newbuffer +
        !           576:                        (el->el_chared.c_redo.pos - el->el_chared.c_redo.buf);
        !           577:        el->el_chared.c_redo.lim = newbuffer +
        !           578:                        (el->el_chared.c_redo.lim - el->el_chared.c_redo.buf);
        !           579:        el->el_chared.c_redo.buf = newbuffer;
1.13      lukem     580:
                    581:        if (!hist_enlargebuf(el, sz, newsz))
                    582:                return 0;
1.12      jdolecek  583:
1.16      christos  584:        /* Safe to set enlarged buffer size */
                    585:        el->el_line.limit  = &newbuffer[newsz - EL_LEAVE];
1.13      lukem     586:        return 1;
1.12      jdolecek  587: }
1.1       cgd       588:
                    589: /* ch_end():
                    590:  *     Free the data structures used by the editor
                    591:  */
                    592: protected void
1.9       lukem     593: ch_end(EditLine *el)
1.1       cgd       594: {
1.9       lukem     595:        el_free((ptr_t) el->el_line.buffer);
                    596:        el->el_line.buffer = NULL;
                    597:        el->el_line.limit = NULL;
                    598:        el_free((ptr_t) el->el_chared.c_undo.buf);
                    599:        el->el_chared.c_undo.buf = NULL;
1.17    ! christos  600:        el_free((ptr_t) el->el_chared.c_redo.buf);
        !           601:        el->el_chared.c_redo.buf = NULL;
        !           602:        el->el_chared.c_redo.pos = NULL;
        !           603:        el->el_chared.c_redo.lim = NULL;
        !           604:        el->el_chared.c_redo.cmd = ED_UNASSIGNED;
1.9       lukem     605:        el_free((ptr_t) el->el_chared.c_kill.buf);
                    606:        el->el_chared.c_kill.buf = NULL;
                    607:        el_free((ptr_t) el->el_chared.c_macro.macro);
                    608:        el->el_chared.c_macro.macro = NULL;
                    609:        ch_reset(el);
1.1       cgd       610: }
                    611:
                    612:
                    613: /* el_insertstr():
                    614:  *     Insert string at cursorI
                    615:  */
                    616: public int
1.9       lukem     617: el_insertstr(EditLine *el, const char *s)
                    618: {
1.14      christos  619:        size_t len;
1.9       lukem     620:
                    621:        if ((len = strlen(s)) == 0)
                    622:                return (-1);
1.12      jdolecek  623:        if (el->el_line.lastchar + len >= el->el_line.limit) {
                    624:                if (!ch_enlargebufs(el, len))
                    625:                        return (-1);
                    626:        }
1.9       lukem     627:
1.14      christos  628:        c_insert(el, (int)len);
1.9       lukem     629:        while (*s)
                    630:                *el->el_line.cursor++ = *s++;
                    631:        return (0);
1.1       cgd       632: }
                    633:
                    634:
                    635: /* el_deletestr():
                    636:  *     Delete num characters before the cursor
                    637:  */
                    638: public void
1.9       lukem     639: el_deletestr(EditLine *el, int n)
                    640: {
                    641:        if (n <= 0)
                    642:                return;
                    643:
                    644:        if (el->el_line.cursor < &el->el_line.buffer[n])
                    645:                return;
                    646:
                    647:        c_delbefore(el, n);             /* delete before dot */
                    648:        el->el_line.cursor -= n;
                    649:        if (el->el_line.cursor < el->el_line.buffer)
                    650:                el->el_line.cursor = el->el_line.buffer;
1.1       cgd       651: }
                    652:
                    653: /* c_gets():
                    654:  *     Get a string
                    655:  */
                    656: protected int
1.9       lukem     657: c_gets(EditLine *el, char *buf)
                    658: {
                    659:        char ch;
                    660:        int len = 0;
1.1       cgd       661:
1.9       lukem     662:        for (ch = 0; ch == 0;) {
                    663:                if (el_getc(el, &ch) != 1)
                    664:                        return (ed_end_of_file(el, 0));
                    665:                switch (ch) {
                    666:                case 0010:      /* Delete and backspace */
                    667:                case 0177:
                    668:                        if (len > 1) {
                    669:                                *el->el_line.cursor-- = '\0';
                    670:                                el->el_line.lastchar = el->el_line.cursor;
                    671:                                buf[len--] = '\0';
                    672:                        } else {
                    673:                                el->el_line.buffer[0] = '\0';
                    674:                                el->el_line.lastchar = el->el_line.buffer;
                    675:                                el->el_line.cursor = el->el_line.buffer;
                    676:                                return (CC_REFRESH);
                    677:                        }
                    678:                        re_refresh(el);
                    679:                        ch = 0;
                    680:                        break;
                    681:
                    682:                case 0033:      /* ESC */
                    683:                case '\r':      /* Newline */
                    684:                case '\n':
                    685:                        break;
                    686:
                    687:                default:
                    688:                        if (len >= EL_BUFSIZ)
                    689:                                term_beep(el);
                    690:                        else {
                    691:                                buf[len++] = ch;
                    692:                                *el->el_line.cursor++ = ch;
                    693:                                el->el_line.lastchar = el->el_line.cursor;
                    694:                        }
                    695:                        re_refresh(el);
                    696:                        ch = 0;
                    697:                        break;
                    698:                }
                    699:        }
                    700:        buf[len] = ch;
                    701:        return (len);
1.1       cgd       702: }
                    703:
                    704:
                    705: /* c_hpos():
                    706:  *     Return the current horizontal position of the cursor
                    707:  */
                    708: protected int
1.9       lukem     709: c_hpos(EditLine *el)
1.1       cgd       710: {
1.9       lukem     711:        char *ptr;
1.1       cgd       712:
1.9       lukem     713:        /*
                    714:         * Find how many characters till the beginning of this line.
                    715:         */
                    716:        if (el->el_line.cursor == el->el_line.buffer)
                    717:                return (0);
                    718:        else {
                    719:                for (ptr = el->el_line.cursor - 1;
                    720:                     ptr >= el->el_line.buffer && *ptr != '\n';
                    721:                     ptr--)
                    722:                        continue;
                    723:                return (el->el_line.cursor - ptr - 1);
                    724:        }
1.1       cgd       725: }

CVSweb <webmaster@jp.NetBSD.org>