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

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

CVSweb <webmaster@jp.NetBSD.org>