• Main Page
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

ext/readline/readline.c

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

Generated on Thu Sep 8 2011 03:50:36 for Ruby by  doxygen 1.7.1