version 1.84, 2009/07/22 15:57:40 |
version 1.95, 2011/07/28 20:50:55 |
Line 50 __RCSID("$NetBSD$"); |
|
Line 50 __RCSID("$NetBSD$"); |
|
#ifdef HAVE_VIS_H |
#ifdef HAVE_VIS_H |
#include <vis.h> |
#include <vis.h> |
#else |
#else |
#include "np/vis.h" |
#include "vis.h" |
#endif |
#endif |
#include "readline/readline.h" |
#include "readline/readline.h" |
#include "el.h" |
#include "el.h" |
Line 70 void rl_deprep_terminal(void); |
|
Line 70 void rl_deprep_terminal(void); |
|
/* readline compatibility stuff - look at readline sources/documentation */ |
/* readline compatibility stuff - look at readline sources/documentation */ |
/* to see what these variables mean */ |
/* to see what these variables mean */ |
const char *rl_library_version = "EditLine wrapper"; |
const char *rl_library_version = "EditLine wrapper"; |
|
int rl_readline_version = RL_READLINE_VERSION; |
static char empty[] = { '\0' }; |
static char empty[] = { '\0' }; |
static char expand_chars[] = { ' ', '\t', '\n', '=', '(', '\0' }; |
static char expand_chars[] = { ' ', '\t', '\n', '=', '(', '\0' }; |
static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$', |
static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$', |
Line 118 Function *rl_startup_hook = NULL; |
|
Line 119 Function *rl_startup_hook = NULL; |
|
VFunction *rl_completion_display_matches_hook = NULL; |
VFunction *rl_completion_display_matches_hook = NULL; |
VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal; |
VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal; |
VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal; |
VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal; |
|
KEYMAP_ENTRY_ARRAY emacs_meta_keymap; |
|
|
/* |
/* |
* The current prompt string. |
* The current prompt string. |
Line 214 _getc_function(EditLine *el, char *c) |
|
Line 216 _getc_function(EditLine *el, char *c) |
|
return 1; |
return 1; |
} |
} |
|
|
|
static void |
|
_resize_fun(EditLine *el, void *a) |
|
{ |
|
const LineInfo *li; |
|
char **ap = a; |
|
|
|
li = el_line(el); |
|
/* a cheesy way to get rid of const cast. */ |
|
*ap = memchr(li->buffer, *li->buffer, 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 |
* READLINE compatibility stuff |
Line 232 rl_set_prompt(const char *prompt) |
|
Line 261 rl_set_prompt(const char *prompt) |
|
if (rl_prompt != NULL && strcmp(rl_prompt, prompt) == 0) |
if (rl_prompt != NULL && strcmp(rl_prompt, prompt) == 0) |
return 0; |
return 0; |
if (rl_prompt) |
if (rl_prompt) |
free(rl_prompt); |
el_free(rl_prompt); |
rl_prompt = strdup(prompt); |
rl_prompt = strdup(prompt); |
if (rl_prompt == NULL) |
if (rl_prompt == NULL) |
return -1; |
return -1; |
|
|
rl_initialize(void) |
rl_initialize(void) |
{ |
{ |
HistEvent ev; |
HistEvent ev; |
const LineInfo *li; |
|
int editmode = 1; |
int editmode = 1; |
struct termios t; |
struct termios t; |
|
|
Line 284 rl_initialize(void) |
|
Line 312 rl_initialize(void) |
|
max_input_history = INT_MAX; |
max_input_history = INT_MAX; |
el_set(e, EL_HIST, history, h); |
el_set(e, EL_HIST, history, h); |
|
|
|
/* Setup resize function */ |
|
el_set(e, EL_RESIZE, _resize_fun, &rl_line_buffer); |
|
|
/* setup getc function if valid */ |
/* setup getc function if valid */ |
if (rl_getc_function) |
if (rl_getc_function) |
el_set(e, EL_GETCFN, _getc_function); |
el_set(e, EL_GETCFN, _getc_function); |
Line 329 rl_initialize(void) |
|
Line 360 rl_initialize(void) |
|
* Unfortunately, some applications really do use rl_point |
* Unfortunately, some applications really do use rl_point |
* and rl_line_buffer directly. |
* and rl_line_buffer directly. |
*/ |
*/ |
li = el_line(e); |
_resize_fun(e, &rl_line_buffer); |
/* a cheesy way to get rid of const cast. */ |
|
rl_line_buffer = memchr(li->buffer, *li->buffer, 1); |
|
_rl_update_pos(); |
_rl_update_pos(); |
|
|
if (rl_startup_hook) |
if (rl_startup_hook) |
Line 446 _rl_compat_sub(const char *str, const ch |
|
Line 475 _rl_compat_sub(const char *str, const ch |
|
} else |
} else |
s++; |
s++; |
} |
} |
r = result = malloc(len + 1); |
r = result = el_malloc((len + 1) * sizeof(*r)); |
if (result == NULL) |
if (result == NULL) |
return NULL; |
return NULL; |
s = str; |
s = str; |
Line 487 get_history_event(const char *cmd, int * |
|
Line 516 get_history_event(const char *cmd, int * |
|
if (history(h, &ev, H_FIRST) != 0) |
if (history(h, &ev, H_FIRST) != 0) |
return(NULL); |
return(NULL); |
*cindex = cmd[idx]? (idx + 1):idx; |
*cindex = cmd[idx]? (idx + 1):idx; |
return(ev.str); |
return ev.str; |
} |
} |
sign = 0; |
sign = 0; |
if (cmd[idx] == '-') { |
if (cmd[idx] == '-') { |
Line 536 get_history_event(const char *cmd, int * |
|
Line 565 get_history_event(const char *cmd, int * |
|
else if (len == 0) |
else if (len == 0) |
return(NULL); |
return(NULL); |
else { |
else { |
if ((pat = malloc(len + 1)) == NULL) |
if ((pat = el_malloc((len + 1) * sizeof(*pat))) == NULL) |
return NULL; |
return NULL; |
(void)strncpy(pat, cmd + begin, len); |
(void)strncpy(pat, cmd + begin, len); |
pat[len] = '\0'; |
pat[len] = '\0'; |
Line 544 get_history_event(const char *cmd, int * |
|
Line 573 get_history_event(const char *cmd, int * |
|
|
|
if (history(h, &ev, H_CURR) != 0) { |
if (history(h, &ev, H_CURR) != 0) { |
if (pat != last_search_pat) |
if (pat != last_search_pat) |
free(pat); |
el_free(pat); |
return (NULL); |
return (NULL); |
} |
} |
num = ev.num; |
num = ev.num; |
Line 552 get_history_event(const char *cmd, int * |
|
Line 581 get_history_event(const char *cmd, int * |
|
if (sub) { |
if (sub) { |
if (pat != last_search_pat) { |
if (pat != last_search_pat) { |
if (last_search_pat) |
if (last_search_pat) |
free(last_search_pat); |
el_free(last_search_pat); |
last_search_pat = pat; |
last_search_pat = pat; |
} |
} |
ret = history_search(pat, -1); |
ret = history_search(pat, -1); |
Line 564 get_history_event(const char *cmd, int * |
|
Line 593 get_history_event(const char *cmd, int * |
|
history(h, &ev, H_FIRST); |
history(h, &ev, H_FIRST); |
(void)fprintf(rl_outstream, "%s: Event not found\n", pat); |
(void)fprintf(rl_outstream, "%s: Event not found\n", pat); |
if (pat != last_search_pat) |
if (pat != last_search_pat) |
free(pat); |
el_free(pat); |
return(NULL); |
return(NULL); |
} |
} |
|
|
if (sub && len) { |
if (sub && len) { |
if (last_search_match && last_search_match != pat) |
if (last_search_match && last_search_match != pat) |
free(last_search_match); |
el_free(last_search_match); |
last_search_match = pat; |
last_search_match = pat; |
} |
} |
|
|
if (pat != last_search_pat) |
if (pat != last_search_pat) |
free(pat); |
el_free(pat); |
|
|
if (history(h, &ev, H_CURR) != 0) |
if (history(h, &ev, H_CURR) != 0) |
return(NULL); |
return(NULL); |
Line 630 _history_expand_command(const char *comm |
|
Line 659 _history_expand_command(const char *comm |
|
} else { |
} else { |
if (command[offs + 1] == '#') { |
if (command[offs + 1] == '#') { |
/* use command so far */ |
/* use command so far */ |
if ((aptr = malloc(offs + 1)) == NULL) |
if ((aptr = el_malloc((offs + 1) * sizeof(*aptr))) |
|
== NULL) |
return -1; |
return -1; |
(void)strncpy(aptr, command, offs); |
(void)strncpy(aptr, command, offs); |
aptr[offs] = '\0'; |
aptr[offs] = '\0'; |
Line 648 _history_expand_command(const char *comm |
|
Line 678 _history_expand_command(const char *comm |
|
return(-1); |
return(-1); |
|
|
if (!has_mods) { |
if (!has_mods) { |
*result = strdup(aptr? aptr : ptr); |
*result = strdup(aptr ? aptr : ptr); |
if (aptr) |
if (aptr) |
free(aptr); |
el_free(aptr); |
|
if (*result == NULL) |
|
return -1; |
return(1); |
return(1); |
} |
} |
|
|
Line 696 _history_expand_command(const char *comm |
|
Line 728 _history_expand_command(const char *comm |
|
(void)fprintf(rl_outstream, "%s: Bad word specifier", |
(void)fprintf(rl_outstream, "%s: Bad word specifier", |
command + offs + idx); |
command + offs + idx); |
if (aptr) |
if (aptr) |
free(aptr); |
el_free(aptr); |
return(-1); |
return(-1); |
} |
} |
} else |
} else |
tmp = strdup(aptr? aptr:ptr); |
tmp = strdup(aptr? aptr:ptr); |
|
|
if (aptr) |
if (aptr) |
free(aptr); |
el_free(aptr); |
|
|
if (*cmd == '\0' || ((size_t)(cmd - (command + offs)) >= cmdlen)) { |
if (*cmd == '\0' || ((size_t)(cmd - (command + offs)) >= cmdlen)) { |
*result = tmp; |
*result = tmp; |
Line 719 _history_expand_command(const char *comm |
|
Line 751 _history_expand_command(const char *comm |
|
} else if (*cmd == 't') { /* remove leading path */ |
} else if (*cmd == 't') { /* remove leading path */ |
if ((aptr = strrchr(tmp, '/')) != NULL) { |
if ((aptr = strrchr(tmp, '/')) != NULL) { |
aptr = strdup(aptr + 1); |
aptr = strdup(aptr + 1); |
free(tmp); |
el_free(tmp); |
tmp = aptr; |
tmp = aptr; |
} |
} |
} else if (*cmd == 'r') { /* remove trailing suffix */ |
} else if (*cmd == 'r') { /* remove trailing suffix */ |
Line 728 _history_expand_command(const char *comm |
|
Line 760 _history_expand_command(const char *comm |
|
} else if (*cmd == 'e') { /* remove all but suffix */ |
} else if (*cmd == 'e') { /* remove all but suffix */ |
if ((aptr = strrchr(tmp, '.')) != NULL) { |
if ((aptr = strrchr(tmp, '.')) != NULL) { |
aptr = strdup(aptr); |
aptr = strdup(aptr); |
free(tmp); |
el_free(tmp); |
tmp = aptr; |
tmp = aptr; |
} |
} |
} else if (*cmd == 'p') /* print only */ |
} else if (*cmd == 'p') /* print only */ |
Line 745 _history_expand_command(const char *comm |
|
Line 777 _history_expand_command(const char *comm |
|
else if (*cmd == 's') { |
else if (*cmd == 's') { |
delim = *(++cmd), cmd++; |
delim = *(++cmd), cmd++; |
size = 16; |
size = 16; |
what = realloc(from, size); |
what = el_realloc(from, size * sizeof(*what)); |
if (what == NULL) { |
if (what == NULL) { |
free(from); |
el_free(from); |
free(tmp); |
el_free(tmp); |
return 0; |
return 0; |
} |
} |
len = 0; |
len = 0; |
Line 757 _history_expand_command(const char *comm |
|
Line 789 _history_expand_command(const char *comm |
|
cmd++; |
cmd++; |
if (len >= size) { |
if (len >= size) { |
char *nwhat; |
char *nwhat; |
nwhat = realloc(what, |
nwhat = el_realloc(what, |
(size <<= 1)); |
(size <<= 1) * |
|
sizeof(*nwhat)); |
if (nwhat == NULL) { |
if (nwhat == NULL) { |
free(what); |
el_free(what); |
free(tmp); |
el_free(tmp); |
return 0; |
return 0; |
} |
} |
what = nwhat; |
what = nwhat; |
Line 771 _history_expand_command(const char *comm |
|
Line 804 _history_expand_command(const char *comm |
|
what[len] = '\0'; |
what[len] = '\0'; |
from = what; |
from = what; |
if (*what == '\0') { |
if (*what == '\0') { |
free(what); |
el_free(what); |
if (search) { |
if (search) { |
from = strdup(search); |
from = strdup(search); |
if (from == NULL) { |
if (from == NULL) { |
free(tmp); |
el_free(tmp); |
return 0; |
return 0; |
} |
} |
} else { |
} else { |
from = NULL; |
from = NULL; |
free(tmp); |
el_free(tmp); |
return (-1); |
return (-1); |
} |
} |
} |
} |
Line 789 _history_expand_command(const char *comm |
|
Line 822 _history_expand_command(const char *comm |
|
continue; |
continue; |
|
|
size = 16; |
size = 16; |
with = realloc(to, size); |
with = el_realloc(to, size * sizeof(*with)); |
if (with == NULL) { |
if (with == NULL) { |
free(to); |
el_free(to); |
free(tmp); |
el_free(tmp); |
return -1; |
return -1; |
} |
} |
len = 0; |
len = 0; |
Line 801 _history_expand_command(const char *comm |
|
Line 834 _history_expand_command(const char *comm |
|
if (len + from_len + 1 >= size) { |
if (len + from_len + 1 >= size) { |
char *nwith; |
char *nwith; |
size += from_len + 1; |
size += from_len + 1; |
nwith = realloc(with, size); |
nwith = el_realloc(with, |
|
size * sizeof(*nwith)); |
if (nwith == NULL) { |
if (nwith == NULL) { |
free(with); |
el_free(with); |
free(tmp); |
el_free(tmp); |
return -1; |
return -1; |
} |
} |
with = nwith; |
with = nwith; |
Line 827 _history_expand_command(const char *comm |
|
Line 861 _history_expand_command(const char *comm |
|
|
|
aptr = _rl_compat_sub(tmp, from, to, g_on); |
aptr = _rl_compat_sub(tmp, from, to, g_on); |
if (aptr) { |
if (aptr) { |
free(tmp); |
el_free(tmp); |
tmp = aptr; |
tmp = aptr; |
} |
} |
g_on = 0; |
g_on = 0; |
Line 859 history_expand(char *str, char **output) |
|
Line 893 history_expand(char *str, char **output) |
|
*output = NULL; |
*output = NULL; |
if (str[0] == history_subst_char) { |
if (str[0] == history_subst_char) { |
/* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */ |
/* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */ |
*output = malloc(strlen(str) + 4 + 1); |
*output = el_malloc((strlen(str) + 4 + 1) * sizeof(*output)); |
if (*output == NULL) |
if (*output == NULL) |
return 0; |
return 0; |
(*output)[0] = (*output)[1] = history_expansion_char; |
(*output)[0] = (*output)[1] = history_expansion_char; |
Line 876 history_expand(char *str, char **output) |
|
Line 910 history_expand(char *str, char **output) |
|
#define ADD_STRING(what, len, fr) \ |
#define ADD_STRING(what, len, fr) \ |
{ \ |
{ \ |
if (idx + len + 1 > size) { \ |
if (idx + len + 1 > size) { \ |
char *nresult = realloc(result, (size += len + 1));\ |
char *nresult = el_realloc(result, \ |
|
(size += len + 1) * sizeof(*nresult)); \ |
if (nresult == NULL) { \ |
if (nresult == NULL) { \ |
free(*output); \ |
el_free(*output); \ |
if (/*CONSTCOND*/fr) \ |
if (/*CONSTCOND*/fr) \ |
free(tmp); \ |
el_free(tmp); \ |
return 0; \ |
return 0; \ |
} \ |
} \ |
result = nresult; \ |
result = nresult; \ |
|
|
ADD_STRING(tmp, len, 1); |
ADD_STRING(tmp, len, 1); |
} |
} |
if (tmp) { |
if (tmp) { |
free(tmp); |
el_free(tmp); |
tmp = NULL; |
tmp = NULL; |
} |
} |
i = j; |
i = j; |
|
|
ret = -1; |
ret = -1; |
#endif |
#endif |
} |
} |
free(*output); |
el_free(*output); |
*output = result; |
*output = result; |
|
|
return (ret); |
return (ret); |
Line 1005 history_arg_extract(int start, int end, |
|
Line 1040 history_arg_extract(int start, int end, |
|
for (i = start, len = 0; i <= (size_t)end; i++) |
for (i = start, len = 0; i <= (size_t)end; i++) |
len += strlen(arr[i]) + 1; |
len += strlen(arr[i]) + 1; |
len++; |
len++; |
result = malloc(len); |
result = el_malloc(len * sizeof(*result)); |
if (result == NULL) |
if (result == NULL) |
goto out; |
goto out; |
|
|
Line 1019 history_arg_extract(int start, int end, |
|
Line 1054 history_arg_extract(int start, int end, |
|
|
|
out: |
out: |
for (i = 0; arr[i]; i++) |
for (i = 0; arr[i]; i++) |
free(arr[i]); |
el_free(arr[i]); |
free(arr); |
el_free(arr); |
|
|
return result; |
return result; |
} |
} |
Line 1059 history_tokenize(const char *str) |
|
Line 1094 history_tokenize(const char *str) |
|
if (idx + 2 >= size) { |
if (idx + 2 >= size) { |
char **nresult; |
char **nresult; |
size <<= 1; |
size <<= 1; |
nresult = realloc(result, size * sizeof(char *)); |
nresult = el_realloc(result, size * sizeof(*nresult)); |
if (nresult == NULL) { |
if (nresult == NULL) { |
free(result); |
el_free(result); |
return NULL; |
return NULL; |
} |
} |
result = nresult; |
result = nresult; |
} |
} |
len = i - start; |
len = i - start; |
temp = malloc(len + 1); |
temp = el_malloc((len + 1) * sizeof(*temp)); |
if (temp == NULL) { |
if (temp == NULL) { |
for (i = 0; i < idx; i++) |
for (i = 0; i < idx; i++) |
free(result[i]); |
el_free(result[i]); |
free(result); |
el_free(result); |
return NULL; |
return NULL; |
} |
} |
(void)strncpy(temp, &str[start], len); |
(void)strncpy(temp, &str[start], len); |
Line 1125 history_is_stifled(void) |
|
Line 1160 history_is_stifled(void) |
|
return (max_input_history != INT_MAX); |
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 |
* read history from a file given |
Line 1136 read_history(const char *filename) |
|
Line 1307 read_history(const char *filename) |
|
|
|
if (h == NULL || e == NULL) |
if (h == NULL || e == NULL) |
rl_initialize(); |
rl_initialize(); |
return (history(h, &ev, H_LOAD, filename) == -1); |
if (filename == NULL && (filename = _default_history_file()) == NULL) |
|
return errno; |
|
return (history(h, &ev, H_LOAD, filename) == -1 ? |
|
(errno ? errno : EINVAL) : 0); |
} |
} |
|
|
|
|
Line 1150 write_history(const char *filename) |
|
Line 1324 write_history(const char *filename) |
|
|
|
if (h == NULL || e == NULL) |
if (h == NULL || e == NULL) |
rl_initialize(); |
rl_initialize(); |
return (history(h, &ev, H_SAVE, filename) == -1); |
if (filename == NULL && (filename = _default_history_file()) == NULL) |
|
return errno; |
|
return (history(h, &ev, H_SAVE, filename) == -1 ? |
|
(errno ? errno : EINVAL) : 0); |
} |
} |
|
|
|
|
Line 1174 history_get(int num) |
|
Line 1351 history_get(int num) |
|
return (NULL); |
return (NULL); |
curr_num = ev.num; |
curr_num = ev.num; |
|
|
/* start from most recent */ |
/* start from the oldest */ |
if (history(h, &ev, H_FIRST) != 0) |
if (history(h, &ev, H_LAST) != 0) |
return (NULL); /* error */ |
return (NULL); /* error */ |
|
|
/* look backwards for event matching specified offset */ |
/* look forwards for event matching specified offset */ |
if (history(h, &ev, H_NEXT_EVENT, num + 1)) |
if (history(h, &ev, H_NEXT_EVDATA, num, &she.data)) |
return (NULL); |
return (NULL); |
|
|
she.line = ev.str; |
she.line = ev.str; |
she.data = NULL; |
|
|
|
/* restore pointer to where it was */ |
/* restore pointer to where it was */ |
(void)history(h, &ev, H_SET, curr_num); |
(void)history(h, &ev, H_SET, curr_num); |
Line 1217 add_history(const char *line) |
|
Line 1393 add_history(const char *line) |
|
HIST_ENTRY * |
HIST_ENTRY * |
remove_history(int num) |
remove_history(int num) |
{ |
{ |
HIST_ENTRY *she; |
HIST_ENTRY *he; |
HistEvent ev; |
HistEvent ev; |
|
|
if (h == NULL || e == NULL) |
if (h == NULL || e == NULL) |
rl_initialize(); |
rl_initialize(); |
|
|
if (history(h, &ev, H_DEL, num) != 0) |
if ((he = el_malloc(sizeof(*he))) == NULL) |
return NULL; |
return NULL; |
|
|
if ((she = malloc(sizeof(*she))) == NULL) |
if (history(h, &ev, H_DELDATA, num, &he->data) != 0) { |
|
el_free(he); |
return NULL; |
return NULL; |
|
} |
|
|
she->line = ev.str; |
he->line = ev.str; |
she->data = NULL; |
if (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; |
|
HistEvent ev; |
|
int curr_num; |
|
|
|
if (h == NULL || e == NULL) |
|
rl_initialize(); |
|
|
|
/* 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 */ |
|
|
|
if ((he = el_malloc(sizeof(*he))) == NULL) |
|
return NULL; |
|
|
|
/* look forwards for event matching specified offset */ |
|
if (history(h, &ev, H_NEXT_EVDATA, num, &he->data)) |
|
goto out; |
|
|
|
he->line = strdup(ev.str); |
|
if (he->line == NULL) |
|
goto out; |
|
|
|
if (history(h, &ev, H_REPLACE, line, data)) |
|
goto out; |
|
|
|
/* restore pointer to where it was */ |
|
if (history(h, &ev, H_SET, curr_num)) |
|
goto out; |
|
|
|
return he; |
|
out: |
|
el_free(he); |
|
return NULL; |
|
} |
|
|
|
/* |
* clear the history list - delete all entries |
* clear the history list - delete all entries |
*/ |
*/ |
void |
void |
Line 1244 clear_history(void) |
|
Line 1469 clear_history(void) |
|
{ |
{ |
HistEvent ev; |
HistEvent ev; |
|
|
history(h, &ev, H_CLEAR); |
(void)history(h, &ev, H_CLEAR); |
|
history_length = 0; |
} |
} |
|
|
|
|
Line 1261 where_history(void) |
|
Line 1487 where_history(void) |
|
return (0); |
return (0); |
curr_num = ev.num; |
curr_num = ev.num; |
|
|
history(h, &ev, H_FIRST); |
(void)history(h, &ev, H_FIRST); |
off = 1; |
off = 1; |
while (ev.num != curr_num && history(h, &ev, H_NEXT) == 0) |
while (ev.num != curr_num && history(h, &ev, H_NEXT) == 0) |
off++; |
off++; |
Line 1295 history_total_bytes(void) |
|
Line 1521 history_total_bytes(void) |
|
return (-1); |
return (-1); |
curr_num = ev.num; |
curr_num = ev.num; |
|
|
history(h, &ev, H_FIRST); |
(void)history(h, &ev, H_FIRST); |
size = 0; |
size = 0; |
do |
do |
size += strlen(ev.str); |
size += strlen(ev.str) * sizeof(*ev.str); |
while (history(h, &ev, H_NEXT) == 0); |
while (history(h, &ev, H_NEXT) == 0); |
|
|
/* get to the same position as before */ |
/* get to the same position as before */ |
Line 1317 history_set_pos(int pos) |
|
Line 1543 history_set_pos(int pos) |
|
HistEvent ev; |
HistEvent ev; |
int curr_num; |
int curr_num; |
|
|
if (pos > history_length || pos < 0) |
if (pos >= history_length || pos < 0) |
return (-1); |
return (-1); |
|
|
history(h, &ev, H_CURR); |
(void)history(h, &ev, H_CURR); |
curr_num = ev.num; |
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 (history(h, &ev, H_DELDATA, pos, (void **)-1)) { |
|
(void)history(h, &ev, H_SET, curr_num); |
return(-1); |
return(-1); |
} |
} |
return (0); |
return (0); |
Line 1373 history_search(const char *str, int dire |
|
Line 1603 history_search(const char *str, int dire |
|
if (history(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0) |
if (history(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0) |
break; |
break; |
} |
} |
history(h, &ev, H_SET, curr_num); |
(void)history(h, &ev, H_SET, curr_num); |
return (-1); |
return (-1); |
} |
} |
|
|
Line 1386 history_search_prefix(const char *str, i |
|
Line 1616 history_search_prefix(const char *str, i |
|
{ |
{ |
HistEvent ev; |
HistEvent ev; |
|
|
return (history(h, &ev, direction < 0? H_PREV_STR:H_NEXT_STR, str)); |
return (history(h, &ev, direction < 0 ? |
|
H_PREV_STR : H_NEXT_STR, str)); |
} |
} |
|
|
|
|
Line 1412 history_search_pos(const char *str, |
|
Line 1643 history_search_pos(const char *str, |
|
if (history_set_pos(off) != 0 || history(h, &ev, H_CURR) != 0) |
if (history_set_pos(off) != 0 || history(h, &ev, H_CURR) != 0) |
return (-1); |
return (-1); |
|
|
|
|
for (;;) { |
for (;;) { |
if (strstr(ev.str, str)) |
if (strstr(ev.str, str)) |
return (off); |
return (off); |
Line 1421 history_search_pos(const char *str, |
|
Line 1651 history_search_pos(const char *str, |
|
} |
} |
|
|
/* set "current" pointer back to previous state */ |
/* set "current" pointer back to previous state */ |
history(h, &ev, (pos < 0) ? H_NEXT_EVENT : H_PREV_EVENT, curr_num); |
(void)history(h, &ev, |
|
pos < 0 ? H_NEXT_EVENT : H_PREV_EVENT, curr_num); |
|
|
return (-1); |
return (-1); |
} |
} |
Line 1446 filename_completion_function(const char |
|
Line 1677 filename_completion_function(const char |
|
* a completion generator for usernames; returns _first_ username |
* a completion generator for usernames; returns _first_ username |
* which starts with supplied text |
* which starts with supplied text |
* text contains a partial username preceded by random character |
* text contains a partial username preceded by random character |
* (usually '~'); state is ignored |
* (usually '~'); state resets search from start (??? should we do that anyway) |
* it's callers responsibility to free returned value |
* it's callers responsibility to free returned value |
*/ |
*/ |
char * |
char * |
username_completion_function(const char *text, int state) |
username_completion_function(const char *text, int state) |
{ |
{ |
struct passwd *pwd, pwres; |
#if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT) |
|
struct passwd pwres; |
char pwbuf[1024]; |
char pwbuf[1024]; |
|
#endif |
|
struct passwd *pass = NULL; |
|
|
if (text[0] == '\0') |
if (text[0] == '\0') |
return (NULL); |
return (NULL); |
Line 1464 username_completion_function(const char |
|
Line 1698 username_completion_function(const char |
|
if (state == 0) |
if (state == 0) |
setpwent(); |
setpwent(); |
|
|
while (getpwent_r(&pwres, pwbuf, sizeof(pwbuf), &pwd) == 0 |
while ( |
&& pwd != NULL && text[0] == pwd->pw_name[0] |
#if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT) |
&& strcmp(text, pwd->pw_name) == 0); |
getpwent_r(&pwres, pwbuf, sizeof(pwbuf), &pass) == 0 && pass != NULL |
|
#else |
|
(pass = getpwent()) != NULL |
|
#endif |
|
&& text[0] == pass->pw_name[0] |
|
&& strcmp(text, pass->pw_name) == 0) |
|
continue; |
|
|
if (pwd == NULL) { |
if (pass == NULL) { |
endpwent(); |
endpwent(); |
return (NULL); |
return NULL; |
} |
} |
return (strdup(pwd->pw_name)); |
return strdup(pass->pw_name); |
} |
} |
|
|
|
|
Line 1518 _rl_completion_append_character_function |
|
Line 1758 _rl_completion_append_character_function |
|
int |
int |
rl_complete(int ignore __attribute__((__unused__)), int invoking_key) |
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) |
if (h == NULL || e == NULL) |
rl_initialize(); |
rl_initialize(); |
|
|
Line 1533 rl_complete(int ignore __attribute__((__ |
|
Line 1777 rl_complete(int ignore __attribute__((__ |
|
return fn_complete(e, |
return fn_complete(e, |
(CPFunction *)rl_completion_entry_function, |
(CPFunction *)rl_completion_entry_function, |
rl_attempted_completion_function, |
rl_attempted_completion_function, |
rl_basic_word_break_characters, rl_special_prefixes, |
ct_decode_string(rl_basic_word_break_characters, &wbreak_conv), |
|
ct_decode_string(rl_special_prefixes, &sprefix_conv), |
_rl_completion_append_character_function, |
_rl_completion_append_character_function, |
(size_t)rl_completion_query_items, |
(size_t)rl_completion_query_items, |
&rl_completion_type, &rl_attempted_completion_over, |
&rl_completion_type, &rl_attempted_completion_over, |
&rl_point, &rl_end); |
&rl_point, &rl_end); |
|
|
|
|
} |
} |
|
|
|
|
Line 1556 _el_rl_complete(EditLine *el __attribute |
|
Line 1803 _el_rl_complete(EditLine *el __attribute |
|
* bind key c to readline-type function func |
* bind key c to readline-type function func |
*/ |
*/ |
int |
int |
rl_bind_key(int c, int func(int, int)) |
rl_bind_key(int c, rl_command_func_t *func) |
{ |
{ |
int retval = -1; |
int retval = -1; |
|
|
Line 1623 rl_insert(int count, int c) |
|
Line 1870 rl_insert(int count, int c) |
|
return (0); |
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*/ |
/*ARGSUSED*/ |
int |
int |
rl_newline(int count, int c) |
rl_newline(int count, int c) |
Line 1686 rl_callback_read_char() |
|
Line 1947 rl_callback_read_char() |
|
} else |
} else |
wbuf = NULL; |
wbuf = NULL; |
(*(void (*)(const char *))rl_linefunc)(wbuf); |
(*(void (*)(const char *))rl_linefunc)(wbuf); |
el_set(e, EL_UNBUFFERED, 1); |
//el_set(e, EL_UNBUFFERED, 1); |
} |
} |
} |
} |
|
|
Line 1860 rl_completion_matches(const char *str, r |
|
Line 2121 rl_completion_matches(const char *str, r |
|
|
|
len = 1; |
len = 1; |
max = 10; |
max = 10; |
if ((list = malloc(max * sizeof(*list))) == NULL) |
if ((list = el_malloc(max * sizeof(*list))) == NULL) |
return NULL; |
return NULL; |
|
|
while ((match = (*fun)(str, (int)(len - 1))) != NULL) { |
while ((match = (*fun)(str, (int)(len - 1))) != NULL) { |
Line 1868 rl_completion_matches(const char *str, r |
|
Line 2129 rl_completion_matches(const char *str, r |
|
if (len == max) { |
if (len == max) { |
char **nl; |
char **nl; |
max += 10; |
max += 10; |
if ((nl = realloc(list, max * sizeof(*nl))) == NULL) |
if ((nl = el_realloc(list, max * sizeof(*nl))) == NULL) |
goto out; |
goto out; |
list = nl; |
list = nl; |
} |
} |
Line 1895 rl_completion_matches(const char *str, r |
|
Line 2156 rl_completion_matches(const char *str, r |
|
if ((list[0] = strdup(str)) == NULL) |
if ((list[0] = strdup(str)) == NULL) |
goto out; |
goto out; |
} else { |
} else { |
if ((list[0] = malloc(min + 1)) == NULL) |
if ((list[0] = el_malloc((min + 1) * sizeof(*list[0]))) == NULL) |
goto out; |
goto out; |
(void)memcpy(list[0], list[1], min); |
(void)memcpy(list[0], list[1], min); |
list[0][min] = '\0'; |
list[0][min] = '\0'; |
Line 1903 rl_completion_matches(const char *str, r |
|
Line 2164 rl_completion_matches(const char *str, r |
|
return list; |
return list; |
|
|
out: |
out: |
free(list); |
el_free(list); |
return NULL; |
return NULL; |
} |
} |
|
|
Line 1933 _rl_qsort_string_compare(char **s1, char |
|
Line 2194 _rl_qsort_string_compare(char **s1, char |
|
return strcoll(*s1, *s2); |
return strcoll(*s1, *s2); |
} |
} |
|
|
|
HISTORY_STATE * |
|
history_get_history_state(void) |
|
{ |
|
HISTORY_STATE *hs; |
|
|
|
if ((hs = el_malloc(sizeof(*hs))) == NULL) |
|
return (NULL); |
|
hs->length = history_length; |
|
return (hs); |
|
} |
|
|
int |
int |
/*ARGSUSED*/ |
/*ARGSUSED*/ |
rl_kill_text(int from, int to) |
rl_kill_text(int from, int to) |
Line 1967 rl_generic_bind(int type, const char * k |
|
Line 2239 rl_generic_bind(int type, const char * k |
|
|
|
int |
int |
/*ARGSUSED*/ |
/*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) |
|
{ |
|
} |
|
|
|
int |
|
rl_on_new_line(void) |
{ |
{ |
return 0; |
return 0; |
} |
} |