summaryrefslogtreecommitdiffstats
path: root/lib/libedit/chared.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libedit/chared.c')
-rw-r--r--lib/libedit/chared.c881
1 files changed, 487 insertions, 394 deletions
diff --git a/lib/libedit/chared.c b/lib/libedit/chared.c
index df1207f34b7..0275dfe6c81 100644
--- a/lib/libedit/chared.c
+++ b/lib/libedit/chared.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: chared.c,v 1.6 2003/06/02 20:18:40 millert Exp $ */
-/* $NetBSD: chared.c,v 1.2 1997/01/11 06:47:48 lukem Exp $ */
+/* $OpenBSD: chared.c,v 1.7 2003/10/31 08:42:24 otto Exp $ */
+/* $NetBSD: chared.c,v 1.19 2003/08/07 16:44:30 agc Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -33,88 +33,106 @@
* SUCH DAMAGE.
*/
+#include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93";
#else
-static const char rcsid[] = "$OpenBSD: chared.c,v 1.6 2003/06/02 20:18:40 millert Exp $";
+static const char rcsid[] = "$OpenBSD: chared.c,v 1.7 2003/10/31 08:42:24 otto Exp $";
#endif
#endif /* not lint && not SCCSID */
-/*
+/*
* chared.c: Character editor utilities
*/
-#include "sys.h"
-
#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
*/
protected void
-cv_undo(el, action, size, ptr)
- EditLine *el;
- int action, size;
- char *ptr;
+cv_undo(EditLine *el)
{
- c_undo_t *vu = &el->el_chared.c_undo;
- vu->action = action;
- vu->ptr = ptr;
- vu->isize = size;
- (void)memcpy(vu->buf, vu->ptr, size);
-#ifdef DEBUG_UNDO
- (void)fprintf(el->el_errfile, "Undo buffer \"%s\" size = +%d -%d\n",
- vu->ptr, vu->isize, vu->dsize);
-#endif
+ c_undo_t *vu = &el->el_chared.c_undo;
+ c_redo_t *r = &el->el_chared.c_redo;
+ uint size;
+
+ /* Save entire line for undo */
+ size = el->el_line.lastchar - el->el_line.buffer;
+ vu->len = size;
+ vu->cursor = el->el_line.cursor - el->el_line.buffer;
+ memcpy(vu->buf, el->el_line.buffer, size);
+
+ /* save command info for redo */
+ r->count = el->el_state.doingarg ? el->el_state.argument : 0;
+ r->action = el->el_chared.c_vcmd.action;
+ r->pos = r->buf;
+ r->cmd = el->el_state.thiscmd;
+ r->ch = el->el_state.thisch;
+}
+
+/* cv_yank():
+ * Save yank/delete data for paste
+ */
+protected void
+cv_yank(EditLine *el, const char *ptr, int size)
+{
+ c_kill_t *k = &el->el_chared.c_kill;
+
+ memcpy(k->buf, ptr, size +0u);
+ k->last = k->buf + size;
}
-/* c_insert():
+/* c_insert():
* Insert num characters
*/
protected void
-c_insert(el, num)
- EditLine *el;
- int num;
+c_insert(EditLine *el, int num)
{
- char *cp;
+ char *cp;
- if (el->el_line.lastchar + num >= el->el_line.limit)
- return; /* can't go past end of buffer */
+ if (el->el_line.lastchar + num >= el->el_line.limit) {
+ if (!ch_enlargebufs(el, num +0u))
+ return; /* can't go past end of buffer */
+ }
- if (el->el_line.cursor < el->el_line.lastchar) {
- /* if I must move chars */
- for (cp = el->el_line.lastchar; cp >= el->el_line.cursor; cp--)
- cp[num] = *cp;
- }
- el->el_line.lastchar += num;
-} /* end c_insert */
+ if (el->el_line.cursor < el->el_line.lastchar) {
+ /* if I must move chars */
+ for (cp = el->el_line.lastchar; cp >= el->el_line.cursor; cp--)
+ cp[num] = *cp;
+ }
+ el->el_line.lastchar += num;
+}
/* c_delafter():
* Delete num characters after the cursor
*/
protected void
-c_delafter(el, num)
- EditLine *el;
- int num;
+c_delafter(EditLine *el, int num)
{
- if (el->el_line.cursor + num > el->el_line.lastchar)
- num = el->el_line.lastchar - el->el_line.cursor;
+ if (el->el_line.cursor + num > el->el_line.lastchar)
+ num = el->el_line.lastchar - el->el_line.cursor;
- if (num > 0) {
- char *cp;
+ if (el->el_map.current != el->el_map.emacs) {
+ cv_undo(el);
+ cv_yank(el, el->el_line.cursor, num);
+ }
- if (el->el_map.current != el->el_map.emacs)
- cv_undo(el, INSERT, num, el->el_line.cursor);
+ if (num > 0) {
+ char *cp;
- for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
- *cp = cp[num];
+ for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
+ *cp = cp[num];
- el->el_line.lastchar -= num;
- }
+ el->el_line.lastchar -= num;
+ }
}
@@ -122,25 +140,27 @@ c_delafter(el, num)
* Delete num characters before the cursor
*/
protected void
-c_delbefore(el, num)
- EditLine *el;
- int num;
+c_delbefore(EditLine *el, int num)
{
- if (el->el_line.cursor - num < el->el_line.buffer)
- num = el->el_line.cursor - el->el_line.buffer;
+ if (el->el_line.cursor - num < el->el_line.buffer)
+ num = el->el_line.cursor - el->el_line.buffer;
- if (num > 0) {
- char *cp;
+ if (el->el_map.current != el->el_map.emacs) {
+ cv_undo(el);
+ cv_yank(el, el->el_line.cursor - num, num);
+ }
- if (el->el_map.current != el->el_map.emacs)
- cv_undo(el, INSERT, num, el->el_line.cursor - num);
+ if (num > 0) {
+ char *cp;
- for (cp = el->el_line.cursor - num; cp <= el->el_line.lastchar; cp++)
- *cp = cp[num];
+ for (cp = el->el_line.cursor - num;
+ cp <= el->el_line.lastchar;
+ cp++)
+ *cp = cp[num];
- el->el_line.lastchar -= num;
- }
+ el->el_line.lastchar -= num;
+ }
}
@@ -148,10 +168,9 @@ c_delbefore(el, num)
* Return if p is part of a word according to emacs
*/
protected int
-ce__isword(p)
- int p;
+ce__isword(int p)
{
- return isalpha(p) || isdigit(p) || strchr("*?_-.[]~=", p) != NULL;
+ return (isalnum(p) || strchr("*?_-.[]~=", p) != NULL);
}
@@ -159,10 +178,23 @@ ce__isword(p)
* Return if p is part of a word according to vi
*/
protected int
-cv__isword(p)
- int p;
+cv__isword(int p)
+{
+ if (isalnum(p) || p == '_')
+ return 1;
+ if (isgraph(p))
+ return 2;
+ return 0;
+}
+
+
+/* cv__isWord():
+ * Return if p is part of a big word according to vi
+ */
+protected int
+cv__isWord(int p)
{
- return !isspace(p);
+ return (!isspace(p));
}
@@ -170,26 +202,23 @@ cv__isword(p)
* Find the previous word
*/
protected char *
-c__prev_word(p, low, n, wtest)
- register char *p, *low;
- register int n;
- int (*wtest)(int);
+c__prev_word(char *p, char *low, int n, int (*wtest)(int))
{
- p--;
-
- while (n--) {
- while ((p >= low) && !(*wtest)((unsigned char) *p))
- p--;
- while ((p >= low) && (*wtest)((unsigned char) *p))
- p--;
- }
-
- /* cp now points to one character before the word */
- p++;
- if (p < low)
- p = low;
- /* cp now points where we want it */
- return p;
+ p--;
+
+ while (n--) {
+ while ((p >= low) && !(*wtest)((unsigned char) *p))
+ p--;
+ while ((p >= low) && (*wtest)((unsigned char) *p))
+ p--;
+ }
+
+ /* cp now points to one character before the word */
+ p++;
+ if (p < low)
+ p = low;
+ /* cp now points where we want it */
+ return (p);
}
@@ -197,53 +226,46 @@ c__prev_word(p, low, n, wtest)
* Find the next word
*/
protected char *
-c__next_word(p, high, n, wtest)
- register char *p, *high;
- register int n;
- int (*wtest)(int);
+c__next_word(char *p, char *high, int n, int (*wtest)(int))
{
- while (n--) {
- while ((p < high) && !(*wtest)((unsigned char) *p))
- p++;
- while ((p < high) && (*wtest)((unsigned char) *p))
- p++;
- }
- if (p > high)
- p = high;
- /* p now points where we want it */
- return p;
+ while (n--) {
+ while ((p < high) && !(*wtest)((unsigned char) *p))
+ p++;
+ while ((p < high) && (*wtest)((unsigned char) *p))
+ p++;
+ }
+ if (p > high)
+ p = high;
+ /* p now points where we want it */
+ return (p);
}
/* cv_next_word():
* Find the next word vi style
*/
protected char *
-cv_next_word(el, p, high, n, wtest)
- EditLine *el;
- register char *p, *high;
- register int n;
- int (*wtest)(int);
+cv_next_word(EditLine *el, char *p, char *high, int n, int (*wtest)(int))
{
- int test;
+ int test;
+
+ while (n--) {
+ test = (*wtest)((unsigned char) *p);
+ while ((p < high) && (*wtest)((unsigned char) *p) == test)
+ p++;
+ /*
+ * vi historically deletes with cw only the word preserving the
+ * trailing whitespace! This is not what 'w' does..
+ */
+ if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT))
+ while ((p < high) && isspace((unsigned char) *p))
+ p++;
+ }
- while (n--) {
- test = (*wtest)((unsigned char) *p);
- while ((p < high) && (*wtest)((unsigned char) *p) == test)
- p++;
- /*
- * vi historically deletes with cw only the word preserving the
- * trailing whitespace! This is not what 'w' does..
- */
- if (el->el_chared.c_vcmd.action != (DELETE|INSERT))
- while ((p < high) && isspace((unsigned char) *p))
- p++;
- }
-
- /* p now points where we want it */
- if (p > high)
- return high;
- else
- return p;
+ /* p now points where we want it */
+ if (p > high)
+ return (high);
+ else
+ return (p);
}
@@ -251,36 +273,25 @@ cv_next_word(el, p, high, n, wtest)
* Find the previous word vi style
*/
protected char *
-cv_prev_word(el, p, low, n, wtest)
- EditLine *el;
- register char *p, *low;
- register int n;
- int (*wtest)(int);
+cv_prev_word(char *p, char *low, int n, int (*wtest)(int))
{
- int test;
+ int test;
- while (n--) {
p--;
- /*
- * vi historically deletes with cb only the word preserving the
- * leading whitespace! This is not what 'b' does..
- */
- if (el->el_chared.c_vcmd.action != (DELETE|INSERT))
- while ((p > low) && isspace((unsigned char) *p))
- p--;
- test = (*wtest)((unsigned char) *p);
- while ((p >= low) && (*wtest)((unsigned char) *p) == test)
- p--;
+ while (n--) {
+ while ((p > low) && isspace((unsigned char) *p))
+ p--;
+ test = (*wtest)((unsigned char) *p);
+ while ((p >= low) && (*wtest)((unsigned char) *p) == test)
+ p--;
+ }
p++;
- while (isspace((unsigned char) *p))
- p++;
- }
-
- /* p now points where we want it */
- if (p < low)
- return low;
- else
- return p;
+
+ /* p now points where we want it */
+ if (p < low)
+ return (low);
+ else
+ return (p);
}
@@ -291,30 +302,30 @@ cv_prev_word(el, p, low, n, wtest)
* Return p pointing to last char used.
*/
protected char *
-c__number(p, num, dval)
- char *p; /* character position */
- int *num; /* Return value */
- int dval; /* dval is the number to subtract from like $-3 */
+c__number(
+ char *p, /* character position */
+ int *num, /* Return value */
+ int dval) /* dval is the number to subtract from like $-3 */
{
- register int i;
- register int sign = 1;
-
- if (*++p == '^') {
- *num = 1;
- return p;
- }
- if (*p == '$') {
- if (*++p != '-') {
- *num = 0x7fffffff; /* Handle $ */
- return --p;
+ int i;
+ int sign = 1;
+
+ if (*++p == '^') {
+ *num = 1;
+ return (p);
+ }
+ if (*p == '$') {
+ if (*++p != '-') {
+ *num = 0x7fffffff; /* Handle $ */
+ return (--p);
+ }
+ sign = -1; /* Handle $- */
+ ++p;
}
- sign = -1; /* Handle $- */
- ++p;
- }
- for (i = 0; isdigit((unsigned char) *p); i = 10 * i + *p++ - '0')
- continue;
- *num = (sign < 0 ? dval - i : i);
- return --p;
+ for (i = 0; isdigit((unsigned char) *p); i = 10 * i + *p++ - '0')
+ continue;
+ *num = (sign < 0 ? dval - i : i);
+ return (--p);
}
#endif
@@ -322,53 +333,37 @@ c__number(p, num, dval)
* Finish vi delete action
*/
protected void
-cv_delfini(el)
- EditLine *el;
+cv_delfini(EditLine *el)
{
- register int size;
- int oaction;
-
- if (el->el_chared.c_vcmd.action & INSERT)
- el->el_map.current = el->el_map.key;
+ int size;
+ int action = el->el_chared.c_vcmd.action;
- oaction = el->el_chared.c_vcmd.action;
- el->el_chared.c_vcmd.action = NOP;
+ if (action & INSERT)
+ el->el_map.current = el->el_map.key;
- if (el->el_chared.c_vcmd.pos == 0)
- return;
+ if (el->el_chared.c_vcmd.pos == 0)
+ /* sanity */
+ return;
-
- if (el->el_line.cursor > el->el_chared.c_vcmd.pos) {
- size = (int) (el->el_line.cursor - el->el_chared.c_vcmd.pos);
- c_delbefore(el, size);
+ size = el->el_line.cursor - el->el_chared.c_vcmd.pos;
+ if (size == 0)
+ size = 1;
el->el_line.cursor = el->el_chared.c_vcmd.pos;
- re_refresh_cursor(el);
- }
- else if (el->el_line.cursor < el->el_chared.c_vcmd.pos) {
- size = (int)(el->el_chared.c_vcmd.pos - el->el_line.cursor);
- c_delafter(el, size);
- }
- else {
- size = 1;
- c_delafter(el, size);
- }
- switch (oaction) {
- case DELETE|INSERT:
- el->el_chared.c_undo.action = DELETE|INSERT;
- break;
- case DELETE:
- el->el_chared.c_undo.action = INSERT;
- break;
- case NOP:
- case INSERT:
- default:
- abort();
- break;
- }
-
-
- el->el_chared.c_undo.ptr = el->el_line.cursor;
- el->el_chared.c_undo.dsize = size;
+ if (action & YANK) {
+ if (size > 0)
+ cv_yank(el, el->el_line.cursor, size);
+ else
+ cv_yank(el, el->el_line.cursor + size, -size);
+ } else {
+ if (size > 0) {
+ c_delafter(el, size);
+ re_refresh_cursor(el);
+ } else {
+ c_delbefore(el, -size);
+ el->el_line.cursor += size;
+ }
+ }
+ el->el_chared.c_vcmd.action = NOP;
}
@@ -377,21 +372,19 @@ cv_delfini(el)
* Go to the end of this word according to emacs
*/
protected char *
-ce__endword(p, high, n)
- char *p, *high;
- int n;
+ce__endword(char *p, char *high, int n)
{
- p++;
+ p++;
- while (n--) {
- while ((p < high) && isspace((unsigned char) *p))
- p++;
- while ((p < high) && !isspace((unsigned char) *p))
- p++;
- }
+ while (n--) {
+ while ((p < high) && isspace((unsigned char) *p))
+ p++;
+ while ((p < high) && !isspace((unsigned char) *p))
+ p++;
+ }
- p--;
- return p;
+ p--;
+ return (p);
}
#endif
@@ -400,124 +393,217 @@ ce__endword(p, high, n)
* Go to the end of this word according to vi
*/
protected char *
-cv__endword(p, high, n)
- char *p, *high;
- int n;
+cv__endword(char *p, char *high, int n, int (*wtest)(int))
{
- p++;
+ int test;
+
+ p++;
- while (n--) {
- while ((p < high) && isspace((unsigned char) *p))
- p++;
+ while (n--) {
+ while ((p < high) && isspace((unsigned char) *p))
+ p++;
- if (isalnum((unsigned char) *p))
- while ((p < high) && isalnum((unsigned char) *p))
- p++;
- else
- while ((p < high) && !(isspace((unsigned char) *p) ||
- isalnum((unsigned char) *p)))
- p++;
- }
- p--;
- return p;
+ test = (*wtest)((unsigned char) *p);
+ while ((p < high) && (*wtest)((unsigned char) *p) == test)
+ p++;
+ }
+ p--;
+ return (p);
}
/* ch_init():
* Initialize the character editor
*/
protected int
-ch_init(el)
- EditLine *el;
+ch_init(EditLine *el)
{
- el->el_line.buffer = (char *) el_malloc(EL_BUFSIZ);
- (void)memset(el->el_line.buffer, 0, EL_BUFSIZ);
- el->el_line.cursor = el->el_line.buffer;
- el->el_line.lastchar = el->el_line.buffer;
- el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - 2];
-
- el->el_chared.c_undo.buf = (char *) el_malloc(EL_BUFSIZ);
- (void)memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ);
- el->el_chared.c_undo.action = NOP;
- el->el_chared.c_undo.isize = 0;
- el->el_chared.c_undo.dsize = 0;
- el->el_chared.c_undo.ptr = el->el_line.buffer;
-
- el->el_chared.c_vcmd.action = NOP;
- el->el_chared.c_vcmd.pos = el->el_line.buffer;
- el->el_chared.c_vcmd.ins = el->el_line.buffer;
-
- el->el_chared.c_kill.buf = (char *) el_malloc(EL_BUFSIZ);
- (void)memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ);
- el->el_chared.c_kill.mark = el->el_line.buffer;
- el->el_chared.c_kill.last = el->el_chared.c_kill.buf;
-
- el->el_map.current = el->el_map.key;
-
- el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */
- el->el_state.doingarg = 0;
- el->el_state.metanext = 0;
- el->el_state.argument = 1;
- el->el_state.lastcmd = ED_UNASSIGNED;
-
- el->el_chared.c_macro.nline = NULL;
- el->el_chared.c_macro.level = -1;
- el->el_chared.c_macro.macro = (char **) el_malloc(EL_MAXMACRO *
- sizeof(char *));
- return 0;
+ el->el_line.buffer = (char *) el_malloc(EL_BUFSIZ);
+ if (el->el_line.buffer == NULL)
+ return (-1);
+
+ (void) memset(el->el_line.buffer, 0, EL_BUFSIZ);
+ el->el_line.cursor = el->el_line.buffer;
+ el->el_line.lastchar = el->el_line.buffer;
+ el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE];
+
+ el->el_chared.c_undo.buf = (char *) el_malloc(EL_BUFSIZ);
+ if (el->el_chared.c_undo.buf == NULL)
+ return (-1);
+ (void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ);
+ el->el_chared.c_undo.len = -1;
+ el->el_chared.c_undo.cursor = 0;
+ el->el_chared.c_redo.buf = (char *) el_malloc(EL_BUFSIZ);
+ if (el->el_chared.c_redo.buf == NULL)
+ return (-1);
+ el->el_chared.c_redo.pos = el->el_chared.c_redo.buf;
+ el->el_chared.c_redo.lim = el->el_chared.c_redo.buf + EL_BUFSIZ;
+ el->el_chared.c_redo.cmd = ED_UNASSIGNED;
+
+ el->el_chared.c_vcmd.action = NOP;
+ el->el_chared.c_vcmd.pos = el->el_line.buffer;
+
+ el->el_chared.c_kill.buf = (char *) el_malloc(EL_BUFSIZ);
+ if (el->el_chared.c_kill.buf == NULL)
+ return (-1);
+ (void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ);
+ el->el_chared.c_kill.mark = el->el_line.buffer;
+ el->el_chared.c_kill.last = el->el_chared.c_kill.buf;
+
+ el->el_map.current = el->el_map.key;
+
+ el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */
+ el->el_state.doingarg = 0;
+ el->el_state.metanext = 0;
+ el->el_state.argument = 1;
+ el->el_state.lastcmd = ED_UNASSIGNED;
+
+ el->el_chared.c_macro.nline = NULL;
+ el->el_chared.c_macro.level = -1;
+ el->el_chared.c_macro.macro = (char **) el_malloc(EL_MAXMACRO *
+ sizeof(char *));
+ if (el->el_chared.c_macro.macro == NULL)
+ return (-1);
+ return (0);
}
/* ch_reset():
* Reset the character editor
*/
protected void
-ch_reset(el)
- EditLine *el;
+ch_reset(EditLine *el)
{
- el->el_line.cursor = el->el_line.buffer;
- el->el_line.lastchar = el->el_line.buffer;
+ el->el_line.cursor = el->el_line.buffer;
+ el->el_line.lastchar = el->el_line.buffer;
- el->el_chared.c_undo.action = NOP;
- el->el_chared.c_undo.isize = 0;
- el->el_chared.c_undo.dsize = 0;
- el->el_chared.c_undo.ptr = el->el_line.buffer;
+ el->el_chared.c_undo.len = -1;
+ el->el_chared.c_undo.cursor = 0;
- el->el_chared.c_vcmd.action = NOP;
- el->el_chared.c_vcmd.pos = el->el_line.buffer;
- el->el_chared.c_vcmd.ins = el->el_line.buffer;
+ el->el_chared.c_vcmd.action = NOP;
+ el->el_chared.c_vcmd.pos = el->el_line.buffer;
- el->el_chared.c_kill.mark = el->el_line.buffer;
+ el->el_chared.c_kill.mark = el->el_line.buffer;
- el->el_map.current = el->el_map.key;
+ el->el_map.current = el->el_map.key;
- el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */
- el->el_state.doingarg = 0;
- el->el_state.metanext = 0;
- el->el_state.argument = 1;
- el->el_state.lastcmd = ED_UNASSIGNED;
+ el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */
+ el->el_state.doingarg = 0;
+ el->el_state.metanext = 0;
+ el->el_state.argument = 1;
+ el->el_state.lastcmd = ED_UNASSIGNED;
- el->el_chared.c_macro.level = -1;
+ el->el_chared.c_macro.level = -1;
- el->el_history.eventno = 0;
+ 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, newsz;
+ char *newbuffer, *oldbuf, *oldkbuf;
+
+ sz = el->el_line.limit - el->el_line.buffer + EL_LEAVE;
+ newsz = sz * 2;
+ /*
+ * 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);
+ /* don't set new size until all buffers are enlarged */
+ el->el_line.limit = &newbuffer[sz - 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.buf = newbuffer;
+
+ newbuffer = el_realloc(el->el_chared.c_redo.buf, newsz);
+ if (!newbuffer)
+ return 0;
+ el->el_chared.c_redo.pos = newbuffer +
+ (el->el_chared.c_redo.pos - el->el_chared.c_redo.buf);
+ el->el_chared.c_redo.lim = newbuffer +
+ (el->el_chared.c_redo.lim - el->el_chared.c_redo.buf);
+ el->el_chared.c_redo.buf = newbuffer;
+
+ if (!hist_enlargebuf(el, sz, newsz))
+ return 0;
+
+ /* Safe to set enlarged buffer size */
+ el->el_line.limit = &newbuffer[newsz - EL_LEAVE];
+ return 1;
+}
/* ch_end():
* Free the data structures used by the editor
*/
protected void
-ch_end(el)
- EditLine *el;
+ch_end(EditLine *el)
{
- el_free((ptr_t) el->el_line.buffer);
- el->el_line.buffer = NULL;
- el->el_line.limit = NULL;
- el_free((ptr_t) el->el_chared.c_undo.buf);
- el->el_chared.c_undo.buf = NULL;
- el_free((ptr_t) el->el_chared.c_kill.buf);
- el->el_chared.c_kill.buf = NULL;
- el_free((ptr_t) el->el_chared.c_macro.macro);
- el->el_chared.c_macro.macro = NULL;
- ch_reset(el);
+ el_free((ptr_t) el->el_line.buffer);
+ el->el_line.buffer = NULL;
+ el->el_line.limit = NULL;
+ el_free((ptr_t) el->el_chared.c_undo.buf);
+ el->el_chared.c_undo.buf = NULL;
+ el_free((ptr_t) el->el_chared.c_redo.buf);
+ el->el_chared.c_redo.buf = NULL;
+ el->el_chared.c_redo.pos = NULL;
+ el->el_chared.c_redo.lim = NULL;
+ el->el_chared.c_redo.cmd = ED_UNASSIGNED;
+ el_free((ptr_t) el->el_chared.c_kill.buf);
+ el->el_chared.c_kill.buf = NULL;
+ el_free((ptr_t) el->el_chared.c_macro.macro);
+ el->el_chared.c_macro.macro = NULL;
+ ch_reset(el);
}
@@ -525,21 +611,21 @@ ch_end(el)
* Insert string at cursorI
*/
public int
-el_insertstr(el, s)
- EditLine *el;
- char *s;
+el_insertstr(EditLine *el, const char *s)
{
- int len;
+ size_t len;
- if ((len = strlen(s)) == 0)
- return -1;
- if (el->el_line.lastchar + len >= el->el_line.limit)
- return -1;
+ if ((len = strlen(s)) == 0)
+ 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)
- *el->el_line.cursor++ = *s++;
- return 0;
+ c_insert(el, (int)len);
+ while (*s)
+ *el->el_line.cursor++ = *s++;
+ return (0);
}
@@ -547,74 +633,82 @@ el_insertstr(el, s)
* Delete num characters before the cursor
*/
public void
-el_deletestr(el, n)
- EditLine *el;
- int n;
+el_deletestr(EditLine *el, int n)
{
- if (n <= 0)
- return;
+ if (n <= 0)
+ return;
- if (el->el_line.cursor < &el->el_line.buffer[n])
- return;
+ if (el->el_line.cursor < &el->el_line.buffer[n])
+ return;
- c_delbefore(el, n); /* delete before dot */
- el->el_line.cursor -= n;
- if (el->el_line.cursor < el->el_line.buffer)
- el->el_line.cursor = el->el_line.buffer;
+ c_delbefore(el, n); /* delete before dot */
+ el->el_line.cursor -= n;
+ if (el->el_line.cursor < el->el_line.buffer)
+ el->el_line.cursor = el->el_line.buffer;
}
/* c_gets():
* Get a string
*/
protected int
-c_gets(el, buf)
- EditLine *el;
- char *buf;
+c_gets(EditLine *el, char *buf, const char *prompt)
{
- char ch;
- int len = 0;
-
- for (ch = 0; ch == 0;) {
- if (el_getc(el, &ch) != 1)
- return ed_end_of_file(el, 0);
- switch (ch) {
- case 0010: /* Delete and backspace */
- case 0177:
- if (len > 1) {
- *el->el_line.cursor-- = '\0';
- el->el_line.lastchar = el->el_line.cursor;
- buf[len--] = '\0';
- }
- else {
- el->el_line.buffer[0] = '\0';
- el->el_line.lastchar = el->el_line.buffer;
- el->el_line.cursor = el->el_line.buffer;
- return CC_REFRESH;
- }
- re_refresh(el);
- ch = 0;
- break;
-
- case 0033: /* ESC */
- case '\r': /* Newline */
- case '\n':
- break;
-
- default:
- if (len >= EL_BUFSIZ)
- term_beep(el);
- else {
- buf[len++] = ch;
- *el->el_line.cursor++ = ch;
- el->el_line.lastchar = el->el_line.cursor;
- }
- re_refresh(el);
- ch = 0;
- break;
+ char ch;
+ int len;
+ char *cp = el->el_line.buffer;
+
+ if (prompt) {
+ len = strlen(prompt);
+ memcpy(cp, prompt, len + 0u);
+ cp += len;
+ }
+ len = 0;
+
+ for (;;) {
+ el->el_line.cursor = cp;
+ *cp = ' ';
+ el->el_line.lastchar = cp + 1;
+ re_refresh(el);
+
+ if (el_getc(el, &ch) != 1) {
+ ed_end_of_file(el, 0);
+ len = -1;
+ break;
+ }
+
+ switch (ch) {
+
+ case 0010: /* Delete and backspace */
+ case 0177:
+ if (len <= 0) {
+ len = -1;
+ break;
+ }
+ cp--;
+ continue;
+
+ case 0033: /* ESC */
+ case '\r': /* Newline */
+ case '\n':
+ buf[len] = ch;
+ break;
+
+ default:
+ if (len >= EL_BUFSIZ - 16)
+ term_beep(el);
+ else {
+ buf[len++] = ch;
+ *cp++ = ch;
+ }
+ continue;
+ }
+ break;
}
- }
- buf[len] = ch;
- return len;
+
+ el->el_line.buffer[0] = '\0';
+ el->el_line.lastchar = el->el_line.buffer;
+ el->el_line.cursor = el->el_line.buffer;
+ return len;
}
@@ -622,21 +716,20 @@ c_gets(el, buf)
* Return the current horizontal position of the cursor
*/
protected int
-c_hpos(el)
- EditLine *el;
+c_hpos(EditLine *el)
{
- char *ptr;
+ char *ptr;
- /*
- * Find how many characters till the beginning of this line.
- */
- if (el->el_line.cursor == el->el_line.buffer)
- return 0;
- else {
- for (ptr = el->el_line.cursor - 1;
- ptr >= el->el_line.buffer && *ptr != '\n';
- ptr--)
- continue;
- return el->el_line.cursor - ptr - 1;
- }
+ /*
+ * Find how many characters till the beginning of this line.
+ */
+ if (el->el_line.cursor == el->el_line.buffer)
+ return (0);
+ else {
+ for (ptr = el->el_line.cursor - 1;
+ ptr >= el->el_line.buffer && *ptr != '\n';
+ ptr--)
+ continue;
+ return (el->el_line.cursor - ptr - 1);
+ }
}