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.76 retrieving revision 1.87 diff -u -p -r1.76 -r1.87 --- src/lib/libedit/readline.c 2009/01/11 15:00:23 1.76 +++ src/lib/libedit/readline.c 2009/12/30 23:54:52 1.87 @@ -1,4 +1,4 @@ -/* $NetBSD: readline.c,v 1.76 2009/01/11 15:00:23 christos Exp $ */ +/* $NetBSD: readline.c,v 1.87 2009/12/30 23:54:52 christos 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.76 2009/01/11 15:00:23 christos Exp $"); +__RCSID("$NetBSD: readline.c,v 1.87 2009/12/30 23:54:52 christos Exp $"); #endif /* not lint && not SCCSID */ #include @@ -52,13 +52,10 @@ __RCSID("$NetBSD: readline.c,v 1.76 2009 #else #include "np/vis.h" #endif -#ifdef HAVE_ALLOCA_H -#include -#endif +#include "readline/readline.h" #include "el.h" #include "fcns.h" /* for EL_NUM_FCNS */ #include "histedit.h" -#include "readline/readline.h" #include "filecomplete.h" void rl_prep_terminal(int); @@ -73,6 +70,7 @@ void rl_deprep_terminal(void); /* readline compatibility stuff - look at readline sources/documentation */ /* to see what these variables mean */ const char *rl_library_version = "EditLine wrapper"; +int rl_readline_version = RL_READLINE_VERSION; static char empty[] = { '\0' }; static char expand_chars[] = { ' ', '\t', '\n', '=', '(', '\0' }; static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$', @@ -121,6 +119,11 @@ Function *rl_startup_hook = NULL; VFunction *rl_completion_display_matches_hook = NULL; VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal; VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal; +KEYMAP_ENTRY_ARRAY emacs_meta_keymap; + +#ifdef WIDECHAR +static ct_buffer_t conv; +#endif /* * The current prompt string. @@ -154,7 +157,7 @@ int rl_completion_append_character = ' ' /* stuff below is used internally by libedit for readline emulation */ -static History *h = NULL; +static TYPE(History) *h = NULL; static EditLine *e = NULL; static Function *map[256]; static jmp_buf topbuf; @@ -188,13 +191,13 @@ _get_prompt(EditLine *el __attribute__(( static HIST_ENTRY * _move_history(int op) { - HistEvent ev; + TYPE(HistEvent) ev; static HIST_ENTRY rl_he; - if (history(h, &ev, op) != 0) + if (FUNW(history)(h, &ev, op) != 0) return (HIST_ENTRY *) NULL; - rl_he.line = ev.str; + rl_he.line = ct_encode_string(ev.str, &conv); rl_he.data = NULL; return (&rl_he); @@ -217,18 +220,58 @@ _getc_function(EditLine *el, char *c) return 1; } +static const char _dothistory[] = "/.history"; + +static const char * +_default_history_file(void) +{ + struct passwd *p; + static char path[PATH_MAX]; + + if (*path) + return path; + if ((p = getpwuid(getuid())) == NULL) + return NULL; + strlcpy(path, p->pw_dir, PATH_MAX); + strlcat(path, _dothistory, PATH_MAX); + return path; +} /* * READLINE compatibility stuff */ /* + * Set the prompt + */ +int +rl_set_prompt(const char *prompt) +{ + char *p; + + if (!prompt) + prompt = ""; + if (rl_prompt != NULL && strcmp(rl_prompt, prompt) == 0) + return 0; + if (rl_prompt) + free(rl_prompt); + rl_prompt = strdup(prompt); + if (rl_prompt == NULL) + return -1; + + while ((p = strchr(rl_prompt, RL_PROMPT_END_IGNORE)) != NULL) + *p = RL_PROMPT_START_IGNORE; + + return 0; +} + +/* * initialize rl compat stuff */ int rl_initialize(void) { - HistEvent ev; + TYPE(HistEvent) ev; const LineInfo *li; int editmode = 1; struct termios t; @@ -236,7 +279,7 @@ rl_initialize(void) if (e != NULL) el_end(e); if (h != NULL) - history_end(h); + FUN(history,end)(h); if (!rl_instream) rl_instream = stdin; @@ -252,13 +295,13 @@ rl_initialize(void) e = el_init(rl_readline_name, rl_instream, rl_outstream, stderr); if (!editmode) - el_set(e, EL_EDITMODE, 0); + FUN(el,set)(e, EL_EDITMODE, 0); - h = history_init(); + h = FUN(history,init)(); if (!e || !h) return (-1); - history(h, &ev, H_SETSIZE, INT_MAX); /* unlimited */ + FUNW(history)(h, &ev, H_SETSIZE, INT_MAX); /* unlimited */ history_length = 0; max_input_history = INT_MAX; el_set(e, EL_HIST, history, h); @@ -268,13 +311,12 @@ rl_initialize(void) el_set(e, EL_GETCFN, _getc_function); /* for proper prompt printing in readline() */ - rl_prompt = strdup(""); - if (rl_prompt == NULL) { - history_end(h); + if (rl_set_prompt("") == -1) { + FUN(history,end)(h); el_end(e); return -1; } - el_set(e, EL_PROMPT, _get_prompt); + el_set(e, EL_PROMPT, _get_prompt, RL_PROMPT_START_IGNORE); el_set(e, EL_SIGNAL, rl_catch_signals); /* set default mode to "emacs"-style and read setting afterwards */ @@ -328,7 +370,7 @@ rl_initialize(void) char * readline(const char *p) { - HistEvent ev; + TYPE(HistEvent) ev; const char * volatile prompt = p; int count; const char *ret; @@ -343,14 +385,8 @@ readline(const char *p) (void)setjmp(topbuf); /* update prompt accordingly to what has been passed */ - if (!prompt) - prompt = ""; - if (strcmp(rl_prompt, prompt) != 0) { - free(rl_prompt); - rl_prompt = strdup(prompt); - if (rl_prompt == NULL) - return NULL; - } + if (rl_set_prompt(prompt) == -1) + return NULL; if (rl_pre_input_hook) (*rl_pre_input_hook)(NULL, 0); @@ -382,7 +418,7 @@ readline(const char *p) } else buf = NULL; - history(h, &ev, H_GETSIZE); + FUNW(history)(h, &ev, H_GETSIZE); history_length = ev.num; return buf; @@ -462,7 +498,7 @@ get_history_event(const char *cmd, int * size_t len; char *pat; const char *rptr; - HistEvent ev; + TYPE(HistEvent) ev; idx = *cindex; if (cmd[idx++] != history_expansion_char) @@ -470,10 +506,10 @@ get_history_event(const char *cmd, int * /* find out which event to take */ if (cmd[idx] == history_expansion_char || cmd[idx] == '\0') { - if (history(h, &ev, H_FIRST) != 0) + if (FUNW(history)(h, &ev, H_FIRST) != 0) return(NULL); *cindex = cmd[idx]? (idx + 1):idx; - return(ev.str); + return ct_encode_string(ev.str, &conv); } sign = 0; if (cmd[idx] == '-') { @@ -528,7 +564,7 @@ get_history_event(const char *cmd, int * pat[len] = '\0'; } - if (history(h, &ev, H_CURR) != 0) { + if (FUNW(history)(h, &ev, H_CURR) != 0) { if (pat != last_search_pat) free(pat); return (NULL); @@ -547,7 +583,7 @@ get_history_event(const char *cmd, int * if (ret == -1) { /* restore to end of list on failed search */ - history(h, &ev, H_FIRST); + FUNW(history)(h, &ev, H_FIRST); (void)fprintf(rl_outstream, "%s: Event not found\n", pat); if (pat != last_search_pat) free(pat); @@ -563,13 +599,13 @@ get_history_event(const char *cmd, int * if (pat != last_search_pat) free(pat); - if (history(h, &ev, H_CURR) != 0) + if (FUNW(history)(h, &ev, H_CURR) != 0) return(NULL); *cindex = idx; - rptr = ev.str; + rptr = ct_encode_string(ev.str, &conv); /* roll back to original position */ - (void)history(h, &ev, H_SET, num); + (void)FUNW(history)(h, &ev, H_SET, num); return rptr; } @@ -634,9 +670,11 @@ _history_expand_command(const char *comm return(-1); if (!has_mods) { - *result = strdup(aptr? aptr : ptr); + *result = strdup(aptr ? aptr : ptr); if (aptr) free(aptr); + if (*result == NULL) + return -1; return(1); } @@ -691,7 +729,7 @@ _history_expand_command(const char *comm if (aptr) free(aptr); - if (*cmd == '\0' || (cmd - (command + offs) >= cmdlen)) { + if (*cmd == '\0' || ((size_t)(cmd - (command + offs)) >= cmdlen)) { *result = tmp; return(1); } @@ -963,52 +1001,52 @@ char * history_arg_extract(int start, int end, const char *str) { size_t i, len, max; - char **arr, *result; + char **arr, *result = NULL; arr = history_tokenize(str); if (!arr) - return(NULL); - if (arr && *arr == NULL) { - free(arr); - return(NULL); - } + return NULL; + if (arr && *arr == NULL) + goto out; for (max = 0; arr[max]; max++) continue; max--; if (start == '$') - start = max; + start = (int)max; if (end == '$') - end = max; + end = (int)max; if (end < 0) - end = max + end + 1; + end = (int)max + end + 1; if (start < 0) start = end; - if (start < 0 || end < 0 || start > max || end > max || start > end) - return(NULL); + if (start < 0 || end < 0 || (size_t)start > max || + (size_t)end > max || start > end) + goto out; - for (i = start, len = 0; i <= end; i++) + for (i = start, len = 0; i <= (size_t)end; i++) len += strlen(arr[i]) + 1; len++; result = malloc(len); if (result == NULL) - return NULL; + goto out; - for (i = start, len = 0; i <= end; i++) { + for (i = start, len = 0; i <= (size_t)end; i++) { (void)strcpy(result + len, arr[i]); len += strlen(arr[i]); - if (i < end) + if (i < (size_t)end) result[len++] = ' '; } result[len] = '\0'; +out: for (i = 0; arr[i]; i++) free(arr[i]); free(arr); - return(result); + return result; } /* @@ -1077,12 +1115,12 @@ history_tokenize(const char *str) void stifle_history(int max) { - HistEvent ev; + TYPE(HistEvent) ev; if (h == NULL || e == NULL) rl_initialize(); - if (history(h, &ev, H_SETSIZE, max) == 0) + if (FUNW(history)(h, &ev, H_SETSIZE, max) == 0) max_input_history = max; } @@ -1093,10 +1131,10 @@ stifle_history(int max) int unstifle_history(void) { - HistEvent ev; + TYPE(HistEvent) ev; int omax; - history(h, &ev, H_SETSIZE, INT_MAX); + FUNW(history)(h, &ev, H_SETSIZE, INT_MAX); omax = max_input_history; max_input_history = INT_MAX; return (omax); /* some value _must_ be returned */ @@ -1111,6 +1149,142 @@ history_is_stifled(void) return (max_input_history != INT_MAX); } +static const char _history_tmp_template[] = "/tmp/.historyXXXXXX"; + +int +history_truncate_file (const char *filename, int nlines) +{ + int ret = 0; + FILE *fp, *tp; + char template[sizeof(_history_tmp_template)]; + char buf[4096]; + int fd; + char *cp; + off_t off; + int count = 0; + ssize_t left = 0; + + if (filename == NULL && (filename = _default_history_file()) == NULL) + return errno; + if ((fp = fopen(filename, "r+")) == NULL) + return errno; + strcpy(template, _history_tmp_template); + if ((fd = mkstemp(template)) == -1) { + ret = errno; + goto out1; + } + + if ((tp = fdopen(fd, "r+")) == NULL) { + close(fd); + ret = errno; + goto out2; + } + + for(;;) { + if (fread(buf, sizeof(buf), 1, fp) != 1) { + if (ferror(fp)) { + ret = errno; + break; + } + if (fseeko(fp, (off_t)sizeof(buf) * count, SEEK_SET) == + (off_t)-1) { + ret = errno; + break; + } + left = fread(buf, 1, sizeof(buf), fp); + if (ferror(fp)) { + ret = errno; + break; + } + if (left == 0) { + count--; + left = sizeof(buf); + } else if (fwrite(buf, (size_t)left, 1, tp) != 1) { + ret = errno; + break; + } + fflush(tp); + break; + } + if (fwrite(buf, sizeof(buf), 1, tp) != 1) { + ret = errno; + break; + } + count++; + } + if (ret) + goto out3; + cp = buf + left - 1; + if(*cp != '\n') + cp++; + for(;;) { + while (--cp >= buf) { + if (*cp == '\n') { + if (--nlines == 0) { + if (++cp >= buf + sizeof(buf)) { + count++; + cp = buf; + } + break; + } + } + } + if (nlines <= 0 || count == 0) + break; + count--; + if (fseeko(tp, (off_t)sizeof(buf) * count, SEEK_SET) < 0) { + ret = errno; + break; + } + if (fread(buf, sizeof(buf), 1, tp) != 1) { + if (ferror(tp)) { + ret = errno; + break; + } + ret = EAGAIN; + break; + } + cp = buf + sizeof(buf); + } + + if (ret || nlines > 0) + goto out3; + + if (fseeko(fp, 0, SEEK_SET) == (off_t)-1) { + ret = errno; + goto out3; + } + + if (fseeko(tp, (off_t)sizeof(buf) * count + (cp - buf), SEEK_SET) == + (off_t)-1) { + ret = errno; + goto out3; + } + + for(;;) { + if ((left = fread(buf, 1, sizeof(buf), tp)) == 0) { + if (ferror(fp)) + ret = errno; + break; + } + if (fwrite(buf, (size_t)left, 1, fp) != 1) { + ret = errno; + break; + } + } + fflush(fp); + if((off = ftello(fp)) > 0) + (void)ftruncate(fileno(fp), off); +out3: + fclose(tp); +out2: + unlink(template); +out1: + fclose(fp); + + return ret; +} + /* * read history from a file given @@ -1118,11 +1292,13 @@ history_is_stifled(void) int read_history(const char *filename) { - HistEvent ev; + TYPE(HistEvent) ev; if (h == NULL || e == NULL) rl_initialize(); - return (history(h, &ev, H_LOAD, filename) == -1); + if (filename == NULL && (filename = _default_history_file()) == NULL) + return errno; + return (FUNW(history)(h, &ev, H_LOAD, filename) == -1 ? (errno ? errno : EINVAL) : 0); } @@ -1132,11 +1308,13 @@ read_history(const char *filename) int write_history(const char *filename) { - HistEvent ev; + TYPE(HistEvent) ev; if (h == NULL || e == NULL) rl_initialize(); - return (history(h, &ev, H_SAVE, filename) == -1); + if (filename == NULL && (filename = _default_history_file()) == NULL) + return errno; + return (FUNW(history)(h, &ev, H_SAVE, filename) == -1 ? (errno ? errno : EINVAL) : 0); } @@ -1149,30 +1327,29 @@ HIST_ENTRY * history_get(int num) { static HIST_ENTRY she; - HistEvent ev; + TYPE(HistEvent) ev; int curr_num; if (h == NULL || e == NULL) rl_initialize(); /* save current position */ - if (history(h, &ev, H_CURR) != 0) + if (FUNW(history)(h, &ev, H_CURR) != 0) return (NULL); curr_num = ev.num; - /* start from most recent */ - if (history(h, &ev, H_FIRST) != 0) + /* start from the oldest */ + if (FUNW(history)(h, &ev, H_LAST) != 0) return (NULL); /* error */ - /* look backwards for event matching specified offset */ - if (history(h, &ev, H_NEXT_EVENT, num + 1)) + /* look forwards for event matching specified offset */ + if (FUNW(history)(h, &ev, H_NEXT_EVDATA, num, &she.data)) return (NULL); - she.line = ev.str; - she.data = NULL; + she.line = ct_encode_string(ev.str, &conv); /* restore pointer to where it was */ - (void)history(h, &ev, H_SET, curr_num); + (void)FUNW(history)(h, &ev, H_SET, curr_num); return (&she); } @@ -1184,13 +1361,13 @@ history_get(int num) int add_history(const char *line) { - HistEvent ev; + TYPE(HistEvent) ev; if (h == NULL || e == NULL) rl_initialize(); - (void)history(h, &ev, H_ENTER, line); - if (history(h, &ev, H_GETSIZE) == 0) + (void)FUNW(history)(h, &ev, H_ENTER, line); + if (FUNW(history)(h, &ev, H_GETSIZE) == 0) history_length = ev.num; return (!(history_length > 0)); /* return 0 if all is okay */ @@ -1203,34 +1380,84 @@ add_history(const char *line) HIST_ENTRY * remove_history(int num) { - HIST_ENTRY *she; - HistEvent ev; + HIST_ENTRY *he; + TYPE(HistEvent) ev; if (h == NULL || e == NULL) rl_initialize(); - if (history(h, &ev, H_DEL, num) != 0) + if ((he = malloc(sizeof(*he))) == NULL) return NULL; - if ((she = malloc(sizeof(*she))) == NULL) + if (FUNW(history)(h, &ev, H_DELDATA, num, &he->data) != 0) { + free(he); return NULL; + } - she->line = ev.str; - she->data = NULL; + he->line = ct_encode_string(ev.str, &conv); + if (FUNW(history)(h, &ev, H_GETSIZE) == 0) + history_length = ev.num; - return she; + return he; } /* + * replace the line and data of the num-th entry + */ +HIST_ENTRY * +replace_history_entry(int num, const char *line, histdata_t data) +{ + HIST_ENTRY *he; + TYPE(HistEvent) ev; + int curr_num; + + if (h == NULL || e == NULL) + rl_initialize(); + + /* save current position */ + if (FUNW(history)(h, &ev, H_CURR) != 0) + return NULL; + curr_num = ev.num; + + /* start from the oldest */ + if (FUNW(history)(h, &ev, H_LAST) != 0) + return NULL; /* error */ + + if ((he = malloc(sizeof(*he))) == NULL) + return NULL; + + /* look forwards for event matching specified offset */ + if (FUNW(history)(h, &ev, H_NEXT_EVDATA, num, &he->data)) + goto out; + + he->line = strdup(ct_encode_string(ev.str, &e->el_scratch)); + if (he->line == NULL) + goto out; + + if (FUNW(history)(h, &ev, H_REPLACE, line, data)) + goto out; + + /* restore pointer to where it was */ + if (FUNW(history)(h, &ev, H_SET, curr_num)) + goto out; + + return he; +out: + free(he); + return NULL; +} + +/* * clear the history list - delete all entries */ void clear_history(void) { - HistEvent ev; + TYPE(HistEvent) ev; - history(h, &ev, H_CLEAR); + FUNW(history)(h, &ev, H_CLEAR); + history_length = 0; } @@ -1240,16 +1467,16 @@ clear_history(void) int where_history(void) { - HistEvent ev; + TYPE(HistEvent) ev; int curr_num, off; - if (history(h, &ev, H_CURR) != 0) + if (FUNW(history)(h, &ev, H_CURR) != 0) return (0); curr_num = ev.num; - history(h, &ev, H_FIRST); + FUNW(history)(h, &ev, H_FIRST); off = 1; - while (ev.num != curr_num && history(h, &ev, H_NEXT) == 0) + while (ev.num != curr_num && FUNW(history)(h, &ev, H_NEXT) == 0) off++; return (off); @@ -1273,23 +1500,24 @@ current_history(void) int history_total_bytes(void) { - HistEvent ev; - int curr_num, size; + TYPE(HistEvent) ev; + int curr_num; + size_t size; - if (history(h, &ev, H_CURR) != 0) + if (FUNW(history)(h, &ev, H_CURR) != 0) return (-1); curr_num = ev.num; - history(h, &ev, H_FIRST); + FUNW(history)(h, &ev, H_FIRST); size = 0; do - size += strlen(ev.str); - while (history(h, &ev, H_NEXT) == 0); + size += Strlen(ev.str) * sizeof(*ev.str); + while (FUNW(history)(h, &ev, H_NEXT) == 0); /* get to the same position as before */ - history(h, &ev, H_PREV_EVENT, curr_num); + FUNW(history)(h, &ev, H_PREV_EVENT, curr_num); - return (size); + return (int)(size); } @@ -1299,17 +1527,21 @@ history_total_bytes(void) int history_set_pos(int pos) { - HistEvent ev; + TYPE(HistEvent) ev; int curr_num; - if (pos > history_length || pos < 0) + if (pos >= history_length || pos < 0) return (-1); - history(h, &ev, H_CURR); + FUNW(history)(h, &ev, H_CURR); curr_num = ev.num; - if (history(h, &ev, H_SET, pos)) { - history(h, &ev, H_SET, curr_num); + /* + * use H_DELDATA to set to nth history (without delete) by passing + * (void **)-1 + */ + if (FUNW(history)(h, &ev, H_DELDATA, pos, (void **)-1)) { + FUNW(history)(h, &ev, H_SET, curr_num); return(-1); } return (0); @@ -1344,21 +1576,23 @@ next_history(void) int history_search(const char *str, int direction) { - HistEvent ev; - const char *strp; + TYPE(HistEvent) ev; + const Char *strp; + const Char *wstr; int curr_num; - if (history(h, &ev, H_CURR) != 0) + if (FUNW(history)(h, &ev, H_CURR) != 0) return (-1); curr_num = ev.num; + wstr = ct_decode_string(str, &conv); for (;;) { - if ((strp = strstr(ev.str, str)) != NULL) + if ((strp = Strstr(ev.str, wstr)) != NULL) return (int) (strp - ev.str); - if (history(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0) + if (FUNW(history)(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0) break; } - history(h, &ev, H_SET, curr_num); + FUNW(history)(h, &ev, H_SET, curr_num); return (-1); } @@ -1369,9 +1603,9 @@ history_search(const char *str, int dire int history_search_prefix(const char *str, int direction) { - HistEvent ev; + TYPE(HistEvent) ev; - return (history(h, &ev, direction < 0? H_PREV_STR:H_NEXT_STR, str)); + return (FUNW(history)(h, &ev, direction < 0? H_PREV_STR:H_NEXT_STR, str)); } @@ -1384,29 +1618,30 @@ int history_search_pos(const char *str, int direction __attribute__((__unused__)), int pos) { - HistEvent ev; + TYPE(HistEvent) ev; int curr_num, off; + const Char *wstr; off = (pos > 0) ? pos : -pos; pos = (pos > 0) ? 1 : -1; - if (history(h, &ev, H_CURR) != 0) + if (FUNW(history)(h, &ev, H_CURR) != 0) return (-1); curr_num = ev.num; - if (history_set_pos(off) != 0 || history(h, &ev, H_CURR) != 0) + if (history_set_pos(off) != 0 || FUNW(history)(h, &ev, H_CURR) != 0) return (-1); - + wstr = ct_decode_string(str, &conv); for (;;) { - if (strstr(ev.str, str)) + if (Strstr(ev.str, wstr)) return (off); - if (history(h, &ev, (pos < 0) ? H_PREV : H_NEXT) != 0) + if (FUNW(history)(h, &ev, (pos < 0) ? H_PREV : H_NEXT) != 0) break; } /* set "current" pointer back to previous state */ - history(h, &ev, (pos < 0) ? H_NEXT_EVENT : H_PREV_EVENT, curr_num); + FUNW(history)(h, &ev, (pos < 0) ? H_NEXT_EVENT : H_PREV_EVENT, curr_num); return (-1); } @@ -1455,9 +1690,9 @@ username_completion_function(const char if (pwd == NULL) { endpwent(); - return (NULL); + return NULL; } - return (strdup(pwd->pw_name)); + return strdup(pwd->pw_name); } @@ -1481,7 +1716,7 @@ void rl_display_match_list(char **matches, int len, int max) { - fn_display_match_list(e, matches, len, max); + fn_display_match_list(e, matches, (size_t)len, (size_t)max); } static const char * @@ -1503,6 +1738,10 @@ _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 + if (h == NULL || e == NULL) rl_initialize(); @@ -1518,8 +1757,10 @@ rl_complete(int ignore __attribute__((__ return fn_complete(e, (CPFunction *)rl_completion_entry_function, rl_attempted_completion_function, - rl_basic_word_break_characters, rl_special_prefixes, - _rl_completion_append_character_function, rl_completion_query_items, + ct_decode_string(rl_basic_word_break_characters, &wbreak_conv), + ct_decode_string(rl_special_prefixes, &sprefix_conv), + _rl_completion_append_character_function, + (size_t)rl_completion_query_items, &rl_completion_type, &rl_attempted_completion_over, &rl_point, &rl_end); } @@ -1540,7 +1781,7 @@ _el_rl_complete(EditLine *el __attribute * bind key c to readline-type function func */ int -rl_bind_key(int c, int func(int, int)) +rl_bind_key(int c, rl_command_func_t *func) { int retval = -1; @@ -1607,6 +1848,20 @@ rl_insert(int count, int c) return (0); } +int +rl_insert_text(const char *text) +{ + if (!text || *text == 0) + return (0); + + if (h == NULL || e == NULL) + rl_initialize(); + + if (el_insertstr(e, text) < 0) + return (0); + return (int)strlen(text); +} + /*ARGSUSED*/ int rl_newline(int count, int c) @@ -1639,7 +1894,7 @@ int rl_add_defun(const char *name, Function *fun, int c) { char dest[8]; - if (c >= sizeof(map) / sizeof(map[0]) || c < 0) + if ((size_t)c >= sizeof(map) / sizeof(map[0]) || c < 0) return -1; map[(unsigned char)c] = fun; el_set(e, EL_ADDFN, name, name, rl_bind_wrapper); @@ -1670,7 +1925,7 @@ 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); } } @@ -1680,9 +1935,7 @@ rl_callback_handler_install(const char * if (e == NULL) { rl_initialize(); } - if (rl_prompt) - free(rl_prompt); - rl_prompt = prompt ? strdup(strchr(prompt, *prompt)) : NULL; + (void)rl_set_prompt(prompt); rl_linefunc = linefunc; el_set(e, EL_UNBUFFERED, 1); } @@ -1770,7 +2023,8 @@ rl_stuff_char(int c) static int _rl_event_read_char(EditLine *el, char *cp) { - int n, num_read = 0; + int n; + ssize_t num_read = 0; *cp = '\0'; while (rl_event_hook) { @@ -1806,7 +2060,7 @@ _rl_event_read_char(EditLine *el, char * } if (!rl_event_hook) el_set(el, EL_GETCFN, EL_BUILTIN_GETCFN); - return(num_read); + return (int)num_read; } static void @@ -1814,8 +2068,8 @@ _rl_update_pos(void) { const LineInfo *li = el_line(e); - rl_point = li->cursor - li->buffer; - rl_end = li->lastchar - li->buffer; + rl_point = (int)(li->cursor - li->buffer); + rl_end = (int)(li->lastchar - li->buffer); } void @@ -1849,6 +2103,7 @@ rl_completion_matches(const char *str, r return NULL; while ((match = (*fun)(str, (int)(len - 1))) != NULL) { + list[len++] = match; if (len == max) { char **nl; max += 10; @@ -1856,7 +2111,6 @@ rl_completion_matches(const char *str, r goto out; list = nl; } - list[len++] = match; } if (len == 1) goto out; @@ -1918,6 +2172,17 @@ _rl_qsort_string_compare(char **s1, char return strcoll(*s1, *s2); } +HISTORY_STATE * +history_get_history_state(void) +{ + HISTORY_STATE *hs; + + if ((hs = malloc(sizeof(HISTORY_STATE))) == NULL) + return (NULL); + hs->length = history_length; + return (hs); +} + int /*ARGSUSED*/ rl_kill_text(int from, int to) @@ -1952,7 +2217,13 @@ rl_generic_bind(int type, const char * k int /*ARGSUSED*/ -rl_bind_key_in_map(int key, Function *fun, Keymap k) +rl_bind_key_in_map(int key, rl_command_func_t *fun, Keymap k) { return 0; } + +/* unsupported, but needed by python */ +void +rl_cleanup_after_signal(void) +{ +}