From 5b6fd65dbfcb7ec622b234a3a55d028c0028f24f Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Mon, 12 Jan 2015 21:33:35 +0000 Subject: [PATCH] Import libedit 2014-01-09 Obtained from: NetBSD --- Makefile | 4 +- TEST/tc1.c | 6 +- TEST/wtc1.c | 2 +- chared.c | 33 ++++++- chared.h | 6 +- editline.3 | 67 ++++++++++--- editrc.5 | 73 +++++++++++---- el.c | 25 ++++- eln.c | 42 ++++++--- filecomplete.c | 11 ++- hist.h | 3 +- histedit.h | 7 +- history.c | 39 ++++++-- map.c | 10 +- map.h | 4 +- parse.c | 13 +-- read.c | 13 ++- readline.c | 49 ++++++---- readline/readline.h | 4 +- shlib_version | 4 +- tty.c | 224 +++++++++++++++++++------------------------- tty.h | 3 +- vi.c | 20 ++-- 23 files changed, 408 insertions(+), 254 deletions(-) diff --git a/Makefile b/Makefile index 0880363d11ec..92bfd5e83877 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.51 2012/08/10 12:20:10 joerg Exp $ +# $NetBSD: Makefile,v 1.52 2014/06/14 20:49:37 mrg Exp $ # @(#)Makefile 8.1 (Berkeley) 6/4/93 USE_SHLIBDIR= yes @@ -127,7 +127,7 @@ tc1: libedit.a tc1.o .include # XXX -.if defined(HAVE_GCC) && ${HAVE_GCC} >= 45 +.if defined(HAVE_GCC) COPTS.editline.c+= -Wno-cast-qual COPTS.tokenizer.c+= -Wno-cast-qual COPTS.tokenizern.c+= -Wno-cast-qual diff --git a/TEST/tc1.c b/TEST/tc1.c index 77f8a515373c..88b3cd6439b4 100644 --- a/TEST/tc1.c +++ b/TEST/tc1.c @@ -1,4 +1,4 @@ -/* $NetBSD: tc1.c,v 1.5 2010/04/18 21:17:47 christos Exp $ */ +/* $NetBSD: tc1.c,v 1.6 2014/06/18 20:12:15 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -42,7 +42,7 @@ __COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\ #if 0 static char sccsid[] = "@(#)test.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: tc1.c,v 1.5 2010/04/18 21:17:47 christos Exp $"); +__RCSID("$NetBSD: tc1.c,v 1.6 2014/06/18 20:12:15 christos Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -189,7 +189,7 @@ main(int argc, char *argv[]) #endif if (gotsig) { - (void) fprintf(stderr, "Got signal %d.\n", gotsig); + (void) fprintf(stderr, "Got signal %d.\n", (int)gotsig); gotsig = 0; el_reset(el); } diff --git a/TEST/wtc1.c b/TEST/wtc1.c index 365bd2e66a72..3e6fa9e81973 100644 --- a/TEST/wtc1.c +++ b/TEST/wtc1.c @@ -170,7 +170,7 @@ main(int argc, char *argv[]) #endif if (gotsig) { - (void)fprintf(stderr, "Got signal %d.\n", gotsig); + (void)fprintf(stderr, "Got signal %d.\n", (int)gotsig); gotsig = 0; el_reset(el); } diff --git a/chared.c b/chared.c index fb75de8f4a51..3934a684f7c6 100644 --- a/chared.c +++ b/chared.c @@ -1,4 +1,4 @@ -/* $NetBSD: chared.c,v 1.37 2012/07/18 17:12:39 christos Exp $ */ +/* $NetBSD: chared.c,v 1.40 2014/06/18 18:12:28 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: chared.c,v 1.37 2012/07/18 17:12:39 christos Exp $"); +__RCSID("$NetBSD: chared.c,v 1.40 2014/06/18 18:12:28 christos Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -434,6 +434,8 @@ ch_init(EditLine *el) el->el_chared.c_kill.last = el->el_chared.c_kill.buf; el->el_chared.c_resizefun = NULL; el->el_chared.c_resizearg = NULL; + el->el_chared.c_aliasfun = NULL; + el->el_chared.c_aliasarg = NULL; el->el_map.current = el->el_map.key; @@ -644,6 +646,25 @@ el_deletestr(EditLine *el, int n) el->el_line.cursor = el->el_line.buffer; } +/* el_cursor(): + * Move the cursor to the left or the right of the current position + */ +public int +el_cursor(EditLine *el, int n) +{ + if (n == 0) + goto out; + + el->el_line.cursor += n; + + if (el->el_line.cursor < el->el_line.buffer) + el->el_line.cursor = el->el_line.buffer; + if (el->el_line.cursor > el->el_line.lastchar) + el->el_line.cursor = el->el_line.lastchar; +out: + return (int)(el->el_line.cursor - el->el_line.buffer); +} + /* c_gets(): * Get a string */ @@ -738,3 +759,11 @@ ch_resizefun(EditLine *el, el_zfunc_t f, void *a) el->el_chared.c_resizearg = a; return 0; } + +protected int +ch_aliasfun(EditLine *el, el_afunc_t f, void *a) +{ + el->el_chared.c_aliasfun = f; + el->el_chared.c_aliasarg = a; + return 0; +} diff --git a/chared.h b/chared.h index 176475ac8f05..6d6ef2341f16 100644 --- a/chared.h +++ b/chared.h @@ -1,4 +1,4 @@ -/* $NetBSD: chared.h,v 1.21 2010/08/28 15:44:59 christos Exp $ */ +/* $NetBSD: chared.h,v 1.22 2014/06/18 18:12:28 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -104,6 +104,7 @@ typedef struct c_kill_t { } c_kill_t; typedef void (*el_zfunc_t)(EditLine *, void *); +typedef const char *(*el_afunc_t)(void *, const char *); /* * Note that we use both data structures because the user can bind @@ -116,7 +117,9 @@ typedef struct el_chared_t { c_vcmd_t c_vcmd; c_macro_t c_macro; el_zfunc_t c_resizefun; + el_afunc_t c_aliasfun; void * c_resizearg; + void * c_aliasarg; } el_chared_t; @@ -165,6 +168,7 @@ protected int c_hpos(EditLine *); protected int ch_init(EditLine *); protected void ch_reset(EditLine *, int); protected int ch_resizefun(EditLine *, el_zfunc_t, void *); +protected int ch_aliasfun(EditLine *, el_afunc_t, void *); protected int ch_enlargebufs(EditLine *, size_t); protected void ch_end(EditLine *); diff --git a/editline.3 b/editline.3 index e869161d7ff1..02a986f8ba42 100644 --- a/editline.3 +++ b/editline.3 @@ -1,6 +1,6 @@ -.\" $NetBSD: editline.3,v 1.77 2012/09/11 20:29:58 christos Exp $ +.\" $NetBSD: editline.3,v 1.84 2014/12/25 13:39:41 wiz Exp $ .\" -.\" Copyright (c) 1997-2003 The NetBSD Foundation, Inc. +.\" Copyright (c) 1997-2014 The NetBSD Foundation, Inc. .\" All rights reserved. .\" .\" This file was contributed to The NetBSD Foundation by Luke Mewburn. @@ -26,12 +26,13 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd September 11, 2012 +.Dd December 25, 2014 .Dt EDITLINE 3 .Os .Sh NAME .Nm editline , .Nm el_init , +.Nm el_init_fd , .Nm el_end , .Nm el_reset , .Nm el_gets , @@ -48,6 +49,7 @@ .Nm el_wget , .Nm el_source , .Nm el_resize , +.Nm el_cursor , .Nm el_line , .Nm el_wline , .Nm el_insertstr , @@ -77,6 +79,8 @@ .In histedit.h .Ft EditLine * .Fn el_init "const char *prog" "FILE *fin" "FILE *fout" "FILE *ferr" +.Ft EditLine * +.Fn el_init_fd "const char *prog" "FILE *fin" "FILE *fout" "FILE *ferr" "int fdin" "int fdout" "int fderr" .Ft void .Fn el_end "EditLine *e" .Ft void @@ -109,8 +113,12 @@ .Fn el_source "EditLine *e" "const char *file" .Ft void .Fn el_resize "EditLine *e" +.Fn int +.Fn el_cursor "EditLine *e" "int count" .Ft const LineInfo * .Fn el_line "EditLine *e" +.Ft const LineInfoW * +.Fn el_wline "EditLine *e" .Ft int .Fn el_insertstr "EditLine *e" "const char *str" .Ft int @@ -170,6 +178,8 @@ The line editing functions use a common data structure, .Fa EditLine , which is created by .Fn el_init +or +.Fn el_init_fd and freed by .Fn el_end . .Pp @@ -180,7 +190,9 @@ The following functions are available: .Bl -tag -width 4n .It Fn el_init Initialise the line editor, and return a data structure -to be used by all other line editing functions. +to be used by all other line editing functions, or +.Dv NULL +on failure. .Fa prog is the name of the invoking program, used when reading the .Xr editrc 5 @@ -193,11 +205,20 @@ are the input, output, and error streams (respectively) to use. In this documentation, references to .Dq the tty are actually to this input/output stream combination. +.It Fn el_init_fd +Like +.Fn el_init +but allows specifying file descriptors for the +.Xr stdio 3 +corresponding streams, in case those were created with +.Xr funopen 3 . .It Fn el_end Clean up and finish with .Fa e , assumed to have been created with -.Fn el_init . +.Fn el_init +or +.Fn el_init_fd . .It Fn el_reset Reset the tty and the parser. This should be called after an error which may have upset the tty's @@ -271,6 +292,7 @@ parameters. .Fa op determines which parameter to set, and each operation has its own parameter list. +Returns 0 on success, \-1 on failure. .Pp The following values for .Fa op @@ -581,13 +603,13 @@ If is .Dv NULL , try -.Pa $PWD/.editrc -then .Pa $HOME/.editrc . Refer to .Xr editrc 5 for details on the format of .Fa file . +.Fn el_source +returns 0 on success and \-1 on error. .It Fn el_resize Must be called if the terminal size changes. If @@ -598,6 +620,11 @@ then this is done automatically. Otherwise, it's the responsibility of the application to call .Fn el_resize on the appropriate occasions. +.It Fn el_cursor +Move the cursor to the right (if positive) or to the left (if negative) +.Fa count +characters. +Returns the resulting offset of the cursor from the beginning of the line. .It Fn el_line Return the editing information for the current line in a .Fa LineInfo @@ -643,7 +670,9 @@ The following functions are available: .Bl -tag -width 4n .It Fn history_init Initialise the history list, and return a data structure -to be used by all other history list functions. +to be used by all other history list functions, or +.Dv NULL +on failure. .It Fn history_end Clean up and finish with .Fa h , @@ -712,12 +741,12 @@ as a new element to the history, and, if necessary, removing the oldest entry to keep the list to the created size. If .Dv H_SETUNIQUE -was has been called with a non-zero arguments, the element +has been called with a non-zero argument, the element will not be entered into the history if its contents match the ones of the current history element. If the element is entered .Fn history -returns 1, if it is ignored as a duplicate returns 0. +returns 1; if it is ignored as a duplicate returns 0. Finally .Fn history returns \-1 if an error occurred. @@ -739,6 +768,11 @@ Load the history list stored in .It Dv H_SAVE , Fa "const char *file" Save the history list to .Fa file . +.It Dv H_SAVE_FP , Fa "FILE *fp" +Save the history list to the opened +.Ft FILE +pointer +.Fa fp . .It Dv H_SETUNIQUE , Fa "int unique" Set flag that adjacent identical event strings should not be entered into the history. @@ -859,17 +893,22 @@ and the readline emulation appeared in appeared in .Nx 1.5 . .Sh AUTHORS +.An -nosplit The .Nm -library was written by Christos Zoulas. -Luke Mewburn wrote this manual and implemented +library was written by +.An Christos Zoulas . +.An Luke Mewburn +wrote this manual and implemented .Dv CC_REDISPLAY , .Dv CC_REFRESH_BEEP , .Dv EL_EDITMODE , and .Dv EL_RPROMPT . -Jaromir Dolecek implemented the readline emulation. -Johny Mattsson implemented wide-character support. +.An Jaromir Dolecek +implemented the readline emulation. +.An Johny Mattsson +implemented wide-character support. .Sh BUGS At this time, it is the responsibility of the caller to check the result of the diff --git a/editrc.5 b/editrc.5 index 0c01605b086c..9f796c772e68 100644 --- a/editrc.5 +++ b/editrc.5 @@ -1,4 +1,4 @@ -.\" $NetBSD: editrc.5,v 1.26 2012/06/02 14:19:20 njoly Exp $ +.\" $NetBSD: editrc.5,v 1.29 2014/12/25 13:39:41 wiz Exp $ .\" .\" Copyright (c) 1997-2000 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -26,7 +26,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd October 18, 2003 +.Dd December 25, 2014 .Dt EDITRC 5 .Os .Sh NAME @@ -42,7 +42,8 @@ file defines various settings to be used by the library. .Pp The format of each line is: -.Dl [prog:]command [arg [...]] +.Pp +.Dl [prog:]command [arg ...] .Pp .Ar command is one of the @@ -103,16 +104,12 @@ to .Ar key . Options include: .Bl -tag -width 4n -.It Fl e -Bind all keys to the standard GNU Emacs-like bindings. -.It Fl v -Bind all keys to the standard -.Xr vi 1 Ns -like -bindings. .It Fl a List or change key bindings in the .Xr vi 1 mode alternate (command mode) key map. +.It Fl e +Bind all keys to the standard GNU Emacs-like bindings. .It Fl k .Ar key is interpreted as a symbolic arrow key name, which may be one of @@ -134,6 +131,10 @@ Bound keys in .Ar command are themselves reinterpreted, and this continues for ten levels of interpretation. +.It Fl v +Bind all keys to the standard +.Xr vi 1 Ns -like +bindings. .El .Pp .Ar command @@ -149,7 +150,7 @@ can contain control characters of the form .Sq No ^ Ar character .Sm on .Po -e.g. +e.g.\& .Sq ^A .Pc , and the following backslashed escape sequences: @@ -186,7 +187,7 @@ and .Sq ^ . .It Ic echotc Oo Fl sv Oc Ar arg Ar ... Exercise terminal capabilities given in -.Ar arg Ar ... . +.Ar arg ... . If .Ar arg is @@ -230,9 +231,6 @@ is non zero, only keep unique history entries. If .Dv n is zero, then keep all entries (the default). -.It Ic telltc -List the values of all the terminal capabilities (see -.Xr termcap 5 ) . .It Ic settc Ar cap Ar val Set the terminal capability .Ar cap @@ -291,6 +289,9 @@ If is empty then the character is set to .Dv _POSIX_VDISABLE . +.It Ic telltc +List the values of all the terminal capabilities (see +.Xr termcap 5 ) . .El .Sh EDITOR COMMANDS The following editor commands are available for use in key bindings: @@ -300,11 +301,11 @@ The following editor commands are available for use in key bindings: Vi paste previous deletion to the right of the cursor. .It Ic vi-paste-prev Vi paste previous deletion to the left of the cursor. -.It Ic vi-prev-space-word +.It Ic vi-prev-big-word Vi move to the previous space delimited word. .It Ic vi-prev-word Vi move to the previous word. -.It Ic vi-next-space-word +.It Ic vi-next-big-word Vi move to the next space delimited word. .It Ic vi-next-word Vi move to the next word. @@ -332,9 +333,9 @@ Vi enter insert mode after the cursor. Vi enter insert mode at end of line. .It Ic vi-delete-meta Vi delete prefix command. -.It Ic vi-end-word +.It Ic vi-end-big-word Vi move to the end of the current space delimited word. -.It Ic vi-to-end-word +.It Ic vi-end-word Vi move to the end of the current word. .It Ic vi-undo Vi undo last change. @@ -368,6 +369,28 @@ Vi move up to the character specified previous. Vi repeat current character search in the same search direction. .It Ic vi-repeat-prev-char Vi repeat current character search in the opposite search direction. +.It Ic vi-match +Vi go to matching () {} or []. +.It Ic vi-undo-line +Vi undo all changes to line. +.It Ic vi-to-column +Vi go to specified column. +.It Ic vi-yank-end +Vi yank to end of line. +.It Ic vi-yank +Vi yank. +.It Ic vi-comment-out +Vi comment out current command. +.It Ic vi-alias +Vi include shell alias. +.It Ic vi-to-history-line +Vi go to specified history file line.. +.It Ic vi-histedit +Vi edit history line with vi. +.It Ic vi-history-word +Vi append word from previous input line. +.It Ic vi-redo +Vi redo last non-motion command. .It Ic em-delete-or-list Delete character under cursor or list completions if at end of line. .It Ic em-delete-next-word @@ -478,14 +501,24 @@ Move down one line. Editline extended command. .El .\" End of section automatically generated with makelist +.Sh FILES +.Bl -tag -width "~/.editrcXXX" +.It Pa ~/.editrc +User configuration file for the +.Xr editline 3 +library. +.El .Sh SEE ALSO .Xr editline 3 , .Xr regex 3 , .Xr termcap 5 .Sh AUTHORS +.An -nosplit The .Nm editline -library was written by Christos Zoulas, -and this manual was written by Luke Mewburn, +library was written by +.An Christos Zoulas , +and this manual was written by +.An Luke Mewburn , with some sections inspired by .Xr tcsh 1 . diff --git a/el.c b/el.c index d62790c1f16f..864193d59719 100644 --- a/el.c +++ b/el.c @@ -1,4 +1,4 @@ -/* $NetBSD: el.c,v 1.71 2012/09/11 11:58:53 christos Exp $ */ +/* $NetBSD: el.c,v 1.73 2014/06/18 18:12:28 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94"; #else -__RCSID("$NetBSD: el.c,v 1.71 2012/09/11 11:58:53 christos Exp $"); +__RCSID("$NetBSD: el.c,v 1.73 2014/06/18 18:12:28 christos Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -59,6 +59,14 @@ __RCSID("$NetBSD: el.c,v 1.71 2012/09/11 11:58:53 christos Exp $"); */ public EditLine * el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr) +{ + return el_init_fd(prog, fin, fout, ferr, fileno(fin), fileno(fout), + fileno(ferr)); +} + +public EditLine * +el_init_fd(const char *prog, FILE *fin, FILE *fout, FILE *ferr, + int fdin, int fdout, int fderr) { EditLine *el = el_malloc(sizeof(*el)); @@ -71,9 +79,9 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr) el->el_outfile = fout; el->el_errfile = ferr; - el->el_infd = fileno(fin); - el->el_outfd = fileno(fout); - el->el_errfd = fileno(ferr); + el->el_infd = fdin; + el->el_outfd = fdout; + el->el_errfd = fderr; el->el_prog = Strdup(ct_decode_string(prog, &el->el_scratch)); if (el->el_prog == NULL) { @@ -186,6 +194,13 @@ FUN(el,set)(EditLine *el, int op, ...) break; } + case EL_ALIAS_TEXT: { + el_afunc_t p = va_arg(ap, el_afunc_t); + void *arg = va_arg(ap, void *); + rv = ch_aliasfun(el, p, arg); + break; + } + case EL_PROMPT_ESC: case EL_RPROMPT_ESC: { el_pfunc_t p = va_arg(ap, el_pfunc_t); diff --git a/eln.c b/eln.c index 1b829c2c6f1b..5bcfb4f2b3b3 100644 --- a/eln.c +++ b/eln.c @@ -1,4 +1,4 @@ -/* $NetBSD: eln.c,v 1.14 2012/03/11 21:15:25 christos Exp $ */ +/* $NetBSD: eln.c,v 1.17 2014/06/18 18:12:28 christos Exp $ */ /*- * Copyright (c) 2009 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include "config.h" #if !defined(lint) && !defined(SCCSID) -__RCSID("$NetBSD: eln.c,v 1.14 2012/03/11 21:15:25 christos Exp $"); +__RCSID("$NetBSD: eln.c,v 1.17 2014/06/18 18:12:28 christos Exp $"); #endif /* not lint && not SCCSID */ #include "histedit.h" @@ -125,6 +125,22 @@ el_set(EditLine *el, int op, ...) break; } + case EL_ALIAS_TEXT: { + el_afunc_t p = va_arg(ap, el_afunc_t); + void *arg = va_arg(ap, void *); + ret = ch_aliasfun(el, p, arg); + break; + } + + case EL_PROMPT_ESC: + case EL_RPROMPT_ESC: { + el_pfunc_t p = va_arg(ap, el_pfunc_t); + int c = va_arg(ap, int); + + ret = prompt_set(el, p, c, op, 0); + break; + } + case EL_TERMINAL: /* const char * */ ret = el_wset(el, op, va_arg(ap, char *)); break; @@ -149,10 +165,10 @@ el_set(EditLine *el, int op, ...) const char *argv[20]; int i; const wchar_t **wargv; - for (i = 1; i < (int)__arraycount(argv); ++i) - if ((argv[i] = va_arg(ap, char *)) == NULL) + for (i = 1; i < (int)__arraycount(argv) - 1; ++i) + if ((argv[i] = va_arg(ap, const char *)) == NULL) break; - argv[0] = NULL; + argv[0] = argv[i] = NULL; wargv = (const wchar_t **) ct_decode_argv(i + 1, argv, &el->el_lgcyconv); if (!wargv) { @@ -220,27 +236,31 @@ el_set(EditLine *el, int op, ...) el->el_flags |= NARROW_HISTORY; break; } + /* XXX: do we need to change el_rfunc_t? */ case EL_GETCFN: /* el_rfunc_t */ ret = el_wset(el, op, va_arg(ap, el_rfunc_t)); el->el_flags |= NARROW_READ; break; + case EL_CLIENTDATA: /* void * */ ret = el_wset(el, op, va_arg(ap, void *)); break; + case EL_SETFP: { /* int, FILE * */ int what = va_arg(ap, int); FILE *fp = va_arg(ap, FILE *); ret = el_wset(el, op, what, fp); break; } - case EL_PROMPT_ESC: /* el_pfunc_t, char */ - case EL_RPROMPT_ESC: { - el_pfunc_t p = va_arg(ap, el_pfunc_t); - char c = (char)va_arg(ap, int); - ret = prompt_set(el, p, c, op, 0); + + case EL_REFRESH: + re_clear_display(el); + re_refresh(el); + terminal__flush(el); + ret = 0; break; - } + default: ret = -1; break; diff --git a/filecomplete.c b/filecomplete.c index 5e98cf56442d..576414d3ba69 100644 --- a/filecomplete.c +++ b/filecomplete.c @@ -1,4 +1,4 @@ -/* $NetBSD: filecomplete.c,v 1.31 2011/09/16 16:13:16 plunky Exp $ */ +/* $NetBSD: filecomplete.c,v 1.34 2014/10/18 15:07:02 riz Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ #include "config.h" #if !defined(lint) && !defined(SCCSID) -__RCSID("$NetBSD: filecomplete.c,v 1.31 2011/09/16 16:13:16 plunky Exp $"); +__RCSID("$NetBSD: filecomplete.c,v 1.34 2014/10/18 15:07:02 riz Exp $"); #endif /* not lint && not SCCSID */ #include @@ -64,7 +64,7 @@ static const Char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', * if ``user'' isn't valid user name or ``txt'' doesn't start * w/ '~', returns pointer to strdup()ed copy of ``txt'' * - * it's callers's responsibility to free() returned string + * it's the caller's responsibility to free() the returned string */ char * fn_tilde_expand(const char *txt) @@ -137,7 +137,7 @@ fn_tilde_expand(const char *txt) * such file can be found * value of ``state'' is ignored * - * it's caller's responsibility to free returned string + * it's the caller's responsibility to free the returned string */ char * fn_filename_completion_function(const char *text, int state) @@ -490,7 +490,8 @@ fn_complete(EditLine *el, if (what_to_do == '?') goto display_matches; - if (matches[2] == NULL && strcmp(matches[0], matches[1]) == 0) { + if (matches[2] == NULL && + (matches[1] == NULL || strcmp(matches[0], matches[1]) == 0)) { /* * We found exact match. Add a space after * it, unless we do filename completion and the diff --git a/hist.h b/hist.h index a63be499dbdb..58e5876c9189 100644 --- a/hist.h +++ b/hist.h @@ -1,4 +1,4 @@ -/* $NetBSD: hist.h,v 1.13 2011/07/28 20:50:55 christos Exp $ */ +/* $NetBSD: hist.h,v 1.14 2014/05/11 01:05:17 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -73,6 +73,7 @@ typedef struct el_history_t { #define HIST_SET(el, num) HIST_FUN(el, H_SET, num) #define HIST_LOAD(el, fname) HIST_FUN(el, H_LOAD fname) #define HIST_SAVE(el, fname) HIST_FUN(el, H_SAVE fname) +#define HIST_SAVE_FP(el, fp) HIST_FUN(el, H_SAVE_FP fp) protected int hist_init(EditLine *); protected void hist_end(EditLine *); diff --git a/histedit.h b/histedit.h index 61f9875873dc..94f33ed2a165 100644 --- a/histedit.h +++ b/histedit.h @@ -1,4 +1,4 @@ -/* $NetBSD: histedit.h,v 1.49 2012/05/31 13:16:39 christos Exp $ */ +/* $NetBSD: histedit.h,v 1.53 2014/06/18 18:12:28 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -84,6 +84,8 @@ typedef struct lineinfo { * Initialization, cleanup, and resetting */ EditLine *el_init(const char *, FILE *, FILE *, FILE *); +EditLine *el_init_fd(const char *, FILE *, FILE *, FILE *, + int, int, int); void el_end(EditLine *); void el_reset(EditLine *); @@ -154,6 +156,7 @@ unsigned char _el_fn_complete(EditLine *, int); #define EL_PROMPT_ESC 21 /* , prompt_func, Char); set/get */ #define EL_RPROMPT_ESC 22 /* , prompt_func, Char); set/get */ #define EL_RESIZE 23 /* , el_zfunc_t, void *); set */ +#define EL_ALIAS_TEXT 24 /* , el_afunc_t, void *); set */ #define EL_BUILTIN_GETCFN (NULL) @@ -222,6 +225,7 @@ int history(History *, HistEvent *, int, ...); #define H_NEXT_EVDATA 23 /* , const int, histdata_t *); */ #define H_DELDATA 24 /* , int, histdata_t *);*/ #define H_REPLACE 25 /* , const char *, histdata_t); */ +#define H_SAVE_FP 26 /* , FILE *); */ @@ -277,6 +281,7 @@ int el_wparse(EditLine *, int, const wchar_t **); int el_wset(EditLine *, int, ...); int el_wget(EditLine *, int, ...); +int el_cursor(EditLine *, int); const LineInfoW *el_wline(EditLine *); int el_winsertstr(EditLine *, const wchar_t *); #define el_wdeletestr el_deletestr diff --git a/history.c b/history.c index 7e8f5209ca5f..6cd05a475b81 100644 --- a/history.c +++ b/history.c @@ -1,4 +1,4 @@ -/* $NetBSD: history.c,v 1.46 2011/11/18 20:39:18 christos Exp $ */ +/* $NetBSD: history.c,v 1.47 2014/05/11 01:05:17 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: history.c,v 1.46 2011/11/18 20:39:18 christos Exp $"); +__RCSID("$NetBSD: history.c,v 1.47 2014/05/11 01:05:17 christos Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -105,6 +105,7 @@ private int history_getunique(TYPE(History) *, TYPE(HistEvent) *); private int history_set_fun(TYPE(History) *, TYPE(History) *); private int history_load(TYPE(History) *, const char *); private int history_save(TYPE(History) *, const char *); +private int history_save_fp(TYPE(History) *, FILE *); private int history_prev_event(TYPE(History) *, TYPE(HistEvent) *, int); private int history_next_event(TYPE(History) *, TYPE(HistEvent) *, int); private int history_next_string(TYPE(History) *, TYPE(HistEvent) *, const Char *); @@ -784,13 +785,12 @@ done: } -/* history_save(): +/* history_save_fp(): * TYPE(History) save function */ private int -history_save(TYPE(History) *h, const char *fname) +history_save_fp(TYPE(History) *h, FILE *fp) { - FILE *fp; TYPE(HistEvent) ev; int i = -1, retval; size_t len, max_size; @@ -800,9 +800,6 @@ history_save(TYPE(History) *h, const char *fname) static ct_buffer_t conv; #endif - if ((fp = fopen(fname, "w")) == NULL) - return -1; - if (fchmod(fileno(fp), S_IRUSR|S_IWUSR) == -1) goto done; if (fputs(hist_cookie, fp) == EOF) @@ -831,11 +828,29 @@ history_save(TYPE(History) *h, const char *fname) oomem: h_free(ptr); done: - (void) fclose(fp); return i; } +/* history_save(): + * History save function + */ +private int +history_save(TYPE(History) *h, const char *fname) +{ + FILE *fp; + int i; + + if ((fp = fopen(fname, "w")) == NULL) + return -1; + + i = history_save_fp(h, fp); + + (void) fclose(fp); + return i; +} + + /* history_prev_event(): * Find the previous event, with number given */ @@ -1016,6 +1031,12 @@ FUNW(history)(TYPE(History) *h, TYPE(HistEvent) *ev, int fun, ...) he_seterrev(ev, _HE_HIST_WRITE); break; + case H_SAVE_FP: + retval = history_save_fp(h, va_arg(va, FILE *)); + if (retval == -1) + he_seterrev(ev, _HE_HIST_WRITE); + break; + case H_PREV_EVENT: retval = history_prev_event(h, ev, va_arg(va, int)); break; diff --git a/map.c b/map.c index 802c37174c24..79f793cb6694 100644 --- a/map.c +++ b/map.c @@ -1,4 +1,4 @@ -/* $NetBSD: map.c,v 1.31 2011/11/18 20:39:18 christos Exp $ */ +/* $NetBSD: map.c,v 1.34 2014/07/06 18:15:34 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: map.c,v 1.31 2011/11/18 20:39:18 christos Exp $"); +__RCSID("$NetBSD: map.c,v 1.34 2014/07/06 18:15:34 christos Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -1249,7 +1249,7 @@ map_bind(EditLine *el, int argc, const Char **argv) Char inbuf[EL_BUFSIZ]; Char outbuf[EL_BUFSIZ]; const Char *in = NULL; - Char *out = NULL; + Char *out; el_bindings_t *bp, *ep; int cmd; int key; @@ -1368,7 +1368,7 @@ map_bind(EditLine *el, int argc, const Char **argv) return -1; } if (key) - terminal_set_arrow(el, in, keymacro_map_str(el, out), ntype); + terminal_set_arrow(el, in, keymacro_map_cmd(el, cmd), ntype); else { if (in[1]) { keymacro_add(el, in, keymacro_map_cmd(el, cmd), ntype); @@ -1396,7 +1396,7 @@ protected int map_addfunc(EditLine *el, const Char *name, const Char *help, el_func_t func) { void *p; - size_t nf = (size_t)el->el_map.nfunc + 1; + size_t nf = el->el_map.nfunc + 1; if (name == NULL || help == NULL || func == NULL) return -1; diff --git a/map.h b/map.h index 8e0c7e4eaa11..f01b58b818be 100644 --- a/map.h +++ b/map.h @@ -1,4 +1,4 @@ -/* $NetBSD: map.h,v 1.9 2009/12/30 22:37:40 christos Exp $ */ +/* $NetBSD: map.h,v 1.10 2014/07/06 18:15:34 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -57,7 +57,7 @@ typedef struct el_map_t { int type; /* Emacs or vi */ el_bindings_t *help; /* The help for the editor functions */ el_func_t *func; /* List of available functions */ - int nfunc; /* The number of functions/help items */ + size_t nfunc; /* The number of functions/help items */ } el_map_t; #define MAP_EMACS 0 diff --git a/parse.c b/parse.c index f1c4391a2f04..47d6f7d9b9d3 100644 --- a/parse.c +++ b/parse.c @@ -1,4 +1,4 @@ -/* $NetBSD: parse.c,v 1.26 2011/08/16 16:25:15 christos Exp $ */ +/* $NetBSD: parse.c,v 1.27 2014/07/06 18:15:34 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: parse.c,v 1.26 2011/08/16 16:25:15 christos Exp $"); +__RCSID("$NetBSD: parse.c,v 1.27 2014/07/06 18:15:34 christos Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -276,10 +276,11 @@ parse__string(Char *out, const Char *in) protected int parse_cmd(EditLine *el, const Char *cmd) { - el_bindings_t *b; + el_bindings_t *b = el->el_map.help; + size_t i; - for (b = el->el_map.help; b->name != NULL; b++) - if (Strcmp(b->name, cmd) == 0) - return b->func; + for (i = 0; i < el->el_map.nfunc; i++) + if (Strcmp(b[i].name, cmd) == 0) + return b[i].func; return -1; } diff --git a/read.c b/read.c index 74796b1db2f8..b81cff609f28 100644 --- a/read.c +++ b/read.c @@ -1,4 +1,4 @@ -/* $NetBSD: read.c,v 1.69 2012/09/11 12:31:08 christos Exp $ */ +/* $NetBSD: read.c,v 1.71 2014/07/06 18:15:34 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: read.c,v 1.69 2012/09/11 12:31:08 christos Exp $"); +__RCSID("$NetBSD: read.c,v 1.71 2014/07/06 18:15:34 christos Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -341,6 +341,13 @@ read_char(EditLine *el, Char *cp) } } + /* Test for EOF */ + if (num_read == 0) { + errno = 0; + *cp = '\0'; + return 0; + } + #ifdef WIDECHAR if (el->el_flags & CHARSET_IS_UTF8) { if (!utf8_islead((unsigned char)cbuf[0])) @@ -590,7 +597,7 @@ FUN(el,gets)(EditLine *el, int *nread) el->el_line.cursor = el->el_line.buffer; break; } - if ((unsigned int)cmdnum >= (unsigned int)el->el_map.nfunc) { /* BUG CHECK command */ + if ((size_t)cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */ #ifdef DEBUG_EDIT (void) fprintf(el->el_errfile, "ERROR: illegal command from key 0%o\r\n", ch); diff --git a/readline.c b/readline.c index 534acd8af241..ba32efb969a8 100644 --- a/readline.c +++ b/readline.c @@ -1,4 +1,4 @@ -/* $NetBSD: readline.c,v 1.105 2012/07/12 18:46:20 christos Exp $ */ +/* $NetBSD: readline.c,v 1.113 2014/10/18 08:33:23 snj Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ #include "config.h" #if !defined(lint) && !defined(SCCSID) -__RCSID("$NetBSD: readline.c,v 1.105 2012/07/12 18:46:20 christos Exp $"); +__RCSID("$NetBSD: readline.c,v 1.113 2014/10/18 08:33:23 snj Exp $"); #endif /* not lint && not SCCSID */ #include @@ -84,6 +84,14 @@ VFunction *rl_event_hook = NULL; KEYMAP_ENTRY_ARRAY emacs_standard_keymap, emacs_meta_keymap, emacs_ctlx_keymap; +/* + * The following is not implemented; we always catch signals in the + * libedit fashion: set handlers on entry to el_gets() and clear them + * on the way out. This simplistic approach works for most cases; if + * it does not work for your application, please let us know. + */ +int rl_catch_signals = 1; +int rl_catch_sigwinch = 1; int history_base = 1; /* probably never subject to change */ int history_length = 0; @@ -109,7 +117,6 @@ char *rl_terminal_name = NULL; int rl_already_prompted = 0; int rl_filename_completion_desired = 0; int rl_ignore_completion_duplicates = 0; -int rl_catch_signals = 1; int readline_echoing_p = 1; int _rl_print_completions_horizontally = 0; VFunction *rl_redisplay_function = NULL; @@ -229,13 +236,20 @@ static const char * _default_history_file(void) { struct passwd *p; - static char path[PATH_MAX]; + static char *path; + size_t len; - if (*path) + if (path) return path; + if ((p = getpwuid(getuid())) == NULL) return NULL; - (void)snprintf(path, sizeof(path), "%s/.history", p->pw_dir); + + len = strlen(p->pw_dir) + sizeof("/.history"); + if ((path = malloc(len)) == NULL) + return NULL; + + (void)snprintf(path, len, "%s/.history", p->pw_dir); return path; } @@ -324,7 +338,7 @@ rl_initialize(void) el_set(e, EL_SIGNAL, rl_catch_signals); /* set default mode to "emacs"-style and read setting afterwards */ - /* so this can be overriden */ + /* so this can be overridden */ el_set(e, EL_EDITOR, "emacs"); if (rl_terminal_name != NULL) el_set(e, EL_TERMINAL, rl_terminal_name); @@ -620,7 +634,7 @@ get_history_event(const char *cmd, int *cindex, int qchar) * returns 0 if data was not modified, 1 if it was and 2 if the string * should be only printed and not executed; in case of error, * returns -1 and *result points to NULL - * it's callers responsibility to free() string returned in *result + * it's the caller's responsibility to free() the string returned in *result */ static int _history_expand_command(const char *command, size_t offs, size_t cmdlen, @@ -1468,6 +1482,9 @@ clear_history(void) { HistEvent ev; + if (h == NULL || e == NULL) + rl_initialize(); + (void)history(h, &ev, H_CLEAR); history_length = 0; } @@ -1677,7 +1694,7 @@ filename_completion_function(const char *name, int state) * which starts with supplied text * text contains a partial username preceded by random character * (usually '~'); state resets search from start (??? should we do that anyway) - * it's callers responsibility to free returned value + * it's the caller's responsibility to free the returned value */ char * username_completion_function(const char *text, int state) @@ -1927,7 +1944,7 @@ rl_add_defun(const char *name, Function *fun, int c) map[(unsigned char)c] = fun; el_set(e, EL_ADDFN, name, name, rl_bind_wrapper); vis(dest, c, VIS_WHITE|VIS_NOSLASH, 0); - el_set(e, EL_BIND, dest, name); + el_set(e, EL_BIND, dest, name, NULL); return 0; } @@ -1953,7 +1970,7 @@ rl_callback_read_char(void) } else wbuf = NULL; (*(void (*)(const char *))rl_linefunc)(wbuf); - //el_set(e, EL_UNBUFFERED, 1); + el_set(e, EL_UNBUFFERED, 1); } } @@ -2035,7 +2052,7 @@ rl_variable_bind(const char *var, const char *value) * The proper return value is undocument, but this is what the * readline source seems to do. */ - return el_set(e, EL_BIND, "", var, value) == -1 ? 1 : 0; + return el_set(e, EL_BIND, "", var, value, NULL) == -1 ? 1 : 0; } void @@ -2104,9 +2121,9 @@ void rl_get_screen_size(int *rows, int *cols) { if (rows) - el_get(e, EL_GETTC, "li", rows); + el_get(e, EL_GETTC, "li", rows, (void *)0); if (cols) - el_get(e, EL_GETTC, "co", cols); + el_get(e, EL_GETTC, "co", cols, (void *)0); } void @@ -2114,9 +2131,9 @@ rl_set_screen_size(int rows, int cols) { char buf[64]; (void)snprintf(buf, sizeof(buf), "%d", rows); - el_set(e, EL_SETTC, "li", buf); + el_set(e, EL_SETTC, "li", buf, NULL); (void)snprintf(buf, sizeof(buf), "%d", cols); - el_set(e, EL_SETTC, "co", buf); + el_set(e, EL_SETTC, "co", buf, NULL); } char ** diff --git a/readline/readline.h b/readline/readline.h index 0d1371345af0..932febb9de34 100644 --- a/readline/readline.h +++ b/readline/readline.h @@ -1,4 +1,4 @@ -/* $NetBSD: readline.h,v 1.33 2012/05/15 17:30:04 christos Exp $ */ +/* $NetBSD: readline.h,v 1.34 2013/05/28 00:10:34 christos Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -125,6 +125,8 @@ extern char *rl_prompt; /* * The following is not implemented */ +extern int rl_catch_signals; +extern int rl_catch_sigwinch; extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap, emacs_meta_keymap, emacs_ctlx_keymap; diff --git a/shlib_version b/shlib_version index 778486cf30d9..303609d268aa 100644 --- a/shlib_version +++ b/shlib_version @@ -1,5 +1,5 @@ -# $NetBSD: shlib_version,v 1.18 2009/01/11 03:07:48 christos Exp $ +# $NetBSD: shlib_version,v 1.19 2013/01/22 20:23:21 christos Exp $ # Remember to update distrib/sets/lists/base/shl.* when changing # major=3 -minor=0 +minor=1 diff --git a/tty.c b/tty.c index 57c8ee8916c8..ce7d86c07db8 100644 --- a/tty.c +++ b/tty.c @@ -1,4 +1,4 @@ -/* $NetBSD: tty.c,v 1.42 2012/05/15 15:59:01 christos Exp $ */ +/* $NetBSD: tty.c,v 1.46 2014/06/18 18:52:49 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: tty.c,v 1.42 2012/05/15 15:59:01 christos Exp $"); +__RCSID("$NetBSD: tty.c,v 1.46 2014/06/18 18:52:49 christos Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -48,6 +48,7 @@ __RCSID("$NetBSD: tty.c,v 1.42 2012/05/15 15:59:01 christos Exp $"); #include #include /* for isatty */ #include /* for ffs */ +#include /* for abort */ #include "el.h" #include "tty.h" @@ -459,6 +460,7 @@ private void tty__getchar(struct termios *, unsigned char *); private void tty__setchar(struct termios *, unsigned char *); private speed_t tty__getspeed(struct termios *); private int tty_setup(EditLine *); +private void tty_setup_flags(EditLine *, struct termios *, int); #define t_qu t_ts @@ -517,17 +519,7 @@ tty_setup(EditLine *el) el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex); el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex); - el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask; - el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][MD_INP].t_setmask; - - el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask; - el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][MD_OUT].t_setmask; - - el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask; - el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][MD_CTL].t_setmask; - - el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask; - el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][MD_LIN].t_setmask; + tty_setup_flags(el, &el->el_tty.t_ex, EX_IO); /* * Reset the tty chars to reasonable defaults @@ -562,17 +554,7 @@ tty_setup(EditLine *el) } } - el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask; - el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask; - - el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask; - el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][MD_OUT].t_setmask; - - el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask; - el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][MD_CTL].t_setmask; - - el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask; - el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][MD_LIN].t_setmask; + tty_setup_flags(el, &el->el_tty.t_ed, ED_IO); tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]); tty_bind_char(el, 1); @@ -938,6 +920,58 @@ tty_bind_char(EditLine *el, int force) } +private tcflag_t * +tty__get_flag(struct termios *t, int kind) { + switch (kind) { + case MD_INP: + return &t->c_iflag; + case MD_OUT: + return &t->c_oflag; + case MD_CTL: + return &t->c_cflag; + case MD_LIN: + return &t->c_lflag; + default: + abort(); + /*NOTREACHED*/ + } +} + + +private tcflag_t +tty_update_flag(EditLine *el, tcflag_t f, int mode, int kind) +{ + f &= ~el->el_tty.t_t[mode][kind].t_clrmask; + f |= el->el_tty.t_t[mode][kind].t_setmask; + return f; +} + + +private void +tty_update_flags(EditLine *el, int kind) +{ + tcflag_t *tt, *ed, *ex; + tt = tty__get_flag(&el->el_tty.t_ts, kind); + ed = tty__get_flag(&el->el_tty.t_ed, kind); + ex = tty__get_flag(&el->el_tty.t_ex, kind); + + if (*tt != *ex && (kind != MD_CTL || *tt != *ed)) { + *ed = tty_update_flag(el, *tt, ED_IO, kind); + *ex = tty_update_flag(el, *tt, EX_IO, kind); + } +} + + +private void +tty_update_char(EditLine *el, int mode, int c) { + if (!((el->el_tty.t_t[mode][MD_CHAR].t_setmask & C_SH(c))) + && (el->el_tty.t_c[TS_IO][c] != el->el_tty.t_c[EX_IO][c])) + el->el_tty.t_c[mode][c] = el->el_tty.t_c[TS_IO][c]; + if (el->el_tty.t_t[mode][MD_CHAR].t_clrmask & C_SH(c)) + el->el_tty.t_c[mode][c] = el->el_tty.t_vdisable; +} + + /* tty_rawmode(): * Set terminal into 1 character at a time mode. */ @@ -973,112 +1007,42 @@ tty_rawmode(EditLine *el) (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed); } if (tty__cooked_mode(&el->el_tty.t_ts)) { - if (el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) { - el->el_tty.t_ex.c_cflag = - el->el_tty.t_ts.c_cflag; - el->el_tty.t_ex.c_cflag &= - ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask; - el->el_tty.t_ex.c_cflag |= - el->el_tty.t_t[EX_IO][MD_CTL].t_setmask; + int i; - el->el_tty.t_ed.c_cflag = - el->el_tty.t_ts.c_cflag; - el->el_tty.t_ed.c_cflag &= - ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask; - el->el_tty.t_ed.c_cflag |= - el->el_tty.t_t[ED_IO][MD_CTL].t_setmask; - } - if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) && - (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) { - el->el_tty.t_ex.c_lflag = - el->el_tty.t_ts.c_lflag; - el->el_tty.t_ex.c_lflag &= - ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask; - el->el_tty.t_ex.c_lflag |= - el->el_tty.t_t[EX_IO][MD_LIN].t_setmask; + for (i = MD_INP; i <= MD_LIN; i++) + tty_update_flags(el, i); - el->el_tty.t_ed.c_lflag = - el->el_tty.t_ts.c_lflag; - el->el_tty.t_ed.c_lflag &= - ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask; - el->el_tty.t_ed.c_lflag |= - el->el_tty.t_t[ED_IO][MD_LIN].t_setmask; - } - if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) && - (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) { - el->el_tty.t_ex.c_iflag = - el->el_tty.t_ts.c_iflag; - el->el_tty.t_ex.c_iflag &= - ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask; - el->el_tty.t_ex.c_iflag |= - el->el_tty.t_t[EX_IO][MD_INP].t_setmask; - - el->el_tty.t_ed.c_iflag = - el->el_tty.t_ts.c_iflag; - el->el_tty.t_ed.c_iflag &= - ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask; - el->el_tty.t_ed.c_iflag |= - el->el_tty.t_t[ED_IO][MD_INP].t_setmask; - } - if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) && - (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) { - el->el_tty.t_ex.c_oflag = - el->el_tty.t_ts.c_oflag; - el->el_tty.t_ex.c_oflag &= - ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask; - el->el_tty.t_ex.c_oflag |= - el->el_tty.t_t[EX_IO][MD_OUT].t_setmask; - - el->el_tty.t_ed.c_oflag = - el->el_tty.t_ts.c_oflag; - el->el_tty.t_ed.c_oflag &= - ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask; - el->el_tty.t_ed.c_oflag |= - el->el_tty.t_t[ED_IO][MD_OUT].t_setmask; - } if (tty__gettabs(&el->el_tty.t_ex) == 0) el->el_tty.t_tabs = 0; else el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0; - { - int i; + tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]); + /* + * Check if the user made any changes. + * If he did, then propagate the changes to the + * edit and execute data structures. + */ + for (i = 0; i < C_NCC; i++) + if (el->el_tty.t_c[TS_IO][i] != + el->el_tty.t_c[EX_IO][i]) + break; - tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]); + if (i != C_NCC) { /* - * Check if the user made any changes. - * If he did, then propagate the changes to the - * edit and execute data structures. - */ + * Propagate changes only to the unprotected + * chars that have been modified just now. + */ for (i = 0; i < C_NCC; i++) - if (el->el_tty.t_c[TS_IO][i] != - el->el_tty.t_c[EX_IO][i]) - break; + tty_update_char(el, ED_IO, i); - if (i != C_NCC) { - /* - * Propagate changes only to the unprotected - * chars that have been modified just now. - */ - for (i = 0; i < C_NCC; i++) { - if (!((el->el_tty.t_t[ED_IO][MD_CHAR].t_setmask & C_SH(i))) - && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i])) - el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i]; - if (el->el_tty.t_t[ED_IO][MD_CHAR].t_clrmask & C_SH(i)) - el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable; - } - tty_bind_char(el, 0); - tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]); + tty_bind_char(el, 0); + tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]); - for (i = 0; i < C_NCC; i++) { - if (!((el->el_tty.t_t[EX_IO][MD_CHAR].t_setmask & C_SH(i))) - && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i])) - el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i]; - if (el->el_tty.t_t[EX_IO][MD_CHAR].t_clrmask & C_SH(i)) - el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable; - } - tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); - } + for (i = 0; i < C_NCC; i++) + tty_update_char(el, EX_IO, i); + + tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); } } if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) { @@ -1129,17 +1093,7 @@ tty_quotemode(EditLine *el) el->el_tty.t_qu = el->el_tty.t_ed; - el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][MD_INP].t_clrmask; - el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][MD_INP].t_setmask; - - el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][MD_OUT].t_clrmask; - el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][MD_OUT].t_setmask; - - el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][MD_CTL].t_clrmask; - el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][MD_CTL].t_setmask; - - el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][MD_LIN].t_clrmask; - el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][MD_LIN].t_setmask; + tty_setup_flags(el, &el->el_tty.t_qu, QU_IO); if (tty_setty(el, TCSADRAIN, &el->el_tty.t_qu) == -1) { #ifdef DEBUG_TTY @@ -1320,6 +1274,7 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv) } } + tty_setup_flags(el, tios, z); if (el->el_tty.t_mode == z) { if (tty_setty(el, TCSADRAIN, tios) == -1) { #ifdef DEBUG_TTY @@ -1357,3 +1312,14 @@ tty_printchar(EditLine *el, unsigned char *s) (void) fprintf(el->el_errfile, "\n"); } #endif /* notyet */ + + +private void +tty_setup_flags(EditLine *el, struct termios *tios, int mode) +{ + int kind; + for (kind = MD_INP; kind <= MD_LIN; kind++) { + tcflag_t *f = tty__get_flag(tios, kind); + *f = tty_update_flag(el, *f, mode, kind); + } +} diff --git a/tty.h b/tty.h index 7bdb0b2bb991..0bf4b64ce477 100644 --- a/tty.h +++ b/tty.h @@ -1,4 +1,4 @@ -/* $NetBSD: tty.h,v 1.14 2012/05/15 15:59:01 christos Exp $ */ +/* $NetBSD: tty.h,v 1.15 2014/05/19 19:54:12 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -442,6 +442,7 @@ #define QU_IO 2 /* used only for quoted chars */ #define NN_IO 3 /* The number of entries */ +/* Don't re-order */ #define MD_INP 0 #define MD_OUT 1 #define MD_CTL 2 diff --git a/vi.c b/vi.c index ec9abbd70c6a..53c478171815 100644 --- a/vi.c +++ b/vi.c @@ -1,4 +1,4 @@ -/* $NetBSD: vi.c,v 1.43 2012/01/16 14:57:45 christos Exp $ */ +/* $NetBSD: vi.c,v 1.45 2014/06/18 18:12:28 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -42,7 +42,7 @@ #if 0 static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: vi.c,v 1.43 2012/01/16 14:57:45 christos Exp $"); +__RCSID("$NetBSD: vi.c,v 1.45 2014/06/18 18:12:28 christos Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -918,34 +918,26 @@ vi_comment_out(EditLine *el, Int c __attribute__((__unused__))) * NB: posix implies that we should enter insert mode, however * this is against historical precedent... */ -#ifdef __weak_reference -__weakref_visible char *my_get_alias_text(const char *) - __weak_reference(get_alias_text); -#endif protected el_action_t /*ARGSUSED*/ vi_alias(EditLine *el, Int c __attribute__((__unused__))) { -#ifdef __weak_reference char alias_name[3]; - char *alias_text; + const char *alias_text; - if (my_get_alias_text == 0) { + if (el->el_chared.c_aliasfun == NULL) return CC_ERROR; - } alias_name[0] = '_'; alias_name[2] = 0; if (el_getc(el, &alias_name[1]) != 1) return CC_ERROR; - alias_text = my_get_alias_text(alias_name); + alias_text = (*el->el_chared.c_aliasfun)(el->el_chared.c_aliasarg, + alias_name); if (alias_text != NULL) FUN(el,push)(el, ct_decode_string(alias_text, &el->el_scratch)); return CC_NORM; -#else - return CC_ERROR; -#endif } /* vi_to_history_line():