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