Ruby  2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)
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
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
fdopen
int int int int int int int int char char int int int int int int int int int char char int int int int int int int int FILE * fdopen(int, const char *)
ID
unsigned long ID
Definition: ruby.h:103
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
strncpy
char * strncpy(char *__restrict, const char *__restrict, size_t)
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
close
int close(int __fildes)
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
rb_scan_args
#define rb_scan_args(argc, argvp, fmt,...)
Definition: rb_mjit_min_header-2.7.0.h:6372
EWOULDBLOCK
#define EWOULDBLOCK
Definition: rubysocket.h:134
rb_gc_force_recycle
void rb_gc_force_recycle(VALUE obj)
Definition: gc.c:7011
EINTR
#define EINTR
Definition: rb_mjit_min_header-2.7.0.h:10941
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
fileno
int fileno(FILE *)
RB_WAITFD_IN
#define RB_WAITFD_IN
Definition: io.h:51
rb_locale_encoding
rb_encoding * rb_locale_encoding(void)
Definition: encoding.c:1372
VALUE
unsigned long VALUE
Definition: ruby.h:102
index
int index
Definition: rb_mjit_min_header-2.7.0.h:11246
rb_obj_as_string
VALUE rb_obj_as_string(VALUE)
Definition: string.c:1440
rb_eArgError
VALUE rb_eArgError
Definition: error.c:923
readline_s_set_completer_quote_characters
#define readline_s_set_completer_quote_characters
Definition: readline.c:1596
rb_intern
#define rb_intern(str)
malloc
void * malloc(size_t) __attribute__((__malloc__)) __attribute__((__warn_unused_result__)) __attribute__((__alloc_size__(1)))
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
int
__inline__ int
Definition: rb_mjit_min_header-2.7.0.h:2839
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:924
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:74
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
ssize_t
_ssize_t ssize_t
Definition: rb_mjit_min_header-2.7.0.h:1329
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)
strncmp
int strncmp(const char *, const char *, size_t)
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:1071
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:2669
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:2712
rb_ivar_get
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1070
T_FILE
#define T_FILE
Definition: ruby.h:534
EAGAIN
#define EAGAIN
Definition: rb_mjit_min_header-2.7.0.h:10948
rb_enc_str_new_static
VALUE rb_enc_str_new_static(const char *, long, rb_encoding *)
Definition: string.c:890
read
_ssize_t read(int __fd, void *__buf, size_t __nbyte)
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:2781
Init_readline
void Init_readline(void)
Definition: readline.c:1927
rb_encoding
const typedef OnigEncodingType rb_encoding
Definition: encoding.h:115
rb_Array
VALUE rb_Array(VALUE)
Equivalent to Kernel#Array in Ruby.
Definition: object.c:3684
i
uint32_t i
Definition: rb_mjit_min_header-2.7.0.h:5464
readline_s_set_special_prefixes
#define readline_s_set_special_prefixes
Definition: readline.c:1507
rb_str_dup_frozen
#define rb_str_dup_frozen
Definition: intern.h:792
rb_jump_tag
void rb_jump_tag(int tag)
Continues the exception caught by rb_protect() and rb_eval_string_protect().
Definition: eval.c:883
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
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:1195
RUBY_UBF_IO
#define RUBY_UBF_IO
Definition: intern.h:945
rb_sys_fail
void rb_sys_fail(const char *mesg)
Definition: error.c:2793
strcpy
char * strcpy(char *__restrict, const char *__restrict)
input
unsigned int input
Definition: nkf.c:4325
RETURN_ENUMERATOR
#define RETURN_ENUMERATOR(obj, argc, argv)
Definition: intern.h:279
RARRAY_AREF
#define RARRAY_AREF(a, i)
Definition: ruby.h:1101
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:7077
rb_str_new_cstr
#define rb_str_new_cstr(str)
Definition: rb_mjit_min_header-2.7.0.h:6117
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:1700
StringValueCStr
#define StringValueCStr(v)
Definition: ruby.h:604
rb_locale_str_new_cstr
#define rb_locale_str_new_cstr(str)
Definition: rb_mjit_min_header-2.7.0.h:6124
readline_s_set_screen_size
#define readline_s_set_screen_size
Definition: readline.c:1120
EOF
#define EOF
Definition: vsnprintf.c:203
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
char
#define char
Definition: rb_mjit_min_header-2.7.0.h:2876
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
n
const char size_t n
Definition: rb_mjit_min_header-2.7.0.h:5456
rb_funcall
#define rb_funcall(recv, mid, argc,...)
Definition: rb_mjit_min_header-2.7.0.h:6585
rb_bug
void rb_bug(const char *fmt,...)
Definition: error.c:634
rl_completion_matches
#define rl_completion_matches
Definition: readline.c:84
T_ARRAY
#define T_ARRAY
Definition: ruby.h:530
argv
char ** argv
Definition: ruby.c:223
f
#define f
readline_s_emacs_editing_mode_p
#define readline_s_emacs_editing_mode_p
Definition: readline.c:1225
strdup
char * strdup(const char *) __attribute__((__malloc__)) __attribute__((__warn_unused_result__))
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:1273
readline_s_get_special_prefixes
#define readline_s_get_special_prefixes
Definition: readline.c:1508
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_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
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:2880
fclose
int fclose(FILE *)
free
#define free(x)
Definition: dln.c:52
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
len
uint8_t len
Definition: escape.c:17
stdin
#define stdin
Definition: rb_mjit_min_header-2.7.0.h:1483
rb_memerror
void rb_memerror(void)
Definition: gc.c:9578
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
h
size_t st_index_t h
Definition: rb_mjit_min_header-2.7.0.h:5462
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
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