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