version 1.79, 2009/02/12 13:39:49 |
version 1.88, 2010/01/03 18:27:10 |
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; |
|
|
|
#ifdef WIDECHAR |
|
static ct_buffer_t conv; |
|
#endif |
|
|
/* |
/* |
* The current prompt string. |
* The current prompt string. |
Line 151 int rl_completion_append_character = ' ' |
|
Line 157 int rl_completion_append_character = ' ' |
|
|
|
/* stuff below is used internally by libedit for readline emulation */ |
/* stuff below is used internally by libedit for readline emulation */ |
|
|
static History *h = NULL; |
static TYPE(History) *h = NULL; |
static EditLine *e = NULL; |
static EditLine *e = NULL; |
static Function *map[256]; |
static Function *map[256]; |
static jmp_buf topbuf; |
static jmp_buf topbuf; |
Line 185 _get_prompt(EditLine *el __attribute__(( |
|
Line 191 _get_prompt(EditLine *el __attribute__(( |
|
static HIST_ENTRY * |
static HIST_ENTRY * |
_move_history(int op) |
_move_history(int op) |
{ |
{ |
HistEvent ev; |
TYPE(HistEvent) ev; |
static HIST_ENTRY rl_he; |
static HIST_ENTRY rl_he; |
|
|
if (history(h, &ev, op) != 0) |
if (FUNW(history)(h, &ev, op) != 0) |
return (HIST_ENTRY *) NULL; |
return (HIST_ENTRY *) NULL; |
|
|
rl_he.line = ev.str; |
rl_he.line = ct_encode_string(ev.str, &conv); |
rl_he.data = NULL; |
rl_he.data = NULL; |
|
|
return (&rl_he); |
return (&rl_he); |
Line 214 _getc_function(EditLine *el, char *c) |
|
Line 220 _getc_function(EditLine *el, char *c) |
|
return 1; |
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 |
* READLINE compatibility stuff |
Line 225 _getc_function(EditLine *el, char *c) |
|
Line 247 _getc_function(EditLine *el, char *c) |
|
int |
int |
rl_set_prompt(const char *prompt) |
rl_set_prompt(const char *prompt) |
{ |
{ |
|
char *p; |
|
|
if (!prompt) |
if (!prompt) |
prompt = ""; |
prompt = ""; |
if (rl_prompt != NULL && strcmp(rl_prompt, prompt) == 0) |
if (rl_prompt != NULL && strcmp(rl_prompt, prompt) == 0) |
Line 232 rl_set_prompt(const char *prompt) |
|
Line 256 rl_set_prompt(const char *prompt) |
|
if (rl_prompt) |
if (rl_prompt) |
free(rl_prompt); |
free(rl_prompt); |
rl_prompt = strdup(prompt); |
rl_prompt = strdup(prompt); |
return rl_prompt == NULL ? -1 : 0; |
if (rl_prompt == NULL) |
|
return -1; |
|
|
|
while ((p = strchr(rl_prompt, RL_PROMPT_END_IGNORE)) != NULL) |
|
*p = RL_PROMPT_START_IGNORE; |
|
|
|
return 0; |
} |
} |
|
|
/* |
/* |
Line 241 rl_set_prompt(const char *prompt) |
|
Line 271 rl_set_prompt(const char *prompt) |
|
int |
int |
rl_initialize(void) |
rl_initialize(void) |
{ |
{ |
HistEvent ev; |
TYPE(HistEvent) ev; |
const LineInfo *li; |
const LineInfo *li; |
int editmode = 1; |
int editmode = 1; |
struct termios t; |
struct termios t; |
Line 249 rl_initialize(void) |
|
Line 279 rl_initialize(void) |
|
if (e != NULL) |
if (e != NULL) |
el_end(e); |
el_end(e); |
if (h != NULL) |
if (h != NULL) |
history_end(h); |
FUN(history,end)(h); |
|
|
if (!rl_instream) |
if (!rl_instream) |
rl_instream = stdin; |
rl_instream = stdin; |
Line 265 rl_initialize(void) |
|
Line 295 rl_initialize(void) |
|
e = el_init(rl_readline_name, rl_instream, rl_outstream, stderr); |
e = el_init(rl_readline_name, rl_instream, rl_outstream, stderr); |
|
|
if (!editmode) |
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) |
if (!e || !h) |
return (-1); |
return (-1); |
|
|
history(h, &ev, H_SETSIZE, INT_MAX); /* unlimited */ |
FUNW(history)(h, &ev, H_SETSIZE, INT_MAX); /* unlimited */ |
history_length = 0; |
history_length = 0; |
max_input_history = INT_MAX; |
max_input_history = INT_MAX; |
el_set(e, EL_HIST, history, h); |
el_set(e, EL_HIST, history, h); |
Line 282 rl_initialize(void) |
|
Line 312 rl_initialize(void) |
|
|
|
/* for proper prompt printing in readline() */ |
/* for proper prompt printing in readline() */ |
if (rl_set_prompt("") == -1) { |
if (rl_set_prompt("") == -1) { |
history_end(h); |
FUN(history,end)(h); |
el_end(e); |
el_end(e); |
return -1; |
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); |
el_set(e, EL_SIGNAL, rl_catch_signals); |
|
|
/* set default mode to "emacs"-style and read setting afterwards */ |
/* set default mode to "emacs"-style and read setting afterwards */ |
Line 340 rl_initialize(void) |
|
Line 370 rl_initialize(void) |
|
char * |
char * |
readline(const char *p) |
readline(const char *p) |
{ |
{ |
HistEvent ev; |
TYPE(HistEvent) ev; |
const char * volatile prompt = p; |
const char * volatile prompt = p; |
int count; |
int count; |
const char *ret; |
const char *ret; |
Line 388 readline(const char *p) |
|
Line 418 readline(const char *p) |
|
} else |
} else |
buf = NULL; |
buf = NULL; |
|
|
history(h, &ev, H_GETSIZE); |
FUNW(history)(h, &ev, H_GETSIZE); |
history_length = ev.num; |
history_length = ev.num; |
|
|
return buf; |
return buf; |
Line 468 get_history_event(const char *cmd, int * |
|
Line 498 get_history_event(const char *cmd, int * |
|
size_t len; |
size_t len; |
char *pat; |
char *pat; |
const char *rptr; |
const char *rptr; |
HistEvent ev; |
TYPE(HistEvent) ev; |
|
|
idx = *cindex; |
idx = *cindex; |
if (cmd[idx++] != history_expansion_char) |
if (cmd[idx++] != history_expansion_char) |
Line 476 get_history_event(const char *cmd, int * |
|
Line 506 get_history_event(const char *cmd, int * |
|
|
|
/* find out which event to take */ |
/* find out which event to take */ |
if (cmd[idx] == history_expansion_char || cmd[idx] == '\0') { |
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); |
return(NULL); |
*cindex = cmd[idx]? (idx + 1):idx; |
*cindex = cmd[idx]? (idx + 1):idx; |
return(ev.str); |
return ct_encode_string(ev.str, &conv); |
} |
} |
sign = 0; |
sign = 0; |
if (cmd[idx] == '-') { |
if (cmd[idx] == '-') { |
Line 534 get_history_event(const char *cmd, int * |
|
Line 564 get_history_event(const char *cmd, int * |
|
pat[len] = '\0'; |
pat[len] = '\0'; |
} |
} |
|
|
if (history(h, &ev, H_CURR) != 0) { |
if (FUNW(history)(h, &ev, H_CURR) != 0) { |
if (pat != last_search_pat) |
if (pat != last_search_pat) |
free(pat); |
free(pat); |
return (NULL); |
return (NULL); |
Line 553 get_history_event(const char *cmd, int * |
|
Line 583 get_history_event(const char *cmd, int * |
|
|
|
if (ret == -1) { |
if (ret == -1) { |
/* restore to end of list on failed search */ |
/* 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); |
(void)fprintf(rl_outstream, "%s: Event not found\n", pat); |
if (pat != last_search_pat) |
if (pat != last_search_pat) |
free(pat); |
free(pat); |
Line 569 get_history_event(const char *cmd, int * |
|
Line 599 get_history_event(const char *cmd, int * |
|
if (pat != last_search_pat) |
if (pat != last_search_pat) |
free(pat); |
free(pat); |
|
|
if (history(h, &ev, H_CURR) != 0) |
if (FUNW(history)(h, &ev, H_CURR) != 0) |
return(NULL); |
return(NULL); |
*cindex = idx; |
*cindex = idx; |
rptr = ev.str; |
rptr = ct_encode_string(ev.str, &conv); |
|
|
/* roll back to original position */ |
/* roll back to original position */ |
(void)history(h, &ev, H_SET, num); |
(void)FUNW(history)(h, &ev, H_SET, num); |
|
|
return rptr; |
return rptr; |
} |
} |
Line 640 _history_expand_command(const char *comm |
|
Line 670 _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); |
free(aptr); |
|
if (*result == NULL) |
|
return -1; |
return(1); |
return(1); |
} |
} |
|
|
|
|
history_arg_extract(int start, int end, const char *str) |
history_arg_extract(int start, int end, const char *str) |
{ |
{ |
size_t i, len, max; |
size_t i, len, max; |
char **arr, *result; |
char **arr, *result = NULL; |
|
|
arr = history_tokenize(str); |
arr = history_tokenize(str); |
if (!arr) |
if (!arr) |
return(NULL); |
return NULL; |
if (arr && *arr == NULL) { |
if (arr && *arr == NULL) |
free(arr); |
goto out; |
return(NULL); |
|
} |
|
|
|
for (max = 0; arr[max]; max++) |
for (max = 0; arr[max]; max++) |
continue; |
continue; |
max--; |
max--; |
|
|
if (start == '$') |
if (start == '$') |
start = max; |
start = (int)max; |
if (end == '$') |
if (end == '$') |
end = max; |
end = (int)max; |
if (end < 0) |
if (end < 0) |
end = max + end + 1; |
end = (int)max + end + 1; |
if (start < 0) |
if (start < 0) |
start = end; |
start = end; |
|
|
if (start < 0 || end < 0 || (size_t)start > max || (size_t)end > max || start > end) |
if (start < 0 || end < 0 || (size_t)start > max || |
return(NULL); |
(size_t)end > max || start > end) |
|
goto out; |
|
|
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 = malloc(len); |
if (result == NULL) |
if (result == NULL) |
return NULL; |
goto out; |
|
|
for (i = start, len = 0; i <= (size_t)end; i++) { |
for (i = start, len = 0; i <= (size_t)end; i++) { |
(void)strcpy(result + len, arr[i]); |
(void)strcpy(result + len, arr[i]); |
Line 1010 history_arg_extract(int start, int end, |
|
Line 1041 history_arg_extract(int start, int end, |
|
} |
} |
result[len] = '\0'; |
result[len] = '\0'; |
|
|
|
out: |
for (i = 0; arr[i]; i++) |
for (i = 0; arr[i]; i++) |
free(arr[i]); |
free(arr[i]); |
free(arr); |
free(arr); |
|
|
return(result); |
return result; |
} |
} |
|
|
/* |
/* |
Line 1083 history_tokenize(const char *str) |
|
Line 1115 history_tokenize(const char *str) |
|
void |
void |
stifle_history(int max) |
stifle_history(int max) |
{ |
{ |
HistEvent ev; |
TYPE(HistEvent) ev; |
|
|
if (h == NULL || e == NULL) |
if (h == NULL || e == NULL) |
rl_initialize(); |
rl_initialize(); |
|
|
if (history(h, &ev, H_SETSIZE, max) == 0) |
if (FUNW(history)(h, &ev, H_SETSIZE, max) == 0) |
max_input_history = max; |
max_input_history = max; |
} |
} |
|
|
Line 1099 stifle_history(int max) |
|
Line 1131 stifle_history(int max) |
|
int |
int |
unstifle_history(void) |
unstifle_history(void) |
{ |
{ |
HistEvent ev; |
TYPE(HistEvent) ev; |
int omax; |
int omax; |
|
|
history(h, &ev, H_SETSIZE, INT_MAX); |
FUNW(history)(h, &ev, H_SETSIZE, INT_MAX); |
omax = max_input_history; |
omax = max_input_history; |
max_input_history = INT_MAX; |
max_input_history = INT_MAX; |
return (omax); /* some value _must_ be returned */ |
return (omax); /* some value _must_ be returned */ |
Line 1117 history_is_stifled(void) |
|
Line 1149 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 1124 history_is_stifled(void) |
|
Line 1292 history_is_stifled(void) |
|
int |
int |
read_history(const char *filename) |
read_history(const char *filename) |
{ |
{ |
HistEvent ev; |
TYPE(HistEvent) ev; |
|
|
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 (FUNW(history)(h, &ev, H_LOAD, filename) == -1 ? |
|
(errno ? errno : EINVAL) : 0); |
} |
} |
|
|
|
|
Line 1138 read_history(const char *filename) |
|
Line 1309 read_history(const char *filename) |
|
int |
int |
write_history(const char *filename) |
write_history(const char *filename) |
{ |
{ |
HistEvent ev; |
TYPE(HistEvent) ev; |
|
|
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 (FUNW(history)(h, &ev, H_SAVE, filename) == -1 ? |
|
(errno ? errno : EINVAL) : 0); |
} |
} |
|
|
|
|
|
|
history_get(int num) |
history_get(int num) |
{ |
{ |
static HIST_ENTRY she; |
static HIST_ENTRY she; |
HistEvent ev; |
TYPE(HistEvent) ev; |
int curr_num; |
int curr_num; |
|
|
if (h == NULL || e == NULL) |
if (h == NULL || e == NULL) |
rl_initialize(); |
rl_initialize(); |
|
|
/* save current position */ |
/* save current position */ |
if (history(h, &ev, H_CURR) != 0) |
if (FUNW(history)(h, &ev, H_CURR) != 0) |
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 (FUNW(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 (FUNW(history)(h, &ev, H_NEXT_EVDATA, num, &she.data)) |
return (NULL); |
return (NULL); |
|
|
she.line = ev.str; |
she.line = ct_encode_string(ev.str, &conv); |
she.data = NULL; |
|
|
|
/* restore pointer to where it was */ |
/* 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); |
return (&she); |
} |
} |
Line 1190 history_get(int num) |
|
Line 1363 history_get(int num) |
|
int |
int |
add_history(const char *line) |
add_history(const char *line) |
{ |
{ |
HistEvent ev; |
TYPE(HistEvent) ev; |
|
|
if (h == NULL || e == NULL) |
if (h == NULL || e == NULL) |
rl_initialize(); |
rl_initialize(); |
|
|
(void)history(h, &ev, H_ENTER, line); |
(void)FUNW(history)(h, &ev, H_ENTER, line); |
if (history(h, &ev, H_GETSIZE) == 0) |
if (FUNW(history)(h, &ev, H_GETSIZE) == 0) |
history_length = ev.num; |
history_length = ev.num; |
|
|
return (!(history_length > 0)); /* return 0 if all is okay */ |
return (!(history_length > 0)); /* return 0 if all is okay */ |
Line 1209 add_history(const char *line) |
|
Line 1382 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; |
TYPE(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 = malloc(sizeof(*he))) == NULL) |
return NULL; |
return NULL; |
|
|
if ((she = malloc(sizeof(*she))) == NULL) |
if (FUNW(history)(h, &ev, H_DELDATA, num, &he->data) != 0) { |
|
free(he); |
return NULL; |
return NULL; |
|
} |
|
|
she->line = ev.str; |
he->line = ct_encode_string(ev.str, &conv); |
she->data = NULL; |
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 |
* clear the history list - delete all entries |
*/ |
*/ |
void |
void |
clear_history(void) |
clear_history(void) |
{ |
{ |
HistEvent ev; |
TYPE(HistEvent) ev; |
|
|
history(h, &ev, H_CLEAR); |
(void)FUNW(history)(h, &ev, H_CLEAR); |
|
history_length = 0; |
} |
} |
|
|
|
|
Line 1246 clear_history(void) |
|
Line 1469 clear_history(void) |
|
int |
int |
where_history(void) |
where_history(void) |
{ |
{ |
HistEvent ev; |
TYPE(HistEvent) ev; |
int curr_num, off; |
int curr_num, off; |
|
|
if (history(h, &ev, H_CURR) != 0) |
if (FUNW(history)(h, &ev, H_CURR) != 0) |
return (0); |
return (0); |
curr_num = ev.num; |
curr_num = ev.num; |
|
|
history(h, &ev, H_FIRST); |
(void)FUNW(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 && FUNW(history)(h, &ev, H_NEXT) == 0) |
off++; |
off++; |
|
|
return (off); |
return (off); |
Line 1279 current_history(void) |
|
Line 1502 current_history(void) |
|
int |
int |
history_total_bytes(void) |
history_total_bytes(void) |
{ |
{ |
HistEvent ev; |
TYPE(HistEvent) ev; |
int curr_num, size; |
int curr_num; |
|
size_t size; |
|
|
if (history(h, &ev, H_CURR) != 0) |
if (FUNW(history)(h, &ev, H_CURR) != 0) |
return (-1); |
return (-1); |
curr_num = ev.num; |
curr_num = ev.num; |
|
|
history(h, &ev, H_FIRST); |
(void)FUNW(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 (FUNW(history)(h, &ev, H_NEXT) == 0); |
|
|
/* get to the same position as before */ |
/* 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); |
} |
} |
|
|
|
|
Line 1305 history_total_bytes(void) |
|
Line 1529 history_total_bytes(void) |
|
int |
int |
history_set_pos(int pos) |
history_set_pos(int pos) |
{ |
{ |
HistEvent ev; |
TYPE(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)FUNW(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 (FUNW(history)(h, &ev, H_DELDATA, pos, (void **)-1)) { |
|
(void)FUNW(history)(h, &ev, H_SET, curr_num); |
return(-1); |
return(-1); |
} |
} |
return (0); |
return (0); |
Line 1350 next_history(void) |
|
Line 1578 next_history(void) |
|
int |
int |
history_search(const char *str, int direction) |
history_search(const char *str, int direction) |
{ |
{ |
HistEvent ev; |
TYPE(HistEvent) ev; |
const char *strp; |
const Char *strp; |
|
const Char *wstr; |
int curr_num; |
int curr_num; |
|
|
if (history(h, &ev, H_CURR) != 0) |
if (FUNW(history)(h, &ev, H_CURR) != 0) |
return (-1); |
return (-1); |
curr_num = ev.num; |
curr_num = ev.num; |
|
|
|
wstr = ct_decode_string(str, &conv); |
for (;;) { |
for (;;) { |
if ((strp = strstr(ev.str, str)) != NULL) |
if ((strp = Strstr(ev.str, wstr)) != NULL) |
return (int) (strp - ev.str); |
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; |
break; |
} |
} |
history(h, &ev, H_SET, curr_num); |
(void)FUNW(history)(h, &ev, H_SET, curr_num); |
return (-1); |
return (-1); |
} |
} |
|
|
Line 1375 history_search(const char *str, int dire |
|
Line 1605 history_search(const char *str, int dire |
|
int |
int |
history_search_prefix(const char *str, int direction) |
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)); |
} |
} |
|
|
|
|
|
|
history_search_pos(const char *str, |
history_search_pos(const char *str, |
int direction __attribute__((__unused__)), int pos) |
int direction __attribute__((__unused__)), int pos) |
{ |
{ |
HistEvent ev; |
TYPE(HistEvent) ev; |
int curr_num, off; |
int curr_num, off; |
|
const Char *wstr; |
|
|
off = (pos > 0) ? pos : -pos; |
off = (pos > 0) ? pos : -pos; |
pos = (pos > 0) ? 1 : -1; |
pos = (pos > 0) ? 1 : -1; |
|
|
if (history(h, &ev, H_CURR) != 0) |
if (FUNW(history)(h, &ev, H_CURR) != 0) |
return (-1); |
return (-1); |
curr_num = ev.num; |
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); |
return (-1); |
|
|
|
wstr = ct_decode_string(str, &conv); |
for (;;) { |
for (;;) { |
if (strstr(ev.str, str)) |
if (Strstr(ev.str, wstr)) |
return (off); |
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; |
break; |
} |
} |
|
|
/* 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)FUNW(history)(h, &ev, |
|
pos < 0 ? H_NEXT_EVENT : H_PREV_EVENT, curr_num); |
|
|
return (-1); |
return (-1); |
} |
} |
Line 1461 username_completion_function(const char |
|
Line 1694 username_completion_function(const char |
|
|
|
if (pwd == NULL) { |
if (pwd == NULL) { |
endpwent(); |
endpwent(); |
return (NULL); |
return NULL; |
} |
} |
return (strdup(pwd->pw_name)); |
return strdup(pwd->pw_name); |
} |
} |
|
|
|
|
|
|
rl_display_match_list(char **matches, int len, int max) |
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 * |
static const char * |
Line 1509 _rl_completion_append_character_function |
|
Line 1742 _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 1524 rl_complete(int ignore __attribute__((__ |
|
Line 1761 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), |
_rl_completion_append_character_function, rl_completion_query_items, |
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_completion_type, &rl_attempted_completion_over, |
&rl_point, &rl_end); |
&rl_point, &rl_end); |
} |
} |
Line 1546 _el_rl_complete(EditLine *el __attribute |
|
Line 1785 _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 1613 rl_insert(int count, int c) |
|
Line 1852 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 1676 rl_callback_read_char() |
|
Line 1929 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 1774 rl_stuff_char(int c) |
|
Line 2027 rl_stuff_char(int c) |
|
static int |
static int |
_rl_event_read_char(EditLine *el, char *cp) |
_rl_event_read_char(EditLine *el, char *cp) |
{ |
{ |
int n, num_read = 0; |
int n; |
|
ssize_t num_read = 0; |
|
|
*cp = '\0'; |
*cp = '\0'; |
while (rl_event_hook) { |
while (rl_event_hook) { |
Line 1810 _rl_event_read_char(EditLine *el, char * |
|
Line 2064 _rl_event_read_char(EditLine *el, char * |
|
} |
} |
if (!rl_event_hook) |
if (!rl_event_hook) |
el_set(el, EL_GETCFN, EL_BUILTIN_GETCFN); |
el_set(el, EL_GETCFN, EL_BUILTIN_GETCFN); |
return(num_read); |
return (int)num_read; |
} |
} |
|
|
static void |
static void |
Line 1818 _rl_update_pos(void) |
|
Line 2072 _rl_update_pos(void) |
|
{ |
{ |
const LineInfo *li = el_line(e); |
const LineInfo *li = el_line(e); |
|
|
rl_point = li->cursor - li->buffer; |
rl_point = (int)(li->cursor - li->buffer); |
rl_end = li->lastchar - li->buffer; |
rl_end = (int)(li->lastchar - li->buffer); |
} |
} |
|
|
void |
void |
Line 1853 rl_completion_matches(const char *str, r |
|
Line 2107 rl_completion_matches(const char *str, r |
|
return NULL; |
return NULL; |
|
|
while ((match = (*fun)(str, (int)(len - 1))) != NULL) { |
while ((match = (*fun)(str, (int)(len - 1))) != NULL) { |
|
list[len++] = match; |
if (len == max) { |
if (len == max) { |
char **nl; |
char **nl; |
max += 10; |
max += 10; |
Line 1860 rl_completion_matches(const char *str, r |
|
Line 2115 rl_completion_matches(const char *str, r |
|
goto out; |
goto out; |
list = nl; |
list = nl; |
} |
} |
list[len++] = match; |
|
} |
} |
if (len == 1) |
if (len == 1) |
goto out; |
goto out; |
Line 1922 _rl_qsort_string_compare(char **s1, char |
|
Line 2176 _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 = malloc(sizeof(HISTORY_STATE))) == 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 1956 rl_generic_bind(int type, const char * k |
|
Line 2221 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; |
return 0; |
} |
} |
|
|
|
/* unsupported, but needed by python */ |
|
void |
|
rl_cleanup_after_signal(void) |
|
{ |
|
} |