Ruby: ext/readline/readline.c Source File

Ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c52d4d35cc6a173c89eda98ceffa2dcf)

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
47static 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"
60static 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"
63static ID quoting_detection_proc;
64#endif
65#if USE_INSERT_IGNORE_ESCAPE
66static ID id_orig_prompt, id_last_prompt;
67#endif
68#if defined(HAVE_RL_PRE_INPUT_HOOK)
69static ID id_pre_input_hook;
70#endif
71#if defined(HAVE_RL_SPECIAL_PREFIXES)
72static 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 RUBY_EXTERN 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
87static int (*history_get_offset_func)(int);
88static int (*history_replace_offset_func)(int);
89#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
90static int readline_completion_append_character;
91#endif
92
93static 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
135static VALUE readline_instream;
136static VALUE readline_outstream;
137static FILE *readline_rl_instream;
138static FILE *readline_rl_outstream;
139
140static void
141mustbe_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
153struct getc_struct {
154 FILE *input;
155 int fd;
156 int ret;
157 int err;
158};
159
160static int
161getc_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
206static void *
207getc_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
216static int
217readline_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) {
233 rb_thread_check_ints();
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
253static int readline_event(void);
254static int
255readline_event(void)
256{
257#if BUSY_WAIT
258 rb_thread_schedule();
259#else
260 rb_wait_for_single_fd(fileno(rl_instream), RB_WAITFD_IN, NULL);
261 return 0;
262#endif
263}
264#endif
265
266#if USE_INSERT_IGNORE_ESCAPE
267static VALUE
268insert_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
341static VALUE
342readline_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
350static void
351clear_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
362static void
363clear_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
374static void
375prepare_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 */
486static VALUE
487readline_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 */
551static VALUE
552readline_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 {
562 Check_Type(input, T_FILE);
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 */
587static VALUE
588readline_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 */
631static VALUE
632 readline_s_set_pre_input_hook(VALUE self, VALUE proc)
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 */
648static VALUE
649 readline_s_get_pre_input_hook(VALUE self)
650{
651 return rb_attr_get(mReadline, id_pre_input_hook);
652}
653
654static int
655readline_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 */
680static VALUE
681 readline_s_insert_text(VALUE self, VALUE str)
682{
683 OutputStringValue(str);
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 RUBY_EXTERN int rl_delete_text(int, int);
693static const char *
694str_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);
699 rb_gc_force_recycle(str);
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 */
715static VALUE
716 readline_s_delete_text(int argc, VALUE *argv, VALUE self)
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;
723 rb_encoding *enc = rb_locale_encoding();
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 */
759static VALUE
760 readline_s_redisplay(VALUE self)
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 */
837static VALUE
838readline_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 */
850static VALUE
851readline_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 */
878static VALUE
879 readline_s_set_quoting_detection_proc(VALUE self, VALUE proc)
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 */
891static VALUE
892 readline_s_get_quoting_detection_proc(VALUE self)
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 */
907static VALUE
908readline_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 */
927static VALUE
928readline_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 */
947static VALUE
948 readline_s_get_line_buffer(VALUE self)
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 */
974static VALUE
975 readline_s_get_point(VALUE self)
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 */
991static VALUE
992 readline_s_set_point(VALUE self, VALUE pos)
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
1002static char **
1003readline_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
1077static int
1078readline_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 */
1113static 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 */
1134static VALUE
1135 readline_s_get_screen_size(VALUE self)
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 RUBY_EXTERN 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 */
1161static VALUE
1162 readline_s_vi_editing_mode(VALUE self)
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 */
1180static VALUE
1181 readline_s_vi_editing_mode_p(VALUE self)
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 RUBY_EXTERN 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 */
1200static VALUE
1201 readline_s_emacs_editing_mode(VALUE self)
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 */
1219static VALUE
1220 readline_s_emacs_editing_mode_p(VALUE self)
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 */
1265static VALUE
1266 readline_s_set_completion_append_character(VALUE self, VALUE str)
1267{
1268 if (NIL_P(str)) {
1269 rl_completion_append_character = '\0';
1270 }
1271 else {
1272 OutputStringValue(str);
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 */
1295static VALUE
1296 readline_s_get_completion_append_character(VALUE self)
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 */
1324static VALUE
1325 readline_s_get_completion_quote_character(VALUE self)
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 */
1350static VALUE
1351 readline_s_set_basic_word_break_characters(VALUE self, VALUE str)
1352{
1353 static char *basic_word_break_characters = NULL;
1354
1355 OutputStringValue(str);
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,
1364 RSTRING_PTR(str), RSTRING_LEN(str));
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 */
1383static VALUE
1384 readline_s_get_basic_word_break_characters(VALUE self)
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 */
1405static VALUE
1406 readline_s_set_completer_word_break_characters(VALUE self, VALUE str)
1407{
1408 static char *completer_word_break_characters = NULL;
1409
1410 OutputStringValue(str);
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,
1419 RSTRING_PTR(str), RSTRING_LEN(str));
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 */
1438static VALUE
1439 readline_s_get_completer_word_break_characters(VALUE self)
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 */
1464static VALUE
1465 readline_s_set_special_prefixes(VALUE self, VALUE str)
1466{
1467 if (!NIL_P(str)) {
1468 OutputStringValue(str);
1469 str = rb_str_dup_frozen(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 */
1494static VALUE
1495 readline_s_get_special_prefixes(VALUE self)
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)) {
1501 str = rb_str_dup_frozen(str);
1502 rb_obj_reveal(str, rb_cString);
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 */
1520static VALUE
1521 readline_s_set_basic_quote_characters(VALUE self, VALUE str)
1522{
1523 static char *basic_quote_characters = NULL;
1524
1525 OutputStringValue(str);
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,
1534 RSTRING_PTR(str), RSTRING_LEN(str));
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 */
1553static VALUE
1554 readline_s_get_basic_quote_characters(VALUE self)
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 */
1576static VALUE
1577 readline_s_set_completer_quote_characters(VALUE self, VALUE str)
1578{
1579 static char *completer_quote_characters = NULL;
1580
1581 OutputStringValue(str);
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 */
1609static VALUE
1610 readline_s_get_completer_quote_characters(VALUE self)
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 */
1630static VALUE
1631 readline_s_set_filename_quote_characters(VALUE self, VALUE str)
1632{
1633 static char *filename_quote_characters = NULL;
1634
1635 OutputStringValue(str);
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 */
1663static VALUE
1664 readline_s_get_filename_quote_characters(VALUE self)
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 RUBY_EXTERN int rl_refresh_line(int, int);
1676/*
1677 * call-seq:
1678 * Readline.refresh_line -> nil
1679 *
1680 * Clear the current input line.
1681 */
1682static VALUE
1683 readline_s_refresh_line(VALUE self)
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
1693static VALUE
1694hist_to_s(VALUE self)
1695{
1696 return rb_str_new_cstr("HISTORY");
1697}
1698
1699static int
1700history_get_offset_history_base(int offset)
1701{
1702 return history_base + offset;
1703}
1704
1705static int
1706history_get_offset_0(int offset)
1707{
1708 return offset;
1709}
1710
1711static VALUE
1712hist_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
1731static VALUE
1732 hist_set(VALUE self, VALUE index, VALUE str)
1733{
1734 HIST_ENTRY *entry = NULL;
1735 int i;
1736
1737 i = NUM2INT(index);
1738 OutputStringValue(str);
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
1754static VALUE
1755hist_push(VALUE self, VALUE str)
1756{
1757 OutputStringValue(str);
1758 add_history(RSTRING_PTR(str));
1759 return self;
1760}
1761
1762static VALUE
1763hist_push_method(int argc, VALUE *argv, VALUE self)
1764{
1765 VALUE str;
1766
1767 while (argc--) {
1768 str = *argv++;
1769 OutputStringValue(str);
1770 add_history(RSTRING_PTR(str));
1771 }
1772 return self;
1773}
1774
1775static VALUE
1776rb_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
1793 UNREACHABLE_RETURN(Qnil);
1794#endif
1795}
1796
1797static VALUE
1798hist_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
1807static VALUE
1808hist_shift(VALUE self)
1809{
1810 if (history_length > 0) {
1811 return rb_remove_history(0);
1812 } else {
1813 return Qnil;
1814 }
1815}
1816
1817static VALUE
1818hist_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
1834static VALUE
1835hist_length(VALUE self)
1836{
1837 return INT2NUM(history_length);
1838}
1839
1840static VALUE
1841hist_empty_p(VALUE self)
1842{
1843 return history_length == 0 ? Qtrue : Qfalse;
1844}
1845
1846static VALUE
1847hist_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
1861static 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
1871static VALUE
1872filename_completion_proc_call(VALUE self, VALUE str)
1873{
1874 VALUE result;
1875 char **matches;
1876 int i;
1877
1878 matches = rl_completion_matches(StringValuePtr(str),
1879 rl_filename_completion_function);
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
1896static VALUE
1897username_completion_proc_call(VALUE self, VALUE str)
1898{
1899 VALUE result;
1900 char **matches;
1901 int i;
1902
1903 matches = rl_completion_matches(StringValuePtr(str),
1904 rl_username_completion_function);
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 RUBY_EXTERN int rl_clear_signals(void);
1923#endif
1924
1925#undef rb_intern
1926void
1927Init_readline(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=",
1970 readline_s_set_quoting_detection_proc, 1);
1971 rb_define_singleton_method(mReadline, "quoting_detection_proc",
1972 readline_s_get_quoting_detection_proc, 0);
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",
1978 readline_s_get_line_buffer, 0);
1979 rb_define_singleton_method(mReadline, "point",
1980 readline_s_get_point, 0);
1981 rb_define_singleton_method(mReadline, "point=",
1982 readline_s_set_point, 1);
1983 rb_define_singleton_method(mReadline, "set_screen_size",
1984 readline_s_set_screen_size, 2);
1985 rb_define_singleton_method(mReadline, "get_screen_size",
1986 readline_s_get_screen_size, 0);
1987 rb_define_singleton_method(mReadline, "vi_editing_mode",
1988 readline_s_vi_editing_mode, 0);
1989 rb_define_singleton_method(mReadline, "vi_editing_mode?",
1990 readline_s_vi_editing_mode_p, 0);
1991 rb_define_singleton_method(mReadline, "emacs_editing_mode",
1992 readline_s_emacs_editing_mode, 0);
1993 rb_define_singleton_method(mReadline, "emacs_editing_mode?",
1994 readline_s_emacs_editing_mode_p, 0);
1995 rb_define_singleton_method(mReadline, "completion_append_character=",
1996 readline_s_set_completion_append_character, 1);
1997 rb_define_singleton_method(mReadline, "completion_append_character",
1998 readline_s_get_completion_append_character, 0);
1999 rb_define_singleton_method(mReadline, "completion_quote_character",
2000 readline_s_get_completion_quote_character, 0);
2001 rb_define_singleton_method(mReadline, "basic_word_break_characters=",
2002 readline_s_set_basic_word_break_characters, 1);
2003 rb_define_singleton_method(mReadline, "basic_word_break_characters",
2004 readline_s_get_basic_word_break_characters, 0);
2005 rb_define_singleton_method(mReadline, "completer_word_break_characters=",
2006 readline_s_set_completer_word_break_characters, 1);
2007 rb_define_singleton_method(mReadline, "completer_word_break_characters",
2008 readline_s_get_completer_word_break_characters, 0);
2009 rb_define_singleton_method(mReadline, "basic_quote_characters=",
2010 readline_s_set_basic_quote_characters, 1);
2011 rb_define_singleton_method(mReadline, "basic_quote_characters",
2012 readline_s_get_basic_quote_characters, 0);
2013 rb_define_singleton_method(mReadline, "completer_quote_characters=",
2014 readline_s_set_completer_quote_characters, 1);
2015 rb_define_singleton_method(mReadline, "completer_quote_characters",
2016 readline_s_get_completer_quote_characters, 0);
2017 rb_define_singleton_method(mReadline, "filename_quote_characters=",
2018 readline_s_set_filename_quote_characters, 1);
2019 rb_define_singleton_method(mReadline, "filename_quote_characters",
2020 readline_s_get_filename_quote_characters, 0);
2021 rb_define_singleton_method(mReadline, "refresh_line",
2022 readline_s_refresh_line, 0);
2023 rb_define_singleton_method(mReadline, "pre_input_hook=",
2024 readline_s_set_pre_input_hook, 1);
2025 rb_define_singleton_method(mReadline, "pre_input_hook",
2026 readline_s_get_pre_input_hook, 0);
2027 rb_define_singleton_method(mReadline, "insert_text",
2028 readline_s_insert_text, 1);
2029 rb_define_singleton_method(mReadline, "delete_text",
2030 readline_s_delete_text, -1);
2031 rb_define_singleton_method(mReadline, "redisplay",
2032 readline_s_redisplay, 0);
2033 rb_define_singleton_method(mReadline, "special_prefixes=",
2034 readline_s_set_special_prefixes, 1);
2035 rb_define_singleton_method(mReadline, "special_prefixes",
2036 readline_s_get_special_prefixes, 0);
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 * <code>HISTORY[4]</code>.
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,
2090 strlen(EDIT_LINE_LIBRARY_VERSION)) == 0) {
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 */
rb_ary_shift
VALUE rb_ary_shift(VALUE ary)
Definition: array.c:1413
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:1301
rb_ary_new
VALUE rb_ary_new(void)
Definition: array.c:749
UNREACHABLE_RETURN
#define UNREACHABLE_RETURN
Definition: assume.h:31
ISALPHA
#define ISALPHA
Definition: ctype.h:42
rb_define_singleton_method
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
Definition: cxxanyargs.hpp:668
rb_define_module_function
#define rb_define_module_function(klass, mid, func, arity)
Defines klass#mid and makes it a module function.
Definition: cxxanyargs.hpp:672
ptr
struct RIMemo * ptr
Definition: debug.c:88
RUBY_EXTERN
#define RUBY_EXTERN
Definition: dllexport.h:36
free
#define free(x)
Definition: dln.c:52
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:1266
rb_enc_check
rb_encoding * rb_enc_check(VALUE str1, VALUE str2)
Definition: encoding.c:1089
rb_locale_encoding
rb_encoding * rb_locale_encoding(void)
Definition: encoding.c:1583
rb_enc_from_encoding
VALUE rb_enc_from_encoding(rb_encoding *encoding)
Definition: encoding.c:188
rb_mEnumerable
VALUE rb_mEnumerable
Definition: enum.c:27
id_call
#define id_call
Definition: enum.c:36
len
uint8_t len
Definition: escape.c:17
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
RSTRING_LEN
#define RSTRING_LEN(string)
Definition: fbuffer.h:22
RSTRING_PTR
#define RSTRING_PTR(string)
Definition: fbuffer.h:19
rb_memerror
void rb_memerror(void)
Definition: gc.c:10309
rb_gc_force_recycle
void rb_gc_force_recycle(VALUE obj)
Definition: gc.c:7968
rb_gc_register_address
void rb_gc_register_address(VALUE *addr)
Inform the garbage collector that valptr points to a live Ruby object that should not be moved.
Definition: gc.c:8040
rb_eIOError
VALUE rb_eIOError
Definition: io.c:185
rb_cString
VALUE rb_cString
Definition: string.c:80
rb_extend_object
void rb_extend_object(VALUE obj, VALUE module)
Extend the object with the module.
Definition: eval.c:1730
rb_define_module
VALUE rb_define_module(const char *name)
Definition: class.c:871
rb_scan_args
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:2296
OBJ_FREEZE
#define OBJ_FREEZE
Definition: fl_type.h:134
rb_notimplement
void rb_notimplement(void)
Definition: error.c:2960
rb_syserr_fail
void rb_syserr_fail(int e, const char *mesg)
Definition: error.c:3029
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2917
rb_bug
void rb_bug(const char *fmt,...)
Definition: error.c:768
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:1105
rb_eArgError
VALUE rb_eArgError
Definition: error.c:1058
rb_eIndexError
VALUE rb_eIndexError
Definition: error.c:1059
rb_jump_tag
void rb_jump_tag(int tag)
Continues the exception caught by rb_protect() and rb_eval_string_protect().
Definition: eval.c:921
rb_sys_fail
void rb_sys_fail(const char *mesg)
Definition: error.c:3041
rb_obj_reveal
VALUE rb_obj_reveal(VALUE obj, VALUE klass)
Make a hidden object visible again.
Definition: object.c:109
rb_cObject
VALUE rb_cObject
Object class.
Definition: object.c:49
rb_obj_alloc
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
Definition: object.c:1900
rb_obj_hide
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
Definition: object.c:92
rb_Array
VALUE rb_Array(VALUE)
Equivalent to Kernel#Array in Ruby.
Definition: object.c:3705
rb_enc_str_new_static
VALUE rb_enc_str_new_static(const char *, long, rb_encoding *)
Definition: string.c:951
rb_enc_strlen
long rb_enc_strlen(const char *, const char *, rb_encoding *)
Definition: string.c:1887
rb_funcall
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:1077
RETURN_ENUMERATOR
#define RETURN_ENUMERATOR(obj, argc, argv)
Definition: enumerator.h:74
rb_check_arity
#define rb_check_arity
Definition: error.h:34
rb_cloexec_dup
int rb_cloexec_dup(int oldfd)
Definition: io.c:346
rb_range_beg_len
VALUE rb_range_beg_len(VALUE, long *, long *, long, int)
Definition: range.c:1398
rb_str_unlocktmp
VALUE rb_str_unlocktmp(VALUE)
Definition: string.c:2825
rb_str_new_shared
VALUE rb_str_new_shared(VALUE)
Definition: string.c:1267
rb_str_subpos
char * rb_str_subpos(VALUE, long, long *)
Definition: string.c:2647
rb_str_cat
VALUE rb_str_cat(VALUE, const char *, long)
Definition: string.c:2962
rb_locale_str_new
VALUE rb_locale_str_new(const char *, long)
Definition: string.c:1169
rb_str_set_len
void rb_str_set_len(VALUE, long)
Definition: string.c:2842
rb_str_tmp_new
VALUE rb_str_tmp_new(long)
Definition: string.c:1427
rb_locale_str_new_cstr
#define rb_locale_str_new_cstr(str)
Definition: string.h:256
rb_str_dup_frozen
#define rb_str_dup_frozen
Definition: string.h:94
rb_str_locktmp
VALUE rb_str_locktmp(VALUE)
rb_obj_as_string
VALUE rb_obj_as_string(VALUE)
Definition: string.c:1529
rb_str_sublen
long rb_str_sublen(VALUE, long)
Definition: string.c:2613
rb_str_new_cstr
#define rb_str_new_cstr(str)
Definition: string.h:219
RUBY_UBF_IO
#define RUBY_UBF_IO
Definition: thread.h:64
rb_thread_check_ints
void rb_thread_check_ints(void)
Definition: thread.c:1577
rb_thread_schedule
void rb_thread_schedule(void)
Definition: thread.c:1623
rb_ivar_get
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1234
rb_attr_get
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1242
rb_ivar_set
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1493
rb_respond_to
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:2561
rb_intern
ID rb_intern(const char *)
Definition: symbol.c:785
rb_define_const
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:3150
io.h
GetOpenFile
#define GetOpenFile
Definition: io.h:125
rb_wait_for_single_fd
int rb_wait_for_single_fd(int fd, int events, struct timeval *tv)
Definition: io.c:1384
rb_io_taint_check
VALUE rb_io_taint_check(VALUE)
Definition: io.c:760
RB_WAITFD_IN
#define RB_WAITFD_IN
Definition: io.h:39
rb_io_check_initialized
void rb_io_check_initialized(rb_io_t *)
Definition: io.c:767
thread.h
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:1801
strdup
#define strdup(s)
Definition: util.h:39
NUM2INT
#define NUM2INT
Definition: int.h:44
INT2NUM
#define INT2NUM
Definition: int.h:43
PRIdSIZE
#define PRIdSIZE
Definition: inttypes.h:124
offset
voidpf uLong offset
Definition: ioapi.h:144
int
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
buf
voidpf void * buf
Definition: ioapi.h:138
rb_yield
VALUE rb_yield(VALUE)
Definition: vm_eval.c:1341
LONG2FIX
#define LONG2FIX
Definition: long.h:49
rb_long2int
#define rb_long2int
Definition: long.h:62
NUM2LONG
#define NUM2LONG
Definition: long.h:51
REALLOC_N
#define REALLOC_N
Definition: memory.h:137
ALLOC_N
#define ALLOC_N
Definition: memory.h:133
input
unsigned int input
Definition: nkf.c:4325
RARRAY_AREF
#define RARRAY_AREF(a, i)
Definition: psych_emitter.c:7
RARRAY_LEN
#define RARRAY_LEN
Definition: rarray.h:52
hist_clear
#define hist_clear
Definition: readline.c:1868
Init_readline
void Init_readline(void)
Definition: readline.c:1927
readline_s_get_completion_quote_character
#define readline_s_get_completion_quote_character
Definition: readline.c:1336
readline_s_refresh_line
#define readline_s_refresh_line
Definition: readline.c:1690
readline_s_vi_editing_mode_p
#define readline_s_vi_editing_mode_p
Definition: readline.c:1186
OutputStringValue
#define OutputStringValue(str)
Definition: readline.c:96
readline_s_set_screen_size
#define readline_s_set_screen_size
Definition: readline.c:1120
readline_s_vi_editing_mode
#define readline_s_vi_editing_mode
Definition: readline.c:1168
readline_s_set_basic_word_break_characters
#define readline_s_set_basic_word_break_characters
Definition: readline.c:1370
readline_s_get_screen_size
#define readline_s_get_screen_size
Definition: readline.c:1147
readline_s_get_special_prefixes
#define readline_s_get_special_prefixes
Definition: readline.c:1508
readline_s_set_point
#define readline_s_set_point
Definition: readline.c:999
readline_s_delete_text
#define readline_s_delete_text
Definition: readline.c:744
readline_s_set_pre_input_hook
#define readline_s_set_pre_input_hook
Definition: readline.c:665
readline_s_set_completion_append_character
#define readline_s_set_completion_append_character
Definition: readline.c:1282
readline_s_set_basic_quote_characters
#define readline_s_set_basic_quote_characters
Definition: readline.c:1541
readline_s_set_completer_word_break_characters
#define readline_s_set_completer_word_break_characters
Definition: readline.c:1425
readline_s_set_filename_quote_characters
#define readline_s_set_filename_quote_characters
Definition: readline.c:1650
readline_s_get_quoting_detection_proc
#define readline_s_get_quoting_detection_proc
Definition: readline.c:898
readline_s_set_quoting_detection_proc
#define readline_s_set_quoting_detection_proc
Definition: readline.c:897
readline_s_emacs_editing_mode
#define readline_s_emacs_editing_mode
Definition: readline.c:1207
rl_completion_matches
#define rl_completion_matches
Definition: readline.c:84
readline_s_get_basic_quote_characters
#define readline_s_get_basic_quote_characters
Definition: readline.c:1561
readline_s_get_pre_input_hook
#define readline_s_get_pre_input_hook
Definition: readline.c:666
hist_set
#define hist_set
Definition: readline.c:1751
rl_filename_completion_function
#define rl_filename_completion_function
Definition: readline.c:76
readline_s_get_filename_quote_characters
#define readline_s_get_filename_quote_characters
Definition: readline.c:1671
readline_s_set_special_prefixes
#define readline_s_set_special_prefixes
Definition: readline.c:1507
COMPLETION_CASE_FOLD
#define COMPLETION_CASE_FOLD
Definition: readline.c:59
readline_s_redisplay
#define readline_s_redisplay
Definition: readline.c:766
readline_s_get_line_buffer
#define readline_s_get_line_buffer
Definition: readline.c:955
readline_s_get_completer_quote_characters
#define readline_s_get_completer_quote_characters
Definition: readline.c:1617
readline_s_get_point
#define readline_s_get_point
Definition: readline.c:998
rl_username_completion_function
#define rl_username_completion_function
Definition: readline.c:79
readline_s_insert_text
#define readline_s_insert_text
Definition: readline.c:688
readline_s_get_completer_word_break_characters
#define readline_s_get_completer_word_break_characters
Definition: readline.c:1446
readline_s_set_completer_quote_characters
#define readline_s_set_completer_quote_characters
Definition: readline.c:1596
EDIT_LINE_LIBRARY_VERSION
#define EDIT_LINE_LIBRARY_VERSION
Definition: readline.c:49
readline_s_get_completion_append_character
#define readline_s_get_completion_append_character
Definition: readline.c:1307
readline_s_emacs_editing_mode_p
#define readline_s_emacs_editing_mode_p
Definition: readline.c:1225
readline_s_get_basic_word_break_characters
#define readline_s_get_basic_word_break_characters
Definition: readline.c:1391
COMPLETION_PROC
#define COMPLETION_PROC
Definition: readline.c:58
NULL
#define NULL
Definition: regenc.h:69
RFILE
#define RFILE(obj)
Definition: rfile.h:35
StringValuePtr
#define StringValuePtr(v)
Definition: rstring.h:51
StringValueCStr
#define StringValueCStr(v)
Definition: rstring.h:52
argc
int argc
Definition: ruby.c:240
argv
char ** argv
Definition: ruby.c:241
EWOULDBLOCK
#define EWOULDBLOCK
Definition: rubysocket.h:164
Qtrue
#define Qtrue
Definition: special_consts.h:52
RTEST
#define RTEST
Definition: special_consts.h:42
Qnil
#define Qnil
Definition: special_consts.h:51
Qfalse
#define Qfalse
Definition: special_consts.h:50
NIL_P
#define NIL_P
Definition: special_consts.h:46
f
#define f
malloc
#define malloc
Definition: st.c:170
strlen
size_t strlen(const char *)
__sFILE
Definition: vsnprintf.c:169
OnigEncodingTypeST
Definition: onigmo.h:160
rb_io_t
Definition: io.h:61
rb_io_t::fd
int fd
Definition: io.h:65
VALUE
unsigned long VALUE
Definition: value.h:38
ID
unsigned long ID
Definition: value.h:39
T_FILE
#define T_FILE
Definition: value_type.h:61
T_ARRAY
#define T_ARRAY
Definition: value_type.h:55
EOF
#define EOF
Definition: vsnprintf.c:203
fileno
#define fileno(p)
Definition: vsnprintf.c:219
err
int err
Definition: win32.c:142
rb_w32_wait_events_blocking
int rb_w32_wait_events_blocking(HANDLE *events, int num, DWORD timeout)
DWORD
IUnknown DWORD
Definition: win32ole.c:33
read
int read(izstream &zs, T *x, Items items)
Definition: zstream.h:115
fdopen
#define fdopen(fd, type)
Definition: zutil.h:181