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-...@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/svn-src-all
> To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Thanks you for this work !!

regards,
Bapt

Attachment: pgpZbQ43ojM3Q.pgp
Description: PGP signature

Reply via email to