Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/lib/libedit/readline.c,v rcsdiff: /ftp/cvs/cvsroot/src/lib/libedit/readline.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.97 retrieving revision 1.140 diff -u -p -r1.97 -r1.140 --- src/lib/libedit/readline.c 2011/07/29 20:58:07 1.97 +++ src/lib/libedit/readline.c 2017/01/09 03:09:05 1.140 @@ -1,4 +1,4 @@ -/* $NetBSD: readline.c,v 1.97 2011/07/29 20:58:07 christos Exp $ */ +/* $NetBSD: readline.c,v 1.140 2017/01/09 03:09:05 christos Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -31,28 +31,28 @@ #include "config.h" #if !defined(lint) && !defined(SCCSID) -__RCSID("$NetBSD: readline.c,v 1.97 2011/07/29 20:58:07 christos Exp $"); +__RCSID("$NetBSD: readline.c,v 1.140 2017/01/09 03:09:05 christos Exp $"); #endif /* not lint && not SCCSID */ #include #include -#include -#include -#include -#include #include -#include -#include -#include +#include #include #include +#include +#include #include +#include +#include +#include +#include +#include #include #include "readline/readline.h" #include "el.h" -#include "fcns.h" /* for EL_NUM_FCNS */ -#include "histedit.h" +#include "fcns.h" #include "filecomplete.h" void rl_prep_terminal(int); @@ -78,15 +78,24 @@ FILE *rl_outstream = NULL; int rl_point = 0; int rl_end = 0; char *rl_line_buffer = NULL; -VCPFunction *rl_linefunc = NULL; +rl_vcpfunc_t *rl_linefunc = NULL; int rl_done = 0; 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; +int history_offset = 0; int max_input_history = 0; char history_expansion_char = '!'; char history_subst_char = '^'; @@ -99,8 +108,9 @@ int rl_attempted_completion_over = 0; char *rl_basic_word_break_characters = break_chars; char *rl_completer_word_break_characters = NULL; char *rl_completer_quote_characters = NULL; -Function *rl_completion_entry_function = NULL; -CPPFunction *rl_attempted_completion_function = NULL; +rl_compentry_func_t *rl_completion_entry_function = NULL; +char *(*rl_completion_word_break_hook)(void) = NULL; +rl_completion_func_t *rl_attempted_completion_function = NULL; Function *rl_pre_input_hook = NULL; Function *rl_startup1_hook = NULL; int (*rl_getc_function)(FILE *) = NULL; @@ -108,7 +118,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; @@ -152,22 +161,22 @@ int rl_completion_append_character = ' ' static History *h = NULL; static EditLine *e = NULL; -static Function *map[256]; +static rl_command_func_t *map[256]; static jmp_buf topbuf; /* internal functions */ static unsigned char _el_rl_complete(EditLine *, int); static unsigned char _el_rl_tstp(EditLine *, int); static char *_get_prompt(EditLine *); -static int _getc_function(EditLine *, char *); -static HIST_ENTRY *_move_history(int); +static int _getc_function(EditLine *, wchar_t *); static int _history_expand_command(const char *, size_t, size_t, char **); static char *_rl_compat_sub(const char *, const char *, const char *, int); -static int _rl_event_read_char(EditLine *, char *); +static int _rl_event_read_char(EditLine *, wchar_t *); static void _rl_update_pos(void); +static HIST_ENTRY rl_he; /* ARGSUSED */ static char * @@ -179,37 +188,18 @@ _get_prompt(EditLine *el __attribute__(( /* - * generic function for moving around history - */ -static HIST_ENTRY * -_move_history(int op) -{ - HistEvent ev; - static HIST_ENTRY rl_he; - - if (history(h, &ev, op) != 0) - return NULL; - - rl_he.line = ev.str; - rl_he.data = NULL; - - return &rl_he; -} - - -/* * read one key from user defined input function */ static int /*ARGSUSED*/ -_getc_function(EditLine *el __attribute__((__unused__)), char *c) +_getc_function(EditLine *el __attribute__((__unused__)), wchar_t *c) { int i; - i = (*rl_getc_function)(NULL); + i = (*rl_getc_function)(rl_instream); if (i == -1) return 0; - *c = i; + *c = (wchar_t)i; return 1; } @@ -221,23 +211,27 @@ _resize_fun(EditLine *el, void *a) li = el_line(el); /* a cheesy way to get rid of const cast. */ - *ap = memchr(li->buffer, *li->buffer, 1); + *ap = memchr(li->buffer, *li->buffer, (size_t)1); } -static const char _dothistory[] = "/.history"; - 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; - strlcpy(path, p->pw_dir, PATH_MAX); - strlcat(path, _dothistory, PATH_MAX); + + 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; } @@ -255,7 +249,7 @@ rl_set_prompt(const char *prompt) if (!prompt) prompt = ""; - if (rl_prompt != NULL && strcmp(rl_prompt, prompt) == 0) + if (rl_prompt != NULL && strcmp(rl_prompt, prompt) == 0) return 0; if (rl_prompt) el_free(rl_prompt); @@ -326,7 +320,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); @@ -349,7 +343,38 @@ rl_initialize(void) "ReadLine compatible suspend function", _el_rl_tstp); el_set(e, EL_BIND, "^Z", "rl_tstp", NULL); - + + /* + * Set some readline compatible key-bindings. + */ + el_set(e, EL_BIND, "^R", "em-inc-search-prev", NULL); + + /* + * Allow the use of Home/End keys. + */ + el_set(e, EL_BIND, "\\e[1~", "ed-move-to-beg", NULL); + el_set(e, EL_BIND, "\\e[4~", "ed-move-to-end", NULL); + el_set(e, EL_BIND, "\\e[7~", "ed-move-to-beg", NULL); + el_set(e, EL_BIND, "\\e[8~", "ed-move-to-end", NULL); + el_set(e, EL_BIND, "\\e[H", "ed-move-to-beg", NULL); + el_set(e, EL_BIND, "\\e[F", "ed-move-to-end", NULL); + + /* + * Allow the use of the Delete/Insert keys. + */ + el_set(e, EL_BIND, "\\e[3~", "ed-delete-next-char", NULL); + el_set(e, EL_BIND, "\\e[2~", "ed-quoted-insert", NULL); + + /* + * Ctrl-left-arrow and Ctrl-right-arrow for word moving. + */ + el_set(e, EL_BIND, "\\e[1;5C", "em-next-word", NULL); + el_set(e, EL_BIND, "\\e[1;5D", "ed-prev-word", NULL); + el_set(e, EL_BIND, "\\e[5C", "em-next-word", NULL); + el_set(e, EL_BIND, "\\e[5D", "ed-prev-word", NULL); + el_set(e, EL_BIND, "\\e\\e[C", "em-next-word", NULL); + el_set(e, EL_BIND, "\\e\\e[D", "ed-prev-word", NULL); + /* read settings from configuration file */ el_source(e, NULL); @@ -441,6 +466,7 @@ using_history(void) { if (h == NULL || e == NULL) rl_initialize(); + history_offset = history_length; } @@ -522,7 +548,7 @@ get_history_event(const char *cmd, int * } if ('0' <= cmd[idx] && cmd[idx] <= '9') { - HIST_ENTRY *rl_he; + HIST_ENTRY *he; num = 0; while (cmd[idx] && '0' <= cmd[idx] && cmd[idx] <= '9') { @@ -530,13 +556,13 @@ get_history_event(const char *cmd, int * idx++; } if (sign) - num = history_length - num + 1; + num = history_length - num + history_base; - if (!(rl_he = history_get(num))) + if (!(he = history_get(num))) return NULL; *cindex = idx; - return rl_he->line; + return he->line; } sub = 0; if (cmd[idx] == '?') { @@ -554,7 +580,7 @@ get_history_event(const char *cmd, int * break; idx++; } - len = idx - begin; + len = (size_t)idx - (size_t)begin; if (sub && cmd[idx] == '?') idx++; if (sub && len == 0 && last_search_pat && *last_search_pat) @@ -622,7 +648,7 @@ get_history_event(const char *cmd, int * * 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, @@ -668,7 +694,7 @@ _history_expand_command(const char *comm qchar = (offs > 0 && command[offs - 1] == '"')? '"':0; ptr = get_history_event(command + offs, &idx, qchar); } - has_mods = command[offs + idx] == ':'; + has_mods = command[offs + (size_t)idx] == ':'; } if (ptr == NULL && aptr == NULL) @@ -890,7 +916,7 @@ history_expand(char *str, char **output) *output = NULL; if (str[0] == history_subst_char) { /* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */ - *output = el_malloc((strlen(str) + 4 + 1) * sizeof(*output)); + *output = el_malloc((strlen(str) + 4 + 1) * sizeof(**output)); if (*output == NULL) return 0; (*output)[0] = (*output)[1] = history_expansion_char; @@ -936,7 +962,8 @@ loop: for (; str[j]; j++) { if (str[j] == '\\' && str[j + 1] == history_expansion_char) { - (void)strcpy(&str[j], &str[j + 1]); + len = strlen(&str[j + 1]) + 1; + memmove(&str[j], &str[j + 1], len); continue; } if (!loop_again) { @@ -1034,14 +1061,14 @@ history_arg_extract(int start, int end, (size_t)end > max || start > end) goto out; - for (i = start, len = 0; i <= (size_t)end; i++) + for (i = (size_t)start, len = 0; i <= (size_t)end; i++) len += strlen(arr[i]) + 1; len++; result = el_malloc(len * sizeof(*result)); if (result == NULL) goto out; - for (i = start, len = 0; i <= (size_t)end; i++) { + for (i = (size_t)start, len = 0; i <= (size_t)end; i++) { (void)strcpy(result + len, arr[i]); len += strlen(arr[i]); if (i < (size_t)end) @@ -1091,15 +1118,15 @@ history_tokenize(const char *str) if (idx + 2 >= size) { char **nresult; size <<= 1; - nresult = el_realloc(result, size * sizeof(*nresult)); + nresult = el_realloc(result, (size_t)size * sizeof(*nresult)); if (nresult == NULL) { el_free(result); return NULL; } result = nresult; } - len = i - start; - temp = el_malloc((len + 1) * sizeof(*temp)); + len = (size_t)i - (size_t)start; + temp = el_malloc((size_t)(len + 1) * sizeof(*temp)); if (temp == NULL) { for (i = 0; i < idx; i++) el_free(result[i]); @@ -1124,12 +1151,22 @@ void stifle_history(int max) { HistEvent ev; + HIST_ENTRY *he; if (h == NULL || e == NULL) rl_initialize(); - if (history(h, &ev, H_SETSIZE, max) == 0) + if (history(h, &ev, H_SETSIZE, max) == 0) { max_input_history = max; + if (history_length > max) + history_base = history_length - max; + while (history_length > max) { + he = remove_history(0); + el_free(he->data); + el_free((void *)(unsigned long)he->line); + el_free(he); + } + } } @@ -1189,7 +1226,7 @@ history_truncate_file (const char *filen } for(;;) { - if (fread(buf, sizeof(buf), 1, fp) != 1) { + if (fread(buf, sizeof(buf), (size_t)1, fp) != 1) { if (ferror(fp)) { ret = errno; break; @@ -1199,7 +1236,7 @@ history_truncate_file (const char *filen ret = errno; break; } - left = fread(buf, 1, sizeof(buf), fp); + left = (ssize_t)fread(buf, (size_t)1, sizeof(buf), fp); if (ferror(fp)) { ret = errno; break; @@ -1207,14 +1244,15 @@ history_truncate_file (const char *filen if (left == 0) { count--; left = sizeof(buf); - } else if (fwrite(buf, (size_t)left, 1, tp) != 1) { + } else if (fwrite(buf, (size_t)left, (size_t)1, tp) + != 1) { ret = errno; break; } fflush(tp); break; } - if (fwrite(buf, sizeof(buf), 1, tp) != 1) { + if (fwrite(buf, sizeof(buf), (size_t)1, tp) != 1) { ret = errno; break; } @@ -1244,7 +1282,7 @@ history_truncate_file (const char *filen ret = errno; break; } - if (fread(buf, sizeof(buf), 1, tp) != 1) { + if (fread(buf, sizeof(buf), (size_t)1, tp) != 1) { if (ferror(tp)) { ret = errno; break; @@ -1258,7 +1296,7 @@ history_truncate_file (const char *filen if (ret || nlines > 0) goto out3; - if (fseeko(fp, 0, SEEK_SET) == (off_t)-1) { + if (fseeko(fp, (off_t)0, SEEK_SET) == (off_t)-1) { ret = errno; goto out3; } @@ -1270,12 +1308,12 @@ history_truncate_file (const char *filen } for(;;) { - if ((left = fread(buf, 1, sizeof(buf), tp)) == 0) { + if ((left = (ssize_t)fread(buf, (size_t)1, sizeof(buf), tp)) == 0) { if (ferror(fp)) ret = errno; break; } - if (fwrite(buf, (size_t)left, 1, fp) != 1) { + if (fwrite(buf, (size_t)left, (size_t)1, fp) != 1) { ret = errno; break; } @@ -1343,25 +1381,37 @@ history_get(int num) if (h == NULL || e == NULL) rl_initialize(); + if (num < history_base) + return NULL; + /* save current position */ if (history(h, &ev, H_CURR) != 0) return NULL; curr_num = ev.num; - /* start from the oldest */ - if (history(h, &ev, H_LAST) != 0) - return NULL; /* error */ - - /* look forwards for event matching specified offset */ - if (history(h, &ev, H_NEXT_EVDATA, num, &she.data)) - return NULL; + /* + * use H_DELDATA to set to nth history (without delete) by passing + * (void **)-1 -- as in history_set_pos + */ + if (history(h, &ev, H_DELDATA, num - history_base, (void **)-1) != 0) + goto out; + /* get current entry */ + if (history(h, &ev, H_CURR) != 0) + goto out; + if (history(h, &ev, H_NEXT_EVDATA, ev.num, &she.data) != 0) + goto out; she.line = ev.str; /* restore pointer to where it was */ (void)history(h, &ev, H_SET, curr_num); return &she; + +out: + /* restore pointer to where it was */ + (void)history(h, &ev, H_SET, curr_num); + return NULL; } @@ -1376,11 +1426,15 @@ add_history(const char *line) if (h == NULL || e == NULL) rl_initialize(); - (void)history(h, &ev, H_ENTER, line); - if (history(h, &ev, H_GETSIZE) == 0) - history_length = ev.num; + if (history(h, &ev, H_ENTER, line) == -1) + return 0; - return !(history_length > 0); /* return 0 if all is okay */ + (void)history(h, &ev, H_GETSIZE); + if (ev.num == history_length) + history_base++; + else + history_length = ev.num; + return 0; } @@ -1466,8 +1520,11 @@ clear_history(void) { HistEvent ev; + if (h == NULL || e == NULL) + rl_initialize(); + (void)history(h, &ev, H_CLEAR); - history_length = 0; + history_offset = history_length = 0; } @@ -1477,21 +1534,42 @@ clear_history(void) int where_history(void) { + return history_offset; +} + +static HIST_ENTRY **_history_listp; +static HIST_ENTRY *_history_list; + +HIST_ENTRY ** +history_list(void) +{ HistEvent ev; - int curr_num, off; + HIST_ENTRY **nlp, *nl; + int i; - if (history(h, &ev, H_CURR) != 0) - return 0; - curr_num = ev.num; + if (history(h, &ev, H_LAST) != 0) + return NULL; - (void)history(h, &ev, H_FIRST); - off = 1; - while (ev.num != curr_num && history(h, &ev, H_NEXT) == 0) - off++; + if ((nlp = el_realloc(_history_listp, + (size_t)history_length * sizeof(*nlp))) == NULL) + return NULL; + _history_listp = nlp; - return off; -} + if ((nl = el_realloc(_history_list, + (size_t)history_length * sizeof(*nl))) == NULL) + return NULL; + _history_list = nl; + i = 0; + do { + _history_listp[i] = &_history_list[i]; + _history_list[i].line = ev.str; + _history_list[i].data = NULL; + if (i++ == history_length) + abort(); + } while (history(h, &ev, H_PREV) == 0); + return _history_listp; +} /* * returns current history event or NULL if there is no such event @@ -1499,8 +1577,14 @@ where_history(void) HIST_ENTRY * current_history(void) { + HistEvent ev; - return _move_history(H_CURR); + if (history(h, &ev, H_PREV_EVENT, history_offset + 1) != 0) + return NULL; + + rl_he.line = ev.str; + rl_he.data = NULL; + return &rl_he; } @@ -1537,35 +1621,31 @@ history_total_bytes(void) int history_set_pos(int pos) { - HistEvent ev; - int curr_num; - if (pos >= history_length || pos < 0) - return -1; - - (void)history(h, &ev, H_CURR); - curr_num = ev.num; + return 0; - /* - * use H_DELDATA to set to nth history (without delete) by passing - * (void **)-1 - */ - if (history(h, &ev, H_DELDATA, pos, (void **)-1)) { - (void)history(h, &ev, H_SET, curr_num); - return -1; - } - return 0; + history_offset = pos; + return 1; } /* * returns previous event in history and shifts pointer accordingly + * Note that readline and editline define directions in opposite ways. */ HIST_ENTRY * previous_history(void) { + HistEvent ev; + + if (history_offset == 0) + return NULL; - return _move_history(H_PREV); + if (history(h, &ev, H_LAST) != 0) + return NULL; + + history_offset--; + return current_history(); } @@ -1575,8 +1655,16 @@ previous_history(void) HIST_ENTRY * next_history(void) { + HistEvent ev; + + if (history_offset >= history_length) + return NULL; + + if (history(h, &ev, H_LAST) != 0) + return NULL; - return _move_history(H_NEXT); + history_offset++; + return current_history(); } @@ -1637,7 +1725,7 @@ history_search_pos(const char *str, return -1; curr_num = ev.num; - if (history_set_pos(off) != 0 || history(h, &ev, H_CURR) != 0) + if (!history_set_pos(off) || history(h, &ev, H_CURR) != 0) return -1; for (;;) { @@ -1675,7 +1763,7 @@ filename_completion_function(const char * 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) @@ -1742,7 +1830,7 @@ _rl_completion_append_character_function __attribute__((__unused__))) { static char buf[2]; - buf[0] = rl_completion_append_character; + buf[0] = (char)rl_completion_append_character; buf[1] = '\0'; return buf; } @@ -1755,9 +1843,8 @@ _rl_completion_append_character_function int rl_complete(int ignore __attribute__((__unused__)), int invoking_key) { -#ifdef WIDECHAR static ct_buffer_t wbreak_conv, sprefix_conv; -#endif + char *breakchars; if (h == NULL || e == NULL) rl_initialize(); @@ -1770,12 +1857,19 @@ rl_complete(int ignore __attribute__((__ return CC_REFRESH; } + if (rl_completion_word_break_hook != NULL) + breakchars = (*rl_completion_word_break_hook)(); + else + breakchars = rl_basic_word_break_characters; + + _rl_update_pos(); + /* Just look at how many global variables modify this operation! */ return fn_complete(e, - (CPFunction *)rl_completion_entry_function, + (rl_compentry_func_t *)rl_completion_entry_function, rl_attempted_completion_function, ct_decode_string(rl_basic_word_break_characters, &wbreak_conv), - ct_decode_string(rl_special_prefixes, &sprefix_conv), + ct_decode_string(breakchars, &sprefix_conv), _rl_completion_append_character_function, (size_t)rl_completion_query_items, &rl_completion_type, &rl_attempted_completion_over, @@ -1858,7 +1952,7 @@ rl_insert(int count, int c) rl_initialize(); /* XXX - int -> char conversion can lose on multichars */ - arr[0] = c; + arr[0] = (char)c; arr[1] = '\0'; for (; count > 0; count--) @@ -1901,7 +1995,7 @@ rl_bind_wrapper(EditLine *el __attribute _rl_update_pos(); - (*map[c])(NULL, c); + (*map[c])(1, c); /* If rl_done was set by the above call, deal with it here */ if (rl_done) @@ -1911,7 +2005,7 @@ rl_bind_wrapper(EditLine *el __attribute } int -rl_add_defun(const char *name, Function *fun, int c) +rl_add_defun(const char *name, rl_command_func_t *fun, int c) { char dest[8]; if ((size_t)c >= sizeof(map) / sizeof(map[0]) || c < 0) @@ -1919,12 +2013,12 @@ rl_add_defun(const char *name, Function 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; } void -rl_callback_read_char() +rl_callback_read_char(void) { int count = 0, done = 0; const char *buf = el_gets(e, &count); @@ -1945,12 +2039,12 @@ rl_callback_read_char() } else wbuf = NULL; (*(void (*)(const char *))rl_linefunc)(wbuf); - //el_set(e, EL_UNBUFFERED, 1); + el_set(e, EL_UNBUFFERED, 1); } } -void -rl_callback_handler_install(const char *prompt, VCPFunction *linefunc) +void +rl_callback_handler_install(const char *prompt, rl_vcpfunc_t *linefunc) { if (e == NULL) { rl_initialize(); @@ -1958,9 +2052,9 @@ rl_callback_handler_install(const char * (void)rl_set_prompt(prompt); rl_linefunc = linefunc; el_set(e, EL_UNBUFFERED, 1); -} +} -void +void rl_callback_handler_remove(void) { el_set(e, EL_UNBUFFERED, 0); @@ -1971,7 +2065,7 @@ void rl_redisplay(void) { char a[2]; - a[0] = e->el_tty.t_c[TS_IO][C_REPRINT]; + a[0] = (char)e->el_tty.t_c[TS_IO][C_REPRINT]; a[1] = '\0'; el_push(e, a); } @@ -1980,7 +2074,7 @@ int rl_get_previous_history(int count, int key) { char a[2]; - a[0] = key; + a[0] = (char)key; a[1] = '\0'; while (count--) el_push(e, a); @@ -2027,7 +2121,7 @@ rl_variable_bind(const char *var, const * 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 @@ -2035,18 +2129,20 @@ rl_stuff_char(int c) { char buf[2]; - buf[0] = c; + buf[0] = (char)c; buf[1] = '\0'; el_insertstr(e, buf); } static int -_rl_event_read_char(EditLine *el, char *cp) +_rl_event_read_char(EditLine *el, wchar_t *wc) { + char ch; int n; ssize_t num_read = 0; - *cp = '\0'; + ch = '\0'; + *wc = L'\0'; while (rl_event_hook) { (*rl_event_hook)(); @@ -2055,7 +2151,7 @@ _rl_event_read_char(EditLine *el, char * if (ioctl(el->el_infd, FIONREAD, &n) < 0) return -1; if (n) - num_read = read(el->el_infd, cp, 1); + num_read = read(el->el_infd, &ch, (size_t)1); else num_read = 0; #elif defined(F_SETFL) && defined(O_NDELAY) @@ -2063,12 +2159,12 @@ _rl_event_read_char(EditLine *el, char * return -1; if (fcntl(el->el_infd, F_SETFL, n|O_NDELAY) < 0) return -1; - num_read = read(el->el_infd, cp, 1); + num_read = read(el->el_infd, &ch, 1); if (fcntl(el->el_infd, F_SETFL, n)) return -1; #else /* not non-blocking, but what you gonna do? */ - num_read = read(el->el_infd, cp, 1); + num_read = read(el->el_infd, &ch, 1); return -1; #endif @@ -2080,6 +2176,7 @@ _rl_event_read_char(EditLine *el, char * } if (!rl_event_hook) el_set(el, EL_GETCFN, EL_BUILTIN_GETCFN); + *wc = (wchar_t)ch; return (int)num_read; } @@ -2096,9 +2193,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 @@ -2106,9 +2203,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 ** @@ -2142,7 +2239,7 @@ rl_completion_matches(const char *str, r } qsort(&list[1], len - 1, sizeof(*list), (int (*)(const void *, const void *)) strcmp); - min = SIZE_T_MAX; + min = SIZE_MAX; for (i = 1, a = list[i]; i < len - 1; i++, a = b) { b = list[i + 1]; for (j = 0; a[j] && a[j] == b[j]; j++) @@ -2160,7 +2257,7 @@ rl_completion_matches(const char *str, r list[0][min] = '\0'; } return list; - + out: el_free(list); return NULL; @@ -2259,3 +2356,15 @@ rl_on_new_line(void) { return 0; } + +void +rl_free_line_state(void) +{ +} + +int +/*ARGSUSED*/ +rl_set_keyboard_input_timeout(int u __attribute__((__unused__))) +{ + return 0; +}