From root@gw.jmrodgers.com  Mon May  4 13:13:34 1998
Received: from gw.jmrodgers.com (gw.jmrodgers.com [205.247.224.2])
          by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id NAA14200
          for <FreeBSD-gnats-submit@freebsd.org>; Mon, 4 May 1998 13:13:22 -0700 (PDT)
          (envelope-from root@gw.jmrodgers.com)
Received: (from root@localhost)
	by gw.jmrodgers.com (8.8.8/8.8.8) id QAA16093;
	Mon, 4 May 1998 16:12:42 -0400 (EDT)
	(envelope-from root)
Message-Id: <199805042012.QAA16093@gw.jmrodgers.com>
Date: Mon, 4 May 1998 16:12:42 -0400 (EDT)
From: meuston@jmrodgers.com
Reply-To: meuston@jmrodgers.com
To: FreeBSD-gnats-submit@freebsd.org
Subject: [Patch] Assorted errors in libedit
X-Send-Pr-Version: 3.2

>Number:         6516
>Category:       bin
>Synopsis:       [Patch] Assorted errors in libedit
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    brian
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon May  4 13:20:01 PDT 1998
>Closed-Date:    Sat Jun 27 09:15:29 PDT 1998
>Last-Modified:  Sat Jun 27 09:16:12 PDT 1998
>Originator:     Max Euston
>Release:        FreeBSD 2.2.5-STABLE i386
>Organization:
>Environment:

	-STABLE (also in -CURRENT)

>Description:
[tagged "Priority==medium" since this was one of the first complaints
 I had when I first installed FreeBSD and "first impressions count"]

Assorted problems with the history edit functions in libedit.  This
affects sh, ftp (and others?).

(All command keys assume the vi- mode of editing).

1) The 'r' command does not reposition the cursor when it is done.
   [ed_insert() needs to return CC_CURSOR since it automatically calls
   vi_command_mode() if MODE_REPLACE_1].

2) The [count] prefix to commands does not work.  [read_getcmd()
   looped while "cmd==0", but ED_ARGUMENT_DIGIT is the first
   (lexographically) command and is assigned a command code of 0.
   read_getcmd() needs to loop while ED_UNASSIGNED].
   [vi_replace_char() and vi_replace_mode() need to return
   CC_ARGHACK instead of CC_NORM since both commands require another
   argument (the character to substitute)].

3) The 'w' and 'b' commands use the emacs(?) definition of a word
   instead of the vi definition of a word.

4) The 'u' command does not work after the 'r' command.  [ed_insert()
   needs to set ...c_undo.action=CHANGE if MODE_REPLACE*].

5) There is no 'U' command (to undo *all* editing on the current line).

There are more bugs in libedit, but these are the (IMO) big ones I have
found (they are the ones that bothered me).

>How-To-Repeat:

(try to) use the vi- style commands above.

>Fix:

diff -u /usr/src/lib/libedit/chared.c ./chared.c
--- /usr/src/lib/libedit/chared.c	Fri Feb 20 17:18:28 1998
+++ ./chared.c	Thu Apr 30 12:47:28 1998
@@ -153,10 +153,25 @@
 
 
 /* cv__isword():
- *	Return if p is part of a word according to vi
+ *	Return type of word for p according to vi
  */
 protected int
 cv__isword(p)
+    int p;
+{
+    if (isspace((unsigned char) p))
+        return 0;
+    if ((unsigned char) p == '_' || isalnum((unsigned char) p))
+        return 1;
+    return 2;
+}
+
+
+/* c___isword():
+ *	Return if p is part of a space-delimited word (!isspace)
+ */
+protected int
+c___isword(p)
     int p;
 {
     return !isspace((unsigned char) p);


diff -u /usr/src/lib/libedit/chared.h ./chared.h
--- /usr/src/lib/libedit/chared.h	Tue May 30 01:42:55 1995
+++ ./chared.h	Tue Mar 31 13:03:46 1998
@@ -138,6 +138,7 @@
 protected void  cv_delfini	__P((EditLine *));
 protected char *cv__endword	__P((char *, char *, int));
 protected int   ce__isword	__P((int));
+protected int   c___isword	__P((int));
 protected void  cv_undo		__P((EditLine *, int, int, char *));
 protected char *cv_next_word	__P((EditLine*, char *, char *, int,
 				     int (*)(int)));


diff -u /usr/src/lib/libedit/common.c ./common.c
--- /usr/src/lib/libedit/common.c	Fri Feb 20 17:18:29 1998
+++ ./common.c	Fri May  1 15:30:43 1998
@@ -110,8 +110,11 @@
 	re_refresh(el);
     }
 
+    if (el->el_state.inputmode == MODE_REPLACE_1 || el->el_state.inputmode == MODE_REPLACE)
+	el->el_chared.c_undo.action=CHANGE;
+
     if (el->el_state.inputmode == MODE_REPLACE_1)
-	(void) vi_command_mode(el, 0);
+	return vi_command_mode(el, 0);
 
     return CC_NORM;
 }


diff -u /usr/src/lib/libedit/map.c ./map.c
--- /usr/src/lib/libedit/map.c	Fri Feb 20 17:18:36 1998
+++ ./map.c	Fri May  1 13:10:53 1998
@@ -701,7 +701,7 @@
     /*  82 */	VI_REPLACE_MODE,	/* R */
     /*  83 */	VI_SUBSTITUTE_LINE,	/* S */
     /*  84 */	VI_TO_PREV_CHAR,	/* T */
-    /*  85 */	ED_UNASSIGNED,		/* U */
+    /*  85 */	VI_UNDO_LINE,		/* U */
     /*  86 */	ED_UNASSIGNED,		/* V */
     /*  87 */	VI_NEXT_SPACE_WORD,	/* W */
     /*  88 */	ED_DELETE_PREV_CHAR,	/* X */


diff -u /usr/src/lib/libedit/read.c ./read.c
--- /usr/src/lib/libedit/read.c	Fri Feb 20 17:18:37 1998
+++ ./read.c	Fri May  1 13:12:30 1998
@@ -196,10 +196,10 @@
     el_action_t *cmdnum;
     char *ch;
 {
-    el_action_t  cmd = 0;
+    el_action_t  cmd = ED_UNASSIGNED;
     int     num;
 
-    while (cmd == 0 || cmd == ED_SEQUENCE_LEAD_IN) {
+    while (cmd == ED_UNASSIGNED || cmd == ED_SEQUENCE_LEAD_IN) {
 	if ((num = el_getc(el, ch)) != 1)	/* if EOF or error */
 	    return num;
 


diff -u /usr/src/lib/libedit/vi.c ./vi.c
--- /usr/src/lib/libedit/vi.c	Fri Feb 20 17:18:48 1998
+++ ./vi.c	Fri May  1 13:10:38 1998
@@ -173,7 +173,7 @@
     el->el_line.cursor = cv_prev_word(el, el->el_line.cursor,
 				      el->el_line.buffer,
 			 	      el->el_state.argument,
-				      cv__isword);
+				      c___isword);
 
     if (el->el_chared.c_vcmd.action & DELETE) {
 	cv_delfini(el);
@@ -186,7 +186,7 @@
 
 /* vi_prev_word():
  *	Vi move to the previous word
- *	[B]
+ *	[b]
  */
 protected el_action_t
 /*ARGSUSED*/
@@ -200,7 +200,7 @@
     el->el_line.cursor = cv_prev_word(el, el->el_line.cursor,
 				      el->el_line.buffer,
 			 	      el->el_state.argument,
-				      ce__isword);
+				      cv__isword);
 
     if (el->el_chared.c_vcmd.action & DELETE) {
 	cv_delfini(el);
@@ -227,7 +227,7 @@
     el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
 				      el->el_line.lastchar,
 				      el->el_state.argument,
-				      cv__isword);
+				      c___isword);
 
     if (el->el_map.type == MAP_VI)
 	if (el->el_chared.c_vcmd.action & DELETE) {
@@ -254,7 +254,7 @@
     el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
 				      el->el_line.lastchar,
 				      el->el_state.argument,
-				      ce__isword);
+				      cv__isword);
 
     if (el->el_map.type == MAP_VI)
 	if (el->el_chared.c_vcmd.action & DELETE) {
@@ -346,7 +346,7 @@
     el->el_chared.c_undo.ptr = el->el_line.cursor;
     el->el_chared.c_undo.isize = 0;
     el->el_chared.c_undo.dsize = 0;
-    return CC_NORM;
+    return CC_ARGHACK;
 }
 
 
@@ -366,13 +366,13 @@
     el->el_chared.c_undo.ptr = el->el_line.cursor;
     el->el_chared.c_undo.isize = 0;
     el->el_chared.c_undo.dsize = 0;
-    return CC_NORM;
+    return CC_ARGHACK;
 }
 
 
 /* vi_substitute_char():
  *	Vi replace character under the cursor and enter insert mode
- *	[r]
+ *	[s]
  */
 protected el_action_t
 /*ARGSUSED*/
@@ -448,7 +448,8 @@
     EditLine *el;
     int c;
 {
-    int ret;
+    el_action_t ret;
+
     el->el_map.current = el->el_map.key;
     if (el->el_line.cursor < el->el_line.lastchar) {
 	el->el_line.cursor++;
@@ -661,6 +662,21 @@
     }
 
     return CC_REFRESH;
+}
+
+
+/* vi_undo_line():
+ *	Vi undo all changes
+ *	[U]
+ */
+protected el_action_t
+/*ARGSUSED*/
+vi_undo_line(el, c)
+    EditLine *el;
+    int c;
+{
+
+    return hist_get(el);
 }
 
 
>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->suspended 
State-Changed-By: phk 
State-Changed-When: Wed May 6 02:20:28 PDT 1998 
State-Changed-Why:  
awaiting committer 
Responsible-Changed-From-To: freebsd-bugs->brian 
Responsible-Changed-By: brian 
Responsible-Changed-When: Sat Jun 27 08:14:49 PDT 1998 
Responsible-Changed-Why:  
I'll do this 
State-Changed-From-To: suspended->closed 
State-Changed-By: brian 
State-Changed-When: Sat Jun 27 09:15:29 PDT 1998 
State-Changed-Why:  
Patches applied to -current.  Will MFC in a few days 
if nobody complains. 
>Unformatted:
