version 1.61, 2006/03/06 21:11:03 |
version 1.72, 2007/08/12 07:41:51 |
|
|
* 2. Redistributions in binary form must reproduce the above copyright |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* 3. Neither the name of The NetBSD Foundation nor the names of its |
* must display the following acknowledgement: |
|
* This product includes software developed by the NetBSD |
|
* Foundation, Inc. and its contributors. |
|
* 4. Neither the name of The NetBSD Foundation nor the names of its |
|
* contributors may be used to endorse or promote products derived |
* contributors may be used to endorse or promote products derived |
* from this software without specific prior written permission. |
* from this software without specific prior written permission. |
* |
* |
Line 53 __RCSID("$NetBSD$"); |
|
Line 49 __RCSID("$NetBSD$"); |
|
#include <limits.h> |
#include <limits.h> |
#include <errno.h> |
#include <errno.h> |
#include <fcntl.h> |
#include <fcntl.h> |
|
#include <setjmp.h> |
#ifdef HAVE_VIS_H |
#ifdef HAVE_VIS_H |
#include <vis.h> |
#include <vis.h> |
#else |
#else |
Line 67 __RCSID("$NetBSD$"); |
|
Line 64 __RCSID("$NetBSD$"); |
|
#include "readline/readline.h" |
#include "readline/readline.h" |
#include "filecomplete.h" |
#include "filecomplete.h" |
|
|
|
void rl_prep_terminal(int); |
|
void rl_deprep_terminal(void); |
|
|
/* for rl_complete() */ |
/* for rl_complete() */ |
#define TAB '\r' |
#define TAB '\r' |
|
|
Line 89 char *rl_line_buffer = NULL; |
|
Line 89 char *rl_line_buffer = NULL; |
|
VCPFunction *rl_linefunc = NULL; |
VCPFunction *rl_linefunc = NULL; |
int rl_done = 0; |
int rl_done = 0; |
VFunction *rl_event_hook = NULL; |
VFunction *rl_event_hook = NULL; |
|
KEYMAP_ENTRY_ARRAY emacs_standard_keymap, |
|
emacs_meta_keymap, |
|
emacs_ctlx_keymap; |
|
|
int history_base = 1; /* probably never subject to change */ |
int history_base = 1; /* probably never subject to change */ |
int history_length = 0; |
int history_length = 0; |
Line 108 Function *rl_completion_entry_function = |
|
Line 111 Function *rl_completion_entry_function = |
|
CPPFunction *rl_attempted_completion_function = NULL; |
CPPFunction *rl_attempted_completion_function = NULL; |
Function *rl_pre_input_hook = NULL; |
Function *rl_pre_input_hook = NULL; |
Function *rl_startup1_hook = NULL; |
Function *rl_startup1_hook = NULL; |
Function *rl_getc_function = NULL; |
int (*rl_getc_function)(FILE *) = NULL; |
char *rl_terminal_name = NULL; |
char *rl_terminal_name = NULL; |
int rl_already_prompted = 0; |
int rl_already_prompted = 0; |
int rl_filename_completion_desired = 0; |
int rl_filename_completion_desired = 0; |
int rl_ignore_completion_duplicates = 0; |
int rl_ignore_completion_duplicates = 0; |
int rl_catch_signals = 1; |
int rl_catch_signals = 1; |
|
int readline_echoing_p = 1; |
|
int _rl_print_completions_horizontally = 0; |
VFunction *rl_redisplay_function = NULL; |
VFunction *rl_redisplay_function = NULL; |
Function *rl_startup_hook = NULL; |
Function *rl_startup_hook = NULL; |
VFunction *rl_completion_display_matches_hook = NULL; |
VFunction *rl_completion_display_matches_hook = NULL; |
VFunction *rl_prep_term_function = NULL; |
VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal; |
VFunction *rl_deprep_term_function = NULL; |
VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal; |
|
|
/* |
/* |
* The current prompt string. |
* The current prompt string. |
Line 155 int rl_completion_append_character = ' ' |
|
Line 160 int rl_completion_append_character = ' ' |
|
static History *h = NULL; |
static History *h = NULL; |
static EditLine *e = NULL; |
static EditLine *e = NULL; |
static Function *map[256]; |
static Function *map[256]; |
|
static jmp_buf topbuf; |
|
|
/* internal functions */ |
/* internal functions */ |
static unsigned char _el_rl_complete(EditLine *, int); |
static unsigned char _el_rl_complete(EditLine *, int); |
Line 207 _getc_function(EditLine *el, char *c) |
|
Line 213 _getc_function(EditLine *el, char *c) |
|
{ |
{ |
int i; |
int i; |
|
|
i = (*rl_getc_function)(NULL, 0); |
i = (*rl_getc_function)(NULL); |
if (i == -1) |
if (i == -1) |
return 0; |
return 0; |
*c = i; |
*c = i; |
Line 323 rl_initialize(void) |
|
Line 329 rl_initialize(void) |
|
* trailing newline (if there is any) |
* trailing newline (if there is any) |
*/ |
*/ |
char * |
char * |
readline(const char *prompt) |
readline(const char *p) |
{ |
{ |
HistEvent ev; |
HistEvent ev; |
|
const char * volatile prompt = p; |
int count; |
int count; |
const char *ret; |
const char *ret; |
char *buf; |
char *buf; |
Line 336 readline(const char *prompt) |
|
Line 343 readline(const char *prompt) |
|
|
|
rl_done = 0; |
rl_done = 0; |
|
|
|
(void)setjmp(topbuf); |
|
|
/* update prompt accordingly to what has been passed */ |
/* update prompt accordingly to what has been passed */ |
if (!prompt) |
if (!prompt) |
prompt = ""; |
prompt = ""; |
Line 728 _history_expand_command(const char *comm |
|
Line 737 _history_expand_command(const char *comm |
|
what = realloc(from, size); |
what = realloc(from, size); |
if (what == NULL) { |
if (what == NULL) { |
free(from); |
free(from); |
|
free(tmp); |
return 0; |
return 0; |
} |
} |
len = 0; |
len = 0; |
Line 740 _history_expand_command(const char *comm |
|
Line 750 _history_expand_command(const char *comm |
|
(size <<= 1)); |
(size <<= 1)); |
if (nwhat == NULL) { |
if (nwhat == NULL) { |
free(what); |
free(what); |
|
free(tmp); |
return 0; |
return 0; |
} |
} |
what = nwhat; |
what = nwhat; |
Line 752 _history_expand_command(const char *comm |
|
Line 763 _history_expand_command(const char *comm |
|
free(what); |
free(what); |
if (search) { |
if (search) { |
from = strdup(search); |
from = strdup(search); |
if (from == NULL) |
if (from == NULL) { |
|
free(tmp); |
return 0; |
return 0; |
|
} |
} else { |
} else { |
from = NULL; |
from = NULL; |
|
free(tmp); |
return (-1); |
return (-1); |
} |
} |
} |
} |
Line 767 _history_expand_command(const char *comm |
|
Line 781 _history_expand_command(const char *comm |
|
with = realloc(to, size); |
with = realloc(to, size); |
if (with == NULL) { |
if (with == NULL) { |
free(to); |
free(to); |
|
free(tmp); |
return -1; |
return -1; |
} |
} |
len = 0; |
len = 0; |
Line 778 _history_expand_command(const char *comm |
|
Line 793 _history_expand_command(const char *comm |
|
nwith = realloc(with, size); |
nwith = realloc(with, size); |
if (nwith == NULL) { |
if (nwith == NULL) { |
free(with); |
free(with); |
|
free(tmp); |
return -1; |
return -1; |
} |
} |
with = nwith; |
with = nwith; |
Line 846 history_expand(char *str, char **output) |
|
Line 862 history_expand(char *str, char **output) |
|
return 0; |
return 0; |
} |
} |
|
|
#define ADD_STRING(what, len) \ |
#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 = realloc(result, (size += len + 1));\ |
if (nresult == NULL) { \ |
if (nresult == NULL) { \ |
free(*output); \ |
free(*output); \ |
|
if (/*CONSTCOND*/fr) \ |
|
free(tmp); \ |
return 0; \ |
return 0; \ |
} \ |
} \ |
result = nresult; \ |
result = nresult; \ |
Line 863 history_expand(char *str, char **output) |
|
Line 881 history_expand(char *str, char **output) |
|
|
|
result = NULL; |
result = NULL; |
size = idx = 0; |
size = idx = 0; |
|
tmp = NULL; |
for (i = 0; str[i];) { |
for (i = 0; str[i];) { |
int qchar, loop_again; |
int qchar, loop_again; |
size_t len, start, j; |
size_t len, start, j; |
|
|
goto loop; |
goto loop; |
} |
} |
len = i - start; |
len = i - start; |
tmp = &str[start]; |
ADD_STRING(&str[start], len, 0); |
ADD_STRING(tmp, len); |
|
|
|
if (str[i] == '\0' || str[i] != history_expansion_char) { |
if (str[i] == '\0' || str[i] != history_expansion_char) { |
len = j - i; |
len = j - i; |
tmp = &str[i]; |
ADD_STRING(&str[i], len, 0); |
ADD_STRING(tmp, len); |
|
if (start == 0) |
if (start == 0) |
ret = 0; |
ret = 0; |
else |
else |
|
|
ret = _history_expand_command (str, i, (j - i), &tmp); |
ret = _history_expand_command (str, i, (j - i), &tmp); |
if (ret > 0 && tmp) { |
if (ret > 0 && tmp) { |
len = strlen(tmp); |
len = strlen(tmp); |
ADD_STRING(tmp, len); |
ADD_STRING(tmp, len, 1); |
|
} |
|
if (tmp) { |
free(tmp); |
free(tmp); |
|
tmp = NULL; |
} |
} |
i = j; |
i = j; |
} |
} |
Line 1148 history_get(int num) |
|
Line 1168 history_get(int num) |
|
return (NULL); /* error */ |
return (NULL); /* error */ |
|
|
/* look backwards for event matching specified offset */ |
/* look backwards for event matching specified offset */ |
if (history(h, &ev, H_NEXT_EVENT, num)) |
if (history(h, &ev, H_NEXT_EVENT, num + 1)) |
return (NULL); |
return (NULL); |
|
|
she.line = ev.str; |
she.line = ev.str; |
Line 1186 add_history(const char *line) |
|
Line 1206 add_history(const char *line) |
|
HIST_ENTRY * |
HIST_ENTRY * |
remove_history(int num) |
remove_history(int num) |
{ |
{ |
static HIST_ENTRY she; |
HIST_ENTRY *she; |
HistEvent ev; |
HistEvent ev; |
|
|
if (h == NULL || e == NULL) |
if (h == NULL || e == NULL) |
Line 1195 remove_history(int num) |
|
Line 1215 remove_history(int num) |
|
if (history(h, &ev, H_DEL, num) != 0) |
if (history(h, &ev, H_DEL, num) != 0) |
return NULL; |
return NULL; |
|
|
she.line = ev.str; |
if ((she = malloc(sizeof(*she))) == NULL) |
she.data = NULL; |
return NULL; |
|
|
return &she; |
she->line = ev.str; |
|
she->data = NULL; |
|
|
|
return she; |
} |
} |
|
|
|
|
Line 1654 rl_callback_read_char() |
|
Line 1677 rl_callback_read_char() |
|
} |
} |
|
|
void |
void |
rl_callback_handler_install (const char *prompt, VCPFunction *linefunc) |
rl_callback_handler_install(const char *prompt, VCPFunction *linefunc) |
{ |
{ |
if (e == NULL) { |
if (e == NULL) { |
rl_initialize(); |
rl_initialize(); |
|
|
rl_callback_handler_remove(void) |
rl_callback_handler_remove(void) |
{ |
{ |
el_set(e, EL_UNBUFFERED, 0); |
el_set(e, EL_UNBUFFERED, 0); |
|
rl_linefunc = NULL; |
} |
} |
|
|
void |
void |
Line 1700 rl_prep_terminal(int meta_flag) |
|
Line 1724 rl_prep_terminal(int meta_flag) |
|
} |
} |
|
|
void |
void |
rl_deprep_terminal() |
rl_deprep_terminal(void) |
{ |
{ |
el_set(e, EL_PREP_TERM, 0); |
el_set(e, EL_PREP_TERM, 0); |
} |
} |
Line 1795 _rl_update_pos(void) |
|
Line 1819 _rl_update_pos(void) |
|
rl_point = li->cursor - li->buffer; |
rl_point = li->cursor - li->buffer; |
rl_end = li->lastchar - li->buffer; |
rl_end = li->lastchar - li->buffer; |
} |
} |
|
|
|
void |
|
rl_get_screen_size(int *rows, int *cols) |
|
{ |
|
if (rows) |
|
el_get(e, EL_GETTC, "li", rows); |
|
if (cols) |
|
el_get(e, EL_GETTC, "co", cols); |
|
} |
|
|
|
void |
|
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); |
|
(void)snprintf(buf, sizeof(buf), "%d", cols); |
|
el_set(e, EL_SETTC, "co", buf); |
|
} |
|
|
|
char ** |
|
rl_completion_matches(const char *str, rl_compentry_func_t *fun) |
|
{ |
|
size_t len, max, i, j, min; |
|
char **list, *match, *a, *b; |
|
|
|
len = 1; |
|
max = 10; |
|
if ((list = malloc(max * sizeof(*list))) == NULL) |
|
return NULL; |
|
|
|
while ((match = (*fun)(str, (int)(len - 1))) != NULL) { |
|
if (len == max) { |
|
char **nl; |
|
max += 10; |
|
if ((nl = realloc(list, max * sizeof(*nl))) == NULL) |
|
goto out; |
|
list = nl; |
|
} |
|
list[len++] = match; |
|
} |
|
if (len == 1) |
|
goto out; |
|
list[len] = NULL; |
|
if (len == 2) { |
|
if ((list[0] = strdup(list[1])) == NULL) |
|
goto out; |
|
return list; |
|
} |
|
qsort(&list[1], len - 1, sizeof(*list), |
|
(int (*)(const void *, const void *)) strcmp); |
|
min = SIZE_T_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++) |
|
continue; |
|
if (min > j) |
|
min = j; |
|
} |
|
if (min == 0 && *str) { |
|
if ((list[0] = strdup(str)) == NULL) |
|
goto out; |
|
} else { |
|
if ((list[0] = malloc(min + 1)) == NULL) |
|
goto out; |
|
(void)memcpy(list[0], list[1], min); |
|
list[0][min] = '\0'; |
|
} |
|
return list; |
|
|
|
out: |
|
free(list); |
|
return NULL; |
|
} |
|
|
|
char * |
|
rl_filename_completion_function (const char *text, int state) |
|
{ |
|
return fn_filename_completion_function(text, state); |
|
} |
|
|
|
int |
|
_rl_abort_internal(void) |
|
{ |
|
el_beep(e); |
|
longjmp(topbuf, 1); |
|
/*NOTREACHED*/ |
|
} |
|
|
|
int |
|
_rl_qsort_string_compare(char **s1, char **s2) |
|
{ |
|
return strcoll(*s1, *s2); |
|
} |
|
|
|
int |
|
/*ARGSUSED*/ |
|
rl_kill_text(int from, int to) |
|
{ |
|
return 0; |
|
} |
|
|
|
Keymap |
|
rl_make_bare_keymap(void) |
|
{ |
|
return NULL; |
|
} |
|
|
|
Keymap |
|
rl_get_keymap(void) |
|
{ |
|
return NULL; |
|
} |
|
|
|
void |
|
/*ARGSUSED*/ |
|
rl_set_keymap(Keymap k) |
|
{ |
|
} |
|
|
|
int |
|
/*ARGSUSED*/ |
|
rl_generic_bind(int type, const char * keyseq, const char * data, Keymap k) |
|
{ |
|
return 0; |
|
} |
|
|
|
int |
|
/*ARGSUSED*/ |
|
rl_bind_key_in_map(int key, Function *fun, Keymap k) |
|
{ |
|
return 0; |
|
} |
|
|