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