summaryrefslogtreecommitdiffstats
path: root/lib/libedit/el.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libedit/el.c')
-rw-r--r--lib/libedit/el.c258
1 files changed, 142 insertions, 116 deletions
diff --git a/lib/libedit/el.c b/lib/libedit/el.c
index d6cfb2d..57ea6e5 100644
--- a/lib/libedit/el.c
+++ b/lib/libedit/el.c
@@ -1,3 +1,5 @@
+/* $NetBSD: el.c,v 1.73 2014/06/18 18:12:28 christos Exp $ */
+
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@@ -28,12 +30,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $NetBSD: el.c,v 1.55 2009/07/25 21:19:23 christos Exp $
*/
+#include "config.h"
#if !defined(lint) && !defined(SCCSID)
+#if 0
static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94";
+#else
+__RCSID("$NetBSD: el.c,v 1.73 2014/06/18 18:12:28 christos Exp $");
+#endif
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -41,29 +46,34 @@ __FBSDID("$FreeBSD$");
/*
* el.c: EditLine interface functions
*/
-#include "sys.h"
-
#include <sys/types.h>
#include <sys/param.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
+#include <locale.h>
+#include <langinfo.h>
#include "el.h"
-#define HAVE_ISSETUGID
-
/* el_init():
* Initialize editline and set default parameters.
*/
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));
+}
- EditLine *el = (EditLine *) el_malloc(sizeof(EditLine));
+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));
if (el == NULL)
- return (NULL);
+ return NULL;
memset(el, 0, sizeof(EditLine));
@@ -71,9 +81,12 @@ 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_infd = fdin;
+ el->el_outfd = fdout;
+ el->el_errfd = fderr;
- if ((el->el_prog = el_strdup(prog)) == NULL) {
+ el->el_prog = Strdup(ct_decode_string(prog, &el->el_scratch));
+ if (el->el_prog == NULL) {
el_free(el);
return NULL;
}
@@ -82,13 +95,19 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
* Initialize all the modules. Order is important!!!
*/
el->el_flags = 0;
+#ifdef WIDECHAR
+ if (setlocale(LC_CTYPE, NULL) != NULL){
+ if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0)
+ el->el_flags |= CHARSET_IS_UTF8;
+ }
+#endif
- if (term_init(el) == -1) {
+ if (terminal_init(el) == -1) {
el_free(el->el_prog);
el_free(el);
return NULL;
}
- (void) key_init(el);
+ (void) keymacro_init(el);
(void) map_init(el);
if (tty_init(el) == -1)
el->el_flags |= NO_TTY;
@@ -99,7 +118,7 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
(void) sig_init(el);
(void) read_init(el);
- return (el);
+ return el;
}
@@ -115,8 +134,8 @@ el_end(EditLine *el)
el_reset(el);
- term_end(el);
- key_end(el);
+ terminal_end(el);
+ keymacro_end(el);
map_end(el);
tty_end(el);
ch_end(el);
@@ -125,8 +144,14 @@ el_end(EditLine *el)
prompt_end(el);
sig_end(el);
- el_free((ptr_t) el->el_prog);
- el_free((ptr_t) el);
+ el_free(el->el_prog);
+#ifdef WIDECHAR
+ el_free(el->el_scratch.cbuff);
+ el_free(el->el_scratch.wbuff);
+ el_free(el->el_lgcyconv.cbuff);
+ el_free(el->el_lgcyconv.wbuff);
+#endif
+ el_free(el);
}
@@ -146,13 +171,13 @@ el_reset(EditLine *el)
* set the editline parameters
*/
public int
-el_set(EditLine *el, int op, ...)
+FUN(el,set)(EditLine *el, int op, ...)
{
va_list ap;
int rv = 0;
if (el == NULL)
- return (-1);
+ return -1;
va_start(ap, op);
switch (op) {
@@ -160,25 +185,39 @@ el_set(EditLine *el, int op, ...)
case EL_RPROMPT: {
el_pfunc_t p = va_arg(ap, el_pfunc_t);
- rv = prompt_set(el, p, 0, op);
+ rv = prompt_set(el, p, 0, op, 1);
+ break;
+ }
+
+ case EL_RESIZE: {
+ el_zfunc_t p = va_arg(ap, el_zfunc_t);
+ void *arg = va_arg(ap, void *);
+ rv = ch_resizefun(el, p, arg);
+ 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);
- char c = va_arg(ap, int);
+ int c = va_arg(ap, int);
- rv = prompt_set(el, p, c, op);
+ rv = prompt_set(el, p, c, op, 1);
break;
}
case EL_TERMINAL:
- rv = term_set(el, va_arg(ap, char *));
+ rv = terminal_set(el, va_arg(ap, char *));
break;
case EL_EDITOR:
- rv = map_set_editor(el, va_arg(ap, char *));
+ rv = map_set_editor(el, va_arg(ap, Char *));
break;
case EL_SIGNAL:
@@ -191,40 +230,39 @@ el_set(EditLine *el, int op, ...)
case EL_BIND:
case EL_TELLTC:
case EL_SETTC:
- case EL_GETTC:
case EL_ECHOTC:
case EL_SETTY:
{
- const char *argv[20];
+ const Char *argv[20];
int i;
- for (i = 1; i < 20; i++)
- if ((argv[i] = va_arg(ap, char *)) == NULL)
+ for (i = 1; i < (int)__arraycount(argv); i++)
+ if ((argv[i] = va_arg(ap, Char *)) == NULL)
break;
switch (op) {
case EL_BIND:
- argv[0] = "bind";
+ argv[0] = STR("bind");
rv = map_bind(el, i, argv);
break;
case EL_TELLTC:
- argv[0] = "telltc";
- rv = term_telltc(el, i, argv);
+ argv[0] = STR("telltc");
+ rv = terminal_telltc(el, i, argv);
break;
case EL_SETTC:
- argv[0] = "settc";
- rv = term_settc(el, i, argv);
+ argv[0] = STR("settc");
+ rv = terminal_settc(el, i, argv);
break;
case EL_ECHOTC:
- argv[0] = "echotc";
- rv = term_echotc(el, i, argv);
+ argv[0] = STR("echotc");
+ rv = terminal_echotc(el, i, argv);
break;
case EL_SETTY:
- argv[0] = "setty";
+ argv[0] = STR("setty");
rv = tty_stty(el, i, argv);
break;
@@ -238,8 +276,8 @@ el_set(EditLine *el, int op, ...)
case EL_ADDFN:
{
- char *name = va_arg(ap, char *);
- char *help = va_arg(ap, char *);
+ Char *name = va_arg(ap, Char *);
+ Char *help = va_arg(ap, Char *);
el_func_t func = va_arg(ap, el_func_t);
rv = map_addfunc(el, name, help, func);
@@ -249,9 +287,11 @@ el_set(EditLine *el, int op, ...)
case EL_HIST:
{
hist_fun_t func = va_arg(ap, hist_fun_t);
- ptr_t ptr = va_arg(ap, char *);
+ void *ptr = va_arg(ap, void *);
rv = hist_set(el, func, ptr);
+ if (!(el->el_flags & CHARSET_IS_UTF8))
+ el->el_flags &= ~NARROW_HISTORY;
break;
}
@@ -267,6 +307,7 @@ el_set(EditLine *el, int op, ...)
{
el_rfunc_t rc = va_arg(ap, el_rfunc_t);
rv = el_read_setfn(el, rc);
+ el->el_flags &= ~NARROW_READ;
break;
}
@@ -311,9 +352,11 @@ el_set(EditLine *el, int op, ...)
break;
case 1:
el->el_outfile = fp;
+ el->el_outfd = fileno(fp);
break;
case 2:
el->el_errfile = fp;
+ el->el_errfd = fileno(fp);
break;
default:
rv = -1;
@@ -325,7 +368,7 @@ el_set(EditLine *el, int op, ...)
case EL_REFRESH:
re_clear_display(el);
re_refresh(el);
- term__flush(el);
+ terminal__flush(el);
break;
default:
@@ -334,7 +377,7 @@ el_set(EditLine *el, int op, ...)
}
va_end(ap);
- return (rv);
+ return rv;
}
@@ -342,7 +385,7 @@ el_set(EditLine *el, int op, ...)
* retrieve the editline parameters
*/
public int
-el_get(EditLine *el, int op, ...)
+FUN(el,get)(EditLine *el, int op, ...)
{
va_list ap;
int rv;
@@ -356,14 +399,20 @@ el_get(EditLine *el, int op, ...)
case EL_PROMPT:
case EL_RPROMPT: {
el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
- char *c = va_arg(ap, char *);
+ rv = prompt_get(el, p, 0, op);
+ break;
+ }
+ case EL_PROMPT_ESC:
+ case EL_RPROMPT_ESC: {
+ el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
+ Char *c = va_arg(ap, Char *);
rv = prompt_get(el, p, c, op);
break;
}
case EL_EDITOR:
- rv = map_get_editor(el, va_arg(ap, const char **));
+ rv = map_get_editor(el, va_arg(ap, const Char **));
break;
case EL_SIGNAL:
@@ -377,7 +426,7 @@ el_get(EditLine *el, int op, ...)
break;
case EL_TERMINAL:
- term_get(el, va_arg(ap, const char **));
+ terminal_get(el, va_arg(ap, const char **));
rv = 0;
break;
@@ -387,44 +436,15 @@ el_get(EditLine *el, int op, ...)
char *argv[20];
int i;
- for (i = 1; i < (int)(sizeof(argv) / sizeof(argv[0])); i++)
+ for (i = 1; i < (int)__arraycount(argv); i++)
if ((argv[i] = va_arg(ap, char *)) == NULL)
break;
- switch (op) {
- case EL_GETTC:
- argv[0] = name;
- rv = term_gettc(el, i, argv);
- break;
-
- default:
- rv = -1;
- EL_ABORT((el->el_errfile, "Bad op %d\n", op));
- break;
- }
+ argv[0] = name;
+ rv = terminal_gettc(el, i, argv);
break;
}
-#if 0 /* XXX */
- case EL_ADDFN:
- {
- char *name = va_arg(ap, char *);
- char *help = va_arg(ap, char *);
- el_func_t func = va_arg(ap, el_func_t);
-
- rv = map_addfunc(el, name, help, func);
- break;
- }
-
- case EL_HIST:
- {
- hist_fun_t func = va_arg(ap, hist_fun_t);
- ptr_t ptr = va_arg(ap, char *);
- rv = hist_set(el, func, ptr);
- }
- break;
-#endif /* XXX */
-
case EL_GETCFN:
*va_arg(ap, el_rfunc_t *) = el_read_getfn(el);
rv = 0;
@@ -436,7 +456,7 @@ el_get(EditLine *el, int op, ...)
break;
case EL_UNBUFFERED:
- *va_arg(ap, int *) = (!(el->el_flags & UNBUFFERED));
+ *va_arg(ap, int *) = (el->el_flags & UNBUFFERED) != 0;
rv = 0;
break;
@@ -470,18 +490,18 @@ el_get(EditLine *el, int op, ...)
}
va_end(ap);
- return (rv);
+ return rv;
}
/* el_line():
* Return editing info
*/
-public const LineInfo *
-el_line(EditLine *el)
+public const TYPE(LineInfo) *
+FUN(el,line)(EditLine *el)
{
- return (const LineInfo *) (void *) &el->el_line;
+ return (const TYPE(LineInfo) *)(void *)&el->el_line;
}
@@ -494,23 +514,24 @@ el_source(EditLine *el, const char *fname)
FILE *fp;
size_t len;
char *ptr;
-#ifdef HAVE_ISSETUGID
- char path[MAXPATHLEN];
-#endif
+ char *path = NULL;
+ const Char *dptr;
+ int error = 0;
fp = NULL;
if (fname == NULL) {
#ifdef HAVE_ISSETUGID
static const char elpath[] = "/.editrc";
+ size_t plen = sizeof(elpath);
if (issetugid())
- return (-1);
+ return -1;
if ((ptr = getenv("HOME")) == NULL)
- return (-1);
- if (strlcpy(path, ptr, sizeof(path)) >= sizeof(path))
- return (-1);
- if (strlcat(path, elpath, sizeof(path)) >= sizeof(path))
- return (-1);
+ return -1;
+ plen += strlen(ptr);
+ if ((path = el_malloc(plen * sizeof(*path))) == NULL)
+ return -1;
+ (void)snprintf(path, plen, "%s%s", ptr, elpath);
fname = path;
#else
/*
@@ -518,33 +539,37 @@ el_source(EditLine *el, const char *fname)
* to keep from inadvertently opening up the user to a security
* hole.
*/
- return (-1);
+ return -1;
#endif
}
if (fp == NULL)
fp = fopen(fname, "r");
- if (fp == NULL)
- return (-1);
+ if (fp == NULL) {
+ el_free(path);
+ return -1;
+ }
while ((ptr = fgetln(fp, &len)) != NULL) {
- if (len > 0 && ptr[len - 1] == '\n')
+ if (*ptr == '\n')
+ continue; /* Empty line. */
+ dptr = ct_decode_string(ptr, &el->el_scratch);
+ if (!dptr)
+ continue;
+ if (len > 0 && dptr[len - 1] == '\n')
--len;
- ptr[len] = '\0';
/* loop until first non-space char or EOL */
- while (*ptr != '\0' && isspace((unsigned char)*ptr))
- ptr++;
- if (*ptr == '#')
+ while (*dptr != '\0' && Isspace(*dptr))
+ dptr++;
+ if (*dptr == '#')
continue; /* ignore, this is a comment line */
-
- if (parse_line(el, ptr) == -1) {
- (void) fclose(fp);
- return (-1);
- }
+ if ((error = parse_line(el, dptr)) == -1)
+ break;
}
+ el_free(path);
(void) fclose(fp);
- return (0);
+ return error;
}
@@ -562,8 +587,8 @@ el_resize(EditLine *el)
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
/* get the correct window size */
- if (term_get_size(el, &lins, &cols))
- term_change_size(el, lins, cols);
+ if (terminal_get_size(el, &lins, &cols))
+ terminal_change_size(el, lins, cols);
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
}
@@ -576,7 +601,7 @@ public void
el_beep(EditLine *el)
{
- term_beep(el);
+ terminal_beep(el);
}
@@ -585,24 +610,25 @@ el_beep(EditLine *el)
*/
protected int
/*ARGSUSED*/
-el_editmode(EditLine *el, int argc, const char **argv)
+el_editmode(EditLine *el, int argc, const Char **argv)
{
- const char *how;
+ const Char *how;
if (argv == NULL || argc != 2 || argv[1] == NULL)
- return (-1);
+ return -1;
how = argv[1];
- if (strcmp(how, "on") == 0) {
+ if (Strcmp(how, STR("on")) == 0) {
el->el_flags &= ~EDIT_DISABLED;
tty_rawmode(el);
- } else if (strcmp(how, "off") == 0) {
+ } else if (Strcmp(how, STR("off")) == 0) {
tty_cookedmode(el);
el->el_flags |= EDIT_DISABLED;
}
else {
- (void) fprintf(el->el_errfile, "edit: Bad value `%s'.\n", how);
- return (-1);
+ (void) fprintf(el->el_errfile, "edit: Bad value `" FSTR "'.\n",
+ how);
+ return -1;
}
- return (0);
+ return 0;
}
OpenPOWER on IntegriCloud