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>
44 #ifdef HAVE_SYS_STAT_H
50 #define EDIT_LINE_LIBRARY_VERSION "EditLine wrapper"
51 #ifndef USE_INSERT_IGNORE_ESCAPE
52 # if !defined(HAVE_EDITLINE_READLINE_H) && defined(RL_PROMPT_START_IGNORE) && defined(RL_PROMPT_END_IGNORE)
53 # define USE_INSERT_IGNORE_ESCAPE 1
55 # define USE_INSERT_IGNORE_ESCAPE 0
59 #define COMPLETION_PROC "completion_proc"
60 #define COMPLETION_CASE_FOLD "completion_case_fold"
62 #if USE_INSERT_IGNORE_ESCAPE
63 static ID id_orig_prompt, id_last_prompt;
65 #if defined(HAVE_RL_PRE_INPUT_HOOK)
66 static ID id_pre_input_hook;
68 #if defined(HAVE_RL_SPECIAL_PREFIXES)
69 static ID id_special_prefixes;
72 #ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION
73 # define rl_filename_completion_function filename_completion_function
75 #ifndef HAVE_RL_USERNAME_COMPLETION_FUNCTION
76 # define rl_username_completion_function username_completion_function
78 #ifndef HAVE_RL_COMPLETION_MATCHES
79 # define rl_completion_matches completion_matches
84 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
85 static int readline_completion_append_character;
91 #define OutputStringValue(str) do {\
92 SafeStringValue(str);\
93 (str) = rb_str_conv_enc((str), rb_enc_get(str), rb_locale_encoding());\
135 #if defined HAVE_RL_GETC_FUNCTION
138 #define rl_getc(f) EOF
149 getc_body(
struct getc_struct *
p)
158 static int prior_key =
'0';
160 if (prior_key > 0xff) {
161 prior_key = rl_getc(p->input);
164 if (PeekConsoleInput((HANDLE)_get_osfhandle(p->fd), &ir, 1, &n)) {
166 if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown) {
167 prior_key = rl_getc(p->input);
170 ReadConsoleInput((HANDLE)_get_osfhandle(p->fd), &ir, 1, &n);
173 HANDLE h = (HANDLE)_get_osfhandle(p->fd);
183 ss = read(p->fd, &ch, 1);
190 return (
unsigned char)ch;
194 getc_func(
void *data1)
196 struct getc_struct *p = data1;
198 p->ret = getc_body(p);
206 struct getc_struct
data;
219 if (
data.err == EINTR) {
226 rb_bug(
"readline_getc: input closed unexpectedly or memory corrupted");
228 if (ret != -1 ||
errno == EINTR)
238 #elif defined HAVE_RL_EVENT_HOOK
241 static int readline_event(
void);
254 #if USE_INSERT_IGNORE_ESCAPE
256 insert_ignore_escape(
VALUE self,
VALUE prompt)
260 const char *s0, *
s, *
e;
262 static const char ignore_code[2] = {RL_PROMPT_START_IGNORE, RL_PROMPT_END_IGNORE};
266 if (orig_prompt == prompt)
return last_prompt;
268 if (
NIL_P(last_prompt)) {
275 while (s < e && *s) {
277 case RL_PROMPT_START_IGNORE:
282 case RL_PROMPT_END_IGNORE:
288 if (++s < e && *s ==
'[') {
291 while (++s < e && *s) {
292 if (
ISALPHA(*(
unsigned char *)s)) {
301 else if (!((
'0' <= *s && *s <=
'9') || *s ==
';')) {
332 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
333 readline_completion_append_character = rl_completion_append_character;
335 return (
VALUE)readline((
char *)prompt);
341 if (readline_rl_instream) {
342 fclose(readline_rl_instream);
343 if (rl_instream == readline_rl_instream)
345 readline_rl_instream =
NULL;
353 if (readline_rl_outstream) {
354 fclose(readline_rl_outstream);
355 if (rl_outstream == readline_rl_outstream)
357 readline_rl_outstream =
NULL;
454 if (
rb_scan_args(argc, argv,
"02", &tmp, &add_hist) > 0) {
456 #if USE_INSERT_IGNORE_ESCAPE
457 tmp = insert_ignore_escape(
self, tmp);
485 #if USE_INSERT_IGNORE_ESCAPE
491 #if defined HAVE_RL_CLEANUP_AFTER_SIGNAL
493 #if defined HAVE_RL_FREE_LINE_STATE
494 rl_free_line_state();
496 rl_cleanup_after_signal();
497 #elif defined HAVE_RL_DEPREP_TERM_FUNCTION
499 if (rl_deprep_term_function !=
NULL)
500 (*rl_deprep_term_function)();
503 rl_deprep_terminal();
508 if (
RTEST(add_hist) && buff) {
516 if (buff)
free(buff);
546 int save_errno =
errno;
551 rl_instream = readline_rl_instream =
f;
583 int save_errno =
errno;
588 rl_outstream = readline_rl_outstream =
f;
594 #if defined(HAVE_RL_PRE_INPUT_HOOK)
634 readline_pre_input_hook(
void)
644 #define readline_s_set_pre_input_hook rb_f_notimplement
645 #define readline_s_get_pre_input_hook rb_f_notimplement
648 #if defined(HAVE_RL_INSERT_TEXT)
667 #define readline_s_insert_text rb_f_notimplement
670 #if defined(HAVE_RL_DELETE_TEXT)
687 if (rl_line_buffer) {
688 char *
p, *
ptr = rl_line_buffer;
689 long beg = 0, len =
strlen(rl_line_buffer);
706 else if (argc == 1) {
718 #define readline_s_delete_text rb_f_notimplement
721 #if defined(HAVE_RL_REDISPLAY)
740 #define readline_s_redisplay rb_f_notimplement
863 #ifdef HAVE_RL_LINE_BUFFER
880 if (rl_line_buffer ==
NULL)
885 #define readline_s_get_line_buffer rb_f_notimplement
928 #define readline_s_get_point rb_f_notimplement
929 #define readline_s_set_point rb_f_notimplement
945 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
946 rl_completion_append_character = readline_completion_append_character;
948 #ifdef HAVE_RL_ATTEMPTED_COMPLETION_OVER
949 rl_attempted_completion_over = 1;
956 if (matches == 0)
return NULL;
957 result = (
char**)
malloc((matches + 2)*
sizeof(
char*));
961 for (i = 0; i < matches; i++) {
969 result[matches + 1] =
NULL;
972 result[0] =
strdup(result[1]);
975 const char *result1 = result[1];
976 long low =
strlen(result1);
978 for (i = 1; i < matches; ++
i) {
982 const char *p2 = result[i + 1];
985 for (i1 = i2 = 0; i1 < low && i2 < l2; i1 += n1, i2 += n2) {
997 result[0] = (
char*)
malloc(low + 1);
999 strncpy(result[0], result[1], low);
1000 result[0][low] =
'\0';
1006 #ifdef HAVE_RL_SET_SCREEN_SIZE
1024 #define readline_s_set_screen_size rb_f_notimplement
1027 #ifdef HAVE_RL_GET_SCREEN_SIZE
1044 rl_get_screen_size(&rows, &columns);
1051 #define readline_s_get_screen_size rb_f_notimplement
1054 #ifdef HAVE_RL_VI_EDITING_MODE
1067 rl_vi_editing_mode(1,0);
1071 #define readline_s_vi_editing_mode rb_f_notimplement
1074 #ifdef HAVE_RL_EDITING_MODE
1089 #define readline_s_vi_editing_mode_p rb_f_notimplement
1092 #ifdef HAVE_RL_EMACS_EDITING_MODE
1105 rl_emacs_editing_mode(1,0);
1109 #define readline_s_emacs_editing_mode rb_f_notimplement
1112 #ifdef HAVE_RL_EDITING_MODE
1127 #define readline_s_emacs_editing_mode_p rb_f_notimplement
1130 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
1171 rl_completion_append_character =
'\0';
1176 rl_completion_append_character =
'\0';
1178 rl_completion_append_character =
RSTRING_PTR(str)[0];
1184 #define readline_s_set_completion_append_character rb_f_notimplement
1187 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
1202 if (rl_completion_append_character ==
'\0')
1205 buf[0] = (char) rl_completion_append_character;
1209 #define readline_s_get_completion_append_character rb_f_notimplement
1212 #ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS
1226 static char *basic_word_break_characters =
NULL;
1229 if (basic_word_break_characters ==
NULL) {
1230 basic_word_break_characters =
1236 strncpy(basic_word_break_characters,
1238 basic_word_break_characters[
RSTRING_LEN(str)] =
'\0';
1239 rl_basic_word_break_characters = basic_word_break_characters;
1243 #define readline_s_set_basic_word_break_characters rb_f_notimplement
1246 #ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS
1259 if (rl_basic_word_break_characters ==
NULL)
1264 #define readline_s_get_basic_word_break_characters rb_f_notimplement
1267 #ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS
1281 static char *completer_word_break_characters =
NULL;
1284 if (completer_word_break_characters ==
NULL) {
1285 completer_word_break_characters =
1291 strncpy(completer_word_break_characters,
1293 completer_word_break_characters[
RSTRING_LEN(str)] =
'\0';
1294 rl_completer_word_break_characters = completer_word_break_characters;
1298 #define readline_s_set_completer_word_break_characters rb_f_notimplement
1301 #ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS
1314 if (rl_completer_word_break_characters ==
NULL)
1319 #define readline_s_get_completer_word_break_characters rb_f_notimplement
1322 #if defined(HAVE_RL_SPECIAL_PREFIXES)
1347 rl_special_prefixes =
NULL;
1371 if (rl_special_prefixes ==
NULL)
return Qnil;
1380 #define readline_s_set_special_prefixes rb_f_notimplement
1381 #define readline_s_get_special_prefixes rb_f_notimplement
1384 #ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS
1396 static char *basic_quote_characters =
NULL;
1399 if (basic_quote_characters ==
NULL) {
1400 basic_quote_characters =
1406 strncpy(basic_quote_characters,
1409 rl_basic_quote_characters = basic_quote_characters;
1414 #define readline_s_set_basic_quote_characters rb_f_notimplement
1417 #ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS
1429 if (rl_basic_quote_characters ==
NULL)
1434 #define readline_s_get_basic_quote_characters rb_f_notimplement
1437 #ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS
1452 static char *completer_quote_characters =
NULL;
1455 if (completer_quote_characters ==
NULL) {
1456 completer_quote_characters =
1463 completer_quote_characters[
RSTRING_LEN(str)] =
'\0';
1464 rl_completer_quote_characters = completer_quote_characters;
1469 #define readline_s_set_completer_quote_characters rb_f_notimplement
1472 #ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS
1485 if (rl_completer_quote_characters ==
NULL)
1490 #define readline_s_get_completer_quote_characters rb_f_notimplement
1493 #ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS
1506 static char *filename_quote_characters =
NULL;
1509 if (filename_quote_characters ==
NULL) {
1510 filename_quote_characters =
1517 filename_quote_characters[
RSTRING_LEN(str)] =
'\0';
1518 rl_filename_quote_characters = filename_quote_characters;
1523 #define readline_s_set_filename_quote_characters rb_f_notimplement
1526 #ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS
1539 if (rl_filename_quote_characters ==
NULL)
1544 #define readline_s_get_filename_quote_characters rb_f_notimplement
1547 #ifdef HAVE_RL_REFRESH_LINE
1557 rl_refresh_line(0, 0);
1561 #define readline_s_refresh_line rb_f_notimplement
1573 return history_base + offset;
1590 i += history_length;
1595 if (entry ==
NULL) {
1601 #ifdef HAVE_REPLACE_HISTORY_ENTRY
1611 i += history_length;
1616 if (entry ==
NULL) {
1622 #define hist_set rb_f_notimplement
1649 #ifdef HAVE_REMOVE_HISTORY
1653 entry = remove_history(index);
1656 free((
void *) entry->line);
1671 if (history_length > 0) {
1681 if (history_length > 0) {
1696 for (i = 0; i < history_length; i++) {
1708 return INT2NUM(history_length);
1724 i += history_length;
1725 if (i < 0 || i > history_length - 1) {
1731 #ifdef HAVE_CLEAR_HISTORY
1739 #define hist_clear rb_f_notimplement
1753 for (i = 0; matches[
i]; i++) {
1778 for (i = 0; matches[
i]; i++) {
1798 rl_readline_name = (
char *)
"Ruby";
1800 #if defined HAVE_RL_GETC_FUNCTION
1804 rl_getc_function = readline_getc;
1805 #elif defined HAVE_RL_EVENT_HOOK
1806 rl_event_hook = readline_event;
1813 #if defined(HAVE_RL_PRE_INPUT_HOOK)
1814 id_pre_input_hook =
rb_intern(
"pre_input_hook");
1816 #if defined(HAVE_RL_SPECIAL_PREFIXES)
1817 id_special_prefixes =
rb_intern(
"special_prefixes");
1894 #if USE_INSERT_IGNORE_ESCAPE
1895 CONST_ID(id_orig_prompt,
"orig_prompt");
1896 CONST_ID(id_last_prompt,
"last_prompt");
1942 #if defined HAVE_RL_LIBRARY_VERSION
1944 #if defined HAVE_CLEAR_HISTORY || defined HAVE_REMOVE_HISTORY
1951 #ifdef HAVE_REPLACE_HISTORY_ENTRY
1952 if (replace_history_entry(0,
"a",
NULL) ==
NULL) {
1956 #ifdef HAVE_CLEAR_HISTORY
1960 HIST_ENTRY *entry = remove_history(0);
1962 free((
char *)entry->line);
1976 #if defined(HAVE_RL_PRE_INPUT_HOOK)
1977 rl_pre_input_hook = (rl_hook_func_t *)readline_pre_input_hook;
1979 #ifdef HAVE_RL_CATCH_SIGNALS
1980 rl_catch_signals = 0;
1982 #ifdef HAVE_RL_CLEAR_SIGNALS
static ID completion_case_fold
#define RB_TYPE_P(obj, type)
rb_encoding * rb_enc_check(VALUE str1, VALUE str2)
#define readline_s_get_line_buffer
void rb_bug(const char *fmt,...)
#define readline_s_get_basic_quote_characters
size_t strlen(const char *)
int rb_w32_wait_events(HANDLE *events, int num, DWORD timeout)
static VALUE readline_get(VALUE prompt)
VALUE rb_str_tmp_new(long)
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
struct RString::@95::@96 heap
static VALUE readline_s_set_input(VALUE self, VALUE input)
rb_funcall(memo->yielder, id_lshift, 1, rb_assoc_new(memo->prev_value, memo->prev_elts))
static VALUE hist_to_s(VALUE self)
VALUE rb_str_locktmp(VALUE)
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
VALUE rb_str_new_cstr(const char *)
#define readline_s_set_pre_input_hook
VALUE rb_enc_from_encoding(rb_encoding *encoding)
static ID completion_proc
long rb_str_strlen(VALUE)
static FILE * readline_rl_outstream
VALUE rb_ary_push(VALUE ary, VALUE item)
#define readline_s_get_special_prefixes
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,...)
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
#define RETURN_ENUMERATOR(obj, argc, argv)
VALUE rb_io_taint_check(VALUE)
RUBY_EXTERN VALUE rb_eIOError
#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)
VALUE rb_obj_reveal(VALUE obj, VALUE klass)
VALUE rb_locale_str_new(const char *, long)
int rb_cloexec_dup(int oldfd)
VALUE rb_str_unlocktmp(VALUE)
static VALUE readline_s_set_output(VALUE self, VALUE output)
#define GetOpenFile(obj, fp)
static int history_get_offset_history_base(int offset)
static VALUE hist_push(VALUE self, VALUE str)
VALUE rb_ivar_get(VALUE, ID)
#define readline_s_delete_text
#define readline_s_vi_editing_mode_p
#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 readline_s_get_pre_input_hook
#define rl_filename_completion_function
static VALUE readline_outstream
#define readline_s_set_completer_quote_characters
#define readline_s_get_basic_word_break_characters
#define StringValuePtr(v)
#define EDIT_LINE_LIBRARY_VERSION
VALUE rb_locale_str_new_cstr(const char *)
#define readline_s_refresh_line
#define StringValueCStr(v)
static VALUE username_completion_proc_call(VALUE self, VALUE str)
void rb_define_const(VALUE, const char *, VALUE)
static VALUE hist_shift(VALUE self)
#define readline_s_get_filename_quote_characters
#define readline_s_vi_editing_mode
#define readline_s_emacs_editing_mode_p
unsigned char buf[MIME_BUF_SIZE]
#define readline_s_set_point
static VALUE hist_push_method(int argc, VALUE *argv, VALUE self)
VALUE rb_str_new_shared(VALUE)
VALUE rb_obj_as_string(VALUE)
VALUE rb_obj_hide(VALUE obj)
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
#define CONST_ID(var, str)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
static int history_get_offset_0(int offset)
#define readline_s_set_special_prefixes
rb_encoding * rb_locale_encoding(void)
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_attr_get(VALUE, ID)
static int(* history_get_offset_func)(int)
void rb_thread_schedule(void)
void rb_sys_fail(const char *mesg)
#define readline_s_get_point
RUBY_EXTERN VALUE rb_cString
void rb_jump_tag(int tag)
static VALUE hist_empty_p(VALUE self)
static VALUE readline_s_set_completion_case_fold(VALUE self, VALUE val)
#define readline_s_set_filename_quote_characters
void rb_gc_register_address(VALUE *)
VALUE rb_str_cat(VALUE, const char *, long)
#define readline_s_redisplay
static VALUE readline_s_get_completion_proc(VALUE self)
static VALUE rb_remove_history(int index)
#define readline_s_get_completer_quote_characters
#define rb_str_dup_frozen
#define readline_s_set_screen_size
static int(* history_replace_offset_func)(int)
RUBY_EXTERN VALUE rb_cObject
static VALUE readline_readline(int argc, VALUE *argv, VALUE self)
int rb_respond_to(VALUE, ID)
static VALUE hist_get(VALUE self, VALUE index)
void rb_notimplement(void)
#define rl_username_completion_function
rb_ivar_set(yielder, id_memo, LONG2NUM(++count))
#define rl_completion_matches
#define readline_s_get_screen_size
#define readline_s_set_basic_word_break_characters
VALUE rb_range_beg_len(VALUE, long *, long *, long, int)
static FILE * readline_rl_instream
VALUE rb_obj_alloc(VALUE)
#define readline_s_get_completion_append_character
char * rb_str_subpos(VALUE, long, long *)
static void version(void)
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)
#define REALLOC_N(var, type, n)
static VALUE hist_delete_at(VALUE self, VALUE index)
#define readline_s_get_completer_word_break_characters
#define readline_s_set_completion_append_character
void rb_str_set_len(VALUE, long)