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
This commit is contained in:
Pedro F. Giffuni 2012-06-22 18:01:22 +00:00
parent 84c4de2d47
commit 8abd4c975c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=237448
20 changed files with 634 additions and 410 deletions

View File

@ -905,7 +905,7 @@ ed_command(EditLine *el, int c __unused)
int tmplen; int tmplen;
tmplen = c_gets(el, tmpbuf, "\n: "); tmplen = c_gets(el, tmpbuf, "\n: ");
term__putc('\n'); term__putc(el, '\n');
if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1) if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
term_beep(el); term_beep(el);

View File

@ -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. .\" Copyright (c) 1997-2003 The NetBSD Foundation, Inc.
.\" All rights reserved. .\" All rights reserved.
@ -28,7 +28,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd January 12, 2007 .Dd July 5, 2009
.Dt EDITLINE 3 .Dt EDITLINE 3
.Os .Os
.Sh NAME .Sh NAME
@ -162,6 +162,14 @@ is modified to contain the number of characters read.
Returns the line read if successful, or Returns the line read if successful, or
.Dv NULL .Dv NULL
if no characters were read or if an error occurred. 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 .It Fn el_getc
Read a character from the tty. Read a character from the tty.
.Fa ch .Fa ch
@ -222,10 +230,30 @@ are supported, along with the required argument list:
Define prompt printing function as Define prompt printing function as
.Fa f , .Fa f ,
which is to return a string that contains the prompt. 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 *)" .It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)"
Define right side prompt printing function as Define right side prompt printing function as
.Fa f , .Fa f ,
which is to return a string that contains the prompt. 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" .It Dv EL_TERMINAL , Fa "const char *type"
Define terminal type of the tty to be Define terminal type of the tty to be
.Fa type , .Fa type ,
@ -259,66 +287,43 @@ reading command input:
and and
.Dv SIGWINCH . .Dv SIGWINCH .
Otherwise, the current signal handlers will be used. Otherwise, the current signal handlers will be used.
.It Dv EL_BIND , Xo .It Dv EL_BIND , Fa "const char *" , Fa "..." , Dv NULL
.Fa "const char *" ,
.Fa "..." ,
.Dv NULL
.Xc
Perform the Perform the
.Ic bind .Ic bind
builtin command. builtin command.
Refer to Refer to
.Xr editrc 5 .Xr editrc 5
for more information. for more information.
.It Dv EL_ECHOTC , Xo .It Dv EL_ECHOTC , Fa "const char *" , Fa "..." , Dv NULL
.Fa "const char *" ,
.Fa "..." ,
.Dv NULL
.Xc
Perform the Perform the
.Ic echotc .Ic echotc
builtin command. builtin command.
Refer to Refer to
.Xr editrc 5 .Xr editrc 5
for more information. for more information.
.It Dv EL_SETTC , Xo .It Dv EL_SETTC , Fa "const char *" , Fa "..." , Dv NULL
.Fa "const char *" ,
.Fa "..." ,
.Dv NULL
.Xc
Perform the Perform the
.Ic settc .Ic settc
builtin command. builtin command.
Refer to Refer to
.Xr editrc 5 .Xr editrc 5
for more information. for more information.
.It Dv EL_SETTY , Xo .It Dv EL_SETTY , Fa "const char *" , Fa "..." , Dv NULL
.Fa "const char *" ,
.Fa "..." ,
.Dv NULL
.Xc
Perform the Perform the
.Ic setty .Ic setty
builtin command. builtin command.
Refer to Refer to
.Xr editrc 5 .Xr editrc 5
for more information. for more information.
.It Dv EL_TELLTC , Xo .It Dv EL_TELLTC , Fa "const char *" , Fa "..." , Dv NULL
.Fa "const char *" ,
.Fa "..." ,
.Dv NULL
.Xc
Perform the Perform the
.Ic telltc .Ic telltc
builtin command. builtin command.
Refer to Refer to
.Xr editrc 5 .Xr editrc 5
for more information. for more information.
.It Dv EL_ADDFN , Xo .It Dv EL_ADDFN , Fa "const char *name" , Fa "const char *help" , \
.Fa "const char *name" , Fa "unsigned char (*func)(EditLine *e, int ch)"
.Fa "const char *help" ,
.Fa "unsigned char (*func)(EditLine *e, int ch)"
.Xc
Add a user defined function, Add a user defined function,
.Fn func , .Fn func ,
referred to as referred to as
@ -360,10 +365,8 @@ Beep, and flush tty.
.It Dv CC_FATAL .It Dv CC_FATAL
Fatal error, reset tty to known state. Fatal error, reset tty to known state.
.El .El
.It Dv EL_HIST , Xo .It Dv EL_HIST , Fa "History *(*func)(History *, int op, ...)" , \
.Fa "History *(*func)(History *, int op, ...)" , Fa "const char *ptr"
.Fa "const char *ptr"
.Xc
Defines which history function to use, which is usually Defines which history function to use, which is usually
.Fn history . .Fn history .
.Fa ptr .Fa ptr
@ -435,10 +438,22 @@ The following values for
are supported, along with actual type of are supported, along with actual type of
.Fa result : .Fa result :
.Bl -tag -width 4n .Bl -tag -width 4n
.It Dv EL_PROMPT , Fa "char *(*f)(EditLine *)" .It Dv EL_PROMPT , Fa "char *(*f)(EditLine *)" , Fa "char *c"
Return a pointer to the function that displays the prompt. Return a pointer to the function that displays the prompt in
.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)" .Fa f .
Return a pointer to the function that displays the rightside prompt. 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 *" .It Dv EL_EDITOR , Fa "const char *"
Return the name of the editor, which will be one of Return the name of the editor, which will be one of
.Dq emacs .Dq emacs
@ -603,18 +618,11 @@ assumed to be created with
.Fn history_init . .Fn history_init .
.It Dv H_CLEAR .It Dv H_CLEAR
Clear the history. Clear the history.
.It Dv H_FUNC , Xo .It Dv H_FUNC , Fa "void *ptr" , Fa "history_gfun_t first" , \
.Fa "void *ptr" , Fa "history_gfun_t next" , Fa "history_gfun_t last" , \
.Fa "history_gfun_t first" , Fa "history_gfun_t prev" , Fa "history_gfun_t curr" , \
.Fa "history_gfun_t next" , Fa "history_sfun_t set" , Fa "history_vfun_t clear" , \
.Fa "history_gfun_t last" , Fa "history_efun_t enter" , Fa "history_efun_t add"
.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
Define functions to perform various history operations. Define functions to perform various history operations.
.Fa ptr .Fa ptr
is the argument given to a function when it is invoked. is the argument given to a function when it is invoked.

View File

@ -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. .\" Copyright (c) 1997-2000 The NetBSD Foundation, Inc.
.\" All rights reserved. .\" All rights reserved.
@ -89,16 +89,8 @@ shell.
.Pp .Pp
The following builtin commands are available: The following builtin commands are available:
.Bl -tag -width 4n .Bl -tag -width 4n
.It Ic bind Xo .It Ic bind Oo Fl a Oc Oo Fl e Oc Oo Fl k Oc Oo Fl l Oc Oo Fl r Oc \
.Op Fl a Oo Fl s Oc Oo Fl v Oc Oo Ar key Op Ar command Oc
.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
Without options, list all bound keys, and the editor command to which Without options, list all bound keys, and the editor command to which
each is bound. each is bound.
If If
@ -192,11 +184,7 @@ if it has any, notably
.Sq \e .Sq \e
and and
.Sq ^ . .Sq ^ .
.It Ic echotc Xo .It Ic echotc Oo Fl sv Oc Ar arg Ar ...
.Op Fl sv
.Ar arg
.Ar ...
.Xc
Exercise terminal capabilities given in Exercise terminal capabilities given in
.Ar arg Ar ... . .Ar arg Ar ... .
If If
@ -252,16 +240,8 @@ to
as defined in as defined in
.Xr termcap 5 . .Xr termcap 5 .
No sanity checking is done. No sanity checking is done.
.It Ic setty Xo .It Ic setty Oo Fl a Oc Oo Fl d Oc Oo Fl q Oc Oo Fl x Oc Oo Ar +mode Oc \
.Op Fl a Oo Ar -mode Oc Oo Ar mode Oc Oo Ar char=c Oc
.Op Fl d
.Op Fl q
.Op Fl x
.Op Ar +mode
.Op Ar -mode
.Op Ar mode
.Op Ar char=c
.Xc
Control which tty modes that Control which tty modes that
.Nm .Nm
will not allow the user to change. will not allow the user to change.

View File

@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * 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) #if !defined(lint) && !defined(SCCSID)
@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#include <ctype.h>
#include "el.h" #include "el.h"
#define HAVE_ISSETUGID #define HAVE_ISSETUGID
@ -156,9 +157,21 @@ el_set(EditLine *el, int op, ...)
switch (op) { switch (op) {
case EL_PROMPT: case EL_PROMPT:
case EL_RPROMPT: case EL_RPROMPT: {
rv = prompt_set(el, va_arg(ap, el_pfunc_t), op); el_pfunc_t p = va_arg(ap, el_pfunc_t);
rv = prompt_set(el, p, 0, op);
break; 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: case EL_TERMINAL:
rv = term_set(el, va_arg(ap, char *)); rv = term_set(el, va_arg(ap, char *));
@ -309,6 +322,12 @@ el_set(EditLine *el, int op, ...)
break; break;
} }
case EL_REFRESH:
re_clear_display(el);
re_refresh(el);
term__flush(el);
break;
default: default:
rv = -1; rv = -1;
break; break;
@ -335,9 +354,13 @@ el_get(EditLine *el, int op, ...)
switch (op) { switch (op) {
case EL_PROMPT: case EL_PROMPT:
case EL_RPROMPT: case EL_RPROMPT: {
rv = prompt_get(el, va_arg(ap, el_pfunc_t *), op); el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
char *c = va_arg(ap, char *);
rv = prompt_get(el, p, c, op);
break; break;
}
case EL_EDITOR: case EL_EDITOR:
rv = map_get_editor(el, va_arg(ap, const char **)); rv = map_get_editor(el, va_arg(ap, const char **));
@ -364,7 +387,7 @@ el_get(EditLine *el, int op, ...)
char *argv[20]; char *argv[20];
int i; 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) if ((argv[i] = va_arg(ap, char *)) == NULL)
break; break;
@ -495,12 +518,14 @@ el_source(EditLine *el, const char *fname)
FILE *fp; FILE *fp;
size_t len; size_t len;
char *ptr; char *ptr;
#ifdef HAVE_ISSETUGID
char path[MAXPATHLEN];
#endif
fp = NULL; fp = NULL;
if (fname == NULL) { if (fname == NULL) {
#ifdef HAVE_ISSETUGID #ifdef HAVE_ISSETUGID
static const char elpath[] = "/.editrc"; static const char elpath[] = "/.editrc";
char path[MAXPATHLEN];
if (issetugid()) if (issetugid())
return (-1); return (-1);
@ -529,6 +554,13 @@ el_source(EditLine *el, const char *fname)
if (len > 0 && ptr[len - 1] == '\n') if (len > 0 && ptr[len - 1] == '\n')
--len; --len;
ptr[len] = '\0'; 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) { if (parse_line(el, ptr) == -1) {
(void) fclose(fp); (void) fclose(fp);
return (-1); return (-1);

View File

@ -115,6 +115,7 @@ struct editline {
FILE *el_errfile; /* Stdio stuff */ FILE *el_errfile; /* Stdio stuff */
int el_infd; /* Input file descriptor */ int el_infd; /* Input file descriptor */
int el_flags; /* Various flags. */ int el_flags; /* Various flags. */
int el_errno; /* Local copy of errno */
coord_t el_cursor; /* Cursor location */ coord_t el_cursor; /* Cursor location */
char **el_display; /* Real screen image = what is there */ char **el_display; /* Real screen image = what is there */
char **el_vdisplay; /* Virtual screen image = what we see */ char **el_vdisplay; /* Virtual screen image = what we see */

View File

@ -133,8 +133,8 @@ unsigned char _el_fn_sh_complete(EditLine *, int);
#define EL_UNBUFFERED 15 /* , int); */ #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_GETTC 17 /* , const char *, ..., NULL); */
#define EL_GETFP 18 /* , int, FILE **) */ #define EL_GETFP 18 /* , int, FILE **); */
#define EL_SETFP 19 /* , int, FILE *) */ #define EL_SETFP 19 /* , int, FILE *); */
#define EL_REFRESH 20 /* , void); set */ #define EL_REFRESH 20 /* , void); set */
#define EL_PROMPT_ESC 21 /* , prompt_func, Char); set/get */ #define EL_PROMPT_ESC 21 /* , prompt_func, Char); set/get */
#define EL_RPROMPT_ESC 22 /* , prompt_func, Char); set/get */ #define EL_RPROMPT_ESC 22 /* , prompt_func, Char); set/get */

View File

@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * 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) #if !defined(lint) && !defined(SCCSID)
@ -116,6 +116,7 @@ private int history_prev_string(History *, HistEvent *, const char *);
*/ */
typedef struct hentry_t { typedef struct hentry_t {
HistEvent ev; /* What we return */ HistEvent ev; /* What we return */
void *data; /* data */
struct hentry_t *next; /* Next entry */ struct hentry_t *next; /* Next entry */
struct hentry_t *prev; /* Previous entry */ struct hentry_t *prev; /* Previous entry */
} hentry_t; } hentry_t;
@ -145,6 +146,9 @@ private int history_def_init(ptr_t *, HistEvent *, int);
private int history_def_insert(history_t *, HistEvent *, const char *); private int history_def_insert(history_t *, HistEvent *, const char *);
private void history_def_delete(history_t *, HistEvent *, hentry_t *); 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_setsize(p, num)(void) (((history_t *)p)->max = (num))
#define history_def_getsize(p) (((history_t *)p)->cur) #define history_def_getsize(p) (((history_t *)p)->cur)
#define history_def_getunique(p) (((((history_t *)p)->flags) & H_UNIQUE) != 0) #define history_def_getunique(p) (((((history_t *)p)->flags) & H_UNIQUE) != 0)
@ -335,6 +339,31 @@ history_def_set(ptr_t p, HistEvent *ev, const int n)
} }
/* 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(): /* history_def_add():
* Append string to element * Append string to element
*/ */
@ -363,6 +392,24 @@ history_def_add(ptr_t p, HistEvent *ev, const char *str)
} }
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(): /* history_def_del():
* Delete element hp of the h list * Delete element hp of the h list
*/ */
@ -392,8 +439,11 @@ history_def_delete(history_t *h,
HistEventPrivate *evp = (void *)&hp->ev; HistEventPrivate *evp = (void *)&hp->ev;
if (hp == &h->list) if (hp == &h->list)
abort(); abort();
if (h->cursor == hp) if (h->cursor == hp) {
h->cursor = hp->prev; h->cursor = hp->prev;
if (h->cursor == &h->list)
h->cursor = hp->next;
}
hp->prev->next = hp->next; hp->prev->next = hp->next;
hp->next->prev = hp->prev; hp->next->prev = hp->prev;
h_free((ptr_t) evp->str); h_free((ptr_t) evp->str);
@ -416,6 +466,7 @@ history_def_insert(history_t *h, HistEvent *ev, const char *str)
h_free((ptr_t)h->cursor); h_free((ptr_t)h->cursor);
goto oomem; goto oomem;
} }
h->cursor->data = NULL;
h->cursor->ev.num = ++h->eventid; h->cursor->ev.num = ++h->eventid;
h->cursor->next = h->list.next; h->cursor->next = h->list.next;
h->cursor->prev = &h->list; h->cursor->prev = &h->list;
@ -711,8 +762,8 @@ history_load(History *h, const char *fname)
(void) strunvis(ptr, line); (void) strunvis(ptr, line);
line[sz] = c; line[sz] = c;
if (HENTER(h, &ev, ptr) == -1) { if (HENTER(h, &ev, ptr) == -1) {
h_free((ptr_t)ptr); i = -1;
return -1; goto oomem;
} }
} }
oomem: oomem:
@ -787,6 +838,23 @@ history_prev_event(History *h, HistEvent *ev, int num)
} }
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(): /* history_next_event():
* Find the next event, with number given * Find the next event, with number given
*/ */
@ -976,11 +1044,42 @@ history(History *h, HistEvent *ev, int fun, ...)
retval = 0; retval = 0;
break; 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: default:
retval = -1; retval = -1;
he_seterrev(ev, _HE_UNKNOWN); he_seterrev(ev, _HE_UNKNOWN);
break; break;
} }
va_end(va); va_end(va);
return (retval); return retval;
} }

View File

@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * 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) #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 void node__put(EditLine *, key_node_t *);
private int node__delete(EditLine *, key_node_t **, const char *); private int node__delete(EditLine *, key_node_t **, const char *);
private int node_lookup(EditLine *, const char *, key_node_t *, private int node_lookup(EditLine *, const char *, key_node_t *,
int); size_t);
private int node_enum(EditLine *, key_node_t *, int); private int node_enum(EditLine *, key_node_t *, size_t);
#define KEY_BUFSIZ EL_BUFSIZ #define KEY_BUFSIZ EL_BUFSIZ
@ -478,9 +478,9 @@ node__free(key_node_t *k)
* Print if last node * Print if last node
*/ */
private int 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) if (ptr == NULL)
return (-1); /* cannot have null ptr */ return (-1); /* cannot have null ptr */
@ -493,7 +493,8 @@ node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt)
/* If match put this char into el->el_key.buf. Recurse */ /* If match put this char into el->el_key.buf. Recurse */
if (ptr->ch == *str) { if (ptr->ch == *str) {
/* match found */ /* 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); (unsigned char) ptr->ch);
if (ptr->next != NULL) if (ptr->next != NULL)
/* not yet at leaf */ /* not yet at leaf */
@ -527,9 +528,9 @@ node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt)
* Traverse the node printing the characters it is bound in buffer * Traverse the node printing the characters it is bound in buffer
*/ */
private int 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 */ if (cnt >= KEY_BUFSIZ - 5) { /* buffer too small */
el->el_key.buf[++cnt] = '"'; el->el_key.buf[++cnt] = '"';
@ -547,7 +548,7 @@ node_enum(EditLine *el, key_node_t *ptr, int cnt)
return (-1); return (-1);
} }
/* put this char at end of str */ /* 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); (unsigned char)ptr->ch);
if (ptr->next == NULL) { if (ptr->next == NULL) {
/* print this key and function */ /* print this key and function */
@ -615,8 +616,8 @@ key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
/* key__decode_char(): /* key__decode_char():
* Put a printable form of char in buf. * Put a printable form of char in buf.
*/ */
protected int protected size_t
key__decode_char(char *buf, int cnt, int off, int ch) key__decode_char(char *buf, size_t cnt, size_t off, int ch)
{ {
char *sb = buf + off; char *sb = buf + off;
char *eb = buf + cnt; char *eb = buf + cnt;
@ -626,7 +627,7 @@ key__decode_char(char *buf, int cnt, int off, int ch)
if (ch == 0) { if (ch == 0) {
ADDC('^'); ADDC('^');
ADDC('@'); ADDC('@');
return b - sb; return (int)(b - sb);
} }
if (iscntrl(ch)) { if (iscntrl(ch)) {
ADDC('^'); ADDC('^');
@ -648,15 +649,15 @@ key__decode_char(char *buf, int cnt, int off, int ch)
ADDC((((unsigned int) ch >> 3) & 7) + '0'); ADDC((((unsigned int) ch >> 3) & 7) + '0');
ADDC((ch & 7) + '0'); ADDC((ch & 7) + '0');
} }
return b - sb; return (size_t)(b - sb);
} }
/* key__decode_str(): /* key__decode_str():
* Make a printable version of the ey * Make a printable version of the ey
*/ */
protected int protected size_t
key__decode_str(const char *str, char *buf, int len, const char *sep) key__decode_str(const char *str, char *buf, size_t len, const char *sep)
{ {
char *b = buf, *eb = b + len; char *b = buf, *eb = b + len;
const char *p; const char *p;
@ -699,7 +700,7 @@ key__decode_str(const char *str, char *buf, int len, const char *sep)
} }
done: done:
ADDC('\0'); ADDC('\0');
if (b - buf >= len) if ((size_t)(b - buf) >= len)
buf[len - 1] = '\0'; buf[len - 1] = '\0';
return b - buf; return (size_t)(b - buf);
} }

View File

@ -76,8 +76,8 @@ protected int key_delete(EditLine *, const char *);
protected void key_print(EditLine *, const char *); protected void key_print(EditLine *, const char *);
protected void key_kprint(EditLine *, const char *, key_value_t *, protected void key_kprint(EditLine *, const char *, key_value_t *,
int); int);
protected int key__decode_str(const char *, char *, int, protected size_t key__decode_str(const char *, char *, size_t,
const char *); 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 */ #endif /* _h_el_key */

View File

@ -85,14 +85,23 @@ prompt_print(EditLine *el, int op)
{ {
el_prompt_t *elp; el_prompt_t *elp;
char *p; char *p;
int ignore = 0;
if (op == EL_PROMPT) if (op == EL_PROMPT)
elp = &el->el_prompt; elp = &el->el_prompt;
else else
elp = &el->el_rprompt; elp = &el->el_rprompt;
p = (elp->p_func) (el);
while (*p) for (p = (*elp->p_func)(el); *p; p++) {
re_putc(el, *p++, 1); 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.v = el->el_refresh.r_cursor.v;
elp->p_pos.h = el->el_refresh.r_cursor.h; 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_func = prompt_default;
el->el_prompt.p_pos.v = 0; el->el_prompt.p_pos.v = 0;
el->el_prompt.p_pos.h = 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_func = prompt_default_r;
el->el_rprompt.p_pos.v = 0; el->el_rprompt.p_pos.v = 0;
el->el_rprompt.p_pos.h = 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 * Install a prompt printing function
*/ */
protected int 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; el_prompt_t *p;
if (op == EL_PROMPT) if (op == EL_PROMPT || op == EL_PROMPT_ESC)
p = &el->el_prompt; p = &el->el_prompt;
else else
p = &el->el_rprompt; p = &el->el_rprompt;
if (prf == NULL) { if (prf == NULL) {
if (op == EL_PROMPT) if (op == EL_PROMPT || op == EL_PROMPT_ESC)
p->p_func = prompt_default; p->p_func = prompt_default;
else else
p->p_func = prompt_default_r; p->p_func = prompt_default_r;
} else } else
p->p_func = prf; p->p_func = prf;
p->p_ignore = c;
p->p_pos.v = 0; p->p_pos.v = 0;
p->p_pos.h = 0; p->p_pos.h = 0;
return (0);
return 0;
} }
@ -155,14 +171,22 @@ prompt_set(EditLine *el, el_pfunc_t prf, int op)
* Retrieve the prompt printing function * Retrieve the prompt printing function
*/ */
protected int 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) if (prf == NULL)
return (-1); return -1;
if (op == EL_PROMPT) if (op == EL_PROMPT)
*prf = el->el_prompt.p_func; p = &el->el_prompt;
else else
p = &el->el_rprompt;
*prf = el->el_rprompt.p_func; *prf = el->el_rprompt.p_func;
return (0);
if (c)
*c = p->p_ignore;
return 0;
} }

View File

@ -47,11 +47,13 @@ typedef char * (*el_pfunc_t)(EditLine*);
typedef struct el_prompt_t { typedef struct el_prompt_t {
el_pfunc_t p_func; /* Function to return the prompt */ el_pfunc_t p_func; /* Function to return the prompt */
coord_t p_pos; /* position in the line after prompt */ coord_t p_pos; /* position in the line after prompt */
char p_ignore; /* character to start/end literal
*/
} el_prompt_t; } el_prompt_t;
protected void prompt_print(EditLine *, int); protected void prompt_print(EditLine *, int);
protected int prompt_set(EditLine *, el_pfunc_t, int); protected int prompt_set(EditLine *, el_pfunc_t, char, int);
protected int prompt_get(EditLine *, el_pfunc_t *, int); protected int prompt_get(EditLine *, el_pfunc_t *, char *, int);
protected int prompt_init(EditLine *); protected int prompt_init(EditLine *);
protected void prompt_end(EditLine *); protected void prompt_end(EditLine *);

View File

@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * 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) #if !defined(lint) && !defined(SCCSID)
@ -49,7 +49,7 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h> #include <stdlib.h>
#include "el.h" #include "el.h"
#define OKCMD -1 #define OKCMD -1 /* must be -1! */
private int read__fixio(int, int); private int read__fixio(int, int);
private int read_preread(EditLine *); private int read_preread(EditLine *);
@ -170,7 +170,7 @@ read__fixio(int fd __unused, int e)
return (e ? 0 : -1); return (e ? 0 : -1);
case EINTR: case EINTR:
return (0); return (-1);
default: default:
return (-1); return (-1);
@ -222,7 +222,7 @@ el_push(EditLine *el, const char *str)
ma->level--; ma->level--;
} }
term_beep(el); term_beep(el);
term__flush(); term__flush(el);
} }
@ -235,9 +235,12 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
el_action_t cmd; el_action_t cmd;
int num; int num;
el->el_errno = 0;
do { 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); return (num);
}
#ifdef KANJI #ifdef KANJI
if ((*ch & 0200)) { if ((*ch & 0200)) {
@ -286,18 +289,25 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
private int private int
read_char(EditLine *el, char *cp) read_char(EditLine *el, char *cp)
{ {
int num_read; ssize_t num_read;
int tried = 0; 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) if (!tried && read__fixio(el->el_infd, errno) == 0)
tried = 1; tried = 1;
else { else {
*cp = '\0'; *cp = '\0';
return (-1); return (-1);
} }
}
return (num_read); return (int)num_read;
} }
/* read_pop(): /* read_pop():
@ -309,8 +319,9 @@ read_pop(c_macro_t *ma)
int i; int i;
el_free(ma->macro[0]); el_free(ma->macro[0]);
for (i = ma->level--; i > 0; i--) for (i = 0; i < ma->level; i++)
ma->macro[i - 1] = ma->macro[i]; ma->macro[i] = ma->macro[i + 1];
ma->level--;
ma->offset = 0; ma->offset = 0;
} }
@ -323,7 +334,7 @@ el_getc(EditLine *el, char *cp)
int num_read; int num_read;
c_macro_t *ma = &el->el_chared.c_macro; c_macro_t *ma = &el->el_chared.c_macro;
term__flush(); term__flush(el);
for (;;) { for (;;) {
if (ma->level < 0) { if (ma->level < 0) {
if (!read_preread(el)) if (!read_preread(el))
@ -382,7 +393,7 @@ read_prepare(EditLine *el)
re_refresh(el); /* print the prompt */ re_refresh(el); /* print the prompt */
if (el->el_flags & UNBUFFERED) if (el->el_flags & UNBUFFERED)
term__flush(); term__flush(el);
} }
protected void protected void
@ -402,15 +413,20 @@ el_gets(EditLine *el, int *nread)
int num; /* how many chars we have read at NL */ int num; /* how many chars we have read at NL */
char ch; char ch;
int crlf = 0; int crlf = 0;
int nrb;
#ifdef FIONREAD #ifdef FIONREAD
c_macro_t *ma = &el->el_chared.c_macro; c_macro_t *ma = &el->el_chared.c_macro;
#endif /* FIONREAD */ #endif /* FIONREAD */
if (nread == NULL)
nread = &nrb;
*nread = 0;
if (el->el_flags & NO_TTY) { if (el->el_flags & NO_TTY) {
char *cp = el->el_line.buffer; char *cp = el->el_line.buffer;
size_t idx; 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 */ /* make sure there is space for next character */
if (cp + 1 >= el->el_line.limit) { if (cp + 1 >= el->el_line.limit) {
idx = (cp - el->el_line.buffer); idx = (cp - el->el_line.buffer);
@ -424,12 +440,16 @@ el_gets(EditLine *el, int *nread)
if (cp[-1] == '\r' || cp[-1] == '\n') if (cp[-1] == '\r' || cp[-1] == '\n')
break; 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; el->el_line.cursor = el->el_line.lastchar = cp;
*cp = '\0'; *cp = '\0';
if (nread) *nread = (int)(el->el_line.cursor - el->el_line.buffer);
*nread = el->el_line.cursor - el->el_line.buffer; goto done;
return (el->el_line.buffer);
} }
@ -440,7 +460,7 @@ el_gets(EditLine *el, int *nread)
(void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs); (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
if (chrs == 0) { if (chrs == 0) {
if (tty_rawmode(el) < 0) { if (tty_rawmode(el) < 0) {
if (nread) errno = 0;
*nread = 0; *nread = 0;
return (NULL); return (NULL);
} }
@ -454,14 +474,15 @@ el_gets(EditLine *el, int *nread)
if (el->el_flags & EDIT_DISABLED) { if (el->el_flags & EDIT_DISABLED) {
char *cp; char *cp;
size_t idx; size_t idx;
if ((el->el_flags & UNBUFFERED) == 0) if ((el->el_flags & UNBUFFERED) == 0)
cp = el->el_line.buffer; cp = el->el_line.buffer;
else else
cp = el->el_line.lastchar; cp = el->el_line.lastchar;
term__flush(); term__flush(el);
while ((*el->el_read.read_char)(el, cp) == 1) { while ((num = (*el->el_read.read_char)(el, cp)) == 1) {
/* make sure there is space next character */ /* make sure there is space next character */
if (cp + 1 >= el->el_line.limit) { if (cp + 1 >= el->el_line.limit) {
idx = (cp - el->el_line.buffer); idx = (cp - el->el_line.buffer);
@ -469,8 +490,6 @@ el_gets(EditLine *el, int *nread)
break; break;
cp = &el->el_line.buffer[idx]; cp = &el->el_line.buffer[idx];
} }
if (*cp == 4) /* ought to be stty eof */
break;
cp++; cp++;
crlf = cp[-1] == '\r' || cp[-1] == '\n'; crlf = cp[-1] == '\r' || cp[-1] == '\n';
if (el->el_flags & UNBUFFERED) if (el->el_flags & UNBUFFERED)
@ -479,11 +498,15 @@ el_gets(EditLine *el, int *nread)
break; 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; el->el_line.cursor = el->el_line.lastchar = cp;
*cp = '\0'; *cp = '\0';
if (nread) goto done;
*nread = el->el_line.cursor - el->el_line.buffer;
return (el->el_line.buffer);
} }
for (num = OKCMD; num == OKCMD;) { /* while still editing this for (num = OKCMD; num == OKCMD;) { /* while still editing this
@ -499,7 +522,13 @@ el_gets(EditLine *el, int *nread)
#endif /* DEBUG_READ */ #endif /* DEBUG_READ */
break; break;
} }
if ((unsigned int)cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */ if (el->el_errno == EINTR) {
el->el_line.buffer[0] = '\0';
el->el_line.lastchar =
el->el_line.cursor = el->el_line.buffer;
break;
}
if ((unsigned int)cmdnum >= (unsigned int)el->el_map.nfunc) { /* BUG CHECK command */
#ifdef DEBUG_EDIT #ifdef DEBUG_EDIT
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
"ERROR: illegal command from key 0%o\r\n", ch); "ERROR: illegal command from key 0%o\r\n", ch);
@ -581,7 +610,7 @@ el_gets(EditLine *el, int *nread)
break; break;
case CC_NEWLINE: /* normal end of line */ case CC_NEWLINE: /* normal end of line */
num = el->el_line.lastchar - el->el_line.buffer; num = (int)(el->el_line.lastchar - el->el_line.buffer);
break; break;
case CC_FATAL: /* fatal error, reset to known state */ case CC_FATAL: /* fatal error, reset to known state */
@ -602,7 +631,7 @@ el_gets(EditLine *el, int *nread)
"*** editor ERROR ***\r\n\n"); "*** editor ERROR ***\r\n\n");
#endif /* DEBUG_READ */ #endif /* DEBUG_READ */
term_beep(el); term_beep(el);
term__flush(); term__flush(el);
break; break;
} }
el->el_state.argument = 1; el->el_state.argument = 1;
@ -612,15 +641,21 @@ el_gets(EditLine *el, int *nread)
break; break;
} }
term__flush(); /* flush any buffered output */ term__flush(el); /* flush any buffered output */
/* make sure the tty is set up correctly */ /* make sure the tty is set up correctly */
if ((el->el_flags & UNBUFFERED) == 0) { if ((el->el_flags & UNBUFFERED) == 0) {
read_finish(el); read_finish(el);
if (nread) *nread = num != -1 ? num : 0;
*nread = num;
} else { } else {
if (nread) *nread = (int)(el->el_line.lastchar - el->el_line.buffer);
*nread = el->el_line.lastchar - el->el_line.buffer;
} }
return (num ? el->el_line.buffer : NULL); done:
if (*nread == 0) {
if (num == -1) {
*nread = -1;
errno = el->el_errno;
}
return NULL;
} else
return el->el_line.buffer;
} }

View File

@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $NetBSD: refresh.c,v 1.27 2005/11/09 22:11:10 christos Exp $ * $NetBSD: refresh.c,v 1.34 2009/12/28 22:15:36 christos Exp $
*/ */
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
#include "el.h" #include "el.h"
private void re_nextline(EditLine *);
private void re_addc(EditLine *, int); private void re_addc(EditLine *, int);
private void re_update_line(EditLine *, char *, char *, int); private void re_update_line(EditLine *, char *, char *, int);
private void re_insert (EditLine *, char *, int, int, char *, int); private void re_insert (EditLine *, char *, int, int, char *, int);
@ -86,6 +87,37 @@ re_printstr(EditLine *el, const char *str, char *f, char *t)
#define ELRE_DEBUG(a, b) #define ELRE_DEBUG(a, b)
#endif #endif
/* re_nextline():
* Move to the next line or scroll
*/
private void
re_nextline(EditLine *el)
{
el->el_refresh.r_cursor.h = 0; /* reset it. */
/*
* If we would overflow (input is longer than terminal size),
* emulate scroll by dropping first line and shuffling the rest.
* We do this via pointer shuffling - it's safe in this case
* and we avoid memcpy().
*/
if (el->el_refresh.r_cursor.v + 1 >= el->el_term.t_size.v) {
int i, lins = el->el_term.t_size.v;
char *firstline = el->el_vdisplay[0];
for(i = 1; i < lins; i++)
el->el_vdisplay[i - 1] = el->el_vdisplay[i];
firstline[0] = '\0'; /* empty the string */
el->el_vdisplay[i - 1] = firstline;
} else
el->el_refresh.r_cursor.v++;
ELRE_ASSERT(el->el_refresh.r_cursor.v >= el->el_term.t_size.v,
(__F, "\r\nre_putc: overflow! r_cursor.v == %d > %d\r\n",
el->el_refresh.r_cursor.v, el->el_term.t_size.v),
abort());
}
/* re_addc(): /* re_addc():
* Draw c, expanding tabs, control chars etc. * Draw c, expanding tabs, control chars etc.
@ -101,10 +133,8 @@ re_addc(EditLine *el, int c)
if (c == '\n') { /* expand the newline */ if (c == '\n') { /* expand the newline */
int oldv = el->el_refresh.r_cursor.v; int oldv = el->el_refresh.r_cursor.v;
re_putc(el, '\0', 0); /* assure end of line */ re_putc(el, '\0', 0); /* assure end of line */
if (oldv == el->el_refresh.r_cursor.v) { /* XXX */ if (oldv == el->el_refresh.r_cursor.v) /* XXX */
el->el_refresh.r_cursor.h = 0; /* reset cursor pos */ re_nextline(el);
el->el_refresh.r_cursor.v++;
}
return; return;
} }
if (c == '\t') { /* expand the tab */ if (c == '\t') { /* expand the tab */
@ -144,33 +174,12 @@ re_putc(EditLine *el, int c, int shift)
el->el_refresh.r_cursor.h++; /* advance to next place */ el->el_refresh.r_cursor.h++; /* advance to next place */
if (el->el_refresh.r_cursor.h >= el->el_term.t_size.h) { if (el->el_refresh.r_cursor.h >= el->el_term.t_size.h) {
el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_term.t_size.h] = '\0';
/* assure end of line */ /* assure end of line */
el->el_refresh.r_cursor.h = 0; /* reset it. */ el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_term.t_size.h]
= '\0';
/* re_nextline(el);
* If we would overflow (input is longer than terminal size),
* emulate scroll by dropping first line and shuffling the rest.
* We do this via pointer shuffling - it's safe in this case
* and we avoid memcpy().
*/
if (el->el_refresh.r_cursor.v + 1 >= el->el_term.t_size.v) {
int i, lins = el->el_term.t_size.v;
char *firstline = el->el_vdisplay[0];
for(i=1; i < lins; i++)
el->el_vdisplay[i-1] = el->el_vdisplay[i];
firstline[0] = '\0'; /* empty the string */
el->el_vdisplay[i-1] = firstline;
} else
el->el_refresh.r_cursor.v++;
ELRE_ASSERT(el->el_refresh.r_cursor.v >= el->el_term.t_size.v,
(__F, "\r\nre_putc: overflow! r_cursor.v == %d > %d\r\n",
el->el_refresh.r_cursor.v, el->el_term.t_size.v),
abort());
} }
} }
@ -298,7 +307,7 @@ re_refresh(EditLine *el)
term_move_to_char(el, 0); term_move_to_char(el, 0);
term_clear_EOL(el, (int) strlen(el->el_display[i])); term_clear_EOL(el, (int) strlen(el->el_display[i]));
#ifdef DEBUG_REFRESH #ifdef DEBUG_REFRESH
term_overwrite(el, "C\b", 2); term_overwrite(el, "C\b", (size_t)2);
#endif /* DEBUG_REFRESH */ #endif /* DEBUG_REFRESH */
el->el_display[i][0] = '\0'; el->el_display[i][0] = '\0';
} }
@ -321,9 +330,9 @@ re_goto_bottom(EditLine *el)
{ {
term_move_to_line(el, el->el_refresh.r_oldcv); term_move_to_line(el, el->el_refresh.r_oldcv);
term__putc('\n'); term__putc(el, '\n');
re_clear_display(el); re_clear_display(el);
term__flush(); term__flush(el);
} }
@ -475,6 +484,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
char *ofd, *ols, *oe, *nfd, *nls, *ne; char *ofd, *ols, *oe, *nfd, *nls, *ne;
char *osb, *ose, *nsb, *nse; char *osb, *ose, *nsb, *nse;
int fx, sx; int fx, sx;
size_t len;
/* /*
* find first diff * find first diff
@ -601,12 +611,12 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* fx is the number of characters we need to insert/delete: in the * fx is the number of characters we need to insert/delete: in the
* beginning to bring the two same begins together * beginning to bring the two same begins together
*/ */
fx = (nsb - nfd) - (osb - ofd); fx = (int)((nsb - nfd) - (osb - ofd));
/* /*
* sx is the number of characters we need to insert/delete: in the * sx is the number of characters we need to insert/delete: in the
* end to bring the two same last parts together * end to bring the two same last parts together
*/ */
sx = (nls - nse) - (ols - ose); sx = (int)((nls - nse) - (ols - ose));
if (!EL_CAN_INSERT) { if (!EL_CAN_INSERT) {
if (fx > 0) { if (fx > 0) {
@ -655,8 +665,8 @@ re_update_line(EditLine *el, char *old, char *new, int i)
/* /*
* Now that we are done with pragmatics we recompute fx, sx * Now that we are done with pragmatics we recompute fx, sx
*/ */
fx = (nsb - nfd) - (osb - ofd); fx = (int)((nsb - nfd) - (osb - ofd));
sx = (nls - nse) - (ols - ose); sx = (int)((nls - nse) - (ols - ose));
ELRE_DEBUG(1, (__F, "fx %d, sx %d\n", fx, sx)); ELRE_DEBUG(1, (__F, "fx %d, sx %d\n", fx, sx));
ELRE_DEBUG(1, (__F, "ofd %d, osb %d, ose %d, ols %d, oe %d\n", ELRE_DEBUG(1, (__F, "ofd %d, osb %d, ose %d, ols %d, oe %d\n",
@ -739,7 +749,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
/* /*
* Move to the first char to insert, where the first diff is. * Move to the first char to insert, where the first diff is.
*/ */
term_move_to_char(el, nfd - new); term_move_to_char(el, (int)(nfd - new));
/* /*
* Check if we have stuff to keep at end * Check if we have stuff to keep at end
*/ */
@ -752,20 +762,21 @@ re_update_line(EditLine *el, char *old, char *new, int i)
ELRE_DEBUG(!EL_CAN_INSERT, (__F, ELRE_DEBUG(!EL_CAN_INSERT, (__F,
"ERROR: cannot insert in early first diff\n")); "ERROR: cannot insert in early first diff\n"));
term_insertwrite(el, nfd, fx); term_insertwrite(el, nfd, fx);
re_insert(el, old, ofd - old, re_insert(el, old, (int)(ofd - old),
el->el_term.t_size.h, nfd, fx); el->el_term.t_size.h, nfd, fx);
} }
/* /*
* write (nsb-nfd) - fx chars of new starting at * write (nsb-nfd) - fx chars of new starting at
* (nfd + fx) * (nfd + fx)
*/ */
term_overwrite(el, nfd + fx, (nsb - nfd) - fx); len = (size_t) ((nsb - nfd) - fx);
re__strncopy(ofd + fx, nfd + fx, term_overwrite(el, (nfd + fx), len);
(size_t) ((nsb - nfd) - fx)); re__strncopy(ofd + fx, nfd + fx, len);
} else { } else {
ELRE_DEBUG(1, (__F, "without anything to save\r\n")); ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
term_overwrite(el, nfd, (nsb - nfd)); len = (size_t)(nsb - nfd);
re__strncopy(ofd, nfd, (size_t) (nsb - nfd)); term_overwrite(el, nfd, len);
re__strncopy(ofd, nfd, len);
/* /*
* Done * Done
*/ */
@ -777,7 +788,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
/* /*
* move to the first char to delete where the first diff is * move to the first char to delete where the first diff is
*/ */
term_move_to_char(el, ofd - old); term_move_to_char(el, (int)(ofd - old));
/* /*
* Check if we have stuff to save * Check if we have stuff to save
*/ */
@ -791,14 +802,15 @@ re_update_line(EditLine *el, char *old, char *new, int i)
ELRE_DEBUG(!EL_CAN_DELETE, (__F, ELRE_DEBUG(!EL_CAN_DELETE, (__F,
"ERROR: cannot delete in first diff\n")); "ERROR: cannot delete in first diff\n"));
term_deletechars(el, -fx); term_deletechars(el, -fx);
re_delete(el, old, ofd - old, re_delete(el, old, (int)(ofd - old),
el->el_term.t_size.h, -fx); el->el_term.t_size.h, -fx);
} }
/* /*
* write (nsb-nfd) chars of new starting at nfd * write (nsb-nfd) chars of new starting at nfd
*/ */
term_overwrite(el, nfd, (nsb - nfd)); len = (size_t) (nsb - nfd);
re__strncopy(ofd, nfd, (size_t) (nsb - nfd)); term_overwrite(el, nfd, len);
re__strncopy(ofd, nfd, len);
} else { } else {
ELRE_DEBUG(1, (__F, ELRE_DEBUG(1, (__F,
@ -806,8 +818,9 @@ re_update_line(EditLine *el, char *old, char *new, int i)
/* /*
* write (nsb-nfd) chars of new starting at nfd * write (nsb-nfd) chars of new starting at nfd
*/ */
term_overwrite(el, nfd, (nsb - nfd)); term_overwrite(el, nfd, (size_t)(nsb - nfd));
re_clear_eol(el, fx, sx, (oe - old) - (ne - new)); re_clear_eol(el, fx, sx,
(int)((oe - old) - (ne - new)));
/* /*
* Done * Done
*/ */
@ -826,7 +839,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* fx is the number of characters inserted (+) or deleted (-) * fx is the number of characters inserted (+) or deleted (-)
*/ */
term_move_to_char(el, (ose - old) + fx); term_move_to_char(el, (int)((ose - old) + fx));
/* /*
* Check if we have stuff to save * Check if we have stuff to save
*/ */
@ -843,12 +856,13 @@ re_update_line(EditLine *el, char *old, char *new, int i)
/* /*
* write (nls-nse) chars of new starting at nse * write (nls-nse) chars of new starting at nse
*/ */
term_overwrite(el, nse, (nls - nse)); term_overwrite(el, nse, (size_t)(nls - nse));
} else { } else {
ELRE_DEBUG(1, (__F, ELRE_DEBUG(1, (__F,
"but with nothing left to save\r\n")); "but with nothing left to save\r\n"));
term_overwrite(el, nse, (nls - nse)); term_overwrite(el, nse, (size_t)(nls - nse));
re_clear_eol(el, fx, sx, (oe - old) - (ne - new)); re_clear_eol(el, fx, sx,
(int)((oe - old) - (ne - new)));
} }
} }
/* /*
@ -858,7 +872,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
ELRE_DEBUG(1, (__F, "late first diff insert at %d...\r\n", ELRE_DEBUG(1, (__F, "late first diff insert at %d...\r\n",
nfd - new)); nfd - new));
term_move_to_char(el, nfd - new); term_move_to_char(el, (int)(nfd - new));
/* /*
* Check if we have stuff to keep at the end * Check if we have stuff to keep at the end
*/ */
@ -869,7 +883,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* to zero above as a flag saying that we hadn't done * to zero above as a flag saying that we hadn't done
* an early first insert. * an early first insert.
*/ */
fx = (nsb - nfd) - (osb - ofd); fx = (int)((nsb - nfd) - (osb - ofd));
if (fx > 0) { if (fx > 0) {
/* /*
* insert fx chars of new starting at nfd * insert fx chars of new starting at nfd
@ -877,20 +891,21 @@ re_update_line(EditLine *el, char *old, char *new, int i)
ELRE_DEBUG(!EL_CAN_INSERT, (__F, ELRE_DEBUG(!EL_CAN_INSERT, (__F,
"ERROR: cannot insert in late first diff\n")); "ERROR: cannot insert in late first diff\n"));
term_insertwrite(el, nfd, fx); term_insertwrite(el, nfd, fx);
re_insert(el, old, ofd - old, re_insert(el, old, (int)(ofd - old),
el->el_term.t_size.h, nfd, fx); el->el_term.t_size.h, nfd, fx);
} }
/* /*
* write (nsb-nfd) - fx chars of new starting at * write (nsb-nfd) - fx chars of new starting at
* (nfd + fx) * (nfd + fx)
*/ */
term_overwrite(el, nfd + fx, (nsb - nfd) - fx); len = (size_t) ((nsb - nfd) - fx);
re__strncopy(ofd + fx, nfd + fx, term_overwrite(el, (nfd + fx), len);
(size_t) ((nsb - nfd) - fx)); re__strncopy(ofd + fx, nfd + fx, len);
} else { } else {
ELRE_DEBUG(1, (__F, "without anything to save\r\n")); ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
term_overwrite(el, nfd, (nsb - nfd)); len = (size_t) (nsb - nfd);
re__strncopy(ofd, nfd, (size_t) (nsb - nfd)); term_overwrite(el, nfd, len);
re__strncopy(ofd, nfd, len);
} }
} }
/* /*
@ -898,8 +913,8 @@ re_update_line(EditLine *el, char *old, char *new, int i)
*/ */
if (sx >= 0) { if (sx >= 0) {
ELRE_DEBUG(1, (__F, ELRE_DEBUG(1, (__F,
"second diff insert at %d...\r\n", nse - new)); "second diff insert at %d...\r\n", (int)(nse - new)));
term_move_to_char(el, nse - new); term_move_to_char(el, (int)(nse - new));
if (ols != oe) { if (ols != oe) {
ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n")); ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n"));
if (sx > 0) { if (sx > 0) {
@ -912,10 +927,11 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* write (nls-nse) - sx chars of new starting at * write (nls-nse) - sx chars of new starting at
* (nse + sx) * (nse + sx)
*/ */
term_overwrite(el, nse + sx, (nls - nse) - sx); term_overwrite(el, (nse + sx),
(size_t)((nls - nse) - sx));
} else { } else {
ELRE_DEBUG(1, (__F, "without anything to save\r\n")); ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
term_overwrite(el, nse, (nls - nse)); term_overwrite(el, nse, (size_t)(nls - nse));
/* /*
* No need to do a clear-to-end here because we were * No need to do a clear-to-end here because we were
@ -974,34 +990,28 @@ re_refresh_cursor(EditLine *el)
/* do input buffer to el->el_line.cursor */ /* do input buffer to el->el_line.cursor */
for (cp = el->el_line.buffer; cp < el->el_line.cursor; cp++) { for (cp = el->el_line.buffer; cp < el->el_line.cursor; cp++) {
c = *cp; c = *cp;
h++; /* all chars at least this long */
if (c == '\n') {/* handle newline in data part too */ switch (c) {
case '\n': /* handle newline in data part too */
h = 0; h = 0;
v++; v++;
} else { break;
if (c == '\t') { /* if a tab, to next tab stop */ case '\t': /* if a tab, to next tab stop */
while (h & 07) { while (++h & 07)
continue;
break;
default:
if (iscntrl((unsigned char) c))
h += 2; /* ^x */
else if (!isprint((unsigned char) c))
h += 4; /* octal \xxx */
else
h++; h++;
} break;
} else if (iscntrl((unsigned char) c)) {
/* if control char */
h++;
if (h > th) { /* if overflow, compensate */
h = 1;
v++;
}
} else if (!isprint((unsigned char) c)) {
h += 3;
if (h > th) { /* if overflow, compensate */
h = h - th;
v++;
}
}
} }
if (h >= th) { /* check, extra long tabs picked up here also */ if (h >= th) { /* check, extra long tabs picked up here also */
h = 0; h -= th;
v++; v++;
} }
} }
@ -1009,7 +1019,7 @@ re_refresh_cursor(EditLine *el)
/* now go there */ /* now go there */
term_move_to_line(el, v); term_move_to_line(el, v);
term_move_to_char(el, h); term_move_to_char(el, h);
term__flush(); term__flush(el);
} }
@ -1020,7 +1030,7 @@ private void
re_fastputc(EditLine *el, int c) re_fastputc(EditLine *el, int c)
{ {
term__putc(c); term__putc(el, c);
el->el_display[el->el_cursor.v][el->el_cursor.h++] = c; el->el_display[el->el_cursor.v][el->el_cursor.h++] = c;
if (el->el_cursor.h >= el->el_term.t_size.h) { if (el->el_cursor.h >= el->el_term.t_size.h) {
/* if we must overflow */ /* if we must overflow */
@ -1036,23 +1046,23 @@ re_fastputc(EditLine *el, int c)
int i, lins = el->el_term.t_size.v; int i, lins = el->el_term.t_size.v;
char *firstline = el->el_display[0]; char *firstline = el->el_display[0];
for(i=1; i < lins; i++) for(i = 1; i < lins; i++)
el->el_display[i-1] = el->el_display[i]; el->el_display[i - 1] = el->el_display[i];
re__copy_and_pad(firstline, "", 0); re__copy_and_pad(firstline, "", 0);
el->el_display[i-1] = firstline; el->el_display[i - 1] = firstline;
} else { } else {
el->el_cursor.v++; el->el_cursor.v++;
el->el_refresh.r_oldcv++; el->el_refresh.r_oldcv++;
} }
if (EL_HAS_AUTO_MARGINS) { if (EL_HAS_AUTO_MARGINS) {
if (EL_HAS_MAGIC_MARGINS) { if (EL_HAS_MAGIC_MARGINS) {
term__putc(' '); term__putc(el, ' ');
term__putc('\b'); term__putc(el, '\b');
} }
} else { } else {
term__putc('\r'); term__putc(el, '\r');
term__putc('\n'); term__putc(el, '\n');
} }
} }
} }
@ -1092,7 +1102,7 @@ re_fastaddc(EditLine *el)
re_fastputc(el, (int)(((((unsigned int)c) >> 3) & 7) + '0')); re_fastputc(el, (int)(((((unsigned int)c) >> 3) & 7) + '0'));
re_fastputc(el, (c & 7) + '0'); re_fastputc(el, (c & 7) + '0');
} }
term__flush(); term__flush(el);
} }
@ -1121,17 +1131,16 @@ re_clear_lines(EditLine *el)
if (EL_CAN_CEOL) { if (EL_CAN_CEOL) {
int i; int i;
term_move_to_char(el, 0); for (i = el->el_refresh.r_oldcv; i >= 0; i--) {
for (i = 0; i <= el->el_refresh.r_oldcv; i++) {
/* for each line on the screen */ /* for each line on the screen */
term_move_to_line(el, i); term_move_to_line(el, i);
term_move_to_char(el, 0);
term_clear_EOL(el, el->el_term.t_size.h); term_clear_EOL(el, el->el_term.t_size.h);
} }
term_move_to_line(el, 0);
} else { } else {
term_move_to_line(el, el->el_refresh.r_oldcv); term_move_to_line(el, el->el_refresh.r_oldcv);
/* go to last line */ /* go to last line */
term__putc('\r'); /* go to BOL */ term__putc(el, '\r'); /* go to BOL */
term__putc('\n'); /* go to new line */ term__putc(el, '\n'); /* go to new line */
} }
} }

View File

@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $NetBSD: search.c,v 1.20 2004/11/04 01:16:03 christos Exp $ * $NetBSD: search.c,v 1.21 2009/02/15 21:55:23 christos Exp $
*/ */
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
@ -207,7 +207,7 @@ ce_inc_search(EditLine *el, int dir)
el_action_t ret = CC_NORM; el_action_t ret = CC_NORM;
int ohisteventno = el->el_history.eventno; int ohisteventno = el->el_history.eventno;
int oldpatlen = el->el_search.patlen; size_t oldpatlen = el->el_search.patlen;
int newdir = dir; int newdir = dir;
int done, redo; int done, redo;

View File

@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $NetBSD: sig.c,v 1.11 2003/08/07 16:44:33 agc Exp $ * $NetBSD: sig.c,v 1.15 2009/02/19 15:20:22 christos Exp $
*/ */
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
@ -73,12 +73,14 @@ sig_handler(int signo)
(void) sigaddset(&nset, signo); (void) sigaddset(&nset, signo);
(void) sigprocmask(SIG_BLOCK, &nset, &oset); (void) sigprocmask(SIG_BLOCK, &nset, &oset);
sel->el_signal->sig_no = signo;
switch (signo) { switch (signo) {
case SIGCONT: case SIGCONT:
tty_rawmode(sel); tty_rawmode(sel);
if (ed_redisplay(sel, 0) == CC_REFRESH) if (ed_redisplay(sel, 0) == CC_REFRESH)
re_refresh(sel); re_refresh(sel);
term__flush(); term__flush(sel);
break; break;
case SIGWINCH: case SIGWINCH:
@ -94,7 +96,10 @@ sig_handler(int signo)
if (signo == sighdl[i]) if (signo == sighdl[i])
break; break;
(void) signal(signo, sel->el_signal[i]); (void) sigaction(signo, &sel->el_signal->sig_action[i], NULL);
sel->el_signal->sig_action[i].sa_handler = SIG_ERR;
sel->el_signal->sig_action[i].sa_flags = 0;
sigemptyset(&sel->el_signal->sig_action[i].sa_mask);
(void) sigprocmask(SIG_SETMASK, &oset, NULL); (void) sigprocmask(SIG_SETMASK, &oset, NULL);
(void) kill(0, signo); (void) kill(0, signo);
} }
@ -106,26 +111,29 @@ sig_handler(int signo)
protected int protected int
sig_init(EditLine *el) sig_init(EditLine *el)
{ {
int i; size_t i;
sigset_t nset, oset; sigset_t *nset, oset;
(void) sigemptyset(&nset); el->el_signal = el_malloc(sizeof(*el->el_signal));
#define _DO(a) (void) sigaddset(&nset, a); if (el->el_signal == NULL)
return -1;
nset = &el->el_signal->sig_set;
(void) sigemptyset(nset);
#define _DO(a) (void) sigaddset(nset, a);
ALLSIGS ALLSIGS
#undef _DO #undef _DO
(void) sigprocmask(SIG_BLOCK, &nset, &oset); (void) sigprocmask(SIG_BLOCK, nset, &oset);
#define SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(el_signalhandler_t)) for (i = 0; sighdl[i] != -1; i++) {
el->el_signal->sig_action[i].sa_handler = SIG_ERR;
el->el_signal = (el_signalhandler_t *) el_malloc(SIGSIZE); el->el_signal->sig_action[i].sa_flags = 0;
if (el->el_signal == NULL) sigemptyset(&el->el_signal->sig_action[i].sa_mask);
return (-1); }
for (i = 0; sighdl[i] != -1; i++)
el->el_signal[i] = SIG_ERR;
(void) sigprocmask(SIG_SETMASK, &oset, NULL); (void) sigprocmask(SIG_SETMASK, &oset, NULL);
return (0); return 0;
} }
@ -147,20 +155,21 @@ sig_end(EditLine *el)
protected void protected void
sig_set(EditLine *el) sig_set(EditLine *el)
{ {
int i; size_t i;
sigset_t nset, oset; sigset_t oset;
struct sigaction osa, nsa;
(void) sigemptyset(&nset); nsa.sa_handler = sig_handler;
#define _DO(a) (void) sigaddset(&nset, a); nsa.sa_flags = 0;
ALLSIGS sigemptyset(&nsa.sa_mask);
#undef _DO
(void) sigprocmask(SIG_BLOCK, &nset, &oset); (void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset);
for (i = 0; sighdl[i] != -1; i++) { for (i = 0; sighdl[i] != -1; i++) {
el_signalhandler_t s;
/* This could happen if we get interrupted */ /* This could happen if we get interrupted */
if ((s = signal(sighdl[i], sig_handler)) != sig_handler) if (sigaction(sighdl[i], &nsa, &osa) != -1 &&
el->el_signal[i] = s; osa.sa_handler != sig_handler)
el->el_signal->sig_action[i] = osa;
} }
sel = el; sel = el;
(void) sigprocmask(SIG_SETMASK, &oset, NULL); (void) sigprocmask(SIG_SETMASK, &oset, NULL);
@ -173,20 +182,17 @@ sig_set(EditLine *el)
protected void protected void
sig_clr(EditLine *el) sig_clr(EditLine *el)
{ {
int i; size_t i;
sigset_t nset, oset; sigset_t oset;
(void) sigemptyset(&nset); (void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset);
#define _DO(a) (void) sigaddset(&nset, a);
ALLSIGS
#undef _DO
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
for (i = 0; sighdl[i] != -1; i++) for (i = 0; sighdl[i] != -1; i++)
if (el->el_signal[i] != SIG_ERR) if (el->el_signal->sig_action[i].sa_handler != SIG_ERR)
(void) signal(sighdl[i], el->el_signal[i]); (void)sigaction(sighdl[i],
&el->el_signal->sig_action[i], NULL);
sel = NULL; /* we are going to die if the handler is sel = NULL; /* we are going to die if the handler is
* called */ * called */
(void) sigprocmask(SIG_SETMASK, &oset, NULL); (void)sigprocmask(SIG_SETMASK, &oset, NULL);
} }

View File

@ -51,15 +51,18 @@
#define ALLSIGS \ #define ALLSIGS \
_DO(SIGINT) \ _DO(SIGINT) \
_DO(SIGTSTP) \ _DO(SIGTSTP) \
_DO(SIGSTOP) \
_DO(SIGQUIT) \ _DO(SIGQUIT) \
_DO(SIGHUP) \ _DO(SIGHUP) \
_DO(SIGTERM) \ _DO(SIGTERM) \
_DO(SIGCONT) \ _DO(SIGCONT) \
_DO(SIGWINCH) _DO(SIGWINCH)
#define ALLSIGSNO 7
typedef void (*el_signalhandler_t)(int); typedef struct {
typedef el_signalhandler_t *el_signal_t; struct sigaction sig_action[ALLSIGSNO];
sigset_t sig_set;
volatile sig_atomic_t sig_no;
} *el_signal_t;
protected void sig_end(EditLine*); protected void sig_end(EditLine*);
protected int sig_init(EditLine*); protected int sig_init(EditLine*);

View File

@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $NetBSD: term.c,v 1.46 2006/11/24 00:01:17 christos Exp $ * $NetBSD: term.c,v 1.56 2009/12/28 21:54:21 christos Exp $
*/ */
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
@ -261,9 +261,13 @@ private int term_alloc_display(EditLine *);
private void term_alloc(EditLine *, const struct termcapstr *, const char *); private void term_alloc(EditLine *, const struct termcapstr *, const char *);
private void term_init_arrow(EditLine *); private void term_init_arrow(EditLine *);
private void term_reset_arrow(EditLine *); private void term_reset_arrow(EditLine *);
private int term_putc(int);
private void term_tputs(EditLine *, const char *, int);
#ifdef _REENTRANT
private FILE *term_outfile = NULL; /* XXX: How do we fix that? */ private pthread_mutex_t term_mutex = PTHREAD_MUTEX_INITIALIZER;
#endif
private FILE *term_outfile = NULL;
/* term_setflags(): /* term_setflags():
@ -311,7 +315,6 @@ term_setflags(EditLine *el)
#endif /* DEBUG_SCREEN */ #endif /* DEBUG_SCREEN */
} }
/* term_init(): /* term_init():
* Initialize the terminal stuff * Initialize the terminal stuff
*/ */
@ -337,7 +340,6 @@ term_init(EditLine *el)
if (el->el_term.t_val == NULL) if (el->el_term.t_val == NULL)
return (-1); return (-1);
(void) memset(el->el_term.t_val, 0, T_val * sizeof(int)); (void) memset(el->el_term.t_val, 0, T_val * sizeof(int));
term_outfile = el->el_outfile;
term_init_arrow(el); term_init_arrow(el);
(void) term_set(el, NULL); (void) term_set(el, NULL);
return (0); return (0);
@ -372,7 +374,7 @@ private void
term_alloc(EditLine *el, const struct termcapstr *t, const char *cap) term_alloc(EditLine *el, const struct termcapstr *t, const char *cap)
{ {
char termbuf[TC_BUFSIZE]; char termbuf[TC_BUFSIZE];
int tlen, clen; size_t tlen, clen;
char **tlist = el->el_term.t_str; char **tlist = el->el_term.t_str;
char **tmp, **str = &tlist[t - tstr]; char **tmp, **str = &tlist[t - tstr];
@ -399,7 +401,7 @@ term_alloc(EditLine *el, const struct termcapstr *t, const char *cap)
/* XXX strcpy is safe */ /* XXX strcpy is safe */
(void) strcpy(*str = &el->el_term.t_buf[el->el_term.t_loc], (void) strcpy(*str = &el->el_term.t_buf[el->el_term.t_loc],
cap); cap);
el->el_term.t_loc += clen + 1; /* one for \0 */ el->el_term.t_loc += (int)clen + 1; /* one for \0 */
return; return;
} }
/* /*
@ -416,7 +418,7 @@ term_alloc(EditLine *el, const struct termcapstr *t, const char *cap)
termbuf[tlen++] = '\0'; termbuf[tlen++] = '\0';
} }
memcpy(el->el_term.t_buf, termbuf, TC_BUFSIZE); memcpy(el->el_term.t_buf, termbuf, TC_BUFSIZE);
el->el_term.t_loc = tlen; el->el_term.t_loc = (int)tlen;
if (el->el_term.t_loc + 3 >= TC_BUFSIZE) { if (el->el_term.t_loc + 3 >= TC_BUFSIZE) {
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
"Out of termcap string space.\n"); "Out of termcap string space.\n");
@ -424,7 +426,7 @@ term_alloc(EditLine *el, const struct termcapstr *t, const char *cap)
} }
/* XXX strcpy is safe */ /* XXX strcpy is safe */
(void) strcpy(*str = &el->el_term.t_buf[el->el_term.t_loc], cap); (void) strcpy(*str = &el->el_term.t_buf[el->el_term.t_loc], cap);
el->el_term.t_loc += clen + 1; /* one for \0 */ el->el_term.t_loc += (int)clen + 1; /* one for \0 */
return; return;
} }
@ -542,19 +544,20 @@ term_move_to_line(EditLine *el, int where)
el->el_display[el->el_cursor.v][0] != '\0') { el->el_display[el->el_cursor.v][0] != '\0') {
/* move without newline */ /* move without newline */
term_move_to_char(el, el->el_term.t_size.h - 1); term_move_to_char(el, el->el_term.t_size.h - 1);
term_overwrite(el, term_overwrite(el, &el->el_display
&el->el_display[el->el_cursor.v][el->el_cursor.h], [el->el_cursor.v][el->el_cursor.h],
1); (size_t)(el->el_term.t_size.h -
el->el_cursor.h));
/* updates Cursor */ /* updates Cursor */
del--; del--;
} else { } else {
if ((del > 1) && GoodStr(T_DO)) { if ((del > 1) && GoodStr(T_DO)) {
(void) tputs(tgoto(Str(T_DO), del, del), term_tputs(el, tgoto(Str(T_DO), del,
del, term__putc); del), del);
del = 0; del = 0;
} else { } else {
for (; del > 0; del--) for (; del > 0; del--)
term__putc('\n'); term__putc(el, '\n');
/* because the \n will become \r\n */ /* because the \n will become \r\n */
el->el_cursor.h = 0; el->el_cursor.h = 0;
} }
@ -562,12 +565,11 @@ term_move_to_line(EditLine *el, int where)
} }
} else { /* del < 0 */ } else { /* del < 0 */
if (GoodStr(T_UP) && (-del > 1 || !GoodStr(T_up))) if (GoodStr(T_UP) && (-del > 1 || !GoodStr(T_up)))
(void) tputs(tgoto(Str(T_UP), -del, -del), -del, term_tputs(el, tgoto(Str(T_UP), -del, -del), -del);
term__putc);
else { else {
if (GoodStr(T_up)) if (GoodStr(T_up))
for (; del < 0; del++) for (; del < 0; del++)
(void) tputs(Str(T_up), 1, term__putc); term_tputs(el, Str(T_up), 1);
} }
} }
el->el_cursor.v = where;/* now where is here */ el->el_cursor.v = where;/* now where is here */
@ -594,7 +596,7 @@ term_move_to_char(EditLine *el, int where)
return; return;
} }
if (!where) { /* if where is first column */ if (!where) { /* if where is first column */
term__putc('\r'); /* do a CR */ term__putc(el, '\r'); /* do a CR */
el->el_cursor.h = 0; el->el_cursor.h = 0;
return; return;
} }
@ -602,25 +604,24 @@ term_move_to_char(EditLine *el, int where)
if ((del < -4 || del > 4) && GoodStr(T_ch)) if ((del < -4 || del > 4) && GoodStr(T_ch))
/* go there directly */ /* go there directly */
(void) tputs(tgoto(Str(T_ch), where, where), where, term__putc); term_tputs(el, tgoto(Str(T_ch), where, where), where);
else { else {
if (del > 0) { /* moving forward */ if (del > 0) { /* moving forward */
if ((del > 4) && GoodStr(T_RI)) if ((del > 4) && GoodStr(T_RI))
(void) tputs(tgoto(Str(T_RI), del, del), term_tputs(el, tgoto(Str(T_RI), del, del), del);
del, term__putc);
else { else {
/* if I can do tabs, use them */ /* if I can do tabs, use them */
if (EL_CAN_TAB) { if (EL_CAN_TAB) {
if ((el->el_cursor.h & 0370) != if ((el->el_cursor.h & 0370) !=
(where & 0370)) { (where & ~0x7)) {
/* if not within tab stop */ /* if not within tab stop */
for (i = for (i =
(el->el_cursor.h & 0370); (el->el_cursor.h & 0370);
i < (where & 0370); i < (where & ~0x7);
i += 8) i += 8)
term__putc('\t'); term__putc(el, '\t');
/* then tab over */ /* then tab over */
el->el_cursor.h = where & 0370; el->el_cursor.h = where & ~0x7;
} }
} }
/* /*
@ -631,15 +632,15 @@ term_move_to_char(EditLine *el, int where)
* NOTE THAT term_overwrite() WILL CHANGE * NOTE THAT term_overwrite() WILL CHANGE
* el->el_cursor.h!!! * el->el_cursor.h!!!
*/ */
term_overwrite(el, term_overwrite(el, &el->el_display[
&el->el_display[el->el_cursor.v][el->el_cursor.h], el->el_cursor.v][el->el_cursor.h],
where - el->el_cursor.h); (size_t)(where - el->el_cursor.h));
} }
} else { /* del < 0 := moving backward */ } else { /* del < 0 := moving backward */
if ((-del > 4) && GoodStr(T_LE)) if ((-del > 4) && GoodStr(T_LE))
(void) tputs(tgoto(Str(T_LE), -del, -del), term_tputs(el, tgoto(Str(T_LE), -del, -del),
-del, term__putc); -del);
else { /* can't go directly there */ else { /* can't go directly there */
/* /*
* if the "cost" is greater than the "cost" * if the "cost" is greater than the "cost"
@ -650,12 +651,12 @@ term_move_to_char(EditLine *el, int where)
(((unsigned int) where >> 3) + (((unsigned int) where >> 3) +
(where & 07))) (where & 07)))
: (-del > where)) { : (-del > where)) {
term__putc('\r'); /* do a CR */ term__putc(el, '\r'); /* do a CR */
el->el_cursor.h = 0; el->el_cursor.h = 0;
goto mc_again; /* and try again */ goto mc_again; /* and try again */
} }
for (i = 0; i < -del; i++) for (i = 0; i < -del; i++)
term__putc('\b'); term__putc(el, '\b');
} }
} }
} }
@ -667,20 +668,21 @@ term_move_to_char(EditLine *el, int where)
* Overstrike num characters * Overstrike num characters
*/ */
protected void protected void
term_overwrite(EditLine *el, const char *cp, int n) term_overwrite(EditLine *el, const char *cp, size_t n)
{ {
if (n <= 0) if (n == 0)
return; /* catch bugs */ return;
if (n > el->el_term.t_size.h) { if (n > (size_t)el->el_term.t_size.h) {
#ifdef DEBUG_SCREEN #ifdef DEBUG_SCREEN
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
"term_overwrite: n is riduculous: %d\r\n", n); "term_overwrite: n is riduculous: %d\r\n", n);
#endif /* DEBUG_SCREEN */ #endif /* DEBUG_SCREEN */
return; return;
} }
do { do {
term__putc(*cp++); term__putc(el, *cp++);
el->el_cursor.h++; el->el_cursor.h++;
} while (--n); } while (--n);
@ -695,12 +697,13 @@ term_overwrite(EditLine *el, const char *cp, int n)
if ((c = el->el_display[el->el_cursor.v][el->el_cursor.h]) if ((c = el->el_display[el->el_cursor.v][el->el_cursor.h])
!= '\0') != '\0')
term_overwrite(el, &c, 1); term_overwrite(el, &c, 1);
else else {
term__putc(' '); term__putc(el, ' ');
el->el_cursor.h = 1; el->el_cursor.h = 1;
} }
}
} else /* no wrap, but cursor stays on screen */ } else /* no wrap, but cursor stays on screen */
el->el_cursor.h = el->el_term.t_size.h; el->el_cursor.h = el->el_term.t_size.h - 1;
} }
} }
@ -730,19 +733,18 @@ term_deletechars(EditLine *el, int num)
if (GoodStr(T_DC)) /* if I have multiple delete */ if (GoodStr(T_DC)) /* if I have multiple delete */
if ((num > 1) || !GoodStr(T_dc)) { /* if dc would be more if ((num > 1) || !GoodStr(T_dc)) { /* if dc would be more
* expen. */ * expen. */
(void) tputs(tgoto(Str(T_DC), num, num), term_tputs(el, tgoto(Str(T_DC), num, num), num);
num, term__putc);
return; return;
} }
if (GoodStr(T_dm)) /* if I have delete mode */ if (GoodStr(T_dm)) /* if I have delete mode */
(void) tputs(Str(T_dm), 1, term__putc); term_tputs(el, Str(T_dm), 1);
if (GoodStr(T_dc)) /* else do one at a time */ if (GoodStr(T_dc)) /* else do one at a time */
while (num--) while (num--)
(void) tputs(Str(T_dc), 1, term__putc); term_tputs(el, Str(T_dc), 1);
if (GoodStr(T_ed)) /* if I have delete mode */ if (GoodStr(T_ed)) /* if I have delete mode */
(void) tputs(Str(T_ed), 1, term__putc); term_tputs(el, Str(T_ed), 1);
} }
@ -771,37 +773,35 @@ term_insertwrite(EditLine *el, char *cp, int num)
if (GoodStr(T_IC)) /* if I have multiple insert */ if (GoodStr(T_IC)) /* if I have multiple insert */
if ((num > 1) || !GoodStr(T_ic)) { if ((num > 1) || !GoodStr(T_ic)) {
/* if ic would be more expensive */ /* if ic would be more expensive */
(void) tputs(tgoto(Str(T_IC), num, num), term_tputs(el, tgoto(Str(T_IC), num, num), num);
num, term__putc); term_overwrite(el, cp, (size_t)num);
term_overwrite(el, cp, num);
/* this updates el_cursor.h */ /* this updates el_cursor.h */
return; return;
} }
if (GoodStr(T_im) && GoodStr(T_ei)) { /* if I have insert mode */ if (GoodStr(T_im) && GoodStr(T_ei)) { /* if I have insert mode */
(void) tputs(Str(T_im), 1, term__putc); term_tputs(el, Str(T_im), 1);
el->el_cursor.h += num; el->el_cursor.h += num;
do do
term__putc(*cp++); term__putc(el, *cp++);
while (--num); while (--num);
if (GoodStr(T_ip)) /* have to make num chars insert */ if (GoodStr(T_ip)) /* have to make num chars insert */
(void) tputs(Str(T_ip), 1, term__putc); term_tputs(el, Str(T_ip), 1);
(void) tputs(Str(T_ei), 1, term__putc); term_tputs(el, Str(T_ei), 1);
return; return;
} }
do { do {
if (GoodStr(T_ic)) /* have to make num chars insert */ if (GoodStr(T_ic)) /* have to make num chars insert */
(void) tputs(Str(T_ic), 1, term__putc); term_tputs(el, Str(T_ic), 1);
/* insert a char */
term__putc(*cp++); term__putc(el, *cp++);
el->el_cursor.h++; el->el_cursor.h++;
if (GoodStr(T_ip)) /* have to make num chars insert */ if (GoodStr(T_ip)) /* have to make num chars insert */
(void) tputs(Str(T_ip), 1, term__putc); term_tputs(el, Str(T_ip), 1);
/* pad the inserted char */ /* pad the inserted char */
} while (--num); } while (--num);
@ -817,10 +817,10 @@ term_clear_EOL(EditLine *el, int num)
int i; int i;
if (EL_CAN_CEOL && GoodStr(T_ce)) if (EL_CAN_CEOL && GoodStr(T_ce))
(void) tputs(Str(T_ce), 1, term__putc); term_tputs(el, Str(T_ce), 1);
else { else {
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
term__putc(' '); term__putc(el, ' ');
el->el_cursor.h += num; /* have written num spaces */ el->el_cursor.h += num; /* have written num spaces */
} }
} }
@ -835,14 +835,14 @@ term_clear_screen(EditLine *el)
if (GoodStr(T_cl)) if (GoodStr(T_cl))
/* send the clear screen code */ /* send the clear screen code */
(void) tputs(Str(T_cl), Val(T_li), term__putc); term_tputs(el, Str(T_cl), Val(T_li));
else if (GoodStr(T_ho) && GoodStr(T_cd)) { else if (GoodStr(T_ho) && GoodStr(T_cd)) {
(void) tputs(Str(T_ho), Val(T_li), term__putc); /* home */ term_tputs(el, Str(T_ho), Val(T_li)); /* home */
/* clear to bottom of screen */ /* clear to bottom of screen */
(void) tputs(Str(T_cd), Val(T_li), term__putc); term_tputs(el, Str(T_cd), Val(T_li));
} else { } else {
term__putc('\r'); term__putc(el, '\r');
term__putc('\n'); term__putc(el, '\n');
} }
} }
@ -855,9 +855,9 @@ term_beep(EditLine *el)
{ {
if (GoodStr(T_bl)) if (GoodStr(T_bl))
/* what termcap says we should use */ /* what termcap says we should use */
(void) tputs(Str(T_bl), 1, term__putc); term_tputs(el, Str(T_bl), 1);
else else
term__putc('\007'); /* an ASCII bell; ^G */ term__putc(el, '\007'); /* an ASCII bell; ^G */
} }
@ -869,9 +869,9 @@ protected void
term_clear_to_bottom(EditLine *el) term_clear_to_bottom(EditLine *el)
{ {
if (GoodStr(T_cd)) if (GoodStr(T_cd))
(void) tputs(Str(T_cd), Val(T_li), term__putc); term_tputs(el, Str(T_cd), Val(T_li));
else if (GoodStr(T_ce)) else if (GoodStr(T_ce))
(void) tputs(Str(T_ce), Val(T_li), term__putc); term_tputs(el, Str(T_ce), Val(T_li));
} }
#endif #endif
@ -1238,26 +1238,49 @@ term_bind_arrow(EditLine *el)
} }
} }
/* term_putc():
* Add a character
*/
private int
term_putc(int c)
{
if (term_outfile == NULL)
return -1;
return fputc(c, term_outfile);
}
private void
term_tputs(EditLine *el, const char *cap, int affcnt)
{
#ifdef _REENTRANT
pthread_mutex_lock(&term_mutex);
#endif
term_outfile = el->el_outfile;
(void)tputs(cap, affcnt, term_putc);
#ifdef _REENTRANT
pthread_mutex_unlock(&term_mutex);
#endif
}
/* term__putc(): /* term__putc():
* Add a character * Add a character
*/ */
protected int protected int
term__putc(int c) term__putc(EditLine *el, int c)
{ {
return (fputc(c, term_outfile)); return fputc(c, el->el_outfile);
} }
/* term__flush(): /* term__flush():
* Flush output * Flush output
*/ */
protected void protected void
term__flush(void) term__flush(EditLine *el)
{ {
(void) fflush(term_outfile); (void) fflush(el->el_outfile);
} }
/* term_writec(): /* term_writec():
@ -1267,10 +1290,10 @@ protected void
term_writec(EditLine *el, int c) term_writec(EditLine *el, int c)
{ {
char buf[8]; char buf[8];
int cnt = key__decode_char(buf, sizeof(buf), 0, c); size_t cnt = key__decode_char(buf, sizeof(buf), 0, c);
buf[cnt] = '\0'; buf[cnt] = '\0';
term_overwrite(el, buf, cnt); term_overwrite(el, buf, (size_t)cnt);
term__flush(); term__flush(el);
} }
@ -1585,7 +1608,7 @@ term_echotc(EditLine *el, int argc __unused,
*argv); *argv);
return (-1); return (-1);
} }
(void) tputs(scap, 1, term__putc); term_tputs(el, scap, 1);
break; break;
case 1: case 1:
argv++; argv++;
@ -1613,7 +1636,7 @@ term_echotc(EditLine *el, int argc __unused,
*argv); *argv);
return (-1); return (-1);
} }
(void) tputs(tgoto(scap, arg_cols, arg_rows), 1, term__putc); term_tputs(el, tgoto(scap, arg_cols, arg_rows), 1);
break; break;
default: default:
/* This is wrong, but I will ignore it... */ /* This is wrong, but I will ignore it... */
@ -1669,8 +1692,7 @@ term_echotc(EditLine *el, int argc __unused,
*argv); *argv);
return (-1); return (-1);
} }
(void) tputs(tgoto(scap, arg_cols, arg_rows), arg_rows, term_tputs(el, tgoto(scap, arg_cols, arg_rows), arg_rows);
term__putc);
break; break;
} }
return (0); return (0);

View File

@ -85,7 +85,7 @@ typedef struct {
protected void term_move_to_line(EditLine *, int); protected void term_move_to_line(EditLine *, int);
protected void term_move_to_char(EditLine *, int); protected void term_move_to_char(EditLine *, int);
protected void term_clear_EOL(EditLine *, int); protected void term_clear_EOL(EditLine *, int);
protected void term_overwrite(EditLine *, const char *, int); protected void term_overwrite(EditLine *, const char *, size_t);
protected void term_insertwrite(EditLine *, char *, int); protected void term_insertwrite(EditLine *, char *, int);
protected void term_deletechars(EditLine *, int); protected void term_deletechars(EditLine *, int);
protected void term_clear_screen(EditLine *); protected void term_clear_screen(EditLine *);
@ -105,8 +105,8 @@ protected int term_gettc(EditLine *, int, char **);
protected int term_telltc(EditLine *, int, const char **); protected int term_telltc(EditLine *, int, const char **);
protected int term_echotc(EditLine *, int, const char **); protected int term_echotc(EditLine *, int, const char **);
protected void term_writec(EditLine *, int); protected void term_writec(EditLine *, int);
protected int term__putc(int); protected int term__putc(EditLine *, int);
protected void term__flush(void); protected void term__flush(EditLine *);
/* /*
* Easy access macros * Easy access macros

View File

@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $NetBSD: tty.c,v 1.24 2006/03/18 09:07:05 christos Exp $ * $NetBSD: tty.c,v 1.25 2006/03/18 09:09:41 christos Exp $
*/ */
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)

View File

@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $NetBSD: vi.c,v 1.25 2006/03/06 21:11:56 christos Exp $ * $NetBSD: vi.c,v 1.30 2009/02/21 23:31:56 christos Exp $
*/ */
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
@ -63,7 +63,7 @@ cv_action(EditLine *el, int c)
if (!(c & YANK)) if (!(c & YANK))
cv_undo(el); cv_undo(el);
cv_yank(el, el->el_line.buffer, cv_yank(el, el->el_line.buffer,
el->el_line.lastchar - el->el_line.buffer); (int)(el->el_line.lastchar - el->el_line.buffer));
el->el_chared.c_vcmd.action = NOP; el->el_chared.c_vcmd.action = NOP;
el->el_chared.c_vcmd.pos = 0; el->el_chared.c_vcmd.pos = 0;
if (!(c & YANK)) { if (!(c & YANK)) {
@ -87,12 +87,12 @@ private el_action_t
cv_paste(EditLine *el, int c) cv_paste(EditLine *el, int c)
{ {
c_kill_t *k = &el->el_chared.c_kill; c_kill_t *k = &el->el_chared.c_kill;
int len = k->last - k->buf; size_t len = (size_t)(k->last - k->buf);
if (k->buf == NULL || len == 0) if (k->buf == NULL || len == 0)
return (CC_ERROR); return (CC_ERROR);
#ifdef DEBUG_PASTE #ifdef DEBUG_PASTE
(void) fprintf(el->el_errfile, "Paste: \"%.*s\"\n", len, k->buf); (void) fprintf(el->el_errfile, "Paste: \"%.*s\"\n", (int)len, k->buf);
#endif #endif
cv_undo(el); cv_undo(el);
@ -100,10 +100,10 @@ cv_paste(EditLine *el, int c)
if (!c && el->el_line.cursor < el->el_line.lastchar) if (!c && el->el_line.cursor < el->el_line.lastchar)
el->el_line.cursor++; el->el_line.cursor++;
c_insert(el, len); c_insert(el, (int)len);
if (el->el_line.cursor + len > el->el_line.lastchar) if (el->el_line.cursor + len > el->el_line.lastchar)
return (CC_ERROR); return (CC_ERROR);
(void) memcpy(el->el_line.cursor, k->buf, len +0u); (void) memcpy(el->el_line.cursor, k->buf, len);
return (CC_REFRESH); return (CC_REFRESH);
} }
@ -358,7 +358,7 @@ vi_substitute_line(EditLine *el, int c __unused)
cv_undo(el); cv_undo(el);
cv_yank(el, el->el_line.buffer, cv_yank(el, el->el_line.buffer,
el->el_line.lastchar - el->el_line.buffer); (int)(el->el_line.lastchar - el->el_line.buffer));
(void) em_kill_line(el, 0); (void) em_kill_line(el, 0);
el->el_map.current = el->el_map.key; el->el_map.current = el->el_map.key;
return (CC_REFRESH); return (CC_REFRESH);
@ -376,7 +376,7 @@ vi_change_to_eol(EditLine *el, int c __unused)
cv_undo(el); cv_undo(el);
cv_yank(el, el->el_line.cursor, cv_yank(el, el->el_line.cursor,
el->el_line.lastchar - el->el_line.cursor); (int)(el->el_line.lastchar - el->el_line.cursor));
(void) ed_kill_line(el, 0); (void) ed_kill_line(el, 0);
el->el_map.current = el->el_map.key; el->el_map.current = el->el_map.key;
return (CC_REFRESH); return (CC_REFRESH);
@ -516,7 +516,8 @@ vi_undo(EditLine *el, int c __unused)
/* switch line buffer and undo buffer */ /* switch line buffer and undo buffer */
el->el_chared.c_undo.buf = el->el_line.buffer; el->el_chared.c_undo.buf = el->el_line.buffer;
el->el_chared.c_undo.len = el->el_line.lastchar - el->el_line.buffer; el->el_chared.c_undo.len = el->el_line.lastchar - el->el_line.buffer;
el->el_chared.c_undo.cursor = el->el_line.cursor - el->el_line.buffer; el->el_chared.c_undo.cursor =
(int)(el->el_line.cursor - el->el_line.buffer);
el->el_line.limit = un.buf + (el->el_line.limit - el->el_line.buffer); el->el_line.limit = un.buf + (el->el_line.limit - el->el_line.buffer);
el->el_line.buffer = un.buf; el->el_line.buffer = un.buf;
el->el_line.cursor = un.buf + un.cursor; el->el_line.cursor = un.buf + un.cursor;
@ -641,7 +642,7 @@ vi_kill_line_prev(EditLine *el, int c __unused)
while (cp < el->el_line.cursor) while (cp < el->el_line.cursor)
*kp++ = *cp++; /* copy it */ *kp++ = *cp++; /* copy it */
el->el_chared.c_kill.last = kp; el->el_chared.c_kill.last = kp;
c_delbefore(el, el->el_line.cursor - el->el_line.buffer); c_delbefore(el, (int)(el->el_line.cursor - el->el_line.buffer));
el->el_line.cursor = el->el_line.buffer; /* zap! */ el->el_line.cursor = el->el_line.buffer; /* zap! */
return (CC_REFRESH); return (CC_REFRESH);
} }
@ -797,7 +798,7 @@ vi_match(EditLine *el, int c)
{ {
const char match_chars[] = "()[]{}"; const char match_chars[] = "()[]{}";
char *cp; char *cp;
int delta, i, count; size_t delta, i, count;
char o_ch, c_ch; char o_ch, c_ch;
*el->el_line.lastchar = '\0'; /* just in case */ *el->el_line.lastchar = '\0'; /* just in case */
@ -872,7 +873,7 @@ vi_yank_end(EditLine *el, int c)
{ {
cv_yank(el, el->el_line.cursor, cv_yank(el, el->el_line.cursor,
el->el_line.lastchar - el->el_line.cursor); (int)(el->el_line.lastchar - el->el_line.cursor));
return CC_REFRESH; return CC_REFRESH;
} }
@ -993,7 +994,8 @@ vi_histedit(EditLine *el, int c)
{ {
int fd; int fd;
pid_t pid; pid_t pid;
int st; ssize_t st;
int status;
char tempfile[] = "/tmp/histedit.XXXXXXXXXX"; char tempfile[] = "/tmp/histedit.XXXXXXXXXX";
char *cp; char *cp;
@ -1006,7 +1008,7 @@ vi_histedit(EditLine *el, int c)
if (fd < 0) if (fd < 0)
return CC_ERROR; return CC_ERROR;
cp = el->el_line.buffer; cp = el->el_line.buffer;
write(fd, cp, el->el_line.lastchar - cp +0u); write(fd, cp, (size_t)(el->el_line.lastchar - cp));
write(fd, "\n", 1); write(fd, "\n", 1);
pid = fork(); pid = fork();
switch (pid) { switch (pid) {
@ -1016,14 +1018,14 @@ vi_histedit(EditLine *el, int c)
return CC_ERROR; return CC_ERROR;
case 0: case 0:
close(fd); close(fd);
execlp("vi", "vi", tempfile, NULL); execlp("vi", "vi", tempfile, (char *)NULL);
exit(0); exit(0);
/*NOTREACHED*/ /*NOTREACHED*/
default: default:
while (waitpid(pid, &st, 0) != pid) while (waitpid(pid, &status, 0) != pid)
continue; continue;
lseek(fd, 0ll, SEEK_SET); lseek(fd, (off_t)0, SEEK_SET);
st = read(fd, cp, el->el_line.limit - cp +0u); st = read(fd, cp, (size_t)(el->el_line.limit - cp));
if (st > 0 && cp[st - 1] == '\n') if (st > 0 && cp[st - 1] == '\n')
st--; st--;
el->el_line.cursor = cp; el->el_line.cursor = cp;
@ -1072,7 +1074,7 @@ vi_history_word(EditLine *el, int c)
return CC_ERROR; return CC_ERROR;
cv_undo(el); cv_undo(el);
len = wep - wsp; len = (int)(wep - wsp);
if (el->el_line.cursor < el->el_line.lastchar) if (el->el_line.cursor < el->el_line.lastchar)
el->el_line.cursor++; el->el_line.cursor++;
c_insert(el, len + 1); c_insert(el, len + 1);