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 USE_INSERT_IGNORE_ESCAPE
62 static ID id_orig_prompt, id_last_prompt;
64 #if defined(HAVE_RL_PRE_INPUT_HOOK)
65 static ID id_pre_input_hook;
67 #if defined(HAVE_RL_SPECIAL_PREFIXES)
68 static ID id_special_prefixes;
71 #ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION
72 # define rl_filename_completion_function filename_completion_function
74 #ifndef HAVE_RL_USERNAME_COMPLETION_FUNCTION
75 # define rl_username_completion_function username_completion_function
77 #ifndef HAVE_RL_COMPLETION_MATCHES
78 # define rl_completion_matches completion_matches
83 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
84 static int readline_completion_append_character;
90 #define OutputStringValue(str) do {\
91 SafeStringValue(str);\
92 (str) = rb_str_conv_enc((str), rb_enc_get(str), rb_locale_encoding());\
131 #if defined HAVE_RL_GETC_FUNCTION
132 static VALUE readline_instream;
135 #define rl_getc(f) EOF
138 static int readline_getc(
FILE *);
144 if (!readline_instream)
return rl_getc(input);
146 if (rl_instream != ifp->
stdio_file)
return rl_getc(input);
151 static int prior_key =
'0';
153 if (prior_key > 0xff) {
157 if (PeekConsoleInput((HANDLE)_get_osfhandle(ifp->
fd), &ir, 1, &n)) {
159 if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown) {
163 ReadConsoleInput((HANDLE)_get_osfhandle(ifp->
fd), &ir, 1, &n);
166 HANDLE h = (HANDLE)_get_osfhandle(ifp->
fd);
179 RL_ISSTATE(RL_STATE_ISEARCH) &&
185 if (meta) rl_execute_next(
ESC);
191 #elif defined HAVE_RL_EVENT_HOOK
194 static int readline_event(
void);
207 #if USE_INSERT_IGNORE_ESCAPE
209 insert_ignore_escape(
VALUE self,
VALUE prompt)
213 const char *s0, *s, *e;
215 static const char ignore_code[2] = {RL_PROMPT_START_IGNORE, RL_PROMPT_END_IGNORE};
219 if (orig_prompt == prompt)
return last_prompt;
221 if (
NIL_P(last_prompt)) {
228 while (s < e && *s) {
230 case RL_PROMPT_START_IGNORE:
235 case RL_PROMPT_END_IGNORE:
241 if (++s < e && *s ==
'[') {
244 while (++s < e && *s) {
254 else if (!(
'0' <= *s && *s <=
'9' || *s ==
';')) {
285 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
286 readline_completion_append_character = rl_completion_append_character;
288 return (
VALUE)readline((
char *)prompt);
386 if (
rb_scan_args(argc, argv,
"02", &tmp, &add_hist) > 0) {
388 #if USE_INSERT_IGNORE_ESCAPE
389 tmp = insert_ignore_escape(
self, tmp);
398 int fd =
fileno(rl_outstream);
399 if (fd < 0 ||
fstat(fd, &stbuf) != 0) {
408 #if USE_INSERT_IGNORE_ESCAPE
414 #if defined HAVE_RL_CLEANUP_AFTER_SIGNAL
416 #if defined HAVE_RL_FREE_LINE_STATE
417 rl_free_line_state();
419 rl_cleanup_after_signal();
420 #elif defined HAVE_RL_DEPREP_TERM_FUNCTION
422 if (rl_deprep_term_function !=
NULL)
423 (*rl_deprep_term_function)();
426 rl_deprep_terminal();
431 if (
RTEST(add_hist) && buff) {
439 if (buff)
free(buff);
461 #ifdef HAVE_RL_GETC_FUNCTION
462 readline_instream =
input;
488 #if defined(HAVE_RL_PRE_INPUT_HOOK)
530 readline_pre_input_hook(
void)
540 #define readline_s_set_pre_input_hook rb_f_notimplement
541 #define readline_s_get_pre_input_hook rb_f_notimplement
544 #if defined(HAVE_RL_INSERT_TEXT)
564 #define readline_s_insert_text rb_f_notimplement
567 #if defined(HAVE_RL_REDISPLAY)
587 #define readline_s_redisplay rb_f_notimplement
722 #ifdef HAVE_RL_LINE_BUFFER
738 if (rl_line_buffer ==
NULL)
743 #define readline_s_get_line_buffer rb_f_notimplement
767 #define readline_s_get_point rb_f_notimplement
773 VALUE proc, ary, temp;
783 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
784 rl_completion_append_character = readline_completion_append_character;
786 #ifdef HAVE_RL_ATTEMPTED_COMPLETION_OVER
787 rl_attempted_completion_over = 1;
794 if (matches == 0)
return NULL;
795 result = (
char**)
malloc((matches + 2)*
sizeof(
char*));
799 for (i = 0; i < matches; i++) {
807 result[matches + 1] =
NULL;
810 result[0] =
strdup(result[1]);
813 const char *result1 = result[1];
814 long low =
strlen(result1);
816 for (i = 1; i < matches; ++
i) {
820 const char *p2 = result[i + 1];
823 for (i1 = i2 = 0; i1 < low && i2 < l2; i1 += n1, i2 += n2) {
835 result[0] = (
char*)
malloc(low + 1);
837 strncpy(result[0], result[1], low);
838 result[0][low] =
'\0';
844 #ifdef HAVE_RL_SET_SCREEN_SIZE
865 #define readline_s_set_screen_size rb_f_notimplement
868 #ifdef HAVE_RL_GET_SCREEN_SIZE
888 rl_get_screen_size(&rows, &columns);
895 #define readline_s_get_screen_size rb_f_notimplement
898 #ifdef HAVE_RL_VI_EDITING_MODE
914 rl_vi_editing_mode(1,0);
918 #define readline_s_vi_editing_mode rb_f_notimplement
921 #ifdef HAVE_RL_EDITING_MODE
939 #define readline_s_vi_editing_mode_p rb_f_notimplement
942 #ifdef HAVE_RL_EMACS_EDITING_MODE
958 rl_emacs_editing_mode(1,0);
962 #define readline_s_emacs_editing_mode rb_f_notimplement
965 #ifdef HAVE_RL_EDITING_MODE
983 #define readline_s_emacs_editing_mode_p rb_f_notimplement
986 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
1030 rl_completion_append_character =
'\0';
1035 rl_completion_append_character =
'\0';
1037 rl_completion_append_character =
RSTRING_PTR(str)[0];
1043 #define readline_s_set_completion_append_character rb_f_notimplement
1046 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
1064 if (rl_completion_append_character ==
'\0')
1067 buf[0] = (char) rl_completion_append_character;
1071 #define readline_s_get_completion_append_character rb_f_notimplement
1074 #ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS
1090 static char *basic_word_break_characters =
NULL;
1094 if (basic_word_break_characters ==
NULL) {
1095 basic_word_break_characters =
1101 strncpy(basic_word_break_characters,
1103 basic_word_break_characters[
RSTRING_LEN(str)] =
'\0';
1104 rl_basic_word_break_characters = basic_word_break_characters;
1108 #define readline_s_set_basic_word_break_characters rb_f_notimplement
1111 #ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS
1127 if (rl_basic_word_break_characters ==
NULL)
1132 #define readline_s_get_basic_word_break_characters rb_f_notimplement
1135 #ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS
1151 static char *completer_word_break_characters =
NULL;
1155 if (completer_word_break_characters ==
NULL) {
1156 completer_word_break_characters =
1162 strncpy(completer_word_break_characters,
1164 completer_word_break_characters[
RSTRING_LEN(str)] =
'\0';
1165 rl_completer_word_break_characters = completer_word_break_characters;
1169 #define readline_s_set_completer_word_break_characters rb_f_notimplement
1172 #ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS
1188 if (rl_completer_word_break_characters ==
NULL)
1193 #define readline_s_get_completer_word_break_characters rb_f_notimplement
1196 #if defined(HAVE_RL_SPECIAL_PREFIXES)
1224 rl_special_prefixes =
NULL;
1251 if (rl_special_prefixes ==
NULL)
return Qnil;
1260 #define readline_s_set_special_prefixes rb_f_notimplement
1261 #define readline_s_get_special_prefixes rb_f_notimplement
1264 #ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS
1278 static char *basic_quote_characters =
NULL;
1282 if (basic_quote_characters ==
NULL) {
1283 basic_quote_characters =
1289 strncpy(basic_quote_characters,
1292 rl_basic_quote_characters = basic_quote_characters;
1297 #define readline_s_set_basic_quote_characters rb_f_notimplement
1300 #ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS
1315 if (rl_basic_quote_characters ==
NULL)
1320 #define readline_s_get_basic_quote_characters rb_f_notimplement
1323 #ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS
1340 static char *completer_quote_characters =
NULL;
1344 if (completer_quote_characters ==
NULL) {
1345 completer_quote_characters =
1352 completer_quote_characters[
RSTRING_LEN(str)] =
'\0';
1353 rl_completer_quote_characters = completer_quote_characters;
1358 #define readline_s_set_completer_quote_characters rb_f_notimplement
1361 #ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS
1377 if (rl_completer_quote_characters ==
NULL)
1382 #define readline_s_get_completer_quote_characters rb_f_notimplement
1385 #ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS
1400 static char *filename_quote_characters =
NULL;
1404 if (filename_quote_characters ==
NULL) {
1405 filename_quote_characters =
1412 filename_quote_characters[
RSTRING_LEN(str)] =
'\0';
1413 rl_filename_quote_characters = filename_quote_characters;
1418 #define readline_s_set_filename_quote_characters rb_f_notimplement
1421 #ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS
1437 if (rl_filename_quote_characters ==
NULL)
1442 #define readline_s_get_filename_quote_characters rb_f_notimplement
1445 #ifdef HAVE_RL_REFRESH_LINE
1458 rl_refresh_line(0, 0);
1462 #define readline_s_refresh_line rb_f_notimplement
1474 return history_base + offset;
1486 HIST_ENTRY *entry =
NULL;
1492 i += history_length;
1497 if (entry ==
NULL) {
1503 #ifdef HAVE_REPLACE_HISTORY_ENTRY
1507 HIST_ENTRY *entry =
NULL;
1514 i += history_length;
1519 if (entry ==
NULL) {
1525 #define hist_set rb_f_notimplement
1554 #ifdef HAVE_REMOVE_HISTORY
1559 entry = remove_history(index);
1562 free((
void *) entry->line);
1578 if (history_length > 0) {
1589 if (history_length > 0) {
1605 for (i = 0; i < history_length; i++) {
1618 return INT2NUM(history_length);
1636 i += history_length;
1637 if (i < 0 || i > history_length - 1) {
1643 #ifdef HAVE_CLEAR_HISTORY
1652 #define hist_clear rb_f_notimplement
1666 for (i = 0; matches[
i]; i++) {
1691 for (i = 0; matches[
i]; i++) {
1711 rl_readline_name = (
char *)
"Ruby";
1713 #if defined HAVE_RL_GETC_FUNCTION
1717 rl_getc_function = readline_getc;
1718 #elif defined HAVE_RL_EVENT_HOOK
1719 rl_event_hook = readline_event;
1726 #if defined(HAVE_RL_PRE_INPUT_HOOK)
1727 id_pre_input_hook =
rb_intern(
"pre_input_hook");
1729 #if defined(HAVE_RL_SPECIAL_PREFIXES)
1730 id_special_prefixes =
rb_intern(
"special_prefixes");
1803 #if USE_INSERT_IGNORE_ESCAPE
1804 CONST_ID(id_orig_prompt,
"orig_prompt");
1805 CONST_ID(id_last_prompt,
"last_prompt");
1851 #if defined HAVE_RL_LIBRARY_VERSION
1853 #if defined HAVE_CLEAR_HISTORY || defined HAVE_REMOVE_HISTORY
1860 #ifdef HAVE_REPLACE_HISTORY_ENTRY
1861 if (replace_history_entry(0,
"a",
NULL) ==
NULL) {
1865 #ifdef HAVE_CLEAR_HISTORY
1869 HIST_ENTRY *entry = remove_history(0);
1871 free((
char *)entry->line);
1885 #if defined(HAVE_RL_PRE_INPUT_HOOK)
1886 rl_pre_input_hook = (rl_hook_func_t *)readline_pre_input_hook;
1888 #ifdef HAVE_RL_CATCH_SIGNALS
1889 rl_catch_signals = 0;
1891 #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
#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.
static VALUE readline_s_set_input(VALUE self, VALUE input)
static VALUE hist_to_s(VALUE self)
VALUE rb_str_locktmp(VALUE)
VALUE rb_ary_shift(VALUE ary)
static char ** readline_attempted_completion_function(const char *text, int start, int end)
#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
VALUE rb_ary_push(VALUE ary, VALUE item)
#define readline_s_get_special_prefixes
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *state)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
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 RETURN_ENUMERATOR(obj, argc, argv)
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_locale_str_new(const char *, long)
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_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
#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
static VALUE hist_push_method(int argc, VALUE *argv, VALUE self)
VALUE rb_str_new_shared(VALUE)
VALUE rb_obj_as_string(VALUE)
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)
VALUE rb_io_ungetbyte(VALUE, VALUE)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
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)
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_io_getbyte(VALUE)
RUBY_EXTERN VALUE rb_stdin
VALUE rb_attr_get(VALUE, ID)
static int(* history_get_offset_func)(int)
void rb_thread_schedule(void)
#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)
VALUE rb_ivar_set(VALUE, ID, VALUE)
#define readline_s_set_filename_quote_characters
VALUE rb_str_cat(VALUE, const char *, long)
int rb_io_read_pending(rb_io_t *)
#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
FILE * rb_io_stdio_file(rb_io_t *fptr)
#define rl_completion_matches
#define readline_s_get_screen_size
#define readline_s_set_basic_word_break_characters
VALUE rb_obj_alloc(VALUE)
#define readline_s_get_completion_append_character
static void version(void)
VALUE rb_define_module(const char *name)
#define readline_s_set_basic_quote_characters
#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)