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