diff options
author | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-07-07 07:36:34 +0000 |
---|---|---|
committer | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-07-07 07:36:34 +0000 |
commit | 441546edcfbb1b346c87b69c5f578d1a0e522e06 (patch) | |
tree | 04f606a008baebc445f38944ad37e87468da29ea /ruby_1_8_6/ext/readline | |
parent | fa93611c0f9a6db146341c792bfe3b7322ec00e2 (diff) |
add tag v1_8_6_269
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_8_6_269@17937 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ruby_1_8_6/ext/readline')
-rw-r--r-- | ruby_1_8_6/ext/readline/.cvsignore | 3 | ||||
-rw-r--r-- | ruby_1_8_6/ext/readline/README | 62 | ||||
-rw-r--r-- | ruby_1_8_6/ext/readline/README.ja | 63 | ||||
-rw-r--r-- | ruby_1_8_6/ext/readline/depend | 1 | ||||
-rw-r--r-- | ruby_1_8_6/ext/readline/extconf.rb | 64 | ||||
-rw-r--r-- | ruby_1_8_6/ext/readline/readline.c | 839 |
6 files changed, 1032 insertions, 0 deletions
diff --git a/ruby_1_8_6/ext/readline/.cvsignore b/ruby_1_8_6/ext/readline/.cvsignore new file mode 100644 index 0000000000..4088712231 --- /dev/null +++ b/ruby_1_8_6/ext/readline/.cvsignore @@ -0,0 +1,3 @@ +Makefile +mkmf.log +*.def diff --git a/ruby_1_8_6/ext/readline/README b/ruby_1_8_6/ext/readline/README new file mode 100644 index 0000000000..9bbf325c99 --- /dev/null +++ b/ruby_1_8_6/ext/readline/README @@ -0,0 +1,62 @@ +Extension for GNU Readline Library + +Example: + + require "readline" + include Readline + + line = readline("Prompt> ", true) + +[Readline] + +<module function> + +readline(prompt, add_history=nil) + + Reads one line with line editing. The inputted line is added to the + history if add_history is true. + +<class methods> + +completion_proc = proc + + Specifies a Proc object to determine completion behavior. It + should take input-string, and return an array of completion + candidates. + +completion_proc + + Returns the completion Proc object. + +completion_case_fold = bool + + Sets whether or not to ignore case on completion. + +completion_case_fold + + Returns true if completion ignores case. + +completion_append_character = char + + Specifies a character to be appended on completion. + Nothing will be appended if an empty string ("") or nil is + specified. + +completion_append_character + + Returns a string containing a character to be appended on + completion. The default is a space (" "). + +vi_editing_mode + + Specifies VI editing mode. + +emacs_editing_mode + + Specifies Emacs editing mode. + +<class constants> + +HISTORY + +The history buffer. It behaves just like an array. diff --git a/ruby_1_8_6/ext/readline/README.ja b/ruby_1_8_6/ext/readline/README.ja new file mode 100644 index 0000000000..beb951fbf0 --- /dev/null +++ b/ruby_1_8_6/ext/readline/README.ja @@ -0,0 +1,63 @@ +GNU Readline Libraryを利用するための拡張モジュールです。 + +require "readline" +include Readline + +line = readline("Prompt> ", true) + +のように使用してください。 + +[Readline] + +<モジュール関数> + +readline(prompt, add_history=nil) + + 一行入力を読み込みます。 + add_historyがtrueの場合、ヒストリに読み込んだ文字列を追加します。 + +<クラスメソッド> + +completion_proc = proc + + 補完時の動作を決定するProcオブジェクトを指定します。 + procは引数に入力文字列を取り、候補文字列の配列を返すように + してください。 + +completion_proc + + 補完時の動作を決定するProcオブジェクトを返します。 + +completion_case_fold = case_fold + + 補完時に大文字小文字を区別しない場合、trueを指定します。 + +completion_case_fold + + 補完時に大文字小文字を区別しない場合、trueを返します。 + +completion_append_character = char + + 補完時に付加される文字を文字列で指定します。先頭の一文字が + 設定され、空文字列 ("") または nil を指定すると何も付加 + されなくなります。 + +completion_append_character + + 補完時に付加される文字を文字列で返します。デフォルトは + 空白 (" ") です。 + +vi_editing_mode + + VIモードになります。 + +emacs_editing_mode + + Emacsモードになります。 + +<クラス定数> + +HISTORY + +ヒストリに対する操作はこの定数を通して行ってください。 +配列と同じように扱えるようになっています。 diff --git a/ruby_1_8_6/ext/readline/depend b/ruby_1_8_6/ext/readline/depend new file mode 100644 index 0000000000..6570c5a036 --- /dev/null +++ b/ruby_1_8_6/ext/readline/depend @@ -0,0 +1 @@ +readline.o: readline.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h diff --git a/ruby_1_8_6/ext/readline/extconf.rb b/ruby_1_8_6/ext/readline/extconf.rb new file mode 100644 index 0000000000..b820c0b32f --- /dev/null +++ b/ruby_1_8_6/ext/readline/extconf.rb @@ -0,0 +1,64 @@ +require "mkmf" + +$readline_headers = ["stdio.h"] + +def have_readline_header(header) + if have_header(header) + $readline_headers.push(header) + return true + else + return false + end +end + +def have_readline_var(var) + return have_var(var, $readline_headers) +end + +dir_config('curses') +dir_config('ncurses') +dir_config('termcap') +dir_config("readline") +enable_libedit = enable_config("libedit") +have_library("user32", nil) if /cygwin/ === RUBY_PLATFORM +have_library("ncurses", "tgetnum") || + have_library("termcap", "tgetnum") || + have_library("curses", "tgetnum") + +if enable_libedit + unless (have_readline_header("editline/readline.h") || + have_readline_header("readline/readline.h")) && + have_library("edit", "readline") + exit + end +else + unless ((have_readline_header("readline/readline.h") && + have_readline_header("readline/history.h")) && + (have_library("readline", "readline") || + have_library("edit", "readline"))) || + (have_readline_header("editline/readline.h") && + have_library("edit", "readline")) + exit + end +end + +have_func("rl_filename_completion_function") +have_func("rl_username_completion_function") +have_func("rl_completion_matches") +have_readline_var("rl_deprep_term_function") +have_readline_var("rl_completion_append_character") +have_readline_var("rl_basic_word_break_characters") +have_readline_var("rl_completer_word_break_characters") +have_readline_var("rl_basic_quote_characters") +have_readline_var("rl_completer_quote_characters") +have_readline_var("rl_filename_quote_characters") +have_readline_var("rl_attempted_completion_over") +have_readline_var("rl_library_version") +have_readline_var("rl_event_hook") +have_func("rl_cleanup_after_signal") +have_func("rl_clear_signals") +have_func("rl_vi_editing_mode") +have_func("rl_emacs_editing_mode") +have_func("replace_history_entry") +have_func("remove_history") +create_makefile("readline") diff --git a/ruby_1_8_6/ext/readline/readline.c b/ruby_1_8_6/ext/readline/readline.c new file mode 100644 index 0000000000..82ddc8a3cb --- /dev/null +++ b/ruby_1_8_6/ext/readline/readline.c @@ -0,0 +1,839 @@ +/* readline.c -- GNU Readline module + Copyright (C) 1997-2001 Shugo Maeda */ + +#include "config.h" +#include <errno.h> +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#ifdef HAVE_READLINE_READLINE_H +#include <readline/readline.h> +#endif +#ifdef HAVE_READLINE_HISTORY_H +#include <readline/history.h> +#endif +#ifdef HAVE_EDITLINE_READLINE_H +#include <editline/readline.h> +#endif + +#include "ruby.h" +#include "rubyio.h" +#include "rubysig.h" + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +static VALUE mReadline; + +#define TOLOWER(c) (isupper(c) ? tolower(c) : c) + +#define COMPLETION_PROC "completion_proc" +#define COMPLETION_CASE_FOLD "completion_case_fold" +static ID completion_proc, completion_case_fold; + +#ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION +# define rl_filename_completion_function filename_completion_function +#endif +#ifndef HAVE_RL_USERNAME_COMPLETION_FUNCTION +# define rl_username_completion_function username_completion_function +#endif +#ifndef HAVE_RL_COMPLETION_MATCHES +# define rl_completion_matches completion_matches +#endif + +static char **readline_attempted_completion_function(const char *text, + int start, int end); + +#ifdef HAVE_RL_EVENT_HOOK +#ifdef DOSISH +#define BUSY_WAIT 1 +#else +#define BUSY_WAIT 0 +#endif + +static int readline_event(void); +static int +readline_event() +{ +#if BUSY_WAIT + rb_thread_schedule(); +#else + fd_set rset; + + FD_ZERO(&rset); + FD_SET(fileno(rl_instream), &rset); + rb_thread_select(fileno(rl_instream) + 1, &rset, NULL, NULL, NULL); + return 0; +#endif +} +#endif + +static VALUE +readline_readline(argc, argv, self) + int argc; + VALUE *argv; + VALUE self; +{ + VALUE tmp, add_hist, result; + char *prompt = NULL; + char *buff; + int status; + OpenFile *ofp, *ifp; + + rb_secure(4); + if (rb_scan_args(argc, argv, "02", &tmp, &add_hist) > 0) { + SafeStringValue(tmp); + prompt = RSTRING(tmp)->ptr; + } + + if (!isatty(0) && errno == EBADF) rb_raise(rb_eIOError, "stdin closed"); + + Check_Type(rb_stdout, T_FILE); + GetOpenFile(rb_stdout, ofp); + rl_outstream = GetWriteFile(ofp); + Check_Type(rb_stdin, T_FILE); + GetOpenFile(rb_stdin, ifp); + rl_instream = GetReadFile(ifp); + buff = (char*)rb_protect((VALUE(*)_((VALUE)))readline, (VALUE)prompt, + &status); + if (status) { +#if defined HAVE_RL_CLEANUP_AFTER_SIGNAL + /* restore terminal mode and signal handler*/ + rl_cleanup_after_signal(); +#elif defined HAVE_RL_DEPREP_TERM_FUNCTION + /* restore terminal mode */ + if (rl_deprep_term_function != NULL) /* NULL in libedit. [ruby-dev:29116] */ + (*rl_deprep_term_function)(); + else +#else + rl_deprep_terminal(); +#endif + rb_jump_tag(status); + } + + if (RTEST(add_hist) && buff) { + add_history(buff); + } + if (buff) + result = rb_tainted_str_new2(buff); + else + result = Qnil; + if (buff) free(buff); + return result; +} + +static VALUE +readline_s_set_completion_proc(self, proc) + VALUE self; + VALUE proc; +{ + rb_secure(4); + if (!rb_respond_to(proc, rb_intern("call"))) + rb_raise(rb_eArgError, "argument must respond to `call'"); + return rb_ivar_set(mReadline, completion_proc, proc); +} + +static VALUE +readline_s_get_completion_proc(self) + VALUE self; +{ + rb_secure(4); + return rb_attr_get(mReadline, completion_proc); +} + +static VALUE +readline_s_set_completion_case_fold(self, val) + VALUE self; + VALUE val; +{ + rb_secure(4); + return rb_ivar_set(mReadline, completion_case_fold, val); +} + +static VALUE +readline_s_get_completion_case_fold(self) + VALUE self; +{ + rb_secure(4); + return rb_attr_get(mReadline, completion_case_fold); +} + +static char ** +readline_attempted_completion_function(text, start, end) + const char *text; + int start; + int end; +{ + VALUE proc, ary, temp; + char **result; + int case_fold; + int i, matches; + + proc = rb_attr_get(mReadline, completion_proc); + if (NIL_P(proc)) + return NULL; +#ifdef HAVE_RL_ATTEMPTED_COMPLETION_OVER + rl_attempted_completion_over = 1; +#endif + case_fold = RTEST(rb_attr_get(mReadline, completion_case_fold)); + ary = rb_funcall(proc, rb_intern("call"), 1, rb_tainted_str_new2(text)); + if (TYPE(ary) != T_ARRAY) + ary = rb_Array(ary); + matches = RARRAY(ary)->len; + if (matches == 0) + return NULL; + result = ALLOC_N(char *, matches + 2); + for (i = 0; i < matches; i++) { + temp = rb_obj_as_string(RARRAY(ary)->ptr[i]); + result[i + 1] = ALLOC_N(char, RSTRING(temp)->len + 1); + strcpy(result[i + 1], RSTRING(temp)->ptr); + } + result[matches + 1] = NULL; + + if (matches == 1) { + result[0] = strdup(result[1]); + } + else { + register int i = 1; + int low = 100000; + + while (i < matches) { + register int c1, c2, si; + + if (case_fold) { + for (si = 0; + (c1 = TOLOWER(result[i][si])) && + (c2 = TOLOWER(result[i + 1][si])); + si++) + if (c1 != c2) break; + } else { + for (si = 0; + (c1 = result[i][si]) && + (c2 = result[i + 1][si]); + si++) + if (c1 != c2) break; + } + + if (low > si) low = si; + i++; + } + result[0] = ALLOC_N(char, low + 1); + strncpy(result[0], result[1], low); + result[0][low] = '\0'; + } + + return result; +} + +static VALUE +readline_s_vi_editing_mode(self) + VALUE self; +{ +#ifdef HAVE_RL_VI_EDITING_MODE + rb_secure(4); + rl_vi_editing_mode(1,0); + return Qnil; +#else + rb_notimplement(); + return Qnil; /* not reached */ +#endif /* HAVE_RL_VI_EDITING_MODE */ +} + +static VALUE +readline_s_emacs_editing_mode(self) + VALUE self; +{ +#ifdef HAVE_RL_EMACS_EDITING_MODE + rb_secure(4); + rl_emacs_editing_mode(1,0); + return Qnil; +#else + rb_notimplement(); + return Qnil; /* not reached */ +#endif /* HAVE_RL_EMACS_EDITING_MODE */ +} + +static VALUE +readline_s_set_completion_append_character(self, str) + VALUE self, str; +{ +#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER + rb_secure(4); + if (NIL_P(str)) { + rl_completion_append_character = '\0'; + } + else { + SafeStringValue(str); + if (RSTRING(str)->len == 0) { + rl_completion_append_character = '\0'; + } else { + rl_completion_append_character = RSTRING(str)->ptr[0]; + } + } + return self; +#else + rb_notimplement(); + return Qnil; /* not reached */ +#endif /* HAVE_RL_COMPLETION_APPEND_CHARACTER */ +} + +static VALUE +readline_s_get_completion_append_character(self) + VALUE self; +{ +#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER + VALUE str; + + rb_secure(4); + if (rl_completion_append_character == '\0') + return Qnil; + + str = rb_str_new("", 1); + RSTRING(str)->ptr[0] = rl_completion_append_character; + return str; +#else + rb_notimplement(); + return Qnil; /* not reached */ +#endif /* HAVE_RL_COMPLETION_APPEND_CHARACTER */ +} + +static VALUE +readline_s_set_basic_word_break_characters(self, str) + VALUE self, str; +{ +#ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS + static char *basic_word_break_characters = NULL; + + rb_secure(4); + SafeStringValue(str); + if (basic_word_break_characters == NULL) { + basic_word_break_characters = + ALLOC_N(char, RSTRING(str)->len + 1); + } + else { + REALLOC_N(basic_word_break_characters, char, RSTRING(str)->len + 1); + } + strncpy(basic_word_break_characters, + RSTRING(str)->ptr, RSTRING(str)->len); + basic_word_break_characters[RSTRING(str)->len] = '\0'; + rl_basic_word_break_characters = basic_word_break_characters; + return self; +#else + rb_notimplement(); + return Qnil; /* not reached */ +#endif /* HAVE_RL_BASIC_WORD_BREAK_CHARACTERS */ +} + +static VALUE +readline_s_get_basic_word_break_characters(self, str) + VALUE self, str; +{ +#ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS + rb_secure(4); + if (rl_basic_word_break_characters == NULL) + return Qnil; + return rb_tainted_str_new2(rl_basic_word_break_characters); +#else + rb_notimplement(); + return Qnil; /* not reached */ +#endif /* HAVE_RL_BASIC_WORD_BREAK_CHARACTERS */ +} + +static VALUE +readline_s_set_completer_word_break_characters(self, str) + VALUE self, str; +{ +#ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS + static char *completer_word_break_characters = NULL; + + rb_secure(4); + SafeStringValue(str); + if (completer_word_break_characters == NULL) { + completer_word_break_characters = + ALLOC_N(char, RSTRING(str)->len + 1); + } + else { + REALLOC_N(completer_word_break_characters, char, RSTRING(str)->len + 1); + } + strncpy(completer_word_break_characters, + RSTRING(str)->ptr, RSTRING(str)->len); + completer_word_break_characters[RSTRING(str)->len] = '\0'; + rl_completer_word_break_characters = completer_word_break_characters; + return self; +#else + rb_notimplement(); + return Qnil; /* not reached */ +#endif /* HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS */ +} + +static VALUE +readline_s_get_completer_word_break_characters(self, str) + VALUE self, str; +{ +#ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS + rb_secure(4); + if (rl_completer_word_break_characters == NULL) + return Qnil; + return rb_tainted_str_new2(rl_completer_word_break_characters); +#else + rb_notimplement(); + return Qnil; /* not reached */ +#endif /* HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS */ +} + +static VALUE +readline_s_set_basic_quote_characters(self, str) + VALUE self, str; +{ +#ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS + static char *basic_quote_characters = NULL; + + rb_secure(4); + SafeStringValue(str); + if (basic_quote_characters == NULL) { + basic_quote_characters = + ALLOC_N(char, RSTRING(str)->len + 1); + } + else { + REALLOC_N(basic_quote_characters, char, RSTRING(str)->len + 1); + } + strncpy(basic_quote_characters, + RSTRING(str)->ptr, RSTRING(str)->len); + basic_quote_characters[RSTRING(str)->len] = '\0'; + rl_basic_quote_characters = basic_quote_characters; + + return self; +#else + rb_notimplement(); + return Qnil; /* not reached */ +#endif /* HAVE_RL_BASIC_QUOTE_CHARACTERS */ +} + +static VALUE +readline_s_get_basic_quote_characters(self, str) + VALUE self, str; +{ +#ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS + rb_secure(4); + if (rl_basic_quote_characters == NULL) + return Qnil; + return rb_tainted_str_new2(rl_basic_quote_characters); +#else + rb_notimplement(); + return Qnil; /* not reached */ +#endif /* HAVE_RL_BASIC_QUOTE_CHARACTERS */ +} + +static VALUE +readline_s_set_completer_quote_characters(self, str) + VALUE self, str; +{ +#ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS + static char *completer_quote_characters = NULL; + + rb_secure(4); + SafeStringValue(str); + if (completer_quote_characters == NULL) { + completer_quote_characters = + ALLOC_N(char, RSTRING(str)->len + 1); + } + else { + REALLOC_N(completer_quote_characters, char, RSTRING(str)->len + 1); + } + strncpy(completer_quote_characters, + RSTRING(str)->ptr, RSTRING(str)->len); + completer_quote_characters[RSTRING(str)->len] = '\0'; + rl_completer_quote_characters = completer_quote_characters; + + return self; +#else + rb_notimplement(); + return Qnil; /* not reached */ +#endif /* HAVE_RL_COMPLETER_QUOTE_CHARACTERS */ +} + +static VALUE +readline_s_get_completer_quote_characters(self, str) + VALUE self, str; +{ +#ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS + rb_secure(4); + if (rl_completer_quote_characters == NULL) + return Qnil; + return rb_tainted_str_new2(rl_completer_quote_characters); +#else + rb_notimplement(); + return Qnil; /* not reached */ +#endif /* HAVE_RL_COMPLETER_QUOTE_CHARACTERS */ +} + +static VALUE +readline_s_set_filename_quote_characters(self, str) + VALUE self, str; +{ +#ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS + static char *filename_quote_characters = NULL; + + rb_secure(4); + SafeStringValue(str); + if (filename_quote_characters == NULL) { + filename_quote_characters = + ALLOC_N(char, RSTRING(str)->len + 1); + } + else { + REALLOC_N(filename_quote_characters, char, RSTRING(str)->len + 1); + } + strncpy(filename_quote_characters, + RSTRING(str)->ptr, RSTRING(str)->len); + filename_quote_characters[RSTRING(str)->len] = '\0'; + rl_filename_quote_characters = filename_quote_characters; + + return self; +#else + rb_notimplement(); + return Qnil; /* not reached */ +#endif /* HAVE_RL_FILENAME_QUOTE_CHARACTERS */ +} + +static VALUE +readline_s_get_filename_quote_characters(self, str) + VALUE self, str; +{ +#ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS + rb_secure(4); + if (rl_filename_quote_characters == NULL) + return Qnil; + return rb_tainted_str_new2(rl_filename_quote_characters); +#else + rb_notimplement(); + return Qnil; /* not reached */ +#endif /* HAVE_RL_FILENAME_QUOTE_CHARACTERS */ +} + +static VALUE +hist_to_s(self) + VALUE self; +{ + return rb_str_new2("HISTORY"); +} + +static VALUE +hist_get(self, index) + VALUE self; + VALUE index; +{ + HIST_ENTRY *entry; + int i; + + rb_secure(4); + i = NUM2INT(index); + if (i < 0) { + i += history_length; + } + entry = history_get(history_base + i); + if (entry == NULL) { + rb_raise(rb_eIndexError, "invalid index"); + } + return rb_tainted_str_new2(entry->line); +} + +static VALUE +hist_set(self, index, str) + VALUE self; + VALUE index; + VALUE str; +{ +#ifdef HAVE_REPLACE_HISTORY_ENTRY + HIST_ENTRY *entry; + int i; + + rb_secure(4); + i = NUM2INT(index); + SafeStringValue(str); + if (i < 0) { + i += history_length; + } + entry = replace_history_entry(i, RSTRING(str)->ptr, NULL); + if (entry == NULL) { + rb_raise(rb_eIndexError, "invalid index"); + } + return str; +#else + rb_notimplement(); + return Qnil; /* not reached */ +#endif +} + +static VALUE +hist_push(self, str) + VALUE self; + VALUE str; +{ + rb_secure(4); + SafeStringValue(str); + add_history(RSTRING(str)->ptr); + return self; +} + +static VALUE +hist_push_method(argc, argv, self) + int argc; + VALUE *argv; + VALUE self; +{ + VALUE str; + + rb_secure(4); + while (argc--) { + str = *argv++; + SafeStringValue(str); + add_history(RSTRING(str)->ptr); + } + return self; +} + +static VALUE +rb_remove_history(index) + int index; +{ +#ifdef HAVE_REMOVE_HISTORY + HIST_ENTRY *entry; + VALUE val; + + rb_secure(4); + entry = remove_history(index); + if (entry) { + val = rb_tainted_str_new2(entry->line); + free(entry->line); + free(entry); + return val; + } + return Qnil; +#else + rb_notimplement(); + return Qnil; /* not reached */ +#endif +} + +static VALUE +hist_pop(self) + VALUE self; +{ + rb_secure(4); + if (history_length > 0) { + return rb_remove_history(history_length - 1); + } else { + return Qnil; + } +} + +static VALUE +hist_shift(self) + VALUE self; +{ + rb_secure(4); + if (history_length > 0) { + return rb_remove_history(0); + } else { + return Qnil; + } +} + +static VALUE +hist_each(self) + VALUE self; +{ + HIST_ENTRY *entry; + int i; + + rb_secure(4); + for (i = 0; i < history_length; i++) { + entry = history_get(history_base + i); + if (entry == NULL) + break; + rb_yield(rb_tainted_str_new2(entry->line)); + } + return self; +} + +static VALUE +hist_length(self) + VALUE self; +{ + rb_secure(4); + return INT2NUM(history_length); +} + +static VALUE +hist_empty_p(self) + VALUE self; +{ + rb_secure(4); + return history_length == 0 ? Qtrue : Qfalse; +} + +static VALUE +hist_delete_at(self, index) + VALUE self; + VALUE index; +{ + int i; + + rb_secure(4); + i = NUM2INT(index); + if (i < 0) + i += history_length; + if (i < 0 || i > history_length - 1) { + rb_raise(rb_eIndexError, "invalid index"); + } + return rb_remove_history(i); +} + +static VALUE +filename_completion_proc_call(self, str) + VALUE self; + VALUE str; +{ + VALUE result; + char **matches; + int i; + + matches = rl_completion_matches(StringValuePtr(str), + rl_filename_completion_function); + if (matches) { + result = rb_ary_new(); + for (i = 0; matches[i]; i++) { + rb_ary_push(result, rb_tainted_str_new2(matches[i])); + free(matches[i]); + } + free(matches); + if (RARRAY(result)->len >= 2) + rb_ary_shift(result); + } + else { + result = Qnil; + } + return result; +} + +static VALUE +username_completion_proc_call(self, str) + VALUE self; + VALUE str; +{ + VALUE result; + char **matches; + int i; + + matches = rl_completion_matches(StringValuePtr(str), + rl_username_completion_function); + if (matches) { + result = rb_ary_new(); + for (i = 0; matches[i]; i++) { + rb_ary_push(result, rb_tainted_str_new2(matches[i])); + free(matches[i]); + } + free(matches); + if (RARRAY(result)->len >= 2) + rb_ary_shift(result); + } + else { + result = Qnil; + } + return result; +} + +void +Init_readline() +{ + VALUE history, fcomp, ucomp; + + /* Allow conditional parsing of the ~/.inputrc file. */ + rl_readline_name = "Ruby"; + + using_history(); + + completion_proc = rb_intern(COMPLETION_PROC); + completion_case_fold = rb_intern(COMPLETION_CASE_FOLD); + + mReadline = rb_define_module("Readline"); + rb_define_module_function(mReadline, "readline", + readline_readline, -1); + rb_define_singleton_method(mReadline, "completion_proc=", + readline_s_set_completion_proc, 1); + rb_define_singleton_method(mReadline, "completion_proc", + readline_s_get_completion_proc, 0); + rb_define_singleton_method(mReadline, "completion_case_fold=", + readline_s_set_completion_case_fold, 1); + rb_define_singleton_method(mReadline, "completion_case_fold", + readline_s_get_completion_case_fold, 0); + rb_define_singleton_method(mReadline, "vi_editing_mode", + readline_s_vi_editing_mode, 0); + rb_define_singleton_method(mReadline, "emacs_editing_mode", + readline_s_emacs_editing_mode, 0); + rb_define_singleton_method(mReadline, "completion_append_character=", + readline_s_set_completion_append_character, 1); + rb_define_singleton_method(mReadline, "completion_append_character", + readline_s_get_completion_append_character, 0); + rb_define_singleton_method(mReadline, "basic_word_break_characters=", + readline_s_set_basic_word_break_characters, 1); + rb_define_singleton_method(mReadline, "basic_word_break_characters", + readline_s_get_basic_word_break_characters, 0); + rb_define_singleton_method(mReadline, "completer_word_break_characters=", + readline_s_set_completer_word_break_characters, 1); + rb_define_singleton_method(mReadline, "completer_word_break_characters", + readline_s_get_completer_word_break_characters, 0); + rb_define_singleton_method(mReadline, "basic_quote_characters=", + readline_s_set_basic_quote_characters, 1); + rb_define_singleton_method(mReadline, "basic_quote_characters", + readline_s_get_basic_quote_characters, 0); + rb_define_singleton_method(mReadline, "completer_quote_characters=", + readline_s_set_completer_quote_characters, 1); + rb_define_singleton_method(mReadline, "completer_quote_characters", + readline_s_get_completer_quote_characters, 0); + rb_define_singleton_method(mReadline, "filename_quote_characters=", + readline_s_set_filename_quote_characters, 1); + rb_define_singleton_method(mReadline, "filename_quote_characters", + readline_s_get_filename_quote_characters, 0); + + history = rb_obj_alloc(rb_cObject); + rb_extend_object(history, rb_mEnumerable); + rb_define_singleton_method(history,"to_s", hist_to_s, 0); + rb_define_singleton_method(history,"[]", hist_get, 1); + rb_define_singleton_method(history,"[]=", hist_set, 2); + rb_define_singleton_method(history,"<<", hist_push, 1); + rb_define_singleton_method(history,"push", hist_push_method, -1); + rb_define_singleton_method(history,"pop", hist_pop, 0); + rb_define_singleton_method(history,"shift", hist_shift, 0); + rb_define_singleton_method(history,"each", hist_each, 0); + rb_define_singleton_method(history,"length", hist_length, 0); + rb_define_singleton_method(history,"size", hist_length, 0); + rb_define_singleton_method(history,"empty?", hist_empty_p, 0); + rb_define_singleton_method(history,"delete_at", hist_delete_at, 1); + rb_define_const(mReadline, "HISTORY", history); + + fcomp = rb_obj_alloc(rb_cObject); + rb_define_singleton_method(fcomp, "call", + filename_completion_proc_call, 1); + rb_define_const(mReadline, "FILENAME_COMPLETION_PROC", fcomp); + + ucomp = rb_obj_alloc(rb_cObject); + rb_define_singleton_method(ucomp, "call", + username_completion_proc_call, 1); + rb_define_const(mReadline, "USERNAME_COMPLETION_PROC", ucomp); +#if defined HAVE_RL_LIBRARY_VERSION + rb_define_const(mReadline, "VERSION", rb_str_new2(rl_library_version)); +#else + rb_define_const(mReadline, "VERSION", + rb_str_new2("2.0 or before version")); +#endif + + rl_attempted_completion_function = readline_attempted_completion_function; +#ifdef HAVE_RL_EVENT_HOOK + rl_event_hook = readline_event; +#endif +#ifdef HAVE_RL_CLEAR_SIGNALS + rl_clear_signals(); +#endif +} |