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