Ruby  2.1.10p492(2016-04-01revision54464)
readline.c
Go to the documentation of this file.
1 /************************************************
2 
3  readline.c - GNU Readline module
4 
5  $Author: nagachika $
6  created at: Wed Jan 20 13:59:32 JST 1999
7 
8  Copyright (C) 1997-2008 Shugo Maeda
9  Copyright (C) 2008-2013 Kouji Takao
10 
11  $Id: readline.c 45772 2014-05-01 11:55:03Z nagachika $
12 
13  Contact:
14  - Kouji Takao <kouji dot takao at gmail dot com> (current maintainer)
15 
16 ************************************************/
17 
18 #ifdef RUBY_EXTCONF_H
19 #include RUBY_EXTCONF_H
20 #endif
21 
22 #include "ruby/config.h"
23 #include <errno.h>
24 #include <stdio.h>
25 #include <string.h>
26 #ifdef HAVE_READLINE_READLINE_H
27 #include <readline/readline.h>
28 #endif
29 #ifdef HAVE_READLINE_HISTORY_H
30 #include <readline/history.h>
31 #endif
32 #ifdef HAVE_EDITLINE_READLINE_H
33 #include <editline/readline.h>
34 #endif
35 
36 #include "ruby/ruby.h"
37 #include "ruby/io.h"
38 #include "ruby/thread.h"
39 
40 #ifdef HAVE_UNISTD_H
41 #include <unistd.h>
42 #endif
43 
44 #ifdef HAVE_SYS_STAT_H
45 #include <sys/stat.h>
46 #endif
47 
49 
50 #define EDIT_LINE_LIBRARY_VERSION "EditLine wrapper"
51 #ifndef USE_INSERT_IGNORE_ESCAPE
52 # if !defined(HAVE_EDITLINE_READLINE_H) && defined(RL_PROMPT_START_IGNORE) && defined(RL_PROMPT_END_IGNORE)
53 # define USE_INSERT_IGNORE_ESCAPE 1
54 # else
55 # define USE_INSERT_IGNORE_ESCAPE 0
56 # endif
57 #endif
58 
59 #define COMPLETION_PROC "completion_proc"
60 #define COMPLETION_CASE_FOLD "completion_case_fold"
62 #if USE_INSERT_IGNORE_ESCAPE
63 static ID id_orig_prompt, id_last_prompt;
64 #endif
65 #if defined(HAVE_RL_PRE_INPUT_HOOK)
66 static ID id_pre_input_hook;
67 #endif
68 #if defined(HAVE_RL_SPECIAL_PREFIXES)
69 static ID id_special_prefixes;
70 #endif
71 
72 #ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION
73 # define rl_filename_completion_function filename_completion_function
74 #endif
75 #ifndef HAVE_RL_USERNAME_COMPLETION_FUNCTION
76 # define rl_username_completion_function username_completion_function
77 #endif
78 #ifndef HAVE_RL_COMPLETION_MATCHES
79 # define rl_completion_matches completion_matches
80 #endif
81 
84 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
85 static int readline_completion_append_character;
86 #endif
87 
88 static char **readline_attempted_completion_function(const char *text,
89  int start, int end);
90 
91 #define OutputStringValue(str) do {\
92  SafeStringValue(str);\
93  (str) = rb_str_conv_enc((str), rb_enc_get(str), rb_locale_encoding());\
94 } while (0)\
95 
96 
97 /*
98  * Document-class: Readline
99  *
100  * The Readline module provides interface for GNU Readline.
101  * This module defines a number of methods to facilitate completion
102  * and accesses input history from the Ruby interpreter.
103  * This module supported Edit Line(libedit) too.
104  * libedit is compatible with GNU Readline.
105  *
106  * GNU Readline:: http://www.gnu.org/directory/readline.html
107  * libedit:: http://www.thrysoee.dk/editline/
108  *
109  * Reads one inputted line with line edit by Readline.readline method.
110  * At this time, the facilitatation completion and the key
111  * bind like Emacs can be operated like GNU Readline.
112  *
113  * require "readline"
114  * while buf = Readline.readline("> ", true)
115  * p buf
116  * end
117  *
118  * The content that the user input can be recorded to the history.
119  * The history can be accessed by Readline::HISTORY constant.
120  *
121  * require "readline"
122  * while buf = Readline.readline("> ", true)
123  * p Readline::HISTORY.to_a
124  * print("-> ", buf, "\n")
125  * end
126  *
127  * Documented by Kouji Takao <kouji dot takao at gmail dot com>.
128  */
129 
134 
135 #if defined HAVE_RL_GETC_FUNCTION
136 
137 #ifndef HAVE_RL_GETC
138 #define rl_getc(f) EOF
139 #endif
140 
141 struct getc_struct {
142  FILE *input;
143  int fd;
144  int ret;
145  int err;
146 };
147 
148 static int
149 getc_body(struct getc_struct *p)
150 {
151  char ch;
152  ssize_t ss;
153 
154 #if defined(_WIN32)
155  {
156  INPUT_RECORD ir;
157  int n;
158  static int prior_key = '0';
159  for (;;) {
160  if (prior_key > 0xff) {
161  prior_key = rl_getc(p->input);
162  return prior_key;
163  }
164  if (PeekConsoleInput((HANDLE)_get_osfhandle(p->fd), &ir, 1, &n)) {
165  if (n == 1) {
166  if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown) {
167  prior_key = rl_getc(p->input);
168  return prior_key;
169  } else {
170  ReadConsoleInput((HANDLE)_get_osfhandle(p->fd), &ir, 1, &n);
171  }
172  } else {
173  HANDLE h = (HANDLE)_get_osfhandle(p->fd);
174  rb_w32_wait_events(&h, 1, INFINITE);
175  }
176  } else {
177  break;
178  }
179  }
180  }
181 #endif
182 
183  ss = read(p->fd, &ch, 1);
184  if (ss == 0) {
185  errno = 0;
186  return EOF;
187  }
188  if (ss != 1)
189  return EOF;
190  return (unsigned char)ch;
191 }
192 
193 static void *
194 getc_func(void *data1)
195 {
196  struct getc_struct *p = data1;
197  errno = 0;
198  p->ret = getc_body(p);
199  p->err = errno;
200  return NULL;
201 }
202 
203 static int
204 readline_getc(FILE *input)
205 {
206  struct getc_struct data;
207  if (input == NULL) /* editline may give NULL as input. */
208  input = stdin;
209  data.input = input;
210  data.fd = fileno(input);
211  again:
212  data.ret = EOF;
213  data.err = EINTR; /* getc_func is not called if already interrupted. */
215  if (data.ret == EOF) {
216  if (data.err == 0) {
217  return EOF;
218  }
219  if (data.err == EINTR) {
221  goto again;
222  }
223  if (data.err == EWOULDBLOCK || data.err == EAGAIN) {
224  int ret;
225  if (fileno(input) != data.fd)
226  rb_bug("readline_getc: input closed unexpectedly or memory corrupted");
228  if (ret != -1 || errno == EINTR)
229  goto again;
230  rb_sys_fail("rb_wait_for_single_fd");
231  }
232  errno = data.err;
233  rb_sys_fail("read");
234  }
235  return data.ret;
236 }
237 
238 #elif defined HAVE_RL_EVENT_HOOK
239 #define BUSY_WAIT 0
240 
241 static int readline_event(void);
242 static int
243 readline_event(void)
244 {
245 #if BUSY_WAIT
247 #else
249  return 0;
250 #endif
251 }
252 #endif
253 
254 #if USE_INSERT_IGNORE_ESCAPE
255 static VALUE
256 insert_ignore_escape(VALUE self, VALUE prompt)
257 {
258  VALUE last_prompt, orig_prompt = rb_attr_get(self, id_orig_prompt);
259  int ignoring = 0;
260  const char *s0, *s, *e;
261  long len;
262  static const char ignore_code[2] = {RL_PROMPT_START_IGNORE, RL_PROMPT_END_IGNORE};
263 
264  prompt = rb_str_new_shared(prompt);
265  last_prompt = rb_attr_get(self, id_last_prompt);
266  if (orig_prompt == prompt) return last_prompt;
267  len = RSTRING_LEN(prompt);
268  if (NIL_P(last_prompt)) {
269  last_prompt = rb_str_tmp_new(len);
270  }
271 
272  s = s0 = RSTRING_PTR(prompt);
273  e = s0 + len;
274  rb_str_set_len(last_prompt, 0);
275  while (s < e && *s) {
276  switch (*s) {
277  case RL_PROMPT_START_IGNORE:
278  ignoring = -1;
279  rb_str_cat(last_prompt, s0, ++s - s0);
280  s0 = s;
281  break;
282  case RL_PROMPT_END_IGNORE:
283  ignoring = 0;
284  rb_str_cat(last_prompt, s0, ++s - s0);
285  s0 = s;
286  break;
287  case '\033':
288  if (++s < e && *s == '[') {
289  rb_str_cat(last_prompt, s0, s - s0 - 1);
290  s0 = s - 1;
291  while (++s < e && *s) {
292  if (ISALPHA(*(unsigned char *)s)) {
293  if (!ignoring) {
294  ignoring = 1;
295  rb_str_cat(last_prompt, ignore_code+0, 1);
296  }
297  rb_str_cat(last_prompt, s0, ++s - s0);
298  s0 = s;
299  break;
300  }
301  else if (!(('0' <= *s && *s <= '9') || *s == ';')) {
302  break;
303  }
304  }
305  }
306  break;
307  default:
308  if (ignoring > 0) {
309  ignoring = 0;
310  rb_str_cat(last_prompt, ignore_code+1, 1);
311  }
312  s++;
313  break;
314  }
315  }
316  if (ignoring > 0) {
317  ignoring = 0;
318  rb_str_cat(last_prompt, ignore_code+1, 1);
319  }
320  rb_str_cat(last_prompt, s0, s - s0);
321 
322  rb_ivar_set(self, id_orig_prompt, prompt);
323  rb_ivar_set(self, id_last_prompt, last_prompt);
324 
325  return last_prompt;
326 }
327 #endif
328 
329 static VALUE
331 {
332 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
333  readline_completion_append_character = rl_completion_append_character;
334 #endif
335  return (VALUE)readline((char *)prompt);
336 }
337 
338 static void
340 {
341  if (readline_rl_instream) {
342  fclose(readline_rl_instream);
343  if (rl_instream == readline_rl_instream)
344  rl_instream = NULL;
345  readline_rl_instream = NULL;
346  }
348 }
349 
350 static void
352 {
353  if (readline_rl_outstream) {
354  fclose(readline_rl_outstream);
355  if (rl_outstream == readline_rl_outstream)
356  rl_outstream = NULL;
357  readline_rl_outstream = NULL;
358  }
360 }
361 
362 /*
363  * call-seq:
364  * Readline.readline(prompt = "", add_hist = false) -> string or nil
365  *
366  * Shows the +prompt+ and reads the inputted line with line editing.
367  * The inputted line is added to the history if +add_hist+ is true.
368  *
369  * Returns nil when the inputted line is empty and user inputs EOF
370  * (Presses ^D on UNIX).
371  *
372  * Raises IOError exception if one of below conditions are satisfied.
373  * 1. stdin was closed.
374  * 2. stdout was closed.
375  *
376  * This method supports thread. Switches the thread context when waits
377  * inputting line.
378  *
379  * Supports line edit when inputs line. Provides VI and Emacs editing mode.
380  * Default is Emacs editing mode.
381  *
382  * NOTE: Terminates ruby interpreter and does not return the terminal
383  * status after user pressed '^C' when wait inputting line.
384  * Give 3 examples that avoid it.
385  *
386  * * Catches the Interrupt exception by pressed ^C after returns
387  * terminal status:
388  *
389  * require "readline"
390  *
391  * stty_save = `stty -g`.chomp
392  * begin
393  * while buf = Readline.readline
394  * p buf
395  * end
396  * rescue Interrupt
397  * system("stty", stty_save)
398  * exit
399  * end
400  * end
401  * end
402  *
403  * * Catches the INT signal by pressed ^C after returns terminal
404  * status:
405  *
406  * require "readline"
407  *
408  * stty_save = `stty -g`.chomp
409  * trap("INT") { system "stty", stty_save; exit }
410  *
411  * while buf = Readline.readline
412  * p buf
413  * end
414  *
415  * * Ignores pressing ^C:
416  *
417  * require "readline"
418  *
419  * trap("INT", "SIG_IGN")
420  *
421  * while buf = Readline.readline
422  * p buf
423  * end
424  *
425  * Can make as follows with Readline::HISTORY constant.
426  * It does not record to the history if the inputted line is empty or
427  * the same it as last one.
428  *
429  * require "readline"
430  *
431  * while buf = Readline.readline("> ", true)
432  * # p Readline::HISTORY.to_a
433  * Readline::HISTORY.pop if /^\s*$/ =~ buf
434  *
435  * begin
436  * if Readline::HISTORY[Readline::HISTORY.length-2] == buf
437  * Readline::HISTORY.pop
438  * end
439  * rescue IndexError
440  * end
441  *
442  * # p Readline::HISTORY.to_a
443  * print "-> ", buf, "\n"
444  * end
445  */
446 static VALUE
448 {
449  VALUE tmp, add_hist, result;
450  char *prompt = NULL;
451  char *buff;
452  int status;
453 
454  if (rb_scan_args(argc, argv, "02", &tmp, &add_hist) > 0) {
455  OutputStringValue(tmp);
456 #if USE_INSERT_IGNORE_ESCAPE
457  tmp = insert_ignore_escape(self, tmp);
458  rb_str_locktmp(tmp);
459 #endif
460  prompt = RSTRING_PTR(tmp);
461  }
462 
463  if (readline_instream) {
464  rb_io_t *ifp;
466  if (ifp->fd < 0) {
468  rb_raise(rb_eIOError, "closed readline input");
469  }
470  }
471 
472  if (readline_outstream) {
473  rb_io_t *ofp;
475  if (ofp->fd < 0) {
477  rb_raise(rb_eIOError, "closed readline output");
478  }
479  }
480 
481 #ifdef _WIN32
482  rl_prep_terminal(1);
483 #endif
484  buff = (char*)rb_protect(readline_get, (VALUE)prompt, &status);
485 #if USE_INSERT_IGNORE_ESCAPE
486  if (prompt) {
487  rb_str_unlocktmp(tmp);
488  }
489 #endif
490  if (status) {
491 #if defined HAVE_RL_CLEANUP_AFTER_SIGNAL
492  /* restore terminal mode and signal handler*/
493 #if defined HAVE_RL_FREE_LINE_STATE
494  rl_free_line_state();
495 #endif
496  rl_cleanup_after_signal();
497 #elif defined HAVE_RL_DEPREP_TERM_FUNCTION
498  /* restore terminal mode */
499  if (rl_deprep_term_function != NULL) /* NULL in libedit. [ruby-dev:29116] */
500  (*rl_deprep_term_function)();
501  else
502 #else
503  rl_deprep_terminal();
504 #endif
505  rb_jump_tag(status);
506  }
507 
508  if (RTEST(add_hist) && buff) {
509  add_history(buff);
510  }
511  if (buff) {
512  result = rb_locale_str_new_cstr(buff);
513  }
514  else
515  result = Qnil;
516  if (buff) free(buff);
517  return result;
518 }
519 
520 /*
521  * call-seq:
522  * Readline.input = input
523  *
524  * Specifies a File object +input+ that is input stream for
525  * Readline.readline method.
526  */
527 static VALUE
529 {
530  rb_io_t *ifp;
531  int fd;
532  FILE *f;
533 
534  if (NIL_P(input)) {
536  }
537  else {
538  Check_Type(input, T_FILE);
539  GetOpenFile(input, ifp);
541  fd = rb_cloexec_dup(ifp->fd);
542  if (fd == -1)
543  rb_sys_fail("dup");
544  f = fdopen(fd, "r");
545  if (f == NULL) {
546  int save_errno = errno;
547  close(fd);
548  errno = save_errno;
549  rb_sys_fail("fdopen");
550  }
551  rl_instream = readline_rl_instream = f;
553  }
554  return input;
555 }
556 
557 /*
558  * call-seq:
559  * Readline.output = output
560  *
561  * Specifies a File object +output+ that is output stream for
562  * Readline.readline method.
563  */
564 static VALUE
566 {
567  rb_io_t *ofp;
568  int fd;
569  FILE *f;
570 
571  if (NIL_P(output)) {
573  }
574  else {
575  Check_Type(output, T_FILE);
576  GetOpenFile(output, ofp);
578  fd = rb_cloexec_dup(ofp->fd);
579  if (fd == -1)
580  rb_sys_fail("dup");
581  f = fdopen(fd, "w");
582  if (f == NULL) {
583  int save_errno = errno;
584  close(fd);
585  errno = save_errno;
586  rb_sys_fail("fdopen");
587  }
588  rl_outstream = readline_rl_outstream = f;
590  }
591  return output;
592 }
593 
594 #if defined(HAVE_RL_PRE_INPUT_HOOK)
595 /*
596  * call-seq:
597  * Readline.pre_input_hook = proc
598  *
599  * Specifies a Proc object +proc+ to call after the first prompt has
600  * been printed and just before readline starts reading input
601  * characters.
602  *
603  * See GNU Readline's rl_pre_input_hook variable.
604  *
605  * Raises ArgumentError if +proc+ does not respond to the call method.
606  *
607  * Raises NotImplementedError if the using readline library does not support.
608  */
609 static VALUE
611 {
612  if (!NIL_P(proc) && !rb_respond_to(proc, rb_intern("call")))
613  rb_raise(rb_eArgError, "argument must respond to `call'");
614  return rb_ivar_set(mReadline, id_pre_input_hook, proc);
615 }
616 
617 /*
618  * call-seq:
619  * Readline.pre_input_hook -> proc
620  *
621  * Returns a Proc object +proc+ to call after the first prompt has
622  * been printed and just before readline starts reading input
623  * characters. The default is nil.
624  *
625  * Raises NotImplementedError if the using readline library does not support.
626  */
627 static VALUE
629 {
630  return rb_attr_get(mReadline, id_pre_input_hook);
631 }
632 
633 static int
634 readline_pre_input_hook(void)
635 {
636  VALUE proc;
637 
638  proc = rb_attr_get(mReadline, id_pre_input_hook);
639  if (!NIL_P(proc))
640  rb_funcall(proc, rb_intern("call"), 0);
641  return 0;
642 }
643 #else
644 #define readline_s_set_pre_input_hook rb_f_notimplement
645 #define readline_s_get_pre_input_hook rb_f_notimplement
646 #endif
647 
648 #if defined(HAVE_RL_INSERT_TEXT)
649 /*
650  * call-seq:
651  * Readline.insert_text(string) -> self
652  *
653  * Insert text into the line at the current cursor position.
654  *
655  * See GNU Readline's rl_insert_text function.
656  *
657  * Raises NotImplementedError if the using readline library does not support.
658  */
659 static VALUE
661 {
662  OutputStringValue(str);
663  rl_insert_text(RSTRING_PTR(str));
664  return self;
665 }
666 #else
667 #define readline_s_insert_text rb_f_notimplement
668 #endif
669 
670 #if defined(HAVE_RL_DELETE_TEXT)
671 /*
672  * call-seq:
673  * Readline.delete_text([start[, length]]) -> self
674  * Readline.delete_text(start..end) -> self
675  * Readline.delete_text() -> self
676  *
677  * Delete text between start and end in the current line.
678  *
679  * See GNU Readline's rl_delete_text function.
680  *
681  * Raises NotImplementedError if the using readline library does not support.
682  */
683 static VALUE
685 {
686  rb_check_arity(argc, 0, 2);
687  if (rl_line_buffer) {
688  char *p, *ptr = rl_line_buffer;
689  long beg = 0, len = strlen(rl_line_buffer);
690  struct RString fakestr;
691  VALUE str = (VALUE)&fakestr;
692 
693  fakestr.basic.flags = T_STRING | RSTRING_NOEMBED;
694  fakestr.as.heap.ptr = ptr;
695  fakestr.as.heap.len = len;
697  OBJ_FREEZE(str);
698  if (argc == 2) {
699  beg = NUM2LONG(argv[0]);
700  len = NUM2LONG(argv[1]);
701  num_pos:
702  p = rb_str_subpos(str, beg, &len);
703  if (!p) rb_raise(rb_eArgError, "invalid index");
704  beg = p - ptr;
705  }
706  else if (argc == 1) {
707  len = rb_str_strlen(str);
708  if (!rb_range_beg_len(argv[0], &beg, &len, len, 1)) {
709  beg = NUM2LONG(argv[0]);
710  goto num_pos;
711  }
712  }
713  rl_delete_text(rb_long2int(beg), rb_long2int(beg + len));
714  }
715  return self;
716 }
717 #else
718 #define readline_s_delete_text rb_f_notimplement
719 #endif
720 
721 #if defined(HAVE_RL_REDISPLAY)
722 /*
723  * call-seq:
724  * Readline.redisplay -> self
725  *
726  * Change what's displayed on the screen to reflect the current
727  * contents.
728  *
729  * See GNU Readline's rl_redisplay function.
730  *
731  * Raises NotImplementedError if the using readline library does not support.
732  */
733 static VALUE
735 {
736  rl_redisplay();
737  return self;
738 }
739 #else
740 #define readline_s_redisplay rb_f_notimplement
741 #endif
742 
743 /*
744  * call-seq:
745  * Readline.completion_proc = proc
746  *
747  * Specifies a Proc object +proc+ to determine completion behavior. It
748  * should take input string and return an array of completion candidates.
749  *
750  * The default completion is used if +proc+ is nil.
751  *
752  * The String that is passed to the Proc depends on the
753  * Readline.completer_word_break_characters property. By default the word
754  * under the cursor is passed to the Proc. For example, if the input is "foo
755  * bar" then only "bar" would be passed to the completion Proc.
756  *
757  * Upon successful completion the Readline.completion_append_character will be
758  * appended to the input so the user can start working on their next argument.
759  *
760  * = Examples
761  *
762  * == Completion for a Static List
763  *
764  * require 'readline'
765  *
766  * LIST = [
767  * 'search', 'download', 'open',
768  * 'help', 'history', 'quit',
769  * 'url', 'next', 'clear',
770  * 'prev', 'past'
771  * ].sort
772  *
773  * comp = proc { |s| LIST.grep(/^#{Regexp.escape(s)}/) }
774  *
775  * Readline.completion_append_character = " "
776  * Readline.completion_proc = comp
777  *
778  * while line = Readline.readline('> ', true)
779  * p line
780  * end
781  *
782  * == Completion For Directory Contents
783  *
784  * require 'readline'
785  *
786  * Readline.completion_append_character = " "
787  * Readline.completion_proc = Proc.new do |str|
788  * Dir[str+'*'].grep(/^#{Regexp.escape(str)}/)
789  * end
790  *
791  * while line = Readline.readline('> ', true)
792  * p line
793  * end
794  *
795  * = Autocomplete strategies
796  *
797  * When working with auto-complete there are some strategies that work well.
798  * To get some ideas you can take a look at the
799  * completion.rb[http://svn.ruby-lang.org/repos/ruby/trunk/lib/irb/completion.rb]
800  * file for irb.
801  *
802  * The common strategy is to take a list of possible completions and filter it
803  * down to those completions that start with the user input. In the above
804  * examples Enumerator.grep is used. The input is escaped to prevent Regexp
805  * special characters from interfering with the matching.
806  *
807  * It may also be helpful to use the Abbrev library to generate completions.
808  *
809  * Raises ArgumentError if +proc+ does not respond to the call method.
810  */
811 static VALUE
813 {
814  if (!NIL_P(proc) && !rb_respond_to(proc, rb_intern("call")))
815  rb_raise(rb_eArgError, "argument must respond to `call'");
816  return rb_ivar_set(mReadline, completion_proc, proc);
817 }
818 
819 /*
820  * call-seq:
821  * Readline.completion_proc -> proc
822  *
823  * Returns the completion Proc object.
824  */
825 static VALUE
827 {
829 }
830 
831 /*
832  * call-seq:
833  * Readline.completion_case_fold = bool
834  *
835  * Sets whether or not to ignore case on completion.
836  */
837 static VALUE
839 {
841 }
842 
843 /*
844  * call-seq:
845  * Readline.completion_case_fold -> bool
846  *
847  * Returns true if completion ignores case. If no, returns false.
848  *
849  * NOTE: Returns the same object that is specified by
850  * Readline.completion_case_fold= method.
851  *
852  * require "readline"
853  *
854  * Readline.completion_case_fold = "This is a String."
855  * p Readline.completion_case_fold # => "This is a String."
856  */
857 static VALUE
859 {
861 }
862 
863 #ifdef HAVE_RL_LINE_BUFFER
864 /*
865  * call-seq:
866  * Readline.line_buffer -> string
867  *
868  * Returns the full line that is being edited. This is useful from
869  * within the complete_proc for determining the context of the
870  * completion request.
871  *
872  * The length of +Readline.line_buffer+ and GNU Readline's rl_end are
873  * same.
874  *
875  * Raises NotImplementedError if the using readline library does not support.
876  */
877 static VALUE
879 {
880  if (rl_line_buffer == NULL)
881  return Qnil;
882  return rb_locale_str_new_cstr(rl_line_buffer);
883 }
884 #else
885 #define readline_s_get_line_buffer rb_f_notimplement
886 #endif
887 
888 #ifdef HAVE_RL_POINT
889 /*
890  * call-seq:
891  * Readline.point -> int
892  *
893  * Returns the index of the current cursor position in
894  * +Readline.line_buffer+.
895  *
896  * The index in +Readline.line_buffer+ which matches the start of
897  * input-string passed to completion_proc is computed by subtracting
898  * the length of input-string from +Readline.point+.
899  *
900  * start = (the length of input-string) - Readline.point
901  *
902  * Raises NotImplementedError if the using readline library does not support.
903  */
904 static VALUE
906 {
907  return INT2NUM(rl_point);
908 }
909 
910 /*
911  * call-seq:
912  * Readline.point = int
913  *
914  * Set the index of the current cursor position in
915  * +Readline.line_buffer+.
916  *
917  * Raises NotImplementedError if the using readline library does not support.
918  *
919  * See +Readline.point+.
920  */
921 static VALUE
923 {
924  rl_point = NUM2INT(pos);
925  return pos;
926 }
927 #else
928 #define readline_s_get_point rb_f_notimplement
929 #define readline_s_set_point rb_f_notimplement
930 #endif
931 
932 static char **
933 readline_attempted_completion_function(const char *text, int start, int end)
934 {
935  VALUE proc, ary, temp;
936  char **result;
937  int case_fold;
938  long i, matches;
939  rb_encoding *enc;
940  VALUE encobj;
941 
943  if (NIL_P(proc))
944  return NULL;
945 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
946  rl_completion_append_character = readline_completion_append_character;
947 #endif
948 #ifdef HAVE_RL_ATTEMPTED_COMPLETION_OVER
949  rl_attempted_completion_over = 1;
950 #endif
952  ary = rb_funcall(proc, rb_intern("call"), 1, rb_locale_str_new_cstr(text));
953  if (!RB_TYPE_P(ary, T_ARRAY))
954  ary = rb_Array(ary);
955  matches = RARRAY_LEN(ary);
956  if (matches == 0) return NULL;
957  result = (char**)malloc((matches + 2)*sizeof(char*));
958  if (result == NULL) rb_memerror();
959  enc = rb_locale_encoding();
960  encobj = rb_enc_from_encoding(enc);
961  for (i = 0; i < matches; i++) {
962  temp = rb_obj_as_string(RARRAY_PTR(ary)[i]);
963  StringValueCStr(temp); /* must be NUL-terminated */
964  rb_enc_check(encobj, temp);
965  result[i + 1] = (char*)malloc(RSTRING_LEN(temp) + 1);
966  if (result[i + 1] == NULL) rb_memerror();
967  strcpy(result[i + 1], RSTRING_PTR(temp));
968  }
969  result[matches + 1] = NULL;
970 
971  if (matches == 1) {
972  result[0] = strdup(result[1]);
973  }
974  else {
975  const char *result1 = result[1];
976  long low = strlen(result1);
977 
978  for (i = 1; i < matches; ++i) {
979  register int c1, c2;
980  long i1, i2, l2;
981  int n1, n2;
982  const char *p2 = result[i + 1];
983 
984  l2 = strlen(p2);
985  for (i1 = i2 = 0; i1 < low && i2 < l2; i1 += n1, i2 += n2) {
986  c1 = rb_enc_codepoint_len(result1 + i1, result1 + low, &n1, enc);
987  c2 = rb_enc_codepoint_len(p2 + i2, p2 + l2, &n2, enc);
988  if (case_fold) {
989  c1 = rb_tolower(c1);
990  c2 = rb_tolower(c2);
991  }
992  if (c1 != c2) break;
993  }
994 
995  low = i1;
996  }
997  result[0] = (char*)malloc(low + 1);
998  if (result[0] == NULL) rb_memerror();
999  strncpy(result[0], result[1], low);
1000  result[0][low] = '\0';
1001  }
1002 
1003  return result;
1004 }
1005 
1006 #ifdef HAVE_RL_SET_SCREEN_SIZE
1007 /*
1008  * call-seq:
1009  * Readline.set_screen_size(rows, columns) -> self
1010  *
1011  * Set terminal size to +rows+ and +columns+.
1012  *
1013  * See GNU Readline's rl_set_screen_size function.
1014  *
1015  * Raises NotImplementedError if the using readline library does not support.
1016  */
1017 static VALUE
1018 readline_s_set_screen_size(VALUE self, VALUE rows, VALUE columns)
1019 {
1020  rl_set_screen_size(NUM2INT(rows), NUM2INT(columns));
1021  return self;
1022 }
1023 #else
1024 #define readline_s_set_screen_size rb_f_notimplement
1025 #endif
1026 
1027 #ifdef HAVE_RL_GET_SCREEN_SIZE
1028 /*
1029  * call-seq:
1030  * Readline.get_screen_size -> [rows, columns]
1031  *
1032  * Returns the terminal's rows and columns.
1033  *
1034  * See GNU Readline's rl_get_screen_size function.
1035  *
1036  * Raises NotImplementedError if the using readline library does not support.
1037  */
1038 static VALUE
1040 {
1041  int rows, columns;
1042  VALUE res;
1043 
1044  rl_get_screen_size(&rows, &columns);
1045  res = rb_ary_new();
1046  rb_ary_push(res, INT2NUM(rows));
1047  rb_ary_push(res, INT2NUM(columns));
1048  return res;
1049 }
1050 #else
1051 #define readline_s_get_screen_size rb_f_notimplement
1052 #endif
1053 
1054 #ifdef HAVE_RL_VI_EDITING_MODE
1055 /*
1056  * call-seq:
1057  * Readline.vi_editing_mode -> nil
1058  *
1059  * Specifies VI editing mode. See the manual of GNU Readline for
1060  * details of VI editing mode.
1061  *
1062  * Raises NotImplementedError if the using readline library does not support.
1063  */
1064 static VALUE
1066 {
1067  rl_vi_editing_mode(1,0);
1068  return Qnil;
1069 }
1070 #else
1071 #define readline_s_vi_editing_mode rb_f_notimplement
1072 #endif
1073 
1074 #ifdef HAVE_RL_EDITING_MODE
1075 /*
1076  * call-seq:
1077  * Readline.vi_editing_mode? -> bool
1078  *
1079  * Returns true if vi mode is active. Returns false if not.
1080  *
1081  * Raises NotImplementedError if the using readline library does not support.
1082  */
1083 static VALUE
1085 {
1086  return rl_editing_mode == 0 ? Qtrue : Qfalse;
1087 }
1088 #else
1089 #define readline_s_vi_editing_mode_p rb_f_notimplement
1090 #endif
1091 
1092 #ifdef HAVE_RL_EMACS_EDITING_MODE
1093 /*
1094  * call-seq:
1095  * Readline.emacs_editing_mode -> nil
1096  *
1097  * Specifies Emacs editing mode. The default is this mode. See the
1098  * manual of GNU Readline for details of Emacs editing mode.
1099  *
1100  * Raises NotImplementedError if the using readline library does not support.
1101  */
1102 static VALUE
1104 {
1105  rl_emacs_editing_mode(1,0);
1106  return Qnil;
1107 }
1108 #else
1109 #define readline_s_emacs_editing_mode rb_f_notimplement
1110 #endif
1111 
1112 #ifdef HAVE_RL_EDITING_MODE
1113 /*
1114  * call-seq:
1115  * Readline.emacs_editing_mode? -> bool
1116  *
1117  * Returns true if emacs mode is active. Returns false if not.
1118  *
1119  * Raises NotImplementedError if the using readline library does not support.
1120  */
1121 static VALUE
1123 {
1124  return rl_editing_mode == 1 ? Qtrue : Qfalse;
1125 }
1126 #else
1127 #define readline_s_emacs_editing_mode_p rb_f_notimplement
1128 #endif
1129 
1130 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
1131 /*
1132  * call-seq:
1133  * Readline.completion_append_character = char
1134  *
1135  * Specifies a character to be appended on completion.
1136  * Nothing will be appended if an empty string ("") or nil is
1137  * specified.
1138  *
1139  * For example:
1140  * require "readline"
1141  *
1142  * Readline.readline("> ", true)
1143  * Readline.completion_append_character = " "
1144  *
1145  * Result:
1146  * >
1147  * Input "/var/li".
1148  *
1149  * > /var/li
1150  * Press TAB key.
1151  *
1152  * > /var/lib
1153  * Completes "b" and appends " ". So, you can continuously input "/usr".
1154  *
1155  * > /var/lib /usr
1156  *
1157  * NOTE: Only one character can be specified. When "string" is
1158  * specified, sets only "s" that is the first.
1159  *
1160  * require "readline"
1161  *
1162  * Readline.completion_append_character = "string"
1163  * p Readline.completion_append_character # => "s"
1164  *
1165  * Raises NotImplementedError if the using readline library does not support.
1166  */
1167 static VALUE
1169 {
1170  if (NIL_P(str)) {
1171  rl_completion_append_character = '\0';
1172  }
1173  else {
1174  OutputStringValue(str);
1175  if (RSTRING_LEN(str) == 0) {
1176  rl_completion_append_character = '\0';
1177  } else {
1178  rl_completion_append_character = RSTRING_PTR(str)[0];
1179  }
1180  }
1181  return self;
1182 }
1183 #else
1184 #define readline_s_set_completion_append_character rb_f_notimplement
1185 #endif
1186 
1187 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
1188 /*
1189  * call-seq:
1190  * Readline.completion_append_character -> char
1191  *
1192  * Returns a string containing a character to be appended on
1193  * completion. The default is a space (" ").
1194  *
1195  * Raises NotImplementedError if the using readline library does not support.
1196  */
1197 static VALUE
1199 {
1200  char buf[1];
1201 
1202  if (rl_completion_append_character == '\0')
1203  return Qnil;
1204 
1205  buf[0] = (char) rl_completion_append_character;
1206  return rb_locale_str_new(buf, 1);
1207 }
1208 #else
1209 #define readline_s_get_completion_append_character rb_f_notimplement
1210 #endif
1211 
1212 #ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS
1213 /*
1214  * call-seq:
1215  * Readline.basic_word_break_characters = string
1216  *
1217  * Sets the basic list of characters that signal a break between words
1218  * for the completer routine. The default is the characters which
1219  * break words for completion in Bash: " \t\n\"\\'`@$><=;|&{(".
1220  *
1221  * Raises NotImplementedError if the using readline library does not support.
1222  */
1223 static VALUE
1225 {
1226  static char *basic_word_break_characters = NULL;
1227 
1228  OutputStringValue(str);
1229  if (basic_word_break_characters == NULL) {
1230  basic_word_break_characters =
1231  ALLOC_N(char, RSTRING_LEN(str) + 1);
1232  }
1233  else {
1234  REALLOC_N(basic_word_break_characters, char, RSTRING_LEN(str) + 1);
1235  }
1236  strncpy(basic_word_break_characters,
1237  RSTRING_PTR(str), RSTRING_LEN(str));
1238  basic_word_break_characters[RSTRING_LEN(str)] = '\0';
1239  rl_basic_word_break_characters = basic_word_break_characters;
1240  return self;
1241 }
1242 #else
1243 #define readline_s_set_basic_word_break_characters rb_f_notimplement
1244 #endif
1245 
1246 #ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS
1247 /*
1248  * call-seq:
1249  * Readline.basic_word_break_characters -> string
1250  *
1251  * Gets the basic list of characters that signal a break between words
1252  * for the completer routine.
1253  *
1254  * Raises NotImplementedError if the using readline library does not support.
1255  */
1256 static VALUE
1258 {
1259  if (rl_basic_word_break_characters == NULL)
1260  return Qnil;
1261  return rb_locale_str_new_cstr(rl_basic_word_break_characters);
1262 }
1263 #else
1264 #define readline_s_get_basic_word_break_characters rb_f_notimplement
1265 #endif
1266 
1267 #ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS
1268 /*
1269  * call-seq:
1270  * Readline.completer_word_break_characters = string
1271  *
1272  * Sets the basic list of characters that signal a break between words
1273  * for rl_complete_internal(). The default is the value of
1274  * Readline.basic_word_break_characters.
1275  *
1276  * Raises NotImplementedError if the using readline library does not support.
1277  */
1278 static VALUE
1280 {
1281  static char *completer_word_break_characters = NULL;
1282 
1283  OutputStringValue(str);
1284  if (completer_word_break_characters == NULL) {
1285  completer_word_break_characters =
1286  ALLOC_N(char, RSTRING_LEN(str) + 1);
1287  }
1288  else {
1289  REALLOC_N(completer_word_break_characters, char, RSTRING_LEN(str) + 1);
1290  }
1291  strncpy(completer_word_break_characters,
1292  RSTRING_PTR(str), RSTRING_LEN(str));
1293  completer_word_break_characters[RSTRING_LEN(str)] = '\0';
1294  rl_completer_word_break_characters = completer_word_break_characters;
1295  return self;
1296 }
1297 #else
1298 #define readline_s_set_completer_word_break_characters rb_f_notimplement
1299 #endif
1300 
1301 #ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS
1302 /*
1303  * call-seq:
1304  * Readline.completer_word_break_characters -> string
1305  *
1306  * Gets the basic list of characters that signal a break between words
1307  * for rl_complete_internal().
1308  *
1309  * Raises NotImplementedError if the using readline library does not support.
1310  */
1311 static VALUE
1313 {
1314  if (rl_completer_word_break_characters == NULL)
1315  return Qnil;
1316  return rb_locale_str_new_cstr(rl_completer_word_break_characters);
1317 }
1318 #else
1319 #define readline_s_get_completer_word_break_characters rb_f_notimplement
1320 #endif
1321 
1322 #if defined(HAVE_RL_SPECIAL_PREFIXES)
1323 /*
1324  * call-seq:
1325  * Readline.special_prefixes = string
1326  *
1327  * Sets the list of characters that are word break characters, but
1328  * should be left in text when it is passed to the completion
1329  * function. Programs can use this to help determine what kind of
1330  * completing to do. For instance, Bash sets this variable to "$@" so
1331  * that it can complete shell variables and hostnames.
1332  *
1333  * See GNU Readline's rl_special_prefixes variable.
1334  *
1335  * Raises NotImplementedError if the using readline library does not support.
1336  */
1337 static VALUE
1339 {
1340  if (!NIL_P(str)) {
1341  OutputStringValue(str);
1342  str = rb_str_dup_frozen(str);
1343  rb_obj_hide(str);
1344  }
1345  rb_ivar_set(mReadline, id_special_prefixes, str);
1346  if (NIL_P(str)) {
1347  rl_special_prefixes = NULL;
1348  }
1349  else {
1350  rl_special_prefixes = RSTRING_PTR(str);
1351  }
1352  return self;
1353 }
1354 
1355 /*
1356  * call-seq:
1357  * Readline.special_prefixes -> string
1358  *
1359  * Gets the list of characters that are word break characters, but
1360  * should be left in text when it is passed to the completion
1361  * function.
1362  *
1363  * See GNU Readline's rl_special_prefixes variable.
1364  *
1365  * Raises NotImplementedError if the using readline library does not support.
1366  */
1367 static VALUE
1369 {
1370  VALUE str;
1371  if (rl_special_prefixes == NULL) return Qnil;
1372  str = rb_ivar_get(mReadline, id_special_prefixes);
1373  if (!NIL_P(str)) {
1374  str = rb_str_dup_frozen(str);
1375  rb_obj_reveal(str, rb_cString);
1376  }
1377  return str;
1378 }
1379 #else
1380 #define readline_s_set_special_prefixes rb_f_notimplement
1381 #define readline_s_get_special_prefixes rb_f_notimplement
1382 #endif
1383 
1384 #ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS
1385 /*
1386  * call-seq:
1387  * Readline.basic_quote_characters = string
1388  *
1389  * Sets a list of quote characters which can cause a word break.
1390  *
1391  * Raises NotImplementedError if the using readline library does not support.
1392  */
1393 static VALUE
1395 {
1396  static char *basic_quote_characters = NULL;
1397 
1398  OutputStringValue(str);
1399  if (basic_quote_characters == NULL) {
1400  basic_quote_characters =
1401  ALLOC_N(char, RSTRING_LEN(str) + 1);
1402  }
1403  else {
1404  REALLOC_N(basic_quote_characters, char, RSTRING_LEN(str) + 1);
1405  }
1406  strncpy(basic_quote_characters,
1407  RSTRING_PTR(str), RSTRING_LEN(str));
1408  basic_quote_characters[RSTRING_LEN(str)] = '\0';
1409  rl_basic_quote_characters = basic_quote_characters;
1410 
1411  return self;
1412 }
1413 #else
1414 #define readline_s_set_basic_quote_characters rb_f_notimplement
1415 #endif
1416 
1417 #ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS
1418 /*
1419  * call-seq:
1420  * Readline.basic_quote_characters -> string
1421  *
1422  * Gets a list of quote characters which can cause a word break.
1423  *
1424  * Raises NotImplementedError if the using readline library does not support.
1425  */
1426 static VALUE
1428 {
1429  if (rl_basic_quote_characters == NULL)
1430  return Qnil;
1431  return rb_locale_str_new_cstr(rl_basic_quote_characters);
1432 }
1433 #else
1434 #define readline_s_get_basic_quote_characters rb_f_notimplement
1435 #endif
1436 
1437 #ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS
1438 /*
1439  * call-seq:
1440  * Readline.completer_quote_characters = string
1441  *
1442  * Sets a list of characters which can be used to quote a substring of
1443  * the line. Completion occurs on the entire substring, and within
1444  * the substring Readline.completer_word_break_characters are treated
1445  * as any other character, unless they also appear within this list.
1446  *
1447  * Raises NotImplementedError if the using readline library does not support.
1448  */
1449 static VALUE
1451 {
1452  static char *completer_quote_characters = NULL;
1453 
1454  OutputStringValue(str);
1455  if (completer_quote_characters == NULL) {
1456  completer_quote_characters =
1457  ALLOC_N(char, RSTRING_LEN(str) + 1);
1458  }
1459  else {
1460  REALLOC_N(completer_quote_characters, char, RSTRING_LEN(str) + 1);
1461  }
1462  strncpy(completer_quote_characters, RSTRING_PTR(str), RSTRING_LEN(str));
1463  completer_quote_characters[RSTRING_LEN(str)] = '\0';
1464  rl_completer_quote_characters = completer_quote_characters;
1465 
1466  return self;
1467 }
1468 #else
1469 #define readline_s_set_completer_quote_characters rb_f_notimplement
1470 #endif
1471 
1472 #ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS
1473 /*
1474  * call-seq:
1475  * Readline.completer_quote_characters -> string
1476  *
1477  * Gets a list of characters which can be used to quote a substring of
1478  * the line.
1479  *
1480  * Raises NotImplementedError if the using readline library does not support.
1481  */
1482 static VALUE
1484 {
1485  if (rl_completer_quote_characters == NULL)
1486  return Qnil;
1487  return rb_locale_str_new_cstr(rl_completer_quote_characters);
1488 }
1489 #else
1490 #define readline_s_get_completer_quote_characters rb_f_notimplement
1491 #endif
1492 
1493 #ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS
1494 /*
1495  * call-seq:
1496  * Readline.filename_quote_characters = string
1497  *
1498  * Sets a list of characters that cause a filename to be quoted by the completer
1499  * when they appear in a completed filename. The default is nil.
1500  *
1501  * Raises NotImplementedError if the using readline library does not support.
1502  */
1503 static VALUE
1505 {
1506  static char *filename_quote_characters = NULL;
1507 
1508  OutputStringValue(str);
1509  if (filename_quote_characters == NULL) {
1510  filename_quote_characters =
1511  ALLOC_N(char, RSTRING_LEN(str) + 1);
1512  }
1513  else {
1514  REALLOC_N(filename_quote_characters, char, RSTRING_LEN(str) + 1);
1515  }
1516  strncpy(filename_quote_characters, RSTRING_PTR(str), RSTRING_LEN(str));
1517  filename_quote_characters[RSTRING_LEN(str)] = '\0';
1518  rl_filename_quote_characters = filename_quote_characters;
1519 
1520  return self;
1521 }
1522 #else
1523 #define readline_s_set_filename_quote_characters rb_f_notimplement
1524 #endif
1525 
1526 #ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS
1527 /*
1528  * call-seq:
1529  * Readline.filename_quote_characters -> string
1530  *
1531  * Gets a list of characters that cause a filename to be quoted by the completer
1532  * when they appear in a completed filename.
1533  *
1534  * Raises NotImplementedError if the using readline library does not support.
1535  */
1536 static VALUE
1538 {
1539  if (rl_filename_quote_characters == NULL)
1540  return Qnil;
1541  return rb_locale_str_new_cstr(rl_filename_quote_characters);
1542 }
1543 #else
1544 #define readline_s_get_filename_quote_characters rb_f_notimplement
1545 #endif
1546 
1547 #ifdef HAVE_RL_REFRESH_LINE
1548 /*
1549  * call-seq:
1550  * Readline.refresh_line -> nil
1551  *
1552  * Clear the current input line.
1553  */
1554 static VALUE
1556 {
1557  rl_refresh_line(0, 0);
1558  return Qnil;
1559 }
1560 #else
1561 #define readline_s_refresh_line rb_f_notimplement
1562 #endif
1563 
1564 static VALUE
1566 {
1567  return rb_str_new_cstr("HISTORY");
1568 }
1569 
1570 static int
1572 {
1573  return history_base + offset;
1574 }
1575 
1576 static int
1578 {
1579  return offset;
1580 }
1581 
1582 static VALUE
1584 {
1585  HIST_ENTRY *entry = NULL;
1586  int i;
1587 
1588  i = NUM2INT(index);
1589  if (i < 0) {
1590  i += history_length;
1591  }
1592  if (i >= 0) {
1593  entry = history_get(history_get_offset_func(i));
1594  }
1595  if (entry == NULL) {
1596  rb_raise(rb_eIndexError, "invalid index");
1597  }
1598  return rb_locale_str_new_cstr(entry->line);
1599 }
1600 
1601 #ifdef HAVE_REPLACE_HISTORY_ENTRY
1602 static VALUE
1603 hist_set(VALUE self, VALUE index, VALUE str)
1604 {
1605  HIST_ENTRY *entry = NULL;
1606  int i;
1607 
1608  i = NUM2INT(index);
1609  OutputStringValue(str);
1610  if (i < 0) {
1611  i += history_length;
1612  }
1613  if (i >= 0) {
1614  entry = replace_history_entry(history_replace_offset_func(i), RSTRING_PTR(str), NULL);
1615  }
1616  if (entry == NULL) {
1617  rb_raise(rb_eIndexError, "invalid index");
1618  }
1619  return str;
1620 }
1621 #else
1622 #define hist_set rb_f_notimplement
1623 #endif
1624 
1625 static VALUE
1627 {
1628  OutputStringValue(str);
1629  add_history(RSTRING_PTR(str));
1630  return self;
1631 }
1632 
1633 static VALUE
1635 {
1636  VALUE str;
1637 
1638  while (argc--) {
1639  str = *argv++;
1640  OutputStringValue(str);
1641  add_history(RSTRING_PTR(str));
1642  }
1643  return self;
1644 }
1645 
1646 static VALUE
1648 {
1649 #ifdef HAVE_REMOVE_HISTORY
1650  HIST_ENTRY *entry;
1651  VALUE val;
1652 
1653  entry = remove_history(index);
1654  if (entry) {
1655  val = rb_locale_str_new_cstr(entry->line);
1656  free((void *) entry->line);
1657  free(entry);
1658  return val;
1659  }
1660  return Qnil;
1661 #else
1662  rb_notimplement();
1663 
1664  UNREACHABLE;
1665 #endif
1666 }
1667 
1668 static VALUE
1670 {
1671  if (history_length > 0) {
1672  return rb_remove_history(history_length - 1);
1673  } else {
1674  return Qnil;
1675  }
1676 }
1677 
1678 static VALUE
1680 {
1681  if (history_length > 0) {
1682  return rb_remove_history(0);
1683  } else {
1684  return Qnil;
1685  }
1686 }
1687 
1688 static VALUE
1690 {
1691  HIST_ENTRY *entry;
1692  int i;
1693 
1694  RETURN_ENUMERATOR(self, 0, 0);
1695 
1696  for (i = 0; i < history_length; i++) {
1697  entry = history_get(history_get_offset_func(i));
1698  if (entry == NULL)
1699  break;
1700  rb_yield(rb_locale_str_new_cstr(entry->line));
1701  }
1702  return self;
1703 }
1704 
1705 static VALUE
1707 {
1708  return INT2NUM(history_length);
1709 }
1710 
1711 static VALUE
1713 {
1714  return history_length == 0 ? Qtrue : Qfalse;
1715 }
1716 
1717 static VALUE
1719 {
1720  int i;
1721 
1722  i = NUM2INT(index);
1723  if (i < 0)
1724  i += history_length;
1725  if (i < 0 || i > history_length - 1) {
1726  rb_raise(rb_eIndexError, "invalid index");
1727  }
1728  return rb_remove_history(i);
1729 }
1730 
1731 #ifdef HAVE_CLEAR_HISTORY
1732 static VALUE
1733 hist_clear(VALUE self)
1734 {
1735  clear_history();
1736  return self;
1737 }
1738 #else
1739 #define hist_clear rb_f_notimplement
1740 #endif
1741 
1742 static VALUE
1744 {
1745  VALUE result;
1746  char **matches;
1747  int i;
1748 
1749  matches = rl_completion_matches(StringValuePtr(str),
1751  if (matches) {
1752  result = rb_ary_new();
1753  for (i = 0; matches[i]; i++) {
1754  rb_ary_push(result, rb_locale_str_new_cstr(matches[i]));
1755  free(matches[i]);
1756  }
1757  free(matches);
1758  if (RARRAY_LEN(result) >= 2)
1759  rb_ary_shift(result);
1760  }
1761  else {
1762  result = Qnil;
1763  }
1764  return result;
1765 }
1766 
1767 static VALUE
1769 {
1770  VALUE result;
1771  char **matches;
1772  int i;
1773 
1774  matches = rl_completion_matches(StringValuePtr(str),
1776  if (matches) {
1777  result = rb_ary_new();
1778  for (i = 0; matches[i]; i++) {
1779  rb_ary_push(result, rb_locale_str_new_cstr(matches[i]));
1780  free(matches[i]);
1781  }
1782  free(matches);
1783  if (RARRAY_LEN(result) >= 2)
1784  rb_ary_shift(result);
1785  }
1786  else {
1787  result = Qnil;
1788  }
1789  return result;
1790 }
1791 
1792 void
1794 {
1795  VALUE history, fcomp, ucomp, version;
1796 
1797  /* Allow conditional parsing of the ~/.inputrc file. */
1798  rl_readline_name = (char *)"Ruby";
1799 
1800 #if defined HAVE_RL_GETC_FUNCTION
1801  /* libedit check rl_getc_function only when rl_initialize() is called, */
1802  /* and using_history() call rl_initialize(). */
1803  /* This assignment should be placed before using_history() */
1804  rl_getc_function = readline_getc;
1805 #elif defined HAVE_RL_EVENT_HOOK
1806  rl_event_hook = readline_event;
1807 #endif
1808 
1809  using_history();
1810 
1813 #if defined(HAVE_RL_PRE_INPUT_HOOK)
1814  id_pre_input_hook = rb_intern("pre_input_hook");
1815 #endif
1816 #if defined(HAVE_RL_SPECIAL_PREFIXES)
1817  id_special_prefixes = rb_intern("special_prefixes");
1818 #endif
1819 
1820  mReadline = rb_define_module("Readline");
1822  readline_readline, -1);
1827  rb_define_singleton_method(mReadline, "completion_proc=",
1829  rb_define_singleton_method(mReadline, "completion_proc",
1831  rb_define_singleton_method(mReadline, "completion_case_fold=",
1833  rb_define_singleton_method(mReadline, "completion_case_fold",
1835  rb_define_singleton_method(mReadline, "line_buffer",
1841  rb_define_singleton_method(mReadline, "set_screen_size",
1843  rb_define_singleton_method(mReadline, "get_screen_size",
1845  rb_define_singleton_method(mReadline, "vi_editing_mode",
1847  rb_define_singleton_method(mReadline, "vi_editing_mode?",
1849  rb_define_singleton_method(mReadline, "emacs_editing_mode",
1851  rb_define_singleton_method(mReadline, "emacs_editing_mode?",
1853  rb_define_singleton_method(mReadline, "completion_append_character=",
1855  rb_define_singleton_method(mReadline, "completion_append_character",
1857  rb_define_singleton_method(mReadline, "basic_word_break_characters=",
1859  rb_define_singleton_method(mReadline, "basic_word_break_characters",
1861  rb_define_singleton_method(mReadline, "completer_word_break_characters=",
1863  rb_define_singleton_method(mReadline, "completer_word_break_characters",
1865  rb_define_singleton_method(mReadline, "basic_quote_characters=",
1867  rb_define_singleton_method(mReadline, "basic_quote_characters",
1869  rb_define_singleton_method(mReadline, "completer_quote_characters=",
1871  rb_define_singleton_method(mReadline, "completer_quote_characters",
1873  rb_define_singleton_method(mReadline, "filename_quote_characters=",
1875  rb_define_singleton_method(mReadline, "filename_quote_characters",
1877  rb_define_singleton_method(mReadline, "refresh_line",
1879  rb_define_singleton_method(mReadline, "pre_input_hook=",
1881  rb_define_singleton_method(mReadline, "pre_input_hook",
1883  rb_define_singleton_method(mReadline, "insert_text",
1885  rb_define_singleton_method(mReadline, "delete_text",
1889  rb_define_singleton_method(mReadline, "special_prefixes=",
1891  rb_define_singleton_method(mReadline, "special_prefixes",
1893 
1894 #if USE_INSERT_IGNORE_ESCAPE
1895  CONST_ID(id_orig_prompt, "orig_prompt");
1896  CONST_ID(id_last_prompt, "last_prompt");
1897 #endif
1898 
1899  history = rb_obj_alloc(rb_cObject);
1900  rb_extend_object(history, rb_mEnumerable);
1901  rb_define_singleton_method(history,"to_s", hist_to_s, 0);
1902  rb_define_singleton_method(history,"[]", hist_get, 1);
1903  rb_define_singleton_method(history,"[]=", hist_set, 2);
1904  rb_define_singleton_method(history,"<<", hist_push, 1);
1905  rb_define_singleton_method(history,"push", hist_push_method, -1);
1906  rb_define_singleton_method(history,"pop", hist_pop, 0);
1907  rb_define_singleton_method(history,"shift", hist_shift, 0);
1908  rb_define_singleton_method(history,"each", hist_each, 0);
1909  rb_define_singleton_method(history,"length", hist_length, 0);
1910  rb_define_singleton_method(history,"size", hist_length, 0);
1911  rb_define_singleton_method(history,"empty?", hist_empty_p, 0);
1912  rb_define_singleton_method(history,"delete_at", hist_delete_at, 1);
1913  rb_define_singleton_method(history,"clear", hist_clear, 0);
1914 
1915  /*
1916  * The history buffer. It extends Enumerable module, so it behaves
1917  * just like an array.
1918  * For example, gets the fifth content that the user input by
1919  * HISTORY[4].
1920  */
1921  rb_define_const(mReadline, "HISTORY", history);
1922 
1923  fcomp = rb_obj_alloc(rb_cObject);
1924  rb_define_singleton_method(fcomp, "call",
1926  /*
1927  * The Object with the call method that is a completion for filename.
1928  * This is sets by Readline.completion_proc= method.
1929  */
1930  rb_define_const(mReadline, "FILENAME_COMPLETION_PROC", fcomp);
1931 
1932  ucomp = rb_obj_alloc(rb_cObject);
1933  rb_define_singleton_method(ucomp, "call",
1935  /*
1936  * The Object with the call method that is a completion for usernames.
1937  * This is sets by Readline.completion_proc= method.
1938  */
1939  rb_define_const(mReadline, "USERNAME_COMPLETION_PROC", ucomp);
1942 #if defined HAVE_RL_LIBRARY_VERSION
1943  version = rb_str_new_cstr(rl_library_version);
1944 #if defined HAVE_CLEAR_HISTORY || defined HAVE_REMOVE_HISTORY
1945  if (strncmp(rl_library_version, EDIT_LINE_LIBRARY_VERSION,
1947  add_history("1");
1948  if (history_get(history_get_offset_func(0)) == NULL) {
1950  }
1951 #ifdef HAVE_REPLACE_HISTORY_ENTRY
1952  if (replace_history_entry(0, "a", NULL) == NULL) {
1954  }
1955 #endif
1956 #ifdef HAVE_CLEAR_HISTORY
1957  clear_history();
1958 #else
1959  {
1960  HIST_ENTRY *entry = remove_history(0);
1961  if (entry) {
1962  free((char *)entry->line);
1963  free(entry);
1964  }
1965  }
1966 #endif
1967  }
1968 #endif
1969 #else
1970  version = rb_str_new_cstr("2.0 or prior version");
1971 #endif
1972  /* Version string of GNU Readline or libedit. */
1973  rb_define_const(mReadline, "VERSION", version);
1974 
1975  rl_attempted_completion_function = readline_attempted_completion_function;
1976 #if defined(HAVE_RL_PRE_INPUT_HOOK)
1977  rl_pre_input_hook = (rl_hook_func_t *)readline_pre_input_hook;
1978 #endif
1979 #ifdef HAVE_RL_CATCH_SIGNALS
1980  rl_catch_signals = 0;
1981 #endif
1982 #ifdef HAVE_RL_CLEAR_SIGNALS
1983  rl_clear_signals();
1984 #endif
1985 
1988 }
VALUE data
Definition: tcltklib.c:3360
static ID completion_case_fold
Definition: readline.c:61
#define RB_TYPE_P(obj, type)
RARRAY_PTR(q->result)[0]
union RString::@95 as
#define rb_check_arity
rb_encoding * rb_enc_check(VALUE str1, VALUE str2)
Definition: encoding.c:838
#define readline_s_get_line_buffer
Definition: readline.c:885
VP_EXPORT int
Definition: bigdecimal.c:5172
void rb_bug(const char *fmt,...)
Definition: error.c:327
void * malloc()
#define readline_s_get_basic_quote_characters
Definition: readline.c:1434
size_t strlen(const char *)
int rb_w32_wait_events(HANDLE *events, int num, DWORD timeout)
static VALUE readline_get(VALUE prompt)
Definition: readline.c:330
VALUE rb_str_tmp_new(long)
Definition: string.c:919
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1646
struct RString::@95::@96 heap
static VALUE mReadline
Definition: readline.c:48
VALUE proc
Definition: tcltklib.c:2955
static VALUE readline_s_set_input(VALUE self, VALUE input)
Definition: readline.c:528
rb_funcall(memo->yielder, id_lshift, 1, rb_assoc_new(memo->prev_value, memo->prev_elts))
Definition: io.h:61
static VALUE hist_to_s(VALUE self)
Definition: readline.c:1565
VALUE rb_str_locktmp(VALUE)
void rb_io_check_initialized(rb_io_t *)
Definition: io.c:609
VALUE rb_ary_shift(VALUE ary)
Definition: array.c:995
static char ** readline_attempted_completion_function(const char *text, int start, int end)
Definition: readline.c:933
void * rb_thread_call_without_gvl2(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
Definition: thread.c:1370
#define readline_s_set_completer_word_break_characters
Definition: readline.c:1298
#define readline_s_emacs_editing_mode
Definition: readline.c:1109
VALUE rb_str_new_cstr(const char *)
Definition: string.c:560
#define readline_s_set_pre_input_hook
Definition: readline.c:644
int ret
Definition: tcltklib.c:285
VALUE rb_enc_from_encoding(rb_encoding *encoding)
Definition: encoding.c:102
static ID completion_proc
Definition: readline.c:61
int status
Definition: tcltklib.c:2197
rb_yield(i)
long rb_str_strlen(VALUE)
Definition: string.c:1284
#define OBJ_FREEZE(x)
static FILE * readline_rl_outstream
Definition: readline.c:133
#define UNREACHABLE
Definition: ruby.h:42
VALUE enc
Definition: tcltklib.c:10318
#define RUBY_UBF_IO
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:900
struct RBasic basic
Definition: ripper.y:821
#define RSTRING_PTR(str)
#define readline_s_get_special_prefixes
Definition: readline.c:1381
NIL_P(eventloop_thread)
Definition: tcltklib.c:4056
#define RFILE(obj)
#define T_ARRAY
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *state)
Definition: eval.c:807
unsigned int rb_enc_codepoint_len(const char *p, const char *e, int *len_p, rb_encoding *enc)
Definition: encoding.c:993
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1857
return Qtrue
Definition: tcltklib.c:9618
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
Definition: encoding.c:826
#define RETURN_ENUMERATOR(obj, argc, argv)
VALUE rb_io_taint_check(VALUE)
Definition: io.c:602
VALUE entry[3]
Definition: ossl_x509name.c:99
#define T_FILE
int index
Definition: tcltklib.c:4468
RUBY_EXTERN VALUE rb_eIOError
Definition: ripper.y:1611
rb_thread_check_ints()
Definition: thread.c:1143
#define readline_s_insert_text
Definition: readline.c:667
#define COMPLETION_CASE_FOLD
Definition: readline.c:60
static VALUE hist_pop(VALUE self)
Definition: readline.c:1669
static VALUE readline_s_get_completion_case_fold(VALUE self)
Definition: readline.c:858
VALUE rb_obj_reveal(VALUE obj, VALUE klass)
Definition: object.c:62
VALUE rb_locale_str_new(const char *, long)
Definition: string.c:719
tmp
Definition: enum.c:447
int rb_cloexec_dup(int oldfd)
Definition: io.c:244
VALUE rb_str_unlocktmp(VALUE)
Definition: string.c:1990
static VALUE readline_s_set_output(VALUE self, VALUE output)
Definition: readline.c:565
#define GetOpenFile(obj, fp)
Definition: io.h:118
static int history_get_offset_history_base(int offset)
Definition: readline.c:1571
static VALUE hist_push(VALUE self, VALUE str)
Definition: readline.c:1626
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1115
#define readline_s_delete_text
Definition: readline.c:718
i
Definition: enum.c:446
#define readline_s_vi_editing_mode_p
Definition: readline.c:1089
VALUE ary
Definition: enum.c:674
#define OutputStringValue(str)
Definition: readline.c:91
#define ISALPHA(c)
Definition: ruby.h:1782
static VALUE hist_length(VALUE self)
Definition: readline.c:1706
static unsigned char * output
Definition: nkf.c:32
static VALUE filename_completion_proc_call(VALUE self, VALUE str)
Definition: readline.c:1743
static VALUE hist_each(VALUE self)
Definition: readline.c:1689
strcpy(cmd2, cmd)
#define readline_s_get_pre_input_hook
Definition: readline.c:645
#define rl_filename_completion_function
Definition: readline.c:73
static VALUE readline_outstream
Definition: readline.c:131
#define readline_s_set_completer_quote_characters
Definition: readline.c:1469
unsigned int input
Definition: nkf.c:4311
return Qfalse
Definition: tcltklib.c:6790
#define RARRAY_LEN(a)
#define readline_s_get_basic_word_break_characters
Definition: readline.c:1264
#define Qnil
Definition: enum.c:67
#define StringValuePtr(v)
#define val
Definition: tcltklib.c:1935
#define COMPLETION_PROC
Definition: readline.c:59
#define EDIT_LINE_LIBRARY_VERSION
Definition: readline.c:50
static VALUE char * str
Definition: tcltklib.c:3539
VALUE rb_locale_str_new_cstr(const char *)
Definition: string.c:725
#define readline_s_refresh_line
Definition: readline.c:1561
VALUE rb_ary_new(void)
Definition: array.c:499
#define StringValueCStr(v)
unsigned long ID
Definition: ripper.y:89
static VALUE username_completion_proc_call(VALUE self, VALUE str)
Definition: readline.c:1768
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2228
Check_Type(i, T_ARRAY)
static VALUE hist_shift(VALUE self)
Definition: readline.c:1679
#define RSTRING_LEN(str)
#define readline_s_get_filename_quote_characters
Definition: readline.c:1544
int fd
Definition: io.h:62
volatile VALUE encobj
Definition: tcltklib.c:10163
#define readline_s_vi_editing_mode
Definition: readline.c:1071
#define T_STRING
#define readline_s_emacs_editing_mode_p
Definition: readline.c:1127
#define RSTRING_NOEMBED
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
int err
Definition: win32.c:114
VALUE rb_eIndexError
Definition: error.c:550
#define readline_s_set_point
Definition: readline.c:929
int len
Definition: enumerator.c:1332
static VALUE hist_push_method(int argc, VALUE *argv, VALUE self)
Definition: readline.c:1634
VALUE rb_str_new_shared(VALUE)
Definition: string.c:799
#define EOF
Definition: vsnprintf.c:207
#define rb_long2int(n)
VALUE rb_obj_as_string(VALUE)
Definition: string.c:1011
VALUE rb_obj_hide(VALUE obj)
Definition: object.c:53
VALUE * argv
Definition: tcltklib.c:1969
#define RTEST(v)
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1661
int errno
VALUE rb_mEnumerable
Definition: enum.c:20
register char * s
Definition: os2.c:56
#define CONST_ID(var, str)
#define strdup(s)
Definition: util.h:67
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1719
static int history_get_offset_0(int offset)
Definition: readline.c:1577
#define readline_s_set_special_prefixes
Definition: readline.c:1380
int argc
Definition: tcltklib.c:1968
rb_encoding * rb_locale_encoding(void)
Definition: encoding.c:1309
static VALUE readline_s_set_completion_proc(VALUE self, VALUE proc)
Definition: readline.c:812
void rb_extend_object(VALUE obj, VALUE module)
Definition: eval.c:1318
int rb_wait_for_single_fd(int fd, int events, struct timeval *tv)
Definition: thread.c:3779
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1127
VALUE flags
Definition: ripper.y:748
static int(* history_get_offset_func)(int)
Definition: readline.c:82
void rb_thread_schedule(void)
Definition: thread.c:1191
void rb_sys_fail(const char *mesg)
Definition: error.c:1976
#define readline_s_get_point
Definition: readline.c:928
RUBY_EXTERN VALUE rb_cString
Definition: ripper.y:1591
void rb_jump_tag(int tag)
Definition: eval.c:706
return ptr
Definition: tcltklib.c:789
#define free(x)
Definition: dln.c:50
static VALUE hist_empty_p(VALUE self)
Definition: readline.c:1712
void rb_memerror(void)
Definition: gc.c:5885
static VALUE readline_s_set_completion_case_fold(VALUE self, VALUE val)
Definition: readline.c:838
gz end
Definition: zlib.c:2272
#define readline_s_set_filename_quote_characters
Definition: readline.c:1523
void rb_gc_register_address(VALUE *)
Definition: gc.c:4930
VALUE rb_str_cat(VALUE, const char *, long)
Definition: string.c:2139
#define readline_s_redisplay
Definition: readline.c:740
#define f
#define NUM2LONG(x)
void Init_readline()
Definition: readline.c:1793
#define hist_set
Definition: readline.c:1622
static VALUE readline_s_get_completion_proc(VALUE self)
Definition: readline.c:826
static VALUE rb_remove_history(int index)
Definition: readline.c:1647
#define readline_s_get_completer_quote_characters
Definition: readline.c:1490
#define rb_str_dup_frozen
#define readline_s_set_screen_size
Definition: readline.c:1024
static int(* history_replace_offset_func)(int)
Definition: readline.c:83
RUBY_EXTERN VALUE rb_cObject
Definition: ripper.y:1561
#define ALLOC_N(type, n)
static VALUE readline_readline(int argc, VALUE *argv, VALUE self)
Definition: readline.c:447
#define INT2NUM(x)
#define EWOULDBLOCK
Definition: rubysocket.h:126
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:1651
static VALUE hist_get(VALUE self, VALUE index)
Definition: readline.c:1583
void rb_notimplement(void)
Definition: error.c:1903
#define hist_clear
Definition: readline.c:1739
#define rl_username_completion_function
Definition: readline.c:76
register C_block * p
Definition: crypt.c:309
rb_ivar_set(yielder, id_memo, LONG2NUM(++count))
#define rl_completion_matches
Definition: readline.c:79
#define readline_s_get_screen_size
Definition: readline.c:1051
int rb_tolower(int c)
Definition: encoding.c:1952
data n
Definition: enum.c:860
#define readline_s_set_basic_word_break_characters
Definition: readline.c:1243
Real * res
Definition: bigdecimal.c:1251
VALUE rb_range_beg_len(VALUE, long *, long *, long, int)
Definition: range.c:1020
#define NUM2INT(x)
static FILE * readline_rl_instream
Definition: readline.c:132
VALUE rb_obj_alloc(VALUE)
Definition: object.c:1804
#define readline_s_get_completion_append_character
Definition: readline.c:1209
BDIGIT e
Definition: bigdecimal.c:5209
unsigned long VALUE
Definition: ripper.y:88
#define fileno(p)
Definition: vsnprintf.c:223
char * rb_str_subpos(VALUE, long, long *)
Definition: string.c:1859
static void version(void)
Definition: nkf.c:898
#define RB_WAITFD_IN
Definition: io.h:47
VALUE rb_define_module(const char *name)
Definition: class.c:727
#define rb_intern(str)
static VALUE readline_instream
Definition: readline.c:130
#define readline_s_set_basic_quote_characters
Definition: readline.c:1414
static void clear_rl_instream(void)
Definition: readline.c:339
static void clear_rl_outstream(void)
Definition: readline.c:351
#define NULL
Definition: _sdbm.c:102
#define REALLOC_N(var, type, n)
static VALUE hist_delete_at(VALUE self, VALUE index)
Definition: readline.c:1718
volatile VALUE result
Definition: enum.c:1989
VALUE rb_eArgError
Definition: error.c:549
#define readline_s_get_completer_word_break_characters
Definition: readline.c:1319
VALUE rb_Array(VALUE)
Definition: object.c:3038
#define readline_s_set_completion_append_character
Definition: readline.c:1184
void rb_str_set_len(VALUE, long)
Definition: string.c:2007