svn commit: r237448 - head/lib/libedit

Baptiste Daroussin bapt at FreeBSD.org
Fri Jun 22 19:48:39 UTC 2012


On Fri, Jun 22, 2012 at 06:01:23PM +0000, Pedro F. Giffuni wrote:
> Author: pfg
> Date: Fri Jun 22 18:01:22 2012
> New Revision: 237448
> URL: http://svn.freebsd.org/changeset/base/237448
> 
> Log:
>   Merge changes from upstream libedit.
>   
>   Our libedit has been diverging from the mainstream version
>   maintained in NetBSD. As a consequence it has been difficult
>   to do an appropriate MFV and we have been bringing only
>   partial updates.
>   
>   Here we update most of the files to at least match the
>   version available in NetBSD's snapshot of 20091228. This
>   version was chosen because it still doesn't include wide
>   character support (UTF-8), which involves many changes and
>   new files.
>   
>   From NetBSD's logs:
>   
>   Dec 15 22:13:33 2006 - editline.3 el.c el.h histedit.h
>   add EL_GETFP, and EL_SETFP.
>   
>   Apr 5 15:53:28 2008 - editline.3 el.c histedit.h readline.c
>   add EL_REFRESH for the benefit of readline
>   
>   Sep 10 15:45:37 2008 - common.c el.c read.c refresh.c sig.c term.c term.h tty.c
>   Allow a single process to control multiple ttys (for pthreads using _REENTRANT)
>   using multiple EditLine objects.
>   
>   Jan 18 12:17:24 2009 - el.c read.c readline.c
>   fix -Wsign-compare issues
>   
>   Feb 6 14:40:32 2009 - history.c
>   Plug memory leak, from MySQL.
>   
>   Feb 5 19:15:44 2009 - histedit.h read.c
>   match documentation in el_push
>   
>   Feb 6 13:14:37 2009 - vi.c
>   Portability fix.
>   
>   Feb 12 13:39:49 2009 - readline.c term.c
>   More fixes for existing portability stuff.
>   
>   Feb 15 21:24:13 2009 - el.h read.c
>   don't restart on EINTR, instead return NULL immediately. From Anon Ymous
>   
>   Feb 15 21:25:01 2009 - sig.c sig.h
>   in order for read() to return EINTR we need to use sigaction, not signal,
>   otherwise SA_RESTART is set.
>   
>   Feb 15 21:55:23 2009 - chared.c chared.h common.c emacs.c filecomplete.c
>   filecomplete.h key.c key.h read.c readline.c refresh.c search.c
>   term.c tokenizer.c tty.c vi.c
>   pass lint on _LP64.
>   
>   Feb 17 21:34:26 2009 - el.c histedit.h	prompt.c prompt.h
>   allow for a prompt argument.
>   
>   Feb 18 15:04:40 2009 - sig.c
>   SA_RESTART for all signals but SIGINT. From Anon Ymous.
>   
>   Feb 19 15:20:22 2009 - read.c sig.c sig.h
>   reset and redraw on sigcont. From Anon Ymous.
>   
>   Feb 21 23:31:56 2009 - key.c key.h readline.c vi.c
>   more size_t stuff.
>   
>   Mar 10 20:46:15 2009 - editline.3 read.c
>   make el_gets set the count to -1 on error to distinguish between EOF and
>   error.
>   
>   Mar 31 17:38:27 2009 - editline.3 el.c histedit.h prompt.c prompt.h
>   refresh.c term.c term.h
>   Implement literal prompt sequences. Now someone can implement
>   RL_PROMPT_START_LITERAL/RL_PROMPT_END_LITERAL :-)
>   
>   Mar 31 21:33:17 2009 - term.c
>   cast to size_t to avoid sign / unsigned comparison warning.
>   
>   Apr 23 02:03 2009 - term.c
>   Apply patch (requested by msaitoh in ticket #2007):
>   Coverity CID 1668: Plug memory leak when malloc() failed.:55 2009
>   
>   May 11 18:33:30 2009 - editline.3 el.c histedit.h
>   restore binary compatibility by providing new prompt functions that take
>   an extra literal character.
>   
>   May 19 21:45:14 2009 - refresh.c
>   always scroll when we advance past bottom. From Caleb Welton
>   cwelton at greenplum dot com.
>   
>   Jul 17 12:27:57 2009 - term.c
>   - off by one in the term.h case.
>   - make code more similar to tcsh (if we want to handle wide chars, this is
>     needed; for now it is a no-op)
>   
>   Jul 22 15:56:29 2009 - el.c
>   Move filename to the scope it is being used.
>   From Michael Cook mcook at bbn dot com
>   
>   Jul 22 15:57:00 2009 - read.c
>   Always initialize nread since it is an out param.
>   From Michael Cook mcook at bbn dot com
>   
>   Jul 22 18:25:26 2009 - el.c
>   Only need path if we have issetugid... From Anon Ymous
>   
>   Jul 25 21:19:23 2009 - el.c
>   Ignore comment lines in .editrc from Jess Thrysoee
>   
>   Sep 7 21:24:33 2009
>   histedit.h history.c readline.c
>   apply apple patches from:
>   http://opensource.apple.com/source/libedit/libedit-11/patches/
>   
>   Dec 28 21:52:43 2009 - refresh.c
>   Fix bug where tab completion on the second or > line that caused listing
>   ended up corrupting the display by an extra space in the beginning. Reported
>   by Mac Chan.
>   
>   Dec 28 22:15:36 2009 - refresh.c term.c
>   reduce diff with tcsh
>   
>   Obtained from:	NetBSD
>   Tested by:	bapt, jilles and current@
>   MFC after:	1 week
> 
> Modified:
>   head/lib/libedit/common.c
>   head/lib/libedit/editline.3
>   head/lib/libedit/editrc.5
>   head/lib/libedit/el.c
>   head/lib/libedit/el.h
>   head/lib/libedit/histedit.h
>   head/lib/libedit/history.c
>   head/lib/libedit/key.c
>   head/lib/libedit/key.h
>   head/lib/libedit/prompt.c
>   head/lib/libedit/prompt.h
>   head/lib/libedit/read.c
>   head/lib/libedit/refresh.c
>   head/lib/libedit/search.c
>   head/lib/libedit/sig.c
>   head/lib/libedit/sig.h
>   head/lib/libedit/term.c
>   head/lib/libedit/term.h
>   head/lib/libedit/tty.c
>   head/lib/libedit/vi.c
> 
> Modified: head/lib/libedit/common.c
> ==============================================================================
> --- head/lib/libedit/common.c	Fri Jun 22 16:31:00 2012	(r237447)
> +++ head/lib/libedit/common.c	Fri Jun 22 18:01:22 2012	(r237448)
> @@ -905,7 +905,7 @@ ed_command(EditLine *el, int c __unused)
>  	int tmplen;
>  
>  	tmplen = c_gets(el, tmpbuf, "\n: ");
> -	term__putc('\n');
> +	term__putc(el, '\n');
>  
>  	if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
>  		term_beep(el);
> 
> Modified: head/lib/libedit/editline.3
> ==============================================================================
> --- head/lib/libedit/editline.3	Fri Jun 22 16:31:00 2012	(r237447)
> +++ head/lib/libedit/editline.3	Fri Jun 22 18:01:22 2012	(r237448)
> @@ -1,4 +1,4 @@
> -.\"	$NetBSD: editline.3,v 1.55 2007/01/12 16:31:13 christos Exp $
> +.\"	$NetBSD: editline.3,v 1.70 2009/07/05 21:55:24 perry Exp $
>  .\"
>  .\" Copyright (c) 1997-2003 The NetBSD Foundation, Inc.
>  .\" All rights reserved.
> @@ -28,7 +28,7 @@
>  .\"
>  .\" $FreeBSD$
>  .\"
> -.Dd January 12, 2007
> +.Dd July 5, 2009
>  .Dt EDITLINE 3
>  .Os
>  .Sh NAME
> @@ -162,6 +162,14 @@ is modified to contain the number of cha
>  Returns the line read if successful, or
>  .Dv NULL
>  if no characters were read or if an error occurred.
> +If an error occurred,
> +.Fa count
> +is set to \-1 and
> +.Dv errno
> +contains the error code that caused it.
> +The return value may not remain valid across calls to
> +.Fn el_gets
> +and must be copied if the data is to be retained.
>  .It Fn el_getc
>  Read a character from the tty.
>  .Fa ch
> @@ -222,10 +230,30 @@ are supported, along with the required a
>  Define prompt printing function as
>  .Fa f ,
>  which is to return a string that contains the prompt.
> +.It Dv EL_PROMPT_ESC , Fa "char *(*f)(EditLine *)" , Fa "char c"
> +Same as
> +.Dv EL_PROMPT ,
> +but the
> +.Fa c
> +argument indicates the start/stop literal prompt character.
> +.Pp
> +If a start/stop literal character is found in the prompt, the
> +character itself
> +is not printed, but characters after it are printed directly to the
> +terminal without affecting the state of the current line.
> +A subsequent second start/stop literal character ends this behavior.
> +This is typically used to embed literal escape sequences that change the
> +color/style of the terminal in the prompt.
> +.Dv 0
> +unsets it.
> +.It Dv EL_REFRESH
> +Re-display the current line on the next terminal line.
>  .It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)"
>  Define right side prompt printing function as
>  .Fa f ,
>  which is to return a string that contains the prompt.
> +.It Dv EL_RPROMPT_ESC , Fa "char *(*f)(EditLine *)" , Fa "char c"
> +Define the right prompt printing function but with a literal escape character.
>  .It Dv EL_TERMINAL , Fa "const char *type"
>  Define terminal type of the tty to be
>  .Fa type ,
> @@ -259,66 +287,43 @@ reading command input:
>  and
>  .Dv SIGWINCH .
>  Otherwise, the current signal handlers will be used.
> -.It Dv EL_BIND , Xo
> -.Fa "const char *" ,
> -.Fa "..." ,
> -.Dv NULL
> -.Xc
> +.It Dv EL_BIND , Fa "const char *" , Fa "..." , Dv NULL
>  Perform the
>  .Ic bind
>  builtin command.
>  Refer to
>  .Xr editrc 5
>  for more information.
> -.It Dv EL_ECHOTC , Xo
> -.Fa "const char *" ,
> -.Fa "..." ,
> -.Dv NULL
> -.Xc
> +.It Dv EL_ECHOTC , Fa "const char *" , Fa "..." , Dv NULL
>  Perform the
>  .Ic echotc
>  builtin command.
>  Refer to
>  .Xr editrc 5
>  for more information.
> -.It Dv EL_SETTC , Xo
> -.Fa "const char *" ,
> -.Fa "..." ,
> -.Dv NULL
> -.Xc
> +.It Dv EL_SETTC , Fa "const char *" , Fa "..." , Dv NULL
>  Perform the
>  .Ic settc
>  builtin command.
>  Refer to
>  .Xr editrc 5
>  for more information.
> -.It Dv EL_SETTY , Xo
> -.Fa "const char *" ,
> -.Fa "..." ,
> -.Dv NULL
> -.Xc
> +.It Dv EL_SETTY , Fa "const char *" , Fa "..." , Dv NULL
>  Perform the
>  .Ic setty
>  builtin command.
>  Refer to
>  .Xr editrc 5
>  for more information.
> -.It Dv EL_TELLTC , Xo
> -.Fa "const char *" ,
> -.Fa "..." ,
> -.Dv NULL
> -.Xc
> +.It Dv EL_TELLTC , Fa "const char *" , Fa "..." , Dv NULL
>  Perform the
>  .Ic telltc
>  builtin command.
>  Refer to
>  .Xr editrc 5
>  for more information.
> -.It Dv EL_ADDFN , Xo
> -.Fa "const char *name" ,
> -.Fa "const char *help" ,
> -.Fa "unsigned char (*func)(EditLine *e, int ch)"
> -.Xc
> +.It Dv EL_ADDFN , Fa "const char *name" , Fa "const char *help" , \
> +Fa "unsigned char (*func)(EditLine *e, int ch)"
>  Add a user defined function,
>  .Fn func ,
>  referred to as
> @@ -360,10 +365,8 @@ Beep, and flush tty.
>  .It Dv CC_FATAL
>  Fatal error, reset tty to known state.
>  .El
> -.It Dv EL_HIST , Xo
> -.Fa "History *(*func)(History *, int op, ...)" ,
> -.Fa "const char *ptr"
> -.Xc
> +.It Dv EL_HIST , Fa "History *(*func)(History *, int op, ...)" , \
> +Fa "const char *ptr"
>  Defines which history function to use, which is usually
>  .Fn history .
>  .Fa ptr
> @@ -435,10 +438,22 @@ The following values for
>  are supported, along with actual type of
>  .Fa result :
>  .Bl -tag -width 4n
> -.It Dv EL_PROMPT , Fa "char *(*f)(EditLine *)"
> -Return a pointer to the function that displays the prompt.
> -.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)"
> -Return a pointer to the function that displays the rightside prompt.
> +.It Dv EL_PROMPT , Fa "char *(*f)(EditLine *)" , Fa "char *c"
> +Return a pointer to the function that displays the prompt in
> +.Fa f .
> +If
> +.Fa c
> +is not
> +.Dv NULL ,
> +return the start/stop literal prompt character in it.
> +.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)" , Fa "char *c"
> +Return a pointer to the function that displays the prompt in
> +.Fa f .
> +If
> +.Fa c
> +is not
> +.Dv NULL ,
> +return the start/stop literal prompt character in it.
>  .It Dv EL_EDITOR , Fa "const char *"
>  Return the name of the editor, which will be one of
>  .Dq emacs
> @@ -603,18 +618,11 @@ assumed to be created with
>  .Fn history_init .
>  .It Dv H_CLEAR
>  Clear the history.
> -.It Dv H_FUNC , Xo
> -.Fa "void *ptr" ,
> -.Fa "history_gfun_t first" ,
> -.Fa "history_gfun_t next" ,
> -.Fa "history_gfun_t last" ,
> -.Fa "history_gfun_t prev" ,
> -.Fa "history_gfun_t curr" ,
> -.Fa "history_sfun_t set" ,
> -.Fa "history_vfun_t clear" ,
> -.Fa "history_efun_t enter" ,
> -.Fa "history_efun_t add"
> -.Xc
> +.It Dv H_FUNC , Fa "void *ptr" , Fa "history_gfun_t first" , \
> +Fa "history_gfun_t next" , Fa "history_gfun_t last" , \
> +Fa "history_gfun_t prev" , Fa "history_gfun_t curr" , \
> +Fa "history_sfun_t set" , Fa "history_vfun_t clear" , \
> +Fa "history_efun_t enter" , Fa "history_efun_t add"
>  Define functions to perform various history operations.
>  .Fa ptr
>  is the argument given to a function when it is invoked.
> 
> Modified: head/lib/libedit/editrc.5
> ==============================================================================
> --- head/lib/libedit/editrc.5	Fri Jun 22 16:31:00 2012	(r237447)
> +++ head/lib/libedit/editrc.5	Fri Jun 22 18:01:22 2012	(r237448)
> @@ -1,4 +1,4 @@
> -.\"	$NetBSD: editrc.5,v 1.20 2006/08/21 12:45:30 christos Exp $
> +.\"	$NetBSD: editrc.5,v 1.24 2009/04/11 22:17:52 wiz Exp $
>  .\"
>  .\" Copyright (c) 1997-2000 The NetBSD Foundation, Inc.
>  .\" All rights reserved.
> @@ -89,16 +89,8 @@ shell.
>  .Pp
>  The following builtin commands are available:
>  .Bl -tag -width 4n
> -.It Ic bind Xo
> -.Op Fl a
> -.Op Fl e
> -.Op Fl k
> -.Op Fl l
> -.Op Fl r
> -.Op Fl s
> -.Op Fl v
> -.Op Ar key Op Ar command
> -.Xc
> +.It Ic bind Oo Fl a Oc Oo Fl e Oc Oo Fl k Oc Oo Fl l Oc Oo Fl r Oc \
> +Oo Fl s Oc Oo Fl v Oc Oo Ar key Op Ar command Oc
>  Without options, list all bound keys, and the editor command to which
>  each is bound.
>  If
> @@ -192,11 +184,7 @@ if it has any, notably
>  .Sq \e
>  and
>  .Sq ^ .
> -.It Ic echotc Xo
> -.Op Fl sv
> -.Ar arg
> -.Ar ...
> -.Xc
> +.It Ic echotc Oo Fl sv Oc Ar arg Ar ...
>  Exercise terminal capabilities given in
>  .Ar arg Ar ... .
>  If
> @@ -252,16 +240,8 @@ to
>  as defined in
>  .Xr termcap 5 .
>  No sanity checking is done.
> -.It Ic setty Xo
> -.Op Fl a
> -.Op Fl d
> -.Op Fl q
> -.Op Fl x
> -.Op Ar +mode
> -.Op Ar -mode
> -.Op Ar mode
> -.Op Ar char=c
> -.Xc
> +.It Ic setty Oo Fl a Oc Oo Fl d Oc Oo Fl q Oc Oo Fl x Oc Oo Ar +mode Oc \
> +Oo Ar -mode Oc Oo Ar mode Oc Oo Ar char=c Oc
>  Control which tty modes that
>  .Nm
>  will not allow the user to change.
> 
> Modified: head/lib/libedit/el.c
> ==============================================================================
> --- head/lib/libedit/el.c	Fri Jun 22 16:31:00 2012	(r237447)
> +++ head/lib/libedit/el.c	Fri Jun 22 18:01:22 2012	(r237448)
> @@ -29,7 +29,7 @@
>   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>   * SUCH DAMAGE.
>   *
> - *	$NetBSD: el.c,v 1.44 2006/12/15 22:13:33 christos Exp $
> + *	$NetBSD: el.c,v 1.55 2009/07/25 21:19:23 christos Exp $
>   */
>  
>  #if !defined(lint) && !defined(SCCSID)
> @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
>  #include <string.h>
>  #include <stdlib.h>
>  #include <stdarg.h>
> +#include <ctype.h>
>  #include "el.h"
>  
>  #define	HAVE_ISSETUGID
> @@ -156,9 +157,21 @@ el_set(EditLine *el, int op, ...)
>  
>  	switch (op) {
>  	case EL_PROMPT:
> -	case EL_RPROMPT:
> -		rv = prompt_set(el, va_arg(ap, el_pfunc_t), op);
> +	case EL_RPROMPT: {
> +		el_pfunc_t p = va_arg(ap, el_pfunc_t);
> +
> +		rv = prompt_set(el, p, 0, op);
>  		break;
> +	}
> +
> +	case EL_PROMPT_ESC:
> +	case EL_RPROMPT_ESC: {
> +		el_pfunc_t p = va_arg(ap, el_pfunc_t);
> +		char c = va_arg(ap, int);
> +
> +		rv = prompt_set(el, p, c, op);
> +		break;
> +	}
>  
>  	case EL_TERMINAL:
>  		rv = term_set(el, va_arg(ap, char *));
> @@ -309,6 +322,12 @@ el_set(EditLine *el, int op, ...)
>  		break;
>  	}
>  
> +	case EL_REFRESH:
> +		re_clear_display(el);
> +		re_refresh(el);
> +		term__flush(el);
> +		break;
> +
>  	default:
>  		rv = -1;
>  		break;
> @@ -335,9 +354,13 @@ el_get(EditLine *el, int op, ...)
>  
>  	switch (op) {
>  	case EL_PROMPT:
> -	case EL_RPROMPT:
> -		rv = prompt_get(el, va_arg(ap, el_pfunc_t *), op);
> +	case EL_RPROMPT: {
> +		el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
> +		char *c = va_arg(ap, char *);
> +
> +		rv = prompt_get(el, p, c, op);
>  		break;
> +	}
>  
>  	case EL_EDITOR:
>  		rv = map_get_editor(el, va_arg(ap, const char **));
> @@ -364,7 +387,7 @@ el_get(EditLine *el, int op, ...)
>  		char *argv[20];
>  		int i;
>  
> - 		for (i = 1; i < sizeof(argv) / sizeof(argv[0]); i++)
> + 		for (i = 1; i < (int)(sizeof(argv) / sizeof(argv[0])); i++)
>  			if ((argv[i] = va_arg(ap, char *)) == NULL)
>  				break;
>  
> @@ -495,12 +518,14 @@ el_source(EditLine *el, const char *fnam
>  	FILE *fp;
>  	size_t len;
>  	char *ptr;
> +#ifdef HAVE_ISSETUGID
> +	char path[MAXPATHLEN];
> +#endif
>  
>  	fp = NULL;
>  	if (fname == NULL) {
>  #ifdef HAVE_ISSETUGID
>  		static const char elpath[] = "/.editrc";
> -		char path[MAXPATHLEN];
>  
>  		if (issetugid())
>  			return (-1);
> @@ -529,6 +554,13 @@ el_source(EditLine *el, const char *fnam
>  		if (len > 0 && ptr[len - 1] == '\n')
>  			--len;
>  		ptr[len] = '\0';
> +
> +		/* loop until first non-space char or EOL */
> +		while (*ptr != '\0' && isspace((unsigned char)*ptr))
> +			ptr++;
> +		if (*ptr == '#')
> +			continue;   /* ignore, this is a comment line */
> +
>  		if (parse_line(el, ptr) == -1) {
>  			(void) fclose(fp);
>  			return (-1);
> 
> Modified: head/lib/libedit/el.h
> ==============================================================================
> --- head/lib/libedit/el.h	Fri Jun 22 16:31:00 2012	(r237447)
> +++ head/lib/libedit/el.h	Fri Jun 22 18:01:22 2012	(r237448)
> @@ -115,6 +115,7 @@ struct editline {
>  	FILE		 *el_errfile;	/* Stdio stuff			*/
>  	int		  el_infd;	/* Input file descriptor	*/
>  	int		  el_flags;	/* Various flags.		*/
> +	int		  el_errno;	/* Local copy of errno		*/
>  	coord_t		  el_cursor;	/* Cursor location		*/
>  	char		**el_display;	/* Real screen image = what is there */
>  	char		**el_vdisplay;	/* Virtual screen image = what we see */
> 
> Modified: head/lib/libedit/histedit.h
> ==============================================================================
> --- head/lib/libedit/histedit.h	Fri Jun 22 16:31:00 2012	(r237447)
> +++ head/lib/libedit/histedit.h	Fri Jun 22 18:01:22 2012	(r237448)
> @@ -131,10 +131,10 @@ unsigned char	_el_fn_sh_complete(EditLin
>  #define	EL_GETCFN	13	/* , el_rfunc_t);		*/
>  #define	EL_CLIENTDATA	14	/* , void *);			*/
>  #define	EL_UNBUFFERED	15	/* , int);			*/
> -#define	EL_PREP_TERM    16      /* , int);                      */
> +#define	EL_PREP_TERM    16	/* , int);                      */
>  #define	EL_GETTC	17	/* , const char *, ..., NULL);	*/
> -#define	EL_GETFP	18	/* , int, FILE **)		*/
> -#define	EL_SETFP	19	/* , int, FILE *)		*/
> +#define	EL_GETFP	18	/* , int, FILE **);		*/
> +#define	EL_SETFP	19	/* , int, FILE *);		*/
>  #define	EL_REFRESH	20	/* , void);			      set     */
>  #define	EL_PROMPT_ESC	21	/* , prompt_func, Char);	      set/get */
>  #define	EL_RPROMPT_ESC	22	/* , prompt_func, Char);	      set/get */
> 
> Modified: head/lib/libedit/history.c
> ==============================================================================
> --- head/lib/libedit/history.c	Fri Jun 22 16:31:00 2012	(r237447)
> +++ head/lib/libedit/history.c	Fri Jun 22 18:01:22 2012	(r237448)
> @@ -29,7 +29,7 @@
>   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>   * SUCH DAMAGE.
>   *
> - *	$NetBSD: history.c,v 1.32 2006/09/28 13:52:51 christos Exp $
> + *	$NetBSD: history.c,v 1.34 2009/09/07 21:24:33 christos Exp $
>   */
>  
>  #if !defined(lint) && !defined(SCCSID)
> @@ -116,6 +116,7 @@ private int history_prev_string(History 
>   */
>  typedef struct hentry_t {
>  	HistEvent ev;		/* What we return		 */
> +	void *data;		/* data				 */
>  	struct hentry_t *next;	/* Next entry			 */
>  	struct hentry_t *prev;	/* Previous entry		 */
>  } hentry_t;
> @@ -145,6 +146,9 @@ private int history_def_init(ptr_t *, Hi
>  private int history_def_insert(history_t *, HistEvent *, const char *);
>  private void history_def_delete(history_t *, HistEvent *, hentry_t *);
>  
> +private int history_deldata_nth(history_t *, HistEvent *, int, void **);
> +private int history_set_nth(ptr_t, HistEvent *, int);
> +
>  #define	history_def_setsize(p, num)(void) (((history_t *)p)->max = (num))
>  #define	history_def_getsize(p)  (((history_t *)p)->cur)
>  #define	history_def_getunique(p) (((((history_t *)p)->flags) & H_UNIQUE) != 0)
> @@ -335,6 +339,31 @@ history_def_set(ptr_t p, HistEvent *ev, 
>  }
>  
>  
> +/* history_set_nth():
> + *	Default function to set the current event in the history to the
> + *	n-th one.
> + */
> +private int
> +history_set_nth(ptr_t p, HistEvent *ev, int n)
> +{
> +	history_t *h = (history_t *) p;
> +
> +	if (h->cur == 0) {
> +		he_seterrev(ev, _HE_EMPTY_LIST);
> +		return (-1);
> +	}
> +	for (h->cursor = h->list.prev; h->cursor != &h->list;
> +	    h->cursor = h->cursor->prev)
> +		if (n-- <= 0)
> +			break;
> +	if (h->cursor == &h->list) {
> +		he_seterrev(ev, _HE_NOT_FOUND);
> +		return (-1);
> +	}
> +	return (0);
> +}
> +
> +
>  /* history_def_add():
>   *	Append string to element
>   */
> @@ -363,6 +392,24 @@ history_def_add(ptr_t p, HistEvent *ev, 
>  }
>  
>  
> +private int
> +history_deldata_nth(history_t *h, HistEvent *ev,
> +    int num, void **data)
> +{
> +	if (history_set_nth(h, ev, num) != 0)
> +		return (-1);
> +	/* magic value to skip delete (just set to n-th history) */
> +	if (data == (void **)-1)
> +		return (0);
> +	ev->str = strdup(h->cursor->ev.str);
> +	ev->num = h->cursor->ev.num;
> +	if (data)
> +		*data = h->cursor->data;
> +	history_def_delete(h, ev, h->cursor);
> +	return (0);
> +}
> +
> +
>  /* history_def_del():
>   *	Delete element hp of the h list
>   */
> @@ -392,8 +439,11 @@ history_def_delete(history_t *h, 
>  	HistEventPrivate *evp = (void *)&hp->ev;
>  	if (hp == &h->list)
>  		abort();
> -	if (h->cursor == hp)
> +	if (h->cursor == hp) {
>  		h->cursor = hp->prev;
> +		if (h->cursor == &h->list)
> +			h->cursor = hp->next;
> +	}
>  	hp->prev->next = hp->next;
>  	hp->next->prev = hp->prev;
>  	h_free((ptr_t) evp->str);
> @@ -416,6 +466,7 @@ history_def_insert(history_t *h, HistEve
>  		h_free((ptr_t)h->cursor);
>  		goto oomem;
>  	}
> +	h->cursor->data = NULL;
>  	h->cursor->ev.num = ++h->eventid;
>  	h->cursor->next = h->list.next;
>  	h->cursor->prev = &h->list;
> @@ -711,8 +762,8 @@ history_load(History *h, const char *fna
>  		(void) strunvis(ptr, line);
>  		line[sz] = c;
>  		if (HENTER(h, &ev, ptr) == -1) {
> -			h_free((ptr_t)ptr);
> -			return -1;
> +			i = -1;
> +			goto oomem;
>  		}
>  	}
>  oomem:
> @@ -787,6 +838,23 @@ history_prev_event(History *h, HistEvent
>  }
>  
>  
> +private int
> +history_next_evdata(History *h, HistEvent *ev, int num, void **d)
> +{
> +	int retval;
> +
> +	for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev))
> +		if (num-- <= 0) {
> +			if (d)
> +				*d = ((history_t *)h->h_ref)->cursor->data;
> +			return (0);
> +		}
> +
> +	he_seterrev(ev, _HE_NOT_FOUND);
> +	return (-1);
> +}
> +
> +
>  /* history_next_event():
>   *	Find the next event, with number given
>   */
> @@ -976,11 +1044,42 @@ history(History *h, HistEvent *ev, int f
>  		retval = 0;
>  		break;
>  
> +	case H_NEXT_EVDATA:
> +	{
> +		int num = va_arg(va, int);
> +		void **d = va_arg(va, void **);
> +		retval = history_next_evdata(h, ev, num, d);
> +		break;
> +	}
> +
> +	case H_DELDATA:
> +	{
> +		int num = va_arg(va, int);
> +		void **d = va_arg(va, void **);
> +		retval = history_deldata_nth((history_t *)h->h_ref, ev, num, d);
> +		break;
> +	}
> +
> +	case H_REPLACE: /* only use after H_NEXT_EVDATA */
> +	{
> +		const char *line = va_arg(va, const char *);
> +		void *d = va_arg(va, void *);
> +		const char *s;
> +		if(!line || !(s = strdup(line))) {
> +			retval = -1;
> +			break;
> +		}
> +		((history_t *)h->h_ref)->cursor->ev.str = s;
> +		((history_t *)h->h_ref)->cursor->data = d;
> +		retval = 0;
> +		break;
> +	}
> +
>  	default:
>  		retval = -1;
>  		he_seterrev(ev, _HE_UNKNOWN);
>  		break;
>  	}
>  	va_end(va);
> -	return (retval);
> +	return retval;
>  }
> 
> Modified: head/lib/libedit/key.c
> ==============================================================================
> --- head/lib/libedit/key.c	Fri Jun 22 16:31:00 2012	(r237447)
> +++ head/lib/libedit/key.c	Fri Jun 22 18:01:22 2012	(r237448)
> @@ -29,7 +29,7 @@
>   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>   * SUCH DAMAGE.
>   *
> - *	$NetBSD: key.c,v 1.19 2006/03/23 20:22:51 christos Exp $
> + *	$NetBSD: key.c,v 1.20 2009/02/15 21:55:23 christos Exp $
>   */
>  
>  #if !defined(lint) && !defined(SCCSID)
> @@ -86,8 +86,8 @@ private void		 node__free(key_node_t *);
>  private void		 node__put(EditLine *, key_node_t *);
>  private int		 node__delete(EditLine *, key_node_t **, const char *);
>  private int		 node_lookup(EditLine *, const char *, key_node_t *,
> -    int);
> -private int		 node_enum(EditLine *, key_node_t *, int);
> +    size_t);
> +private int		 node_enum(EditLine *, key_node_t *, size_t);
>  
>  #define	KEY_BUFSIZ	EL_BUFSIZ
>  
> @@ -478,9 +478,9 @@ node__free(key_node_t *k)
>   *	Print if last node
>   */
>  private int
> -node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt)
> +node_lookup(EditLine *el, const char *str, key_node_t *ptr, size_t cnt)
>  {
> -	int ncnt;
> +	size_t ncnt;
>  
>  	if (ptr == NULL)
>  		return (-1);	/* cannot have null ptr */
> @@ -493,7 +493,8 @@ node_lookup(EditLine *el, const char *st
>  		/* If match put this char into el->el_key.buf.  Recurse */
>  		if (ptr->ch == *str) {
>  			/* match found */
> -			ncnt = key__decode_char(el->el_key.buf, KEY_BUFSIZ, cnt,
> +			ncnt = key__decode_char(el->el_key.buf,
> +			    (size_t)KEY_BUFSIZ, cnt,
>  			    (unsigned char) ptr->ch);
>  			if (ptr->next != NULL)
>  				/* not yet at leaf */
> @@ -527,9 +528,9 @@ node_lookup(EditLine *el, const char *st
>   *	Traverse the node printing the characters it is bound in buffer
>   */
>  private int
> -node_enum(EditLine *el, key_node_t *ptr, int cnt)
> +node_enum(EditLine *el, key_node_t *ptr, size_t cnt)
>  {
> -	int ncnt;
> +	size_t ncnt;
>  
>  	if (cnt >= KEY_BUFSIZ - 5) {	/* buffer too small */
>  		el->el_key.buf[++cnt] = '"';
> @@ -547,7 +548,7 @@ node_enum(EditLine *el, key_node_t *ptr,
>  		return (-1);
>  	}
>  	/* put this char at end of str */
> -	ncnt = key__decode_char(el->el_key.buf, KEY_BUFSIZ, cnt,
> +	ncnt = key__decode_char(el->el_key.buf, (size_t)KEY_BUFSIZ, cnt,
>  	    (unsigned char)ptr->ch);
>  	if (ptr->next == NULL) {
>  		/* print this key and function */
> @@ -615,8 +616,8 @@ key_kprint(EditLine *el, const char *key
>  /* key__decode_char():
>   *	Put a printable form of char in buf.
>   */
> -protected int
> -key__decode_char(char *buf, int cnt, int off, int ch)
> +protected size_t
> +key__decode_char(char *buf, size_t cnt, size_t off, int ch)
>  {
>  	char *sb = buf + off;
>  	char *eb = buf + cnt;
> @@ -626,7 +627,7 @@ key__decode_char(char *buf, int cnt, int
>  	if (ch == 0) {
>  		ADDC('^');
>  		ADDC('@');
> -		return b - sb;
> +		return (int)(b - sb);
>  	}
>  	if (iscntrl(ch)) {
>  		ADDC('^');
> @@ -648,15 +649,15 @@ key__decode_char(char *buf, int cnt, int
>  		ADDC((((unsigned int) ch >> 3) & 7) + '0');
>  		ADDC((ch & 7) + '0');
>  	}
> -	return b - sb;
> +	return (size_t)(b - sb);
>  }
>  
>  
>  /* key__decode_str():
>   *	Make a printable version of the ey
>   */
> -protected int
> -key__decode_str(const char *str, char *buf, int len, const char *sep)
> +protected size_t
> +key__decode_str(const char *str, char *buf, size_t len, const char *sep)
>  {
>  	char *b = buf, *eb = b + len;
>  	const char *p;
> @@ -699,7 +700,7 @@ key__decode_str(const char *str, char *b
>  	}
>  done:
>  	ADDC('\0');
> -	if (b - buf >= len)
> +	if ((size_t)(b - buf) >= len)
>  	    buf[len - 1] = '\0';
> -	return b - buf;
> +	return (size_t)(b - buf);
>  }
> 
> Modified: head/lib/libedit/key.h
> ==============================================================================
> --- head/lib/libedit/key.h	Fri Jun 22 16:31:00 2012	(r237447)
> +++ head/lib/libedit/key.h	Fri Jun 22 18:01:22 2012	(r237448)
> @@ -76,8 +76,8 @@ protected int		 key_delete(EditLine *, c
>  protected void		 key_print(EditLine *, const char *);
>  protected void	         key_kprint(EditLine *, const char *, key_value_t *,
>      int);
> -protected int		 key__decode_str(const char *, char *, int,
> +protected size_t	 key__decode_str(const char *, char *, size_t,
>      const char *);
> -protected int		 key__decode_char(char *, int, int, int);
> +protected size_t	 key__decode_char(char *, size_t, size_t, int);
>  
>  #endif /* _h_el_key */
> 
> Modified: head/lib/libedit/prompt.c
> ==============================================================================
> --- head/lib/libedit/prompt.c	Fri Jun 22 16:31:00 2012	(r237447)
> +++ head/lib/libedit/prompt.c	Fri Jun 22 18:01:22 2012	(r237448)
> @@ -85,14 +85,23 @@ prompt_print(EditLine *el, int op)
>  {
>  	el_prompt_t *elp;
>  	char *p;
> +	int ignore = 0;
>  
>  	if (op == EL_PROMPT)
>  		elp = &el->el_prompt;
>  	else
>  		elp = &el->el_rprompt;
> -	p = (elp->p_func) (el);
> -	while (*p)
> -		re_putc(el, *p++, 1);
> +
> +	for (p = (*elp->p_func)(el); *p; p++) {
> +		if (elp->p_ignore == *p) {
> +			ignore = !ignore;
> +			continue;
> +		}
> +		if (ignore)
> +			term__putc(el, *p);
> +		else
> +			re_putc(el, *p, 1);
> +	}
>  
>  	elp->p_pos.v = el->el_refresh.r_cursor.v;
>  	elp->p_pos.h = el->el_refresh.r_cursor.h;
> @@ -109,10 +118,12 @@ prompt_init(EditLine *el)
>  	el->el_prompt.p_func = prompt_default;
>  	el->el_prompt.p_pos.v = 0;
>  	el->el_prompt.p_pos.h = 0;
> +	el->el_prompt.p_ignore = '\0';
>  	el->el_rprompt.p_func = prompt_default_r;
>  	el->el_rprompt.p_pos.v = 0;
>  	el->el_rprompt.p_pos.h = 0;
> -	return (0);
> +	el->el_rprompt.p_ignore = '\0';
> +	return 0;
>  }
>  
>  
> @@ -130,24 +141,29 @@ prompt_end(EditLine *el __unused)
>   *	Install a prompt printing function
>   */
>  protected int
> -prompt_set(EditLine *el, el_pfunc_t prf, int op)
> +prompt_set(EditLine *el, el_pfunc_t prf, char c, int op)
>  {
>  	el_prompt_t *p;
>  
> -	if (op == EL_PROMPT)
> +	if (op == EL_PROMPT || op == EL_PROMPT_ESC)
>  		p = &el->el_prompt;
>  	else
>  		p = &el->el_rprompt;
> +
>  	if (prf == NULL) {
> -		if (op == EL_PROMPT)
> +		if (op == EL_PROMPT || op == EL_PROMPT_ESC)
>  			p->p_func = prompt_default;
>  		else
>  			p->p_func = prompt_default_r;
>  	} else
>  		p->p_func = prf;
> +
> +	p->p_ignore = c;
> +
>  	p->p_pos.v = 0;
>  	p->p_pos.h = 0;
> -	return (0);
> +
> +	return 0;
>  }
>  
>  
> @@ -155,14 +171,22 @@ prompt_set(EditLine *el, el_pfunc_t prf,
>   *	Retrieve the prompt printing function
>   */
>  protected int
> -prompt_get(EditLine *el, el_pfunc_t *prf, int op)
> +prompt_get(EditLine *el, el_pfunc_t *prf, char *c, int op)
>  {
> +	el_prompt_t *p;
>  
>  	if (prf == NULL)
> -		return (-1);
> +		return -1;
> +
>  	if (op == EL_PROMPT)
> -		*prf = el->el_prompt.p_func;
> +		p = &el->el_prompt;
>  	else
> -		*prf = el->el_rprompt.p_func;
> -	return (0);
> +		p = &el->el_rprompt;
> +
> +	*prf = el->el_rprompt.p_func;
> +
> +	if (c)
> +		*c = p->p_ignore;
> +
> +	return 0;
>  }
> 
> Modified: head/lib/libedit/prompt.h
> ==============================================================================
> --- head/lib/libedit/prompt.h	Fri Jun 22 16:31:00 2012	(r237447)
> +++ head/lib/libedit/prompt.h	Fri Jun 22 18:01:22 2012	(r237448)
> @@ -47,11 +47,13 @@ typedef char * (*el_pfunc_t)(EditLine*);
>  typedef struct el_prompt_t {
>  	el_pfunc_t	p_func;	/* Function to return the prompt	*/
>  	coord_t		p_pos;	/* position in the line after prompt	*/
> +	char		p_ignore;	/* character to start/end literal 
> +*/
>  } el_prompt_t;
>  
>  protected void	prompt_print(EditLine *, int);
> -protected int	prompt_set(EditLine *, el_pfunc_t, int);
> -protected int	prompt_get(EditLine *, el_pfunc_t *, int);
> +protected int	prompt_set(EditLine *, el_pfunc_t, char, int);
> +protected int	prompt_get(EditLine *, el_pfunc_t *, char *, int);
>  protected int	prompt_init(EditLine *);
>  protected void	prompt_end(EditLine *);
>  
> 
> Modified: head/lib/libedit/read.c
> ==============================================================================
> --- head/lib/libedit/read.c	Fri Jun 22 16:31:00 2012	(r237447)
> +++ head/lib/libedit/read.c	Fri Jun 22 18:01:22 2012	(r237448)
> @@ -29,7 +29,7 @@
>   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>   * SUCH DAMAGE.
>   *
> - *	$NetBSD: read.c,v 1.40 2007/03/01 21:41:45 christos Exp $
> + *	$NetBSD: read.c,v 1.52 2009/07/22 15:57:00 christos Exp $
>   */
>  
>  #if !defined(lint) && !defined(SCCSID)
> @@ -49,7 +49,7 @@ __FBSDID("$FreeBSD$");
>  #include <stdlib.h>
>  #include "el.h"
>  
> -#define	OKCMD	-1
> +#define	OKCMD	-1	/* must be -1! */
>  
>  private int	read__fixio(int, int);
>  private int	read_preread(EditLine *);
> @@ -170,7 +170,7 @@ read__fixio(int fd __unused, int e)
>  		return (e ? 0 : -1);
>  
>  	case EINTR:
> -		return (0);
> +		return (-1);
>  
>  	default:
>  		return (-1);
> @@ -222,7 +222,7 @@ el_push(EditLine *el, const char *str)
>  		ma->level--;
>  	}
>  	term_beep(el);
> -	term__flush();
> +	term__flush(el);
>  }
>  
>  
> @@ -235,9 +235,12 @@ read_getcmd(EditLine *el, el_action_t *c
>  	el_action_t cmd;
>  	int num;
>  
> +	el->el_errno = 0;
>  	do {
> -		if ((num = el_getc(el, ch)) != 1)	/* if EOF or error */
> +		if ((num = el_getc(el, ch)) != 1) {	/* if EOF or error */
> +			el->el_errno = num == 0 ? 0 : errno;
>  			return (num);
> +		}
>  
>  #ifdef	KANJI
>  		if ((*ch & 0200)) {
> @@ -286,18 +289,25 @@ read_getcmd(EditLine *el, el_action_t *c
>  private int
>  read_char(EditLine *el, char *cp)
>  {
> -	int num_read;
> +	ssize_t num_read;
>  	int tried = 0;
>  
> -	while ((num_read = read(el->el_infd, cp, 1)) == -1)
> + again:
> +	el->el_signal->sig_no = 0;
> +	while ((num_read = read(el->el_infd, cp, 1)) == -1) {
> +		if (el->el_signal->sig_no == SIGCONT) {
> +			sig_set(el);
> +			el_set(el, EL_REFRESH);
> +			goto again;
> +		}
>  		if (!tried && read__fixio(el->el_infd, errno) == 0)
>  			tried = 1;
>  		else {
>  			*cp = '\0';
>  			return (-1);
>  		}
> -
> -	return (num_read);
> +	}
> +	return (int)num_read;
>  }
>  
>  /* read_pop():
> @@ -309,8 +319,9 @@ read_pop(c_macro_t *ma)
>  	int i;
>  
>  	el_free(ma->macro[0]);
> -	for (i = ma->level--; i > 0; i--)
> -		ma->macro[i - 1] = ma->macro[i];
> +	for (i = 0; i < ma->level; i++)
> +		ma->macro[i] = ma->macro[i + 1];
> +	ma->level--;
>  	ma->offset = 0;
>  }
>  
> @@ -323,7 +334,7 @@ el_getc(EditLine *el, char *cp)
>  	int num_read;
>  	c_macro_t *ma = &el->el_chared.c_macro;
>  
> -	term__flush();
> +	term__flush(el);
>  	for (;;) {
>  		if (ma->level < 0) {
>  			if (!read_preread(el))
> @@ -382,7 +393,7 @@ read_prepare(EditLine *el)
>  	re_refresh(el);		/* print the prompt */
>  
>  	if (el->el_flags & UNBUFFERED)
> -		term__flush();
> +		term__flush(el);
>  }
>  
>  protected void
> @@ -402,15 +413,20 @@ el_gets(EditLine *el, int *nread)
>  	int num;		/* how many chars we have read at NL */
>  	char ch;
>  	int crlf = 0;
> +	int nrb;
>  #ifdef FIONREAD
>  	c_macro_t *ma = &el->el_chared.c_macro;
>  #endif /* FIONREAD */
>  
> +	if (nread == NULL)
> +		nread = &nrb;
> +	*nread = 0;
> +
>  	if (el->el_flags & NO_TTY) {
>  		char *cp = el->el_line.buffer;
>  		size_t idx;
>  
> -		while ((*el->el_read.read_char)(el, cp) == 1) {
> +		while ((num = (*el->el_read.read_char)(el, cp)) == 1) {
>  			/* make sure there is space for next character */
>  			if (cp + 1 >= el->el_line.limit) {
>  				idx = (cp - el->el_line.buffer);
> @@ -424,12 +440,16 @@ el_gets(EditLine *el, int *nread)
>  			if (cp[-1] == '\r' || cp[-1] == '\n')
>  				break;
>  		}
> +		if (num == -1) {
> +			if (errno == EINTR)
> +				cp = el->el_line.buffer;
> +			el->el_errno = errno;
> +		}
>  
>  		el->el_line.cursor = el->el_line.lastchar = cp;
>  		*cp = '\0';
> -		if (nread)
> -			*nread = el->el_line.cursor - el->el_line.buffer;
> -		return (el->el_line.buffer);
> +		*nread = (int)(el->el_line.cursor - el->el_line.buffer);
> +		goto done;
>  	}
>  
>  
> @@ -440,8 +460,8 @@ el_gets(EditLine *el, int *nread)
>  		(void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
> 
> *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
> _______________________________________________
> svn-src-all at freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/svn-src-all
> To unsubscribe, send any mail to "svn-src-all-unsubscribe at freebsd.org"

Thanks you for this work !!

regards,
Bapt
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/svn-src-head/attachments/20120622/e6199e97/attachment.pgp


More information about the svn-src-head mailing list