19 #include RUBY_EXTCONF_H 22 #include "ruby/config.h" 26 #ifdef HAVE_READLINE_READLINE_H 27 #include <readline/readline.h> 29 #ifdef HAVE_READLINE_HISTORY_H 30 #include <readline/history.h> 32 #ifdef HAVE_EDITLINE_READLINE_H 33 #include <editline/readline.h> 43 #ifdef HAVE_SYS_STAT_H 49 #define EDIT_LINE_LIBRARY_VERSION "EditLine wrapper" 50 #ifndef USE_INSERT_IGNORE_ESCAPE 51 # if !defined(HAVE_EDITLINE_READLINE_H) && defined(RL_PROMPT_START_IGNORE) && defined(RL_PROMPT_END_IGNORE) 52 # define USE_INSERT_IGNORE_ESCAPE 1 54 # define USE_INSERT_IGNORE_ESCAPE 0 58 #define COMPLETION_PROC "completion_proc" 59 #define COMPLETION_CASE_FOLD "completion_case_fold" 61 #if defined HAVE_RL_CHAR_IS_QUOTED_P 62 #define QUOTING_DETECTION_PROC "quoting_detection_proc" 63 static ID quoting_detection_proc;
65 #if USE_INSERT_IGNORE_ESCAPE 66 static ID id_orig_prompt, id_last_prompt;
68 #if defined(HAVE_RL_PRE_INPUT_HOOK) 69 static ID id_pre_input_hook;
71 #if defined(HAVE_RL_SPECIAL_PREFIXES) 72 static ID id_special_prefixes;
75 #ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION 76 # define rl_filename_completion_function filename_completion_function 78 #ifndef HAVE_RL_USERNAME_COMPLETION_FUNCTION 79 # define rl_username_completion_function username_completion_function 81 #ifndef HAVE_RL_COMPLETION_MATCHES 82 # define rl_completion_matches completion_matches 87 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER 88 static int readline_completion_append_character;
94 #define OutputStringValue(str) do {\ 95 SafeStringValue(str);\ 96 (str) = rb_str_conv_enc((str), rb_enc_get(str), rb_locale_encoding());\ 145 #if defined HAVE_RL_GETC_FUNCTION 148 #define rl_getc(f) EOF 159 getc_body(
struct getc_struct *p)
168 static int prior_key =
'0';
170 if (prior_key > 0xff) {
171 prior_key = rl_getc(p->input);
174 if (PeekConsoleInput((HANDLE)_get_osfhandle(p->fd), &ir, 1, &n)) {
176 if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown) {
177 prior_key = rl_getc(p->input);
180 ReadConsoleInput((HANDLE)_get_osfhandle(p->fd), &ir, 1, &n);
183 HANDLE h = (HANDLE)_get_osfhandle(p->fd);
193 ss = read(p->fd, &ch, 1);
200 return (
unsigned char)ch;
204 getc_func(
void *data1)
206 struct getc_struct *p = data1;
208 p->ret = getc_body(p);
216 struct getc_struct data;
225 if (data.ret ==
EOF) {
229 if (data.err == EINTR) {
233 if (data.err ==
EWOULDBLOCK || data.err == EAGAIN) {
235 if (
fileno(input) != data.fd)
236 rb_bug(
"readline_getc: input closed unexpectedly or memory corrupted");
238 if (ret != -1 ||
errno == EINTR)
247 #elif defined HAVE_RL_EVENT_HOOK 250 static int readline_event(
void);
263 #if USE_INSERT_IGNORE_ESCAPE 265 insert_ignore_escape(
VALUE self,
VALUE prompt)
269 const char *s0, *s, *e;
271 static const char ignore_code[2] = {RL_PROMPT_START_IGNORE, RL_PROMPT_END_IGNORE};
275 if (orig_prompt == prompt)
return last_prompt;
277 if (
NIL_P(last_prompt)) {
284 while (s < e && *s) {
286 case RL_PROMPT_START_IGNORE:
291 case RL_PROMPT_END_IGNORE:
297 if (++s < e && *s ==
'[') {
300 while (++s < e && *s) {
301 if (
ISALPHA(*(
unsigned char *)s)) {
310 else if (!((
'0' <= *s && *s <=
'9') || *s ==
';')) {
341 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER 342 readline_completion_append_character = rl_completion_append_character;
344 return (
VALUE)readline((
char *)prompt);
350 if (readline_rl_instream) {
351 fclose(readline_rl_instream);
352 if (rl_instream == readline_rl_instream)
354 readline_rl_instream =
NULL;
362 if (readline_rl_outstream) {
363 fclose(readline_rl_outstream);
364 if (rl_outstream == readline_rl_outstream)
366 readline_rl_outstream =
NULL;
374 static int initialized = 0;
491 if (
rb_scan_args(argc, argv,
"02", &tmp, &add_hist) > 0) {
493 #if USE_INSERT_IGNORE_ESCAPE 494 tmp = insert_ignore_escape(
self, tmp);
506 #if USE_INSERT_IGNORE_ESCAPE 512 #if defined HAVE_RL_CLEANUP_AFTER_SIGNAL 514 #if defined HAVE_RL_FREE_LINE_STATE 515 rl_free_line_state();
517 rl_cleanup_after_signal();
518 #elif defined HAVE_RL_DEPREP_TERM_FUNCTION 520 if (rl_deprep_term_function !=
NULL)
521 (*rl_deprep_term_function)();
524 rl_deprep_terminal();
529 if (
RTEST(add_hist) && buff) {
537 if (buff)
free(buff);
567 int save_errno =
errno;
571 rl_instream = readline_rl_instream =
f;
603 int save_errno =
errno;
607 rl_outstream = readline_rl_outstream =
f;
613 #if defined(HAVE_RL_PRE_INPUT_HOOK) 652 readline_pre_input_hook(
void)
662 #define readline_s_set_pre_input_hook rb_f_notimplement 663 #define readline_s_get_pre_input_hook rb_f_notimplement 666 #if defined(HAVE_RL_INSERT_TEXT) 685 #define readline_s_insert_text rb_f_notimplement 688 #if defined(HAVE_RL_DELETE_TEXT) 690 str_subpos(
const char *ptr,
const char *end,
long beg,
long *sublen,
rb_encoding *enc)
715 if (rl_line_buffer) {
716 const char *p, *ptr = rl_line_buffer;
718 const char *end = ptr +
len;
724 p = str_subpos(ptr, end, beg, &len, enc);
728 else if (
argc == 1) {
740 #define readline_s_delete_text rb_f_notimplement 743 #if defined(HAVE_RL_REDISPLAY) 762 #define readline_s_redisplay rb_f_notimplement 852 #ifdef HAVE_RL_CHAR_IS_QUOTED_P 893 #define readline_s_set_quoting_detection_proc rb_f_notimplement 894 #define readline_s_get_quoting_detection_proc rb_f_notimplement 929 #ifdef HAVE_RL_LINE_BUFFER 946 if (rl_line_buffer ==
NULL)
951 #define readline_s_get_line_buffer rb_f_notimplement 994 #define readline_s_get_point rb_f_notimplement 995 #define readline_s_set_point rb_f_notimplement 1001 VALUE proc, ary, temp;
1011 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER 1012 rl_completion_append_character = readline_completion_append_character;
1014 #ifdef HAVE_RL_ATTEMPTED_COMPLETION_OVER 1015 rl_attempted_completion_over = 1;
1022 if (matches == 0)
return NULL;
1023 result = (
char**)
malloc((matches + 2)*
sizeof(
char*));
1027 for (i = 0; i < matches; i++) {
1035 result[matches + 1] =
NULL;
1038 result[0] =
strdup(result[1]);
1041 const char *result1 = result[1];
1042 long low =
strlen(result1);
1044 for (i = 1; i < matches; ++i) {
1045 register int c1, c2;
1048 const char *p2 = result[i + 1];
1051 for (i1 = i2 = 0; i1 < low && i2 < l2; i1 += n1, i2 += n2) {
1058 if (c1 != c2)
break;
1063 result[0] = (
char*)
malloc(low + 1);
1065 strncpy(result[0], result[1], low);
1066 result[0][low] =
'\0';
1072 #ifdef HAVE_RL_CHAR_IS_QUOTED_P 1074 readline_char_is_quoted(
char *text,
int byte_index)
1086 if (byte_index < 0 || len < (
size_t)byte_index) {
1094 return RTEST(result);
1098 #ifdef HAVE_RL_SET_SCREEN_SIZE 1116 #define readline_s_set_screen_size rb_f_notimplement 1119 #ifdef HAVE_RL_GET_SCREEN_SIZE 1136 rl_get_screen_size(&rows, &columns);
1143 #define readline_s_get_screen_size rb_f_notimplement 1146 #ifdef HAVE_RL_VI_EDITING_MODE 1159 rl_vi_editing_mode(1,0);
1163 #define readline_s_vi_editing_mode rb_f_notimplement 1166 #ifdef HAVE_RL_EDITING_MODE 1181 #define readline_s_vi_editing_mode_p rb_f_notimplement 1184 #ifdef HAVE_RL_EMACS_EDITING_MODE 1197 rl_emacs_editing_mode(1,0);
1201 #define readline_s_emacs_editing_mode rb_f_notimplement 1204 #ifdef HAVE_RL_EDITING_MODE 1219 #define readline_s_emacs_editing_mode_p rb_f_notimplement 1222 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER 1263 rl_completion_append_character =
'\0';
1268 rl_completion_append_character =
'\0';
1270 rl_completion_append_character =
RSTRING_PTR(str)[0];
1276 #define readline_s_set_completion_append_character rb_f_notimplement 1279 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER 1294 if (rl_completion_append_character ==
'\0')
1297 buf[0] = (char) rl_completion_append_character;
1301 #define readline_s_get_completion_append_character rb_f_notimplement 1304 #ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS 1318 static char *basic_word_break_characters =
NULL;
1321 if (basic_word_break_characters ==
NULL) {
1322 basic_word_break_characters =
1328 strncpy(basic_word_break_characters,
1330 basic_word_break_characters[
RSTRING_LEN(str)] =
'\0';
1331 rl_basic_word_break_characters = basic_word_break_characters;
1335 #define readline_s_set_basic_word_break_characters rb_f_notimplement 1338 #ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS 1351 if (rl_basic_word_break_characters ==
NULL)
1356 #define readline_s_get_basic_word_break_characters rb_f_notimplement 1359 #ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS 1373 static char *completer_word_break_characters =
NULL;
1376 if (completer_word_break_characters ==
NULL) {
1377 completer_word_break_characters =
1383 strncpy(completer_word_break_characters,
1385 completer_word_break_characters[
RSTRING_LEN(str)] =
'\0';
1386 rl_completer_word_break_characters = completer_word_break_characters;
1390 #define readline_s_set_completer_word_break_characters rb_f_notimplement 1393 #ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS 1406 if (rl_completer_word_break_characters ==
NULL)
1411 #define readline_s_get_completer_word_break_characters rb_f_notimplement 1414 #if defined(HAVE_RL_SPECIAL_PREFIXES) 1439 rl_special_prefixes =
NULL;
1463 if (rl_special_prefixes ==
NULL)
return Qnil;
1472 #define readline_s_set_special_prefixes rb_f_notimplement 1473 #define readline_s_get_special_prefixes rb_f_notimplement 1476 #ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS 1488 static char *basic_quote_characters =
NULL;
1491 if (basic_quote_characters ==
NULL) {
1492 basic_quote_characters =
1498 strncpy(basic_quote_characters,
1501 rl_basic_quote_characters = basic_quote_characters;
1506 #define readline_s_set_basic_quote_characters rb_f_notimplement 1509 #ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS 1521 if (rl_basic_quote_characters ==
NULL)
1526 #define readline_s_get_basic_quote_characters rb_f_notimplement 1529 #ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS 1544 static char *completer_quote_characters =
NULL;
1547 if (completer_quote_characters ==
NULL) {
1548 completer_quote_characters =
1555 completer_quote_characters[
RSTRING_LEN(str)] =
'\0';
1556 rl_completer_quote_characters = completer_quote_characters;
1561 #define readline_s_set_completer_quote_characters rb_f_notimplement 1564 #ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS 1577 if (rl_completer_quote_characters ==
NULL)
1582 #define readline_s_get_completer_quote_characters rb_f_notimplement 1585 #ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS 1598 static char *filename_quote_characters =
NULL;
1601 if (filename_quote_characters ==
NULL) {
1602 filename_quote_characters =
1609 filename_quote_characters[
RSTRING_LEN(str)] =
'\0';
1610 rl_filename_quote_characters = filename_quote_characters;
1615 #define readline_s_set_filename_quote_characters rb_f_notimplement 1618 #ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS 1631 if (rl_filename_quote_characters ==
NULL)
1636 #define readline_s_get_filename_quote_characters rb_f_notimplement 1639 #ifdef HAVE_RL_REFRESH_LINE 1650 rl_refresh_line(0, 0);
1654 #define readline_s_refresh_line rb_f_notimplement 1666 return history_base + offset;
1678 HIST_ENTRY *entry =
NULL;
1683 i += history_length;
1688 if (entry ==
NULL) {
1694 #ifdef HAVE_REPLACE_HISTORY_ENTRY 1698 HIST_ENTRY *entry =
NULL;
1704 i += history_length;
1709 if (entry ==
NULL) {
1715 #define hist_set rb_f_notimplement 1742 #ifdef HAVE_REMOVE_HISTORY 1746 entry = remove_history(index);
1749 free((
void *) entry->line);
1764 if (history_length > 0) {
1774 if (history_length > 0) {
1789 for (i = 0; i < history_length; i++) {
1801 return INT2NUM(history_length);
1817 i += history_length;
1818 if (i < 0 || i > history_length - 1) {
1824 #ifdef HAVE_CLEAR_HISTORY 1832 #define hist_clear rb_f_notimplement 1846 for (i = 0; matches[i]; i++) {
1871 for (i = 0; matches[i]; i++) {
1892 rl_readline_name = (
char *)
"Ruby";
1894 #if defined HAVE_RL_GETC_FUNCTION 1898 rl_getc_function = readline_getc;
1899 #elif defined HAVE_RL_EVENT_HOOK 1900 rl_event_hook = readline_event;
1908 #if defined(HAVE_RL_PRE_INPUT_HOOK) 1909 id_pre_input_hook =
rb_intern(
"pre_input_hook");
1911 #if defined(HAVE_RL_SPECIAL_PREFIXES) 1912 id_special_prefixes =
rb_intern(
"special_prefixes");
1914 #if defined HAVE_RL_CHAR_IS_QUOTED_P 1915 quoting_detection_proc =
rb_intern(QUOTING_DETECTION_PROC);
1996 #if USE_INSERT_IGNORE_ESCAPE 1997 CONST_ID(id_orig_prompt,
"orig_prompt");
1998 CONST_ID(id_last_prompt,
"last_prompt");
2044 #if defined HAVE_RL_LIBRARY_VERSION 2046 #if defined HAVE_CLEAR_HISTORY || defined HAVE_REMOVE_HISTORY 2053 #ifdef HAVE_REPLACE_HISTORY_ENTRY 2054 if (replace_history_entry(0,
"a",
NULL) ==
NULL) {
2058 #ifdef HAVE_CLEAR_HISTORY 2062 HIST_ENTRY *entry = remove_history(0);
2064 free((
char *)entry->line);
2078 #if defined(HAVE_RL_PRE_INPUT_HOOK) 2079 rl_pre_input_hook = readline_pre_input_hook;
2081 #if defined HAVE_RL_CHAR_IS_QUOTED_P 2082 rl_char_is_quoted_p = &readline_char_is_quoted;
2084 #ifdef HAVE_RL_CATCH_SIGNALS 2085 rl_catch_signals = 0;
2087 #ifdef HAVE_RL_CLEAR_SIGNALS RUBY_EXTERN VALUE rb_cString
static ID completion_case_fold
void rb_thread_schedule(void)
rb_encoding * rb_enc_check(VALUE str1, VALUE str2)
#define readline_s_get_line_buffer
void rb_bug(const char *fmt,...)
static int rb_tolower(int c)
#define readline_s_get_basic_quote_characters
size_t strlen(const char *)
int rb_w32_wait_events(HANDLE *events, int num, DWORD timeout)
void rb_syserr_fail(int e, const char *mesg)
static VALUE readline_get(VALUE prompt)
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
VALUE rb_str_cat(VALUE, const char *, long)
static VALUE readline_s_set_input(VALUE self, VALUE input)
static VALUE hist_to_s(VALUE self)
void rb_io_check_initialized(rb_io_t *)
VALUE rb_ary_shift(VALUE ary)
static char ** readline_attempted_completion_function(const char *text, int start, int end)
void * rb_thread_call_without_gvl2(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
#define readline_s_set_completer_word_break_characters
#define readline_s_emacs_editing_mode
#define readline_s_set_pre_input_hook
VALUE rb_str_unlocktmp(VALUE)
VALUE rb_enc_from_encoding(rb_encoding *encoding)
static ID completion_proc
static FILE * readline_rl_outstream
VALUE rb_ary_push(VALUE ary, VALUE item)
#define readline_s_get_special_prefixes
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
void rb_str_set_len(VALUE, long)
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *state)
unsigned int rb_enc_codepoint_len(const char *p, const char *e, int *len_p, rb_encoding *enc)
void rb_raise(VALUE exc, const char *fmt,...)
#define readline_s_get_quoting_detection_proc
VALUE rb_ivar_get(VALUE, ID)
VALUE rb_io_taint_check(VALUE)
#define readline_s_insert_text
#define COMPLETION_CASE_FOLD
static VALUE hist_pop(VALUE self)
static VALUE readline_s_get_completion_case_fold(VALUE self)
char * rb_str_subpos(VALUE, long, long *)
VALUE rb_range_beg_len(VALUE, long *, long *, long, int)
void rb_gc_register_address(VALUE *addr)
void rb_gc_force_recycle(VALUE obj)
static VALUE readline_s_set_output(VALUE self, VALUE output)
VALUE rb_str_dup_frozen(VALUE)
VALUE rb_str_tmp_new(long)
#define GetOpenFile(obj, fp)
static int history_get_offset_history_base(int offset)
static VALUE hist_push(VALUE self, VALUE str)
#define readline_s_delete_text
#define readline_s_vi_editing_mode_p
VALUE rb_enc_str_new_static(const char *, long, rb_encoding *)
#define OutputStringValue(str)
static VALUE hist_length(VALUE self)
static unsigned char * output
static VALUE filename_completion_proc_call(VALUE self, VALUE str)
static VALUE hist_each(VALUE self)
#define RB_TYPE_P(obj, type)
#define readline_s_get_pre_input_hook
#define rl_filename_completion_function
static VALUE readline_outstream
#define readline_s_set_quoting_detection_proc
#define readline_s_set_completer_quote_characters
VALUE rb_str_new_shared(VALUE)
#define readline_s_get_basic_word_break_characters
RUBY_EXTERN VALUE rb_cObject
#define EDIT_LINE_LIBRARY_VERSION
VALUE rb_obj_as_string(VALUE)
#define readline_s_refresh_line
static VALUE username_completion_proc_call(VALUE self, VALUE str)
VALUE rb_locale_str_new(const char *, long)
static VALUE hist_shift(VALUE self)
#define readline_s_get_filename_quote_characters
void rb_define_const(VALUE, const char *, VALUE)
#define readline_s_vi_editing_mode
#define readline_s_emacs_editing_mode_p
VALUE rb_obj_alloc(VALUE)
VALUE rb_obj_reveal(VALUE obj, VALUE klass)
#define readline_s_set_point
static VALUE hist_push_method(int argc, VALUE *argv, VALUE self)
VALUE rb_locale_str_new_cstr(const char *)
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
#define REALLOC_N(var, type, n)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
VALUE rb_ivar_set(VALUE, ID, VALUE)
unsigned char buf[MIME_BUF_SIZE]
static int history_get_offset_0(int offset)
#define readline_s_set_special_prefixes
rb_encoding * rb_locale_encoding(void)
VALUE rb_obj_hide(VALUE obj)
static VALUE readline_s_set_completion_proc(VALUE self, VALUE proc)
void rb_extend_object(VALUE obj, VALUE module)
int rb_wait_for_single_fd(int fd, int events, struct timeval *tv)
VALUE rb_str_new_cstr(const char *)
static void prepare_readline(void)
void rb_sys_fail(const char *mesg)
#define readline_s_get_point
void rb_jump_tag(int tag)
static VALUE hist_empty_p(VALUE self)
int rb_respond_to(VALUE, ID)
register unsigned int len
static VALUE readline_s_set_completion_case_fold(VALUE self, VALUE val)
#define StringValueCStr(v)
#define readline_s_set_filename_quote_characters
#define readline_s_redisplay
long rb_enc_strlen(const char *, const char *, rb_encoding *)
#define RARRAY_AREF(a, i)
static VALUE readline_s_get_completion_proc(VALUE self)
static VALUE rb_remove_history(int index)
#define readline_s_get_completer_quote_characters
#define readline_s_set_screen_size
static VALUE readline_readline(int argc, VALUE *argv, VALUE self)
static void mustbe_callable(VALUE proc)
void rb_thread_check_ints(void)
VALUE rb_str_locktmp(VALUE)
long rb_str_sublen(VALUE, long)
static VALUE hist_get(VALUE self, VALUE index)
void rb_notimplement(void)
#define rl_username_completion_function
#define RETURN_ENUMERATOR(obj, argc, argv)
#define rl_completion_matches
#define readline_s_get_screen_size
#define readline_s_set_basic_word_break_characters
RUBY_EXTERN VALUE rb_eIOError
static FILE * readline_rl_instream
#define readline_s_get_completion_append_character
#define StringValuePtr(v)
static int(* history_get_offset_func)(int)
int rb_cloexec_dup(int oldfd)
#define CONST_ID(var, str)
VALUE rb_define_module(const char *name)
static VALUE readline_instream
#define readline_s_set_basic_quote_characters
static void clear_rl_instream(void)
static void clear_rl_outstream(void)
static VALUE hist_delete_at(VALUE self, VALUE index)
VALUE rb_attr_get(VALUE, ID)
#define readline_s_get_completer_word_break_characters
static int(* history_replace_offset_func)(int)
#define readline_s_set_completion_append_character