Ruby 1.9.3p327(2012-11-10revision37606)
ext/readline/readline.c
Go to the documentation of this file.
00001 /************************************************
00002 
00003   readline.c - GNU Readline module
00004 
00005   $Author: nobu $
00006   created at: Wed Jan 20 13:59:32 JST 1999
00007 
00008   Copyright (C) 1997-2008  Shugo Maeda
00009   Copyright (C) 2008-2009  TAKAO Kouji
00010 
00011   $Id: readline.c 34505 2012-02-09 03:25:07Z nobu $
00012 
00013   Contact:
00014    - TAKAO Kouji <kouji at takao7 dot net> (current maintainer)
00015 
00016 ************************************************/
00017 
00018 #ifdef RUBY_EXTCONF_H
00019 #include RUBY_EXTCONF_H
00020 #endif
00021 
00022 #include "ruby/config.h"
00023 #include <errno.h>
00024 #include <stdio.h>
00025 #include <string.h>
00026 #ifdef HAVE_READLINE_READLINE_H
00027 #include <readline/readline.h>
00028 #endif
00029 #ifdef HAVE_READLINE_HISTORY_H
00030 #include <readline/history.h>
00031 #endif
00032 #ifdef HAVE_EDITLINE_READLINE_H
00033 #include <editline/readline.h>
00034 #endif
00035 
00036 #include "ruby/ruby.h"
00037 #include "ruby/io.h"
00038 
00039 #ifdef HAVE_UNISTD_H
00040 #include <unistd.h>
00041 #endif
00042 
00043 #ifdef HAVE_SYS_STAT_H
00044 #include <sys/stat.h>
00045 #endif
00046 
00047 static VALUE mReadline;
00048 
00049 #define EDIT_LINE_LIBRARY_VERSION "EditLine wrapper"
00050 #ifndef USE_INSERT_IGNORE_ESCAPE
00051 # if !defined(HAVE_EDITLINE_READLINE_H) && defined(HAVE_RL_PROMPT_START_IGNORE) && defined(HAVE_RL_PROMPT_END_IGNORE)
00052 #  define USE_INSERT_IGNORE_ESCAPE 1
00053 # else
00054 #  define USE_INSERT_IGNORE_ESCAPE 0
00055 # endif
00056 #endif
00057 
00058 #define COMPLETION_PROC "completion_proc"
00059 #define COMPLETION_CASE_FOLD "completion_case_fold"
00060 static ID completion_proc, completion_case_fold;
00061 #if USE_INSERT_IGNORE_ESCAPE
00062 static ID id_orig_prompt, id_last_prompt;
00063 #endif
00064 
00065 #ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION
00066 # define rl_filename_completion_function filename_completion_function
00067 #endif
00068 #ifndef HAVE_RL_USERNAME_COMPLETION_FUNCTION
00069 # define rl_username_completion_function username_completion_function
00070 #endif
00071 #ifndef HAVE_RL_COMPLETION_MATCHES
00072 # define rl_completion_matches completion_matches
00073 #endif
00074 
00075 static int (*history_get_offset_func)(int);
00076 static int (*history_replace_offset_func)(int);
00077 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
00078 static int readline_completion_append_character;
00079 #endif
00080 
00081 static char **readline_attempted_completion_function(const char *text,
00082                                                      int start, int end);
00083 
00084 #define OutputStringValue(str) do {\
00085     SafeStringValue(str);\
00086     (str) = rb_str_conv_enc((str), rb_enc_get(str), rb_locale_encoding());\
00087 } while (0)\
00088 
00089 
00090 /*
00091  * Document-class: Readline
00092  *
00093  * The Readline module provides interface for GNU Readline.
00094  * This module defines a number of methods to facilitate completion
00095  * and accesses input history from the Ruby interpreter.
00096  * This module supported Edit Line(libedit) too.
00097  * libedit is compatible with GNU Readline.
00098  *
00099  * GNU Readline:: http://www.gnu.org/directory/readline.html
00100  * libedit::      http://www.thrysoee.dk/editline/
00101  *
00102  * Reads one inputted line with line edit by Readline.readline method.
00103  * At this time, the facilitatation completion and the key
00104  * bind like Emacs can be operated like GNU Readline.
00105  *
00106  *   require "readline"
00107  *   while buf = Readline.readline("> ", true)
00108  *     p buf
00109  *   end
00110  *
00111  * The content that the user input can be recorded to the history.
00112  * The history can be accessed by Readline::HISTORY constant.
00113  *
00114  *   require "readline"
00115  *   while buf = Readline.readline("> ", true)
00116  *     p Readline::HISTORY.to_a
00117  *     print("-> ", buf, "\n")
00118  *   end
00119  *
00120  * Most of methods raise SecurityError exception if $SAFE is 4.
00121  *
00122  * Documented by TAKAO Kouji <kouji at takao7 dot net>.
00123  */
00124 
00125 #if defined HAVE_RL_GETC_FUNCTION
00126 static VALUE readline_instream;
00127 static ID id_getbyte;
00128 
00129 #ifndef HAVE_RL_GETC
00130 #define rl_getc(f) EOF
00131 #endif
00132 
00133 static int readline_getc(FILE *);
00134 static int
00135 readline_getc(FILE *input)
00136 {
00137     rb_io_t *ifp = 0;
00138     VALUE c;
00139     if (!readline_instream) return rl_getc(input);
00140     GetOpenFile(readline_instream, ifp);
00141     if (rl_instream != ifp->stdio_file) return rl_getc(input);
00142 #if defined(_WIN32)
00143     {
00144         INPUT_RECORD ir;
00145         int n;
00146         static int prior_key = '0';
00147         for (;;) {
00148             if (prior_key > 0xff) {
00149                 prior_key = rl_getc(ifp->stdio_file);
00150                 return prior_key;
00151             }
00152             if (PeekConsoleInput((HANDLE)_get_osfhandle(ifp->fd), &ir, 1, &n)) {
00153                 if (n == 1) {
00154                     if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown) {
00155                         prior_key = rl_getc(ifp->stdio_file);
00156                         return prior_key;
00157                     } else {
00158                         ReadConsoleInput((HANDLE)_get_osfhandle(ifp->fd), &ir, 1, &n);
00159                     }
00160                 } else {
00161                     HANDLE h = (HANDLE)_get_osfhandle(ifp->fd);
00162                     rb_w32_wait_events(&h, 1, INFINITE);
00163                 }
00164             } else {
00165                 break;
00166             }
00167         }
00168     }
00169 #endif
00170     c = rb_funcall(readline_instream, id_getbyte, 0, 0);
00171     if (NIL_P(c)) return EOF;
00172     return NUM2CHR(c);
00173 }
00174 #elif defined HAVE_RL_EVENT_HOOK
00175 #define BUSY_WAIT 0
00176 
00177 static int readline_event(void);
00178 static int
00179 readline_event(void)
00180 {
00181 #if BUSY_WAIT
00182     rb_thread_schedule();
00183 #else
00184     rb_wait_for_single_fd(fileno(rl_instream), RB_WAITFD_IN, NULL);
00185     return 0;
00186 #endif
00187 }
00188 #endif
00189 
00190 #if USE_INSERT_IGNORE_ESCAPE
00191 static VALUE
00192 insert_ignore_escape(VALUE self, VALUE prompt)
00193 {
00194     VALUE last_prompt, orig_prompt = rb_attr_get(self, id_orig_prompt);
00195     int ignoring = 0;
00196     const char *s0, *s, *e;
00197     long len;
00198     static const char ignore_code[2] = {RL_PROMPT_START_IGNORE, RL_PROMPT_END_IGNORE};
00199 
00200     prompt = rb_str_new_shared(prompt);
00201     last_prompt = rb_attr_get(self, id_last_prompt);
00202     if (orig_prompt == prompt) return last_prompt;
00203     len = RSTRING_LEN(prompt);
00204     if (NIL_P(last_prompt)) {
00205         last_prompt = rb_str_tmp_new(len);
00206     }
00207 
00208     s = s0 = RSTRING_PTR(prompt);
00209     e = s0 + len;
00210     rb_str_set_len(last_prompt, 0);
00211     while (s < e && *s) {
00212         switch (*s) {
00213           case RL_PROMPT_START_IGNORE:
00214             ignoring = -1;
00215             rb_str_cat(last_prompt, s0, ++s - s0);
00216             s0 = s;
00217             break;
00218           case RL_PROMPT_END_IGNORE:
00219             ignoring = 0;
00220             rb_str_cat(last_prompt, s0, ++s - s0);
00221             s0 = s;
00222             break;
00223           case '\033':
00224             if (++s < e && *s == '[') {
00225                 rb_str_cat(last_prompt, s0, s - s0 - 1);
00226                 s0 = s - 1;
00227                 while (++s < e && *s) {
00228                     if (ISALPHA(*s)) {
00229                         if (!ignoring) {
00230                             ignoring = 1;
00231                             rb_str_cat(last_prompt, ignore_code+0, 1);
00232                         }
00233                         rb_str_cat(last_prompt, s0, ++s - s0);
00234                         s0 = s;
00235                         break;
00236                     }
00237                     else if (!('0' <= *s && *s <= '9' || *s == ';')) {
00238                         break;
00239                     }
00240                 }
00241             }
00242             break;
00243           default:
00244             if (ignoring > 0) {
00245                 ignoring = 0;
00246                 rb_str_cat(last_prompt, ignore_code+1, 1);
00247             }
00248             s++;
00249             break;
00250         }
00251     }
00252     if (ignoring > 0) {
00253         ignoring = 0;
00254         rb_str_cat(last_prompt, ignore_code+1, 1);
00255     }
00256     rb_str_cat(last_prompt, s0, s - s0);
00257 
00258     rb_ivar_set(self, id_orig_prompt, prompt);
00259     rb_ivar_set(self, id_last_prompt, last_prompt);
00260 
00261     return last_prompt;
00262 }
00263 #endif
00264 
00265 static VALUE
00266 readline_get(VALUE prompt)
00267 {
00268 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
00269     readline_completion_append_character = rl_completion_append_character;
00270 #endif
00271     return (VALUE)readline((char *)prompt);
00272 }
00273 
00274 /*
00275  * call-seq:
00276  *   Readline.readline(prompt = "", add_hist = false) -> string or nil
00277  *
00278  * Shows the +prompt+ and reads the inputted line with line editing.
00279  * The inputted line is added to the history if +add_hist+ is true.
00280  *
00281  * Returns nil when the inputted line is empty and user inputs EOF
00282  * (Presses ^D on UNIX).
00283  *
00284  * Raises IOError exception if below conditions are satisfied.
00285  * 1. stdin is not tty.
00286  * 2. stdin was closed. (errno is EBADF after called isatty(2).)
00287  *
00288  * This method supports thread. Switchs the thread context when waits
00289  * inputting line.
00290  *
00291  * Supports line edit when inputs line. Provides VI and Emacs editing mode.
00292  * Default is Emacs editing mode.
00293  *
00294  * NOTE: Terminates ruby interpreter and does not return the terminal
00295  * status after user pressed '^C' when wait inputting line.
00296  * Give 3 examples that avoid it.
00297  *
00298  * * Catches the Interrupt exception by pressed ^C after returns
00299  *   terminal status:
00300  *
00301  *     require "readline"
00302  *
00303  *     stty_save = `stty -g`.chomp
00304  *     begin
00305  *       while buf = Readline.readline
00306  *           p buf
00307  *           end
00308  *         rescue Interrupt
00309  *           system("stty", stty_save)
00310  *           exit
00311  *         end
00312  *       end
00313  *     end
00314  *
00315  * * Catches the INT signal by pressed ^C after returns terminal
00316  *   status:
00317  *
00318  *     require "readline"
00319  *
00320  *     stty_save = `stty -g`.chomp
00321  *     trap("INT") { system "stty", stty_save; exit }
00322  *
00323  *     while buf = Readline.readline
00324  *       p buf
00325  *     end
00326  *
00327  * * Ignores pressing ^C:
00328  *
00329  *     require "readline"
00330  *
00331  *     trap("INT", "SIG_IGN")
00332  *
00333  *     while buf = Readline.readline
00334  *       p buf
00335  *     end
00336  *
00337  * Can make as follows with Readline::HISTORY constant.
00338  * It does not record to the history if the inputted line is empty or
00339  * the same it as last one.
00340  *
00341  *   require "readline"
00342  *
00343  *   while buf = Readline.readline("> ", true)
00344  *     # p Readline::HISTORY.to_a
00345  *     Readline::HISTORY.pop if /^\s*$/ =~ buf
00346  *
00347  *     begin
00348  *       if Readline::HISTORY[Readline::HISTORY.length-2] == buf
00349  *         Readline::HISTORY.pop
00350  *       end
00351  *     rescue IndexError
00352  *     end
00353  *
00354  *     # p Readline::HISTORY.to_a
00355  *     print "-> ", buf, "\n"
00356  *   end
00357  *
00358  * Raises SecurityError exception if $SAFE is 4.
00359  */
00360 static VALUE
00361 readline_readline(int argc, VALUE *argv, VALUE self)
00362 {
00363     VALUE tmp, add_hist, result;
00364     char *prompt = NULL;
00365     char *buff;
00366     int status;
00367 
00368     rb_secure(4);
00369     if (rb_scan_args(argc, argv, "02", &tmp, &add_hist) > 0) {
00370         OutputStringValue(tmp);
00371 #if USE_INSERT_IGNORE_ESCAPE
00372         tmp = insert_ignore_escape(self, tmp);
00373         rb_str_locktmp(tmp);
00374 #endif
00375         prompt = RSTRING_PTR(tmp);
00376     }
00377 
00378     if (!isatty(fileno(rl_instream)) && errno == EBADF) rb_raise(rb_eIOError, "closed stdin");
00379     if (rl_outstream) {
00380         struct stat stbuf;
00381         int fd = fileno(rl_outstream);
00382         if (fd < 0 || fstat(fd, &stbuf) != 0) {
00383             rb_raise(rb_eIOError, "closed stdout");
00384         }
00385     }
00386 
00387 #ifdef _WIN32
00388     rl_prep_terminal(1);
00389 #endif
00390     buff = (char*)rb_protect(readline_get, (VALUE)prompt, &status);
00391 #if USE_INSERT_IGNORE_ESCAPE
00392     if (prompt) {
00393         rb_str_unlocktmp(tmp);
00394     }
00395 #endif
00396     if (status) {
00397 #if defined HAVE_RL_CLEANUP_AFTER_SIGNAL
00398         /* restore terminal mode and signal handler*/
00399 #if defined HAVE_RL_FREE_LINE_STATE
00400         rl_free_line_state();
00401 #endif
00402         rl_cleanup_after_signal();
00403 #elif defined HAVE_RL_DEPREP_TERM_FUNCTION
00404         /* restore terminal mode */
00405         if (rl_deprep_term_function != NULL) /* NULL in libedit. [ruby-dev:29116] */
00406             (*rl_deprep_term_function)();
00407         else
00408 #else
00409         rl_deprep_terminal();
00410 #endif
00411         rb_jump_tag(status);
00412     }
00413 
00414     if (RTEST(add_hist) && buff) {
00415         add_history(buff);
00416     }
00417     if (buff) {
00418         result = rb_locale_str_new_cstr(buff);
00419     }
00420     else
00421         result = Qnil;
00422     if (buff) free(buff);
00423     return result;
00424 }
00425 
00426 /*
00427  * call-seq:
00428  *   Readline.input = input
00429  *
00430  * Specifies a File object +input+ that is input stream for
00431  * Readline.readline method.
00432  *
00433  * Raises SecurityError exception if $SAFE is 4.
00434  */
00435 static VALUE
00436 readline_s_set_input(VALUE self, VALUE input)
00437 {
00438     rb_io_t *ifp;
00439 
00440     rb_secure(4);
00441     Check_Type(input, T_FILE);
00442     GetOpenFile(input, ifp);
00443     rl_instream = rb_io_stdio_file(ifp);
00444 #ifdef HAVE_RL_GETC_FUNCTION
00445     readline_instream = input;
00446 #endif
00447     return input;
00448 }
00449 
00450 /*
00451  * call-seq:
00452  *   Readline.output = output
00453  *
00454  * Specifies a File object +output+ that is output stream for
00455  * Readline.readline method.
00456  *
00457  * Raises SecurityError exception if $SAFE is 4.
00458  */
00459 static VALUE
00460 readline_s_set_output(VALUE self, VALUE output)
00461 {
00462     rb_io_t *ofp;
00463 
00464     rb_secure(4);
00465     Check_Type(output, T_FILE);
00466     GetOpenFile(output, ofp);
00467     rl_outstream = rb_io_stdio_file(ofp);
00468     return output;
00469 }
00470 
00471 /*
00472  * call-seq:
00473  *   Readline.completion_proc = proc
00474  *
00475  * Specifies a Proc object +proc+ to determine completion behavior.  It
00476  * should take input string and return an array of completion candidates.
00477  *
00478  * The default completion is used if +proc+ is nil.
00479  *
00480  * The String that is passed to the Proc depends on the
00481  * Readline.completer_word_break_characters property.  By default the word
00482  * under the cursor is passed to the Proc.  For example, if the input is "foo
00483  * bar" then only "bar" would be passed to the completion Proc.
00484  *
00485  * Upon successful completion the Readline.completion_append_character will be
00486  * appended to the input so the user can start working on their next argument.
00487  *
00488  * = Examples
00489  *
00490  * == Completion for a Static List
00491  *
00492  *   require 'readline'
00493  *
00494  *   LIST = [
00495  *     'search', 'download', 'open',
00496  *     'help', 'history', 'quit',
00497  *     'url', 'next', 'clear',
00498  *     'prev', 'past'
00499  *   ].sort
00500  *
00501  *   comp = proc { |s| LIST.grep(/^#{Regexp.escape(s)}/) }
00502  *
00503  *   Readline.completion_append_character = " "
00504  *   Readline.completion_proc = comp
00505  *
00506  *   while line = Readline.readline('> ', true)
00507  *     p line
00508  *   end
00509  *
00510  * == Completion For Directory Contents
00511  *
00512  *   require 'readline'
00513  *
00514  *   Readline.completion_append_character = " "
00515  *   Readline.completion_proc = Proc.new do |str|
00516  *     Dir[str+'*'].grep(/^#{Regexp.escape(str)}/)
00517  *   end
00518  *
00519  *   while line = Readline.readline('> ', true)
00520  *     p line
00521  *   end
00522  *
00523  * = Autocomplete strategies
00524  *
00525  * When working with auto-complete there are some strategies that work well.
00526  * To get some ideas you can take a look at the
00527  * completion.rb[http://svn.ruby-lang.org/repos/ruby/trunk/lib/irb/completion.rb]
00528  * file for irb.
00529  *
00530  * The common strategy is to take a list of possible completions and filter it
00531  * down to those completions that start with the user input.  In the above
00532  * examples Enumerator.grep is used.  The input is escaped to prevent Regexp
00533  * special characters from interfering with the matching.
00534  *
00535  * It may also be helpful to use the Abbrev library to generate completions.
00536  *
00537  * Raises ArgumentError if +proc+ does not respond to the call method.
00538  *
00539  * Raises SecurityError if $SAFE is 4.
00540  */
00541 static VALUE
00542 readline_s_set_completion_proc(VALUE self, VALUE proc)
00543 {
00544     rb_secure(4);
00545     if (!NIL_P(proc) && !rb_respond_to(proc, rb_intern("call")))
00546         rb_raise(rb_eArgError, "argument must respond to `call'");
00547     return rb_ivar_set(mReadline, completion_proc, proc);
00548 }
00549 
00550 /*
00551  * call-seq:
00552  *   Readline.completion_proc -> proc
00553  *
00554  * Returns the completion Proc object.
00555  *
00556  * Raises SecurityError exception if $SAFE is 4.
00557  */
00558 static VALUE
00559 readline_s_get_completion_proc(VALUE self)
00560 {
00561     rb_secure(4);
00562     return rb_attr_get(mReadline, completion_proc);
00563 }
00564 
00565 /*
00566  * call-seq:
00567  *   Readline.completion_case_fold = bool
00568  *
00569  * Sets whether or not to ignore case on completion.
00570  *
00571  * Raises SecurityError exception if $SAFE is 4.
00572  */
00573 static VALUE
00574 readline_s_set_completion_case_fold(VALUE self, VALUE val)
00575 {
00576     rb_secure(4);
00577     return rb_ivar_set(mReadline, completion_case_fold, val);
00578 }
00579 
00580 /*
00581  * call-seq:
00582  *   Readline.completion_case_fold -> bool
00583  *
00584  * Returns true if completion ignores case. If no, returns false.
00585  *
00586  * NOTE: Returns the same object that is specified by
00587  * Readline.completion_case_fold= method.
00588  *
00589  *   require "readline"
00590  *
00591  *   Readline.completion_case_fold = "This is a String."
00592  *   p Readline.completion_case_fold # => "This is a String."
00593  *
00594  * Raises SecurityError exception if $SAFE is 4.
00595  */
00596 static VALUE
00597 readline_s_get_completion_case_fold(VALUE self)
00598 {
00599     rb_secure(4);
00600     return rb_attr_get(mReadline, completion_case_fold);
00601 }
00602 
00603 #ifdef HAVE_RL_LINE_BUFFER
00604 /*
00605  * call-seq:
00606  *   Readline.line_buffer -> string
00607  *
00608  * Returns the full line that is being edited. This is useful from
00609  * within the complete_proc for determining the context of the
00610  * completion request.
00611  *
00612  * The length of +Readline.line_buffer+ and GNU Readline's rl_end are
00613  * same.
00614  */
00615 static VALUE
00616 readline_s_get_line_buffer(VALUE self)
00617 {
00618     rb_secure(4);
00619     if (rl_line_buffer == NULL)
00620         return Qnil;
00621     return rb_locale_str_new_cstr(rl_line_buffer);
00622 }
00623 #else
00624 #define readline_s_get_line_buffer rb_f_notimplement
00625 #endif
00626 
00627 #ifdef HAVE_RL_POINT
00628 /*
00629  * call-seq:
00630  *   Readline.point -> int
00631  *
00632  * Returns the index of the current cursor position in
00633  * +Readline.line_buffer+.
00634  *
00635  * The index in +Readline.line_buffer+ which matches the start of
00636  * input-string passed to completion_proc is computed by subtracting
00637  * the length of input-string from +Readline.point+.
00638  *
00639  *   start = (the length of input-string) - Readline.point
00640  */
00641 static VALUE
00642 readline_s_get_point(VALUE self)
00643 {
00644     rb_secure(4);
00645     return INT2NUM(rl_point);
00646 }
00647 #else
00648 #define readline_s_get_point rb_f_notimplement
00649 #endif
00650 
00651 static char **
00652 readline_attempted_completion_function(const char *text, int start, int end)
00653 {
00654     VALUE proc, ary, temp;
00655     char **result;
00656     int case_fold;
00657     long i, matches;
00658     rb_encoding *enc;
00659     VALUE encobj;
00660 
00661     proc = rb_attr_get(mReadline, completion_proc);
00662     if (NIL_P(proc))
00663         return NULL;
00664 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
00665     rl_completion_append_character = readline_completion_append_character;
00666 #endif
00667 #ifdef HAVE_RL_ATTEMPTED_COMPLETION_OVER
00668     rl_attempted_completion_over = 1;
00669 #endif
00670     case_fold = RTEST(rb_attr_get(mReadline, completion_case_fold));
00671     ary = rb_funcall(proc, rb_intern("call"), 1, rb_locale_str_new_cstr(text));
00672     if (!RB_TYPE_P(ary, T_ARRAY))
00673         ary = rb_Array(ary);
00674     matches = RARRAY_LEN(ary);
00675     if (matches == 0) return NULL;
00676     result = (char**)malloc((matches + 2)*sizeof(char*));
00677     if (result == NULL) rb_raise(rb_eNoMemError, "failed to allocate memory");
00678     enc = rb_locale_encoding();
00679     encobj = rb_enc_from_encoding(enc);
00680     for (i = 0; i < matches; i++) {
00681         temp = rb_obj_as_string(RARRAY_PTR(ary)[i]);
00682         StringValueCStr(temp);  /* must be NUL-terminated */
00683         rb_enc_check(encobj, temp);
00684         result[i + 1] = (char*)malloc(RSTRING_LEN(temp) + 1);
00685         if (result[i + 1]  == NULL) rb_memerror();
00686         strcpy(result[i + 1], RSTRING_PTR(temp));
00687     }
00688     result[matches + 1] = NULL;
00689 
00690     if (matches == 1) {
00691         result[0] = strdup(result[1]);
00692     }
00693     else {
00694         const char *result1 = result[1];
00695         long low = strlen(result1);
00696 
00697         for (i = 1; i < matches; ++i) {
00698             register int c1, c2;
00699             long i1, i2, l2;
00700             int n1, n2;
00701             const char *p2 = result[i + 1];
00702 
00703             l2 = strlen(p2);
00704             for (i1 = i2 = 0; i1 < low && i2 < l2; i1 += n1, i2 += n2) {
00705                 c1 = rb_enc_codepoint_len(result1 + i1, result1 + low, &n1, enc);
00706                 c2 = rb_enc_codepoint_len(p2 + i2, p2 + l2, &n2, enc);
00707                 if (case_fold) {
00708                     c1 = rb_tolower(c1);
00709                     c2 = rb_tolower(c2);
00710                 }
00711                 if (c1 != c2) break;
00712             }
00713 
00714             low = i1;
00715         }
00716         result[0] = ALLOC_N(char, low + 1);
00717         strncpy(result[0], result[1], low);
00718         result[0][low] = '\0';
00719     }
00720 
00721     return result;
00722 }
00723 
00724 #ifdef HAVE_RL_SET_SCREEN_SIZE
00725 /*
00726  * call-seq:
00727  *   Readline.set_screen_size(rows, columns) -> self
00728  *
00729  * Set terminal size to +rows+ and +columns+.
00730  *
00731  * See GNU Readline's rl_set_screen_size function.
00732  *
00733  * Raises NotImplementedError if the using readline library does not support.
00734  *
00735  * Raises SecurityError exception if $SAFE is 4.
00736  */
00737 static VALUE
00738 readline_s_set_screen_size(VALUE self, VALUE rows, VALUE columns)
00739 {
00740     rb_secure(4);
00741     rl_set_screen_size(NUM2INT(rows), NUM2INT(columns));
00742     return self;
00743 }
00744 #else
00745 #define readline_s_set_screen_size rb_f_notimplement
00746 #endif
00747 
00748 #ifdef HAVE_RL_GET_SCREEN_SIZE
00749 /*
00750  * call-seq:
00751  *   Readline.get_screen_size -> [rows, columns]
00752  *
00753  * Returns the terminal's rows and columns.
00754  *
00755  * See GNU Readline's rl_get_screen_size function.
00756  *
00757  * Raises NotImplementedError if the using readline library does not support.
00758  *
00759  * Raises SecurityError exception if $SAFE is 4.
00760  */
00761 static VALUE
00762 readline_s_get_screen_size(VALUE self)
00763 {
00764     int rows, columns;
00765     VALUE res;
00766 
00767     rb_secure(4);
00768     rl_get_screen_size(&rows, &columns);
00769     res = rb_ary_new();
00770     rb_ary_push(res, INT2NUM(rows));
00771     rb_ary_push(res, INT2NUM(columns));
00772     return res;
00773 }
00774 #else
00775 #define readline_s_get_screen_size rb_f_notimplement
00776 #endif
00777 
00778 #ifdef HAVE_RL_VI_EDITING_MODE
00779 /*
00780  * call-seq:
00781  *   Readline.vi_editing_mode -> nil
00782  *
00783  * Specifies VI editing mode. See the manual of GNU Readline for
00784  * details of VI editing mode.
00785  *
00786  * Raises NotImplementedError if the using readline library does not support.
00787  *
00788  * Raises SecurityError exception if $SAFE is 4.
00789  */
00790 static VALUE
00791 readline_s_vi_editing_mode(VALUE self)
00792 {
00793     rb_secure(4);
00794     rl_vi_editing_mode(1,0);
00795     return Qnil;
00796 }
00797 #else
00798 #define readline_s_vi_editing_mode rb_f_notimplement
00799 #endif
00800 
00801 #ifdef HAVE_RL_EDITING_MODE
00802 /*
00803  * call-seq:
00804  *   Readline.vi_editing_mode? -> bool
00805  *
00806  * Returns true if vi mode is active. Returns false if not.
00807  *
00808  * Raises NotImplementedError if the using readline library does not support.
00809  *
00810  * Raises SecurityError exception if $SAFE is 4.
00811  */
00812 static VALUE
00813 readline_s_vi_editing_mode_p(VALUE self)
00814 {
00815     rb_secure(4);
00816     return rl_editing_mode == 0 ? Qtrue : Qfalse;
00817 }
00818 #else
00819 #define readline_s_vi_editing_mode_p rb_f_notimplement
00820 #endif
00821 
00822 #ifdef HAVE_RL_EMACS_EDITING_MODE
00823 /*
00824  * call-seq:
00825  *   Readline.emacs_editing_mode -> nil
00826  *
00827  * Specifies Emacs editing mode. The default is this mode. See the
00828  * manual of GNU Readline for details of Emacs editing mode.
00829  *
00830  * Raises NotImplementedError if the using readline library does not support.
00831  *
00832  * Raises SecurityError exception if $SAFE is 4.
00833  */
00834 static VALUE
00835 readline_s_emacs_editing_mode(VALUE self)
00836 {
00837     rb_secure(4);
00838     rl_emacs_editing_mode(1,0);
00839     return Qnil;
00840 }
00841 #else
00842 #define readline_s_emacs_editing_mode rb_f_notimplement
00843 #endif
00844 
00845 #ifdef  HAVE_RL_EDITING_MODE
00846 /*
00847  * call-seq:
00848  *   Readline.emacs_editing_mode? -> bool
00849  *
00850  * Returns true if emacs mode is active. Returns false if not.
00851  *
00852  * Raises NotImplementedError if the using readline library does not support.
00853  *
00854  * Raises SecurityError exception if $SAFE is 4.
00855  */
00856 static VALUE
00857 readline_s_emacs_editing_mode_p(VALUE self)
00858 {
00859     rb_secure(4);
00860     return rl_editing_mode == 1 ? Qtrue : Qfalse;
00861 }
00862 #else
00863 #define readline_s_emacs_editing_mode_p rb_f_notimplement
00864 #endif
00865 
00866 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
00867 /*
00868  * call-seq:
00869  *   Readline.completion_append_character = char
00870  *
00871  * Specifies a character to be appended on completion.
00872  * Nothing will be appended if an empty string ("") or nil is
00873  * specified.
00874  *
00875  * For example:
00876  *   require "readline"
00877  *
00878  *   Readline.readline("> ", true)
00879  *   Readline.completion_append_character = " "
00880  *
00881  * Result:
00882  *   >
00883  *   Input "/var/li".
00884  *
00885  *   > /var/li
00886  *   Press TAB key.
00887  *
00888  *   > /var/lib
00889  *   Completes "b" and appends " ". So, you can continuously input "/usr".
00890  *
00891  *   > /var/lib /usr
00892  *
00893  * NOTE: Only one character can be specified. When "string" is
00894  * specified, sets only "s" that is the first.
00895  *
00896  *   require "readline"
00897  *
00898  *   Readline.completion_append_character = "string"
00899  *   p Readline.completion_append_character # => "s"
00900  *
00901  * Raises NotImplementedError if the using readline library does not support.
00902  *
00903  * Raises SecurityError exception if $SAFE is 4.
00904  */
00905 static VALUE
00906 readline_s_set_completion_append_character(VALUE self, VALUE str)
00907 {
00908     rb_secure(4);
00909     if (NIL_P(str)) {
00910         rl_completion_append_character = '\0';
00911     }
00912     else {
00913         OutputStringValue(str);
00914         if (RSTRING_LEN(str) == 0) {
00915             rl_completion_append_character = '\0';
00916         } else {
00917             rl_completion_append_character = RSTRING_PTR(str)[0];
00918         }
00919     }
00920     return self;
00921 }
00922 #else
00923 #define readline_s_set_completion_append_character rb_f_notimplement
00924 #endif
00925 
00926 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
00927 /*
00928  * call-seq:
00929  *   Readline.completion_append_character -> char
00930  *
00931  * Returns a string containing a character to be appended on
00932  * completion. The default is a space (" ").
00933  *
00934  * Raises NotImplementedError if the using readline library does not support.
00935  *
00936  * Raises SecurityError exception if $SAFE is 4.
00937  */
00938 static VALUE
00939 readline_s_get_completion_append_character(VALUE self)
00940 {
00941     char buf[1];
00942 
00943     rb_secure(4);
00944     if (rl_completion_append_character == '\0')
00945         return Qnil;
00946 
00947     buf[0] = (char) rl_completion_append_character;
00948     return rb_locale_str_new(buf, 1);
00949 }
00950 #else
00951 #define readline_s_get_completion_append_character rb_f_notimplement
00952 #endif
00953 
00954 #ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS
00955 /*
00956  * call-seq:
00957  *   Readline.basic_word_break_characters = string
00958  *
00959  * Sets the basic list of characters that signal a break between words
00960  * for the completer routine. The default is the characters which
00961  * break words for completion in Bash: "\t\n\"\\'`@$><=;|&{(".
00962  *
00963  * Raises NotImplementedError if the using readline library does not support.
00964  *
00965  * Raises SecurityError exception if $SAFE is 4.
00966  */
00967 static VALUE
00968 readline_s_set_basic_word_break_characters(VALUE self, VALUE str)
00969 {
00970     static char *basic_word_break_characters = NULL;
00971 
00972     rb_secure(4);
00973     OutputStringValue(str);
00974     if (basic_word_break_characters == NULL) {
00975         basic_word_break_characters =
00976             ALLOC_N(char, RSTRING_LEN(str) + 1);
00977     }
00978     else {
00979         REALLOC_N(basic_word_break_characters, char, RSTRING_LEN(str) + 1);
00980     }
00981     strncpy(basic_word_break_characters,
00982             RSTRING_PTR(str), RSTRING_LEN(str));
00983     basic_word_break_characters[RSTRING_LEN(str)] = '\0';
00984     rl_basic_word_break_characters = basic_word_break_characters;
00985     return self;
00986 }
00987 #else
00988 #define readline_s_set_basic_word_break_characters rb_f_notimplement
00989 #endif
00990 
00991 #ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS
00992 /*
00993  * call-seq:
00994  *   Readline.basic_word_break_characters -> string
00995  *
00996  * Gets the basic list of characters that signal a break between words
00997  * for the completer routine.
00998  *
00999  * Raises NotImplementedError if the using readline library does not support.
01000  *
01001  * Raises SecurityError exception if $SAFE is 4.
01002  */
01003 static VALUE
01004 readline_s_get_basic_word_break_characters(VALUE self, VALUE str)
01005 {
01006     rb_secure(4);
01007     if (rl_basic_word_break_characters == NULL)
01008         return Qnil;
01009     return rb_locale_str_new_cstr(rl_basic_word_break_characters);
01010 }
01011 #else
01012 #define readline_s_get_basic_word_break_characters rb_f_notimplement
01013 #endif
01014 
01015 #ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS
01016 /*
01017  * call-seq:
01018  *   Readline.completer_word_break_characters = string
01019  *
01020  * Sets the basic list of characters that signal a break between words
01021  * for rl_complete_internal(). The default is the value of
01022  * Readline.basic_word_break_characters.
01023  *
01024  * Raises NotImplementedError if the using readline library does not support.
01025  *
01026  * Raises SecurityError exception if $SAFE is 4.
01027  */
01028 static VALUE
01029 readline_s_set_completer_word_break_characters(VALUE self, VALUE str)
01030 {
01031     static char *completer_word_break_characters = NULL;
01032 
01033     rb_secure(4);
01034     OutputStringValue(str);
01035     if (completer_word_break_characters == NULL) {
01036         completer_word_break_characters =
01037             ALLOC_N(char, RSTRING_LEN(str) + 1);
01038     }
01039     else {
01040         REALLOC_N(completer_word_break_characters, char, RSTRING_LEN(str) + 1);
01041     }
01042     strncpy(completer_word_break_characters,
01043             RSTRING_PTR(str), RSTRING_LEN(str));
01044     completer_word_break_characters[RSTRING_LEN(str)] = '\0';
01045     rl_completer_word_break_characters = completer_word_break_characters;
01046     return self;
01047 }
01048 #else
01049 #define readline_s_set_completer_word_break_characters rb_f_notimplement
01050 #endif
01051 
01052 #ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS
01053 /*
01054  * call-seq:
01055  *   Readline.completer_word_break_characters -> string
01056  *
01057  * Gets the basic list of characters that signal a break between words
01058  * for rl_complete_internal().
01059  *
01060  * Raises NotImplementedError if the using readline library does not support.
01061  *
01062  * Raises SecurityError exception if $SAFE is 4.
01063  */
01064 static VALUE
01065 readline_s_get_completer_word_break_characters(VALUE self, VALUE str)
01066 {
01067     rb_secure(4);
01068     if (rl_completer_word_break_characters == NULL)
01069         return Qnil;
01070     return rb_locale_str_new_cstr(rl_completer_word_break_characters);
01071 }
01072 #else
01073 #define readline_s_get_completer_word_break_characters rb_f_notimplement
01074 #endif
01075 
01076 #ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS
01077 /*
01078  * call-seq:
01079  *   Readline.basic_quote_characters = string
01080  *
01081  * Sets a list of quote characters which can cause a word break.
01082  *
01083  * Raises NotImplementedError if the using readline library does not support.
01084  *
01085  * Raises SecurityError exception if $SAFE is 4.
01086  */
01087 static VALUE
01088 readline_s_set_basic_quote_characters(VALUE self, VALUE str)
01089 {
01090     static char *basic_quote_characters = NULL;
01091 
01092     rb_secure(4);
01093     OutputStringValue(str);
01094     if (basic_quote_characters == NULL) {
01095         basic_quote_characters =
01096             ALLOC_N(char, RSTRING_LEN(str) + 1);
01097     }
01098     else {
01099         REALLOC_N(basic_quote_characters, char, RSTRING_LEN(str) + 1);
01100     }
01101     strncpy(basic_quote_characters,
01102             RSTRING_PTR(str), RSTRING_LEN(str));
01103     basic_quote_characters[RSTRING_LEN(str)] = '\0';
01104     rl_basic_quote_characters = basic_quote_characters;
01105 
01106     return self;
01107 }
01108 #else
01109 #define readline_s_set_basic_quote_characters rb_f_notimplement
01110 #endif
01111 
01112 #ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS
01113 /*
01114  * call-seq:
01115  *   Readline.basic_quote_characters -> string
01116  *
01117  * Gets a list of quote characters which can cause a word break.
01118  *
01119  * Raises NotImplementedError if the using readline library does not support.
01120  *
01121  * Raises SecurityError exception if $SAFE is 4.
01122  */
01123 static VALUE
01124 readline_s_get_basic_quote_characters(VALUE self, VALUE str)
01125 {
01126     rb_secure(4);
01127     if (rl_basic_quote_characters == NULL)
01128         return Qnil;
01129     return rb_locale_str_new_cstr(rl_basic_quote_characters);
01130 }
01131 #else
01132 #define readline_s_get_basic_quote_characters rb_f_notimplement
01133 #endif
01134 
01135 #ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS
01136 /*
01137  * call-seq:
01138  *   Readline.completer_quote_characters = string
01139  *
01140  * Sets a list of characters which can be used to quote a substring of
01141  * the line. Completion occurs on the entire substring, and within
01142  * the substring Readline.completer_word_break_characters are treated
01143  * as any other character, unless they also appear within this list.
01144  *
01145  * Raises NotImplementedError if the using readline library does not support.
01146  *
01147  * Raises SecurityError exception if $SAFE is 4.
01148  */
01149 static VALUE
01150 readline_s_set_completer_quote_characters(VALUE self, VALUE str)
01151 {
01152     static char *completer_quote_characters = NULL;
01153 
01154     rb_secure(4);
01155     OutputStringValue(str);
01156     if (completer_quote_characters == NULL) {
01157         completer_quote_characters =
01158             ALLOC_N(char, RSTRING_LEN(str) + 1);
01159     }
01160     else {
01161         REALLOC_N(completer_quote_characters, char, RSTRING_LEN(str) + 1);
01162     }
01163     strncpy(completer_quote_characters, RSTRING_PTR(str), RSTRING_LEN(str));
01164     completer_quote_characters[RSTRING_LEN(str)] = '\0';
01165     rl_completer_quote_characters = completer_quote_characters;
01166 
01167     return self;
01168 }
01169 #else
01170 #define readline_s_set_completer_quote_characters rb_f_notimplement
01171 #endif
01172 
01173 #ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS
01174 /*
01175  * call-seq:
01176  *   Readline.completer_quote_characters -> string
01177  *
01178  * Gets a list of characters which can be used to quote a substring of
01179  * the line.
01180  *
01181  * Raises NotImplementedError if the using readline library does not support.
01182  *
01183  * Raises SecurityError exception if $SAFE is 4.
01184  */
01185 static VALUE
01186 readline_s_get_completer_quote_characters(VALUE self, VALUE str)
01187 {
01188     rb_secure(4);
01189     if (rl_completer_quote_characters == NULL)
01190         return Qnil;
01191     return rb_locale_str_new_cstr(rl_completer_quote_characters);
01192 }
01193 #else
01194 #define readline_s_get_completer_quote_characters rb_f_notimplement
01195 #endif
01196 
01197 #ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS
01198 /*
01199  * call-seq:
01200  *   Readline.filename_quote_characters = string
01201  *
01202  * Sets a list of characters that cause a filename to be quoted by the completer
01203  * when they appear in a completed filename. The default is nil.
01204  *
01205  * Raises NotImplementedError if the using readline library does not support.
01206  *
01207  * Raises SecurityError exception if $SAFE is 4.
01208  */
01209 static VALUE
01210 readline_s_set_filename_quote_characters(VALUE self, VALUE str)
01211 {
01212     static char *filename_quote_characters = NULL;
01213 
01214     rb_secure(4);
01215     OutputStringValue(str);
01216     if (filename_quote_characters == NULL) {
01217         filename_quote_characters =
01218             ALLOC_N(char, RSTRING_LEN(str) + 1);
01219     }
01220     else {
01221         REALLOC_N(filename_quote_characters, char, RSTRING_LEN(str) + 1);
01222     }
01223     strncpy(filename_quote_characters, RSTRING_PTR(str), RSTRING_LEN(str));
01224     filename_quote_characters[RSTRING_LEN(str)] = '\0';
01225     rl_filename_quote_characters = filename_quote_characters;
01226 
01227     return self;
01228 }
01229 #else
01230 #define readline_s_set_filename_quote_characters rb_f_notimplement
01231 #endif
01232 
01233 #ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS
01234 /*
01235  * call-seq:
01236  *   Readline.filename_quote_characters -> string
01237  *
01238  * Gets a list of characters that cause a filename to be quoted by the completer
01239  * when they appear in a completed filename.
01240  *
01241  * Raises NotImplementedError if the using readline library does not support.
01242  *
01243  * Raises SecurityError exception if $SAFE is 4.
01244  */
01245 static VALUE
01246 readline_s_get_filename_quote_characters(VALUE self, VALUE str)
01247 {
01248     rb_secure(4);
01249     if (rl_filename_quote_characters == NULL)
01250         return Qnil;
01251     return rb_locale_str_new_cstr(rl_filename_quote_characters);
01252 }
01253 #else
01254 #define readline_s_get_filename_quote_characters rb_f_notimplement
01255 #endif
01256 
01257 #ifdef HAVE_RL_REFRESH_LINE
01258 /*
01259  * call-seq:
01260  *   Readline.refresh_line -> nil
01261  *
01262  * Clear the current input line.
01263  *
01264  * Raises SecurityError exception if $SAFE is 4.
01265  */
01266 static VALUE
01267 readline_s_refresh_line(VALUE self)
01268 {
01269     rb_secure(4);
01270     rl_refresh_line(0, 0);
01271     return Qnil;
01272 }
01273 #else
01274 #define readline_s_refresh_line rb_f_notimplement
01275 #endif
01276 
01277 static VALUE
01278 hist_to_s(VALUE self)
01279 {
01280     return rb_str_new_cstr("HISTORY");
01281 }
01282 
01283 static int
01284 history_get_offset_history_base(int offset)
01285 {
01286     return history_base + offset;
01287 }
01288 
01289 static int
01290 history_get_offset_0(int offset)
01291 {
01292     return offset;
01293 }
01294 
01295 static VALUE
01296 hist_get(VALUE self, VALUE index)
01297 {
01298     HIST_ENTRY *entry = NULL;
01299     int i;
01300 
01301     rb_secure(4);
01302     i = NUM2INT(index);
01303     if (i < 0) {
01304         i += history_length;
01305     }
01306     if (i >= 0) {
01307         entry = history_get(history_get_offset_func(i));
01308     }
01309     if (entry == NULL) {
01310         rb_raise(rb_eIndexError, "invalid index");
01311     }
01312     return rb_locale_str_new_cstr(entry->line);
01313 }
01314 
01315 #ifdef HAVE_REPLACE_HISTORY_ENTRY
01316 static VALUE
01317 hist_set(VALUE self, VALUE index, VALUE str)
01318 {
01319     HIST_ENTRY *entry = NULL;
01320     int i;
01321 
01322     rb_secure(4);
01323     i = NUM2INT(index);
01324     OutputStringValue(str);
01325     if (i < 0) {
01326         i += history_length;
01327     }
01328     if (i >= 0) {
01329         entry = replace_history_entry(history_replace_offset_func(i), RSTRING_PTR(str), NULL);
01330     }
01331     if (entry == NULL) {
01332         rb_raise(rb_eIndexError, "invalid index");
01333     }
01334     return str;
01335 }
01336 #else
01337 #define hist_set rb_f_notimplement
01338 #endif
01339 
01340 static VALUE
01341 hist_push(VALUE self, VALUE str)
01342 {
01343     rb_secure(4);
01344     OutputStringValue(str);
01345     add_history(RSTRING_PTR(str));
01346     return self;
01347 }
01348 
01349 static VALUE
01350 hist_push_method(int argc, VALUE *argv, VALUE self)
01351 {
01352     VALUE str;
01353 
01354     rb_secure(4);
01355     while (argc--) {
01356         str = *argv++;
01357         OutputStringValue(str);
01358         add_history(RSTRING_PTR(str));
01359     }
01360     return self;
01361 }
01362 
01363 static VALUE
01364 rb_remove_history(int index)
01365 {
01366 #ifdef HAVE_REMOVE_HISTORY
01367     HIST_ENTRY *entry;
01368     VALUE val;
01369 
01370     rb_secure(4);
01371     entry = remove_history(index);
01372     if (entry) {
01373         val = rb_locale_str_new_cstr(entry->line);
01374         free((void *) entry->line);
01375         free(entry);
01376         return val;
01377     }
01378     return Qnil;
01379 #else
01380     rb_notimplement();
01381     return Qnil; /* not reached */
01382 #endif
01383 }
01384 
01385 static VALUE
01386 hist_pop(VALUE self)
01387 {
01388     rb_secure(4);
01389     if (history_length > 0) {
01390         return rb_remove_history(history_length - 1);
01391     } else {
01392         return Qnil;
01393     }
01394 }
01395 
01396 static VALUE
01397 hist_shift(VALUE self)
01398 {
01399     rb_secure(4);
01400     if (history_length > 0) {
01401         return rb_remove_history(0);
01402     } else {
01403         return Qnil;
01404     }
01405 }
01406 
01407 static VALUE
01408 hist_each(VALUE self)
01409 {
01410     HIST_ENTRY *entry;
01411     int i;
01412 
01413     RETURN_ENUMERATOR(self, 0, 0);
01414 
01415     rb_secure(4);
01416     for (i = 0; i < history_length; i++) {
01417         entry = history_get(history_get_offset_func(i));
01418         if (entry == NULL)
01419             break;
01420         rb_yield(rb_locale_str_new_cstr(entry->line));
01421     }
01422     return self;
01423 }
01424 
01425 static VALUE
01426 hist_length(VALUE self)
01427 {
01428     rb_secure(4);
01429     return INT2NUM(history_length);
01430 }
01431 
01432 static VALUE
01433 hist_empty_p(VALUE self)
01434 {
01435     rb_secure(4);
01436     return history_length == 0 ? Qtrue : Qfalse;
01437 }
01438 
01439 static VALUE
01440 hist_delete_at(VALUE self, VALUE index)
01441 {
01442     int i;
01443 
01444     rb_secure(4);
01445     i = NUM2INT(index);
01446     if (i < 0)
01447         i += history_length;
01448     if (i < 0 || i > history_length - 1) {
01449         rb_raise(rb_eIndexError, "invalid index");
01450     }
01451     return rb_remove_history(i);
01452 }
01453 
01454 #ifdef HAVE_CLEAR_HISTORY
01455 static VALUE
01456 hist_clear(VALUE self)
01457 {
01458     rb_secure(4);
01459     clear_history();
01460     return self;
01461 }
01462 #else
01463 #define hist_clear rb_f_notimplement
01464 #endif
01465 
01466 static VALUE
01467 filename_completion_proc_call(VALUE self, VALUE str)
01468 {
01469     VALUE result;
01470     char **matches;
01471     int i;
01472 
01473     matches = rl_completion_matches(StringValuePtr(str),
01474                                     rl_filename_completion_function);
01475     if (matches) {
01476         result = rb_ary_new();
01477         for (i = 0; matches[i]; i++) {
01478             rb_ary_push(result, rb_locale_str_new_cstr(matches[i]));
01479             free(matches[i]);
01480         }
01481         free(matches);
01482         if (RARRAY_LEN(result) >= 2)
01483             rb_ary_shift(result);
01484     }
01485     else {
01486         result = Qnil;
01487     }
01488     return result;
01489 }
01490 
01491 static VALUE
01492 username_completion_proc_call(VALUE self, VALUE str)
01493 {
01494     VALUE result;
01495     char **matches;
01496     int i;
01497 
01498     matches = rl_completion_matches(StringValuePtr(str),
01499                                     rl_username_completion_function);
01500     if (matches) {
01501         result = rb_ary_new();
01502         for (i = 0; matches[i]; i++) {
01503             rb_ary_push(result, rb_locale_str_new_cstr(matches[i]));
01504             free(matches[i]);
01505         }
01506         free(matches);
01507         if (RARRAY_LEN(result) >= 2)
01508             rb_ary_shift(result);
01509     }
01510     else {
01511         result = Qnil;
01512     }
01513     return result;
01514 }
01515 
01516 void
01517 Init_readline()
01518 {
01519     VALUE history, fcomp, ucomp, version;
01520 
01521     /* Allow conditional parsing of the ~/.inputrc file. */
01522     rl_readline_name = (char *)"Ruby";
01523 
01524 #if defined HAVE_RL_GETC_FUNCTION
01525     /* libedit check rl_getc_function only when rl_initialize() is called, */
01526     /* and using_history() call rl_initialize(). */
01527     /* This assignment should be placed before using_history() */
01528     rl_getc_function = readline_getc;
01529     id_getbyte = rb_intern_const("getbyte");
01530 #elif defined HAVE_RL_EVENT_HOOK
01531     rl_event_hook = readline_event;
01532 #endif
01533 
01534     using_history();
01535 
01536     completion_proc = rb_intern(COMPLETION_PROC);
01537     completion_case_fold = rb_intern(COMPLETION_CASE_FOLD);
01538 
01539     mReadline = rb_define_module("Readline");
01540     rb_define_module_function(mReadline, "readline",
01541                               readline_readline, -1);
01542     rb_define_singleton_method(mReadline, "input=",
01543                                readline_s_set_input, 1);
01544     rb_define_singleton_method(mReadline, "output=",
01545                                readline_s_set_output, 1);
01546     rb_define_singleton_method(mReadline, "completion_proc=",
01547                                readline_s_set_completion_proc, 1);
01548     rb_define_singleton_method(mReadline, "completion_proc",
01549                                readline_s_get_completion_proc, 0);
01550     rb_define_singleton_method(mReadline, "completion_case_fold=",
01551                                readline_s_set_completion_case_fold, 1);
01552     rb_define_singleton_method(mReadline, "completion_case_fold",
01553                                readline_s_get_completion_case_fold, 0);
01554     rb_define_singleton_method(mReadline, "line_buffer",
01555                                readline_s_get_line_buffer, 0);
01556     rb_define_singleton_method(mReadline, "point",
01557                                readline_s_get_point, 0);
01558     rb_define_singleton_method(mReadline, "set_screen_size",
01559                                readline_s_set_screen_size, 2);
01560     rb_define_singleton_method(mReadline, "get_screen_size",
01561                                readline_s_get_screen_size, 0);
01562     rb_define_singleton_method(mReadline, "vi_editing_mode",
01563                                readline_s_vi_editing_mode, 0);
01564     rb_define_singleton_method(mReadline, "vi_editing_mode?",
01565                                readline_s_vi_editing_mode_p, 0);
01566     rb_define_singleton_method(mReadline, "emacs_editing_mode",
01567                                readline_s_emacs_editing_mode, 0);
01568     rb_define_singleton_method(mReadline, "emacs_editing_mode?",
01569                                readline_s_emacs_editing_mode_p, 0);
01570     rb_define_singleton_method(mReadline, "completion_append_character=",
01571                                readline_s_set_completion_append_character, 1);
01572     rb_define_singleton_method(mReadline, "completion_append_character",
01573                                readline_s_get_completion_append_character, 0);
01574     rb_define_singleton_method(mReadline, "basic_word_break_characters=",
01575                                readline_s_set_basic_word_break_characters, 1);
01576     rb_define_singleton_method(mReadline, "basic_word_break_characters",
01577                                readline_s_get_basic_word_break_characters, 0);
01578     rb_define_singleton_method(mReadline, "completer_word_break_characters=",
01579                                readline_s_set_completer_word_break_characters, 1);
01580     rb_define_singleton_method(mReadline, "completer_word_break_characters",
01581                                readline_s_get_completer_word_break_characters, 0);
01582     rb_define_singleton_method(mReadline, "basic_quote_characters=",
01583                                readline_s_set_basic_quote_characters, 1);
01584     rb_define_singleton_method(mReadline, "basic_quote_characters",
01585                                readline_s_get_basic_quote_characters, 0);
01586     rb_define_singleton_method(mReadline, "completer_quote_characters=",
01587                                readline_s_set_completer_quote_characters, 1);
01588     rb_define_singleton_method(mReadline, "completer_quote_characters",
01589                                readline_s_get_completer_quote_characters, 0);
01590     rb_define_singleton_method(mReadline, "filename_quote_characters=",
01591                                readline_s_set_filename_quote_characters, 1);
01592     rb_define_singleton_method(mReadline, "filename_quote_characters",
01593                                readline_s_get_filename_quote_characters, 0);
01594     rb_define_singleton_method(mReadline, "refresh_line",
01595                                readline_s_refresh_line, 0);
01596 
01597 #if USE_INSERT_IGNORE_ESCAPE
01598     CONST_ID(id_orig_prompt, "orig_prompt");
01599     CONST_ID(id_last_prompt, "last_prompt");
01600 #endif
01601 
01602     history = rb_obj_alloc(rb_cObject);
01603     rb_extend_object(history, rb_mEnumerable);
01604     rb_define_singleton_method(history,"to_s", hist_to_s, 0);
01605     rb_define_singleton_method(history,"[]", hist_get, 1);
01606     rb_define_singleton_method(history,"[]=", hist_set, 2);
01607     rb_define_singleton_method(history,"<<", hist_push, 1);
01608     rb_define_singleton_method(history,"push", hist_push_method, -1);
01609     rb_define_singleton_method(history,"pop", hist_pop, 0);
01610     rb_define_singleton_method(history,"shift", hist_shift, 0);
01611     rb_define_singleton_method(history,"each", hist_each, 0);
01612     rb_define_singleton_method(history,"length", hist_length, 0);
01613     rb_define_singleton_method(history,"size", hist_length, 0);
01614     rb_define_singleton_method(history,"empty?", hist_empty_p, 0);
01615     rb_define_singleton_method(history,"delete_at", hist_delete_at, 1);
01616     rb_define_singleton_method(history,"clear", hist_clear, 0);
01617 
01618     /*
01619      * The history buffer. It extends Enumerable module, so it behaves
01620      * just like an array.
01621      * For example, gets the fifth content that the user input by
01622      * HISTORY[4].
01623      */
01624     rb_define_const(mReadline, "HISTORY", history);
01625 
01626     fcomp = rb_obj_alloc(rb_cObject);
01627     rb_define_singleton_method(fcomp, "call",
01628                                filename_completion_proc_call, 1);
01629     /*
01630      * The Object with the call method that is a completion for filename.
01631      * This is sets by Readline.completion_proc= method.
01632      */
01633     rb_define_const(mReadline, "FILENAME_COMPLETION_PROC", fcomp);
01634 
01635     ucomp = rb_obj_alloc(rb_cObject);
01636     rb_define_singleton_method(ucomp, "call",
01637                                username_completion_proc_call, 1);
01638     /*
01639      * The Object with the call method that is a completion for usernames.
01640      * This is sets by Readline.completion_proc= method.
01641      */
01642     rb_define_const(mReadline, "USERNAME_COMPLETION_PROC", ucomp);
01643     history_get_offset_func = history_get_offset_history_base;
01644     history_replace_offset_func = history_get_offset_0;
01645 #if defined HAVE_RL_LIBRARY_VERSION
01646     version = rb_str_new_cstr(rl_library_version);
01647 #if defined HAVE_CLEAR_HISTORY || defined HAVE_REMOVE_HISTORY
01648     if (strncmp(rl_library_version, EDIT_LINE_LIBRARY_VERSION,
01649                 strlen(EDIT_LINE_LIBRARY_VERSION)) == 0) {
01650         add_history("1");
01651         if (history_get(history_get_offset_func(0)) == NULL) {
01652             history_get_offset_func = history_get_offset_0;
01653         }
01654 #ifdef HAVE_REPLACE_HISTORY_ENTRY
01655         if (replace_history_entry(0, "a", NULL) == NULL) {
01656             history_replace_offset_func = history_get_offset_history_base;
01657         }
01658 #endif
01659 #ifdef HAVE_CLEAR_HISTORY
01660         clear_history();
01661 #else
01662         {
01663             HIST_ENTRY *entry = remove_history(0);
01664             if (entry) {
01665                 free((char *)entry->line);
01666                 free(entry);
01667             }
01668         }
01669 #endif
01670     }
01671 #endif
01672 #else
01673     version = rb_str_new_cstr("2.0 or prior version");
01674 #endif
01675     /* Version string of GNU Readline or libedit. */
01676     rb_define_const(mReadline, "VERSION", version);
01677 
01678     rl_attempted_completion_function = readline_attempted_completion_function;
01679 #ifdef HAVE_RL_CATCH_SIGNALS
01680     rl_catch_signals = 0;
01681 #endif
01682 #ifdef HAVE_RL_CATCH_SIGWINCH
01683     rl_catch_sigwinch = 0;
01684 #endif
01685 #ifdef HAVE_RL_CLEAR_SIGNALS
01686     rl_clear_signals();
01687 #endif
01688 
01689     readline_s_set_input(mReadline, rb_stdin);
01690 }
01691