Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libedit Enlarge editline buffers as needed to support ar...



details:   https://anonhg.NetBSD.org/src/rev/4155fb90f9f8
branches:  trunk
changeset: 501996:4155fb90f9f8
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Wed Jan 10 07:45:41 2001 +0000

description:
Enlarge editline buffers as needed to support arbitrary length lines.
This also addresses lib/9712 by Phil Nelson.

diffstat:

 lib/libedit/chared.c  |   89 ++++++++++++++++++++++++++++++++++++++-
 lib/libedit/chared.h  |    3 +-
 lib/libedit/common.c  |   17 ++++--
 lib/libedit/emacs.c   |   10 ++-
 lib/libedit/hist.c    |   34 +++++++++++++-
 lib/libedit/hist.h    |    4 +-
 lib/libedit/prompt.c  |    6 +-
 lib/libedit/read.c    |   31 +++++++++----
 lib/libedit/refresh.c |  111 +++++++++++++++++++++++++++++++++++++------------
 lib/libedit/refresh.h |    4 +-
 10 files changed, 246 insertions(+), 63 deletions(-)

diffs (truncated from 653 to 300 lines):

diff -r bebd536471dc -r 4155fb90f9f8 lib/libedit/chared.c
--- a/lib/libedit/chared.c      Wed Jan 10 05:23:43 2001 +0000
+++ b/lib/libedit/chared.c      Wed Jan 10 07:45:41 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: chared.c,v 1.11 2001/01/04 15:56:31 christos Exp $     */
+/*     $NetBSD: chared.c,v 1.12 2001/01/10 07:45:41 jdolecek Exp $     */
 
 /*-
  * Copyright (c) 1992, 1993
@@ -41,7 +41,7 @@
 #if 0
 static char sccsid[] = "@(#)chared.c   8.1 (Berkeley) 6/4/93";
 #else
-__RCSID("$NetBSD: chared.c,v 1.11 2001/01/04 15:56:31 christos Exp $");
+__RCSID("$NetBSD: chared.c,v 1.12 2001/01/10 07:45:41 jdolecek Exp $");
 #endif
 #endif /* not lint && not SCCSID */
 
@@ -53,6 +53,9 @@
 #include <stdlib.h>
 #include "el.h"
 
+/* value to leave unused in line buffer */
+#define        EL_LEAVE        2
+
 /* cv_undo():
  *     Handle state for the vi undo command
  */
@@ -482,6 +485,82 @@
        el->el_history.eventno          = 0;
 }
 
+/* ch_enlargebufs():
+ *     Enlarge line buffer to be able to hold twice as much characters.
+ *     Returns 1 if successful, 0 if not.
+ */
+protected int
+ch_enlargebufs(el, addlen)
+    EditLine *el;
+    size_t addlen;
+{
+    size_t sz = el->el_line.limit - el->el_line.buffer + EL_LEAVE;
+    size_t newsz = sz * 2;
+    char *newbuffer, *oldbuf, *oldkbuf;
+
+    /*
+     * If newly required length is longer than current buffer, we need
+     * to make the buffer big enough to hold both old and new stuff.
+     */
+    if (addlen > sz) {
+       while(newsz - sz < addlen)
+               newsz *= 2;
+    }
+
+    /*
+     * Reallocate line buffer.
+     */
+    newbuffer = el_realloc(el->el_line.buffer, newsz);
+    if (!newbuffer)
+       return 0;
+
+    /* zero the newly added memory, leave old data in */
+    (void) memset(&newbuffer[sz], 0, newsz - sz);
+       
+    oldbuf = el->el_line.buffer;
+
+    el->el_line.buffer = newbuffer;
+    el->el_line.cursor = newbuffer + (el->el_line.cursor - oldbuf);
+    el->el_line.lastchar = newbuffer + (el->el_line.lastchar - oldbuf);
+    el->el_line.limit  = &newbuffer[newsz - EL_LEAVE];
+
+    /*
+     * Reallocate kill buffer.
+     */
+    newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz);
+    if (!newbuffer)
+       return 0;
+
+    /* zero the newly added memory, leave old data in */
+    (void) memset(&newbuffer[sz], 0, newsz - sz);
+
+    oldkbuf = el->el_chared.c_kill.buf;
+
+    el->el_chared.c_kill.buf   = newbuffer;
+    el->el_chared.c_kill.last  = newbuffer +
+                                       (el->el_chared.c_kill.last - oldkbuf);
+    el->el_chared.c_kill.mark  = el->el_line.buffer +
+                                       (el->el_chared.c_kill.mark - oldbuf);
+
+    /*
+     * Reallocate undo buffer.
+     */
+    newbuffer = el_realloc(el->el_chared.c_undo.buf, newsz);
+    if (!newbuffer)
+       return 0;
+
+    /* zero the newly added memory, leave old data in */
+    (void) memset(&newbuffer[sz], 0, newsz - sz);
+
+    el->el_chared.c_undo.ptr = el->el_line.buffer +
+                               (el->el_chared.c_undo.ptr - oldbuf);
+    el->el_chared.c_undo.buf = newbuffer;
+    
+    if (!hist_enlargebuf(el, sz, newsz))
+       return 0;
+
+    return 1;
+}
 
 /* ch_end():
  *     Free the data structures used by the editor
@@ -512,8 +591,10 @@
 
        if ((len = strlen(s)) == 0)
                return (-1);
-       if (el->el_line.lastchar + len >= el->el_line.limit)
-               return (-1);
+       if (el->el_line.lastchar + len >= el->el_line.limit) {
+               if (!ch_enlargebufs(el, len))
+                       return (-1);
+       }
 
        c_insert(el, len);
        while (*s)
diff -r bebd536471dc -r 4155fb90f9f8 lib/libedit/chared.h
--- a/lib/libedit/chared.h      Wed Jan 10 05:23:43 2001 +0000
+++ b/lib/libedit/chared.h      Wed Jan 10 07:45:41 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: chared.h,v 1.5 2000/09/04 22:06:29 lukem Exp $ */
+/*     $NetBSD: chared.h,v 1.6 2001/01/10 07:45:41 jdolecek Exp $      */
 
 /*-
  * Copyright (c) 1992, 1993
@@ -153,6 +153,7 @@
 
 protected int   ch_init(EditLine *);
 protected void  ch_reset(EditLine *);
+protected int   ch_enlargebufs __P((EditLine *, size_t));
 protected void  ch_end(EditLine *);
 
 #endif /* _h_el_chared */
diff -r bebd536471dc -r 4155fb90f9f8 lib/libedit/common.c
--- a/lib/libedit/common.c      Wed Jan 10 05:23:43 2001 +0000
+++ b/lib/libedit/common.c      Wed Jan 10 07:45:41 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: common.c,v 1.9 2000/09/04 22:06:29 lukem Exp $ */
+/*     $NetBSD: common.c,v 1.10 2001/01/10 07:45:41 jdolecek Exp $     */
 
 /*-
  * Copyright (c) 1992, 1993
@@ -41,7 +41,7 @@
 #if 0
 static char sccsid[] = "@(#)common.c   8.1 (Berkeley) 6/4/93";
 #else
-__RCSID("$NetBSD: common.c,v 1.9 2000/09/04 22:06:29 lukem Exp $");
+__RCSID("$NetBSD: common.c,v 1.10 2001/01/10 07:45:41 jdolecek Exp $");
 #endif
 #endif /* not lint && not SCCSID */
 
@@ -79,8 +79,11 @@
                return (CC_ERROR);
 
        if (el->el_line.lastchar + el->el_state.argument >=
-           el->el_line.limit)
-               return (CC_ERROR);      /* end of buffer space */
+           el->el_line.limit) {
+               /* end of buffer space, try to allocate more */
+               if (!ch_enlargebufs(el, (size_t) el->el_state.argument))
+                       return CC_ERROR;        /* error allocating more */
+       }
 
        if (el->el_state.argument == 1) {
                if (el->el_state.inputmode != MODE_INSERT) {
@@ -410,8 +413,10 @@
                }
                return (CC_ARGHACK);
        } else {
-               if (el->el_line.lastchar + 1 >= el->el_line.limit)
-                       return (CC_ERROR);
+               if (el->el_line.lastchar + 1 >= el->el_line.limit) {
+                       if (!ch_enlargebufs(el, 1))
+                               return (CC_ERROR);
+               }
 
                if (el->el_state.inputmode != MODE_INSERT) {
                        el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] =
diff -r bebd536471dc -r 4155fb90f9f8 lib/libedit/emacs.c
--- a/lib/libedit/emacs.c       Wed Jan 10 05:23:43 2001 +0000
+++ b/lib/libedit/emacs.c       Wed Jan 10 07:45:41 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: emacs.c,v 1.8 2000/09/04 22:06:29 lukem Exp $  */
+/*     $NetBSD: emacs.c,v 1.9 2001/01/10 07:45:41 jdolecek Exp $       */
 
 /*-
  * Copyright (c) 1992, 1993
@@ -41,7 +41,7 @@
 #if 0
 static char sccsid[] = "@(#)emacs.c    8.1 (Berkeley) 6/4/93";
 #else
-__RCSID("$NetBSD: emacs.c,v 1.8 2000/09/04 22:06:29 lukem Exp $");
+__RCSID("$NetBSD: emacs.c,v 1.9 2001/01/10 07:45:41 jdolecek Exp $");
 #endif
 #endif /* not lint && not SCCSID */
 
@@ -124,8 +124,10 @@
 {
        char *kp, *cp;
 
-       if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
-               return (CC_ERROR);
+       if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf) {
+               if (!ch_enlargebufs(el, 1))
+                       return (CC_ERROR);
+       }
 
        if (el->el_line.lastchar +
            (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
diff -r bebd536471dc -r 4155fb90f9f8 lib/libedit/hist.c
--- a/lib/libedit/hist.c        Wed Jan 10 05:23:43 2001 +0000
+++ b/lib/libedit/hist.c        Wed Jan 10 07:45:41 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: hist.c,v 1.7 2001/01/04 15:56:31 christos Exp $        */
+/*     $NetBSD: hist.c,v 1.8 2001/01/10 07:45:41 jdolecek Exp $        */
 
 /*-
  * Copyright (c) 1992, 1993
@@ -41,7 +41,7 @@
 #if 0
 static char sccsid[] = "@(#)hist.c     8.1 (Berkeley) 6/4/93";
 #else
-__RCSID("$NetBSD: hist.c,v 1.7 2001/01/04 15:56:31 christos Exp $");
+__RCSID("$NetBSD: hist.c,v 1.8 2001/01/10 07:45:41 jdolecek Exp $");
 #endif
 #endif /* not lint && not SCCSID */
 
@@ -62,6 +62,7 @@
        el->el_history.fun = NULL;
        el->el_history.ref = NULL;
        el->el_history.buf = (char *) el_malloc(EL_BUFSIZ);
+       el->el_history.sz  = EL_BUFSIZ;
        if (el->el_history.buf == NULL)
                return (-1);
        el->el_history.last = el->el_history.buf;
@@ -106,7 +107,7 @@
 
        if (el->el_history.eventno == 0) {      /* if really the current line */
                (void) strncpy(el->el_line.buffer, el->el_history.buf,
-                   EL_BUFSIZ);
+                   el->el_history.sz);
                el->el_line.lastchar = el->el_line.buffer +
                    (el->el_history.last - el->el_history.buf);
 
@@ -132,7 +133,8 @@
                        el->el_history.eventno = h;
                        return (CC_ERROR);
                }
-       (void) strncpy(el->el_line.buffer, hp, EL_BUFSIZ);
+       (void) strncpy(el->el_line.buffer, hp,
+                       el->el_line.limit - el->el_line.buffer);
        el->el_line.lastchar = el->el_line.buffer + strlen(el->el_line.buffer);
 
        if (el->el_line.lastchar > el->el_line.buffer) {
@@ -170,3 +172,27 @@
                    el->el_history.ev.num, str);
        return (0);
 }
+
+/* hist_enlargebuf()
+ *     Enlarge history buffer to specified value. Called from el_enlargebufs().
+ *     Return 0 for failure, 1 for success.
+ */
+protected int
+/*ARGSUSED*/
+hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz)
+{
+       char *newbuf;
+
+       newbuf = realloc(el->el_history.buf, newsz);
+       if (!newbuf)
+               return 0;
+
+       (void) memset(&newbuf[oldsz], '\0', newsz - oldsz);
+
+       el->el_history.last = newbuf +
+                               (el->el_history.last - el->el_history.buf);
+       el->el_history.buf = newbuf;
+       el->el_history.sz  = newsz;
+
+       return 1;
+}
diff -r bebd536471dc -r 4155fb90f9f8 lib/libedit/hist.h
--- a/lib/libedit/hist.h        Wed Jan 10 05:23:43 2001 +0000
+++ b/lib/libedit/hist.h        Wed Jan 10 07:45:41 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: hist.h,v 1.5 2000/09/04 22:06:30 lukem Exp $   */
+/*     $NetBSD: hist.h,v 1.6 2001/01/10 07:45:41 jdolecek Exp $        */
 
 /*-
  * Copyright (c) 1992, 1993
@@ -50,6 +50,7 @@



Home | Main Index | Thread Index | Old Index