Change soft-fail to use the config, rather than env
[rbx.git] / stdlib / ext / readline / readline.c
blob559e1c677bdba00be9524af9ef030801429e99c4
1 /* readline.c -- GNU Readline module
2 Copyright (C) 1997-2001 Shugo Maeda */
4 #include "config.h"
5 #include <errno.h>
6 #include <stdio.h>
7 #include <ctype.h>
8 #include <string.h>
9 #ifdef HAVE_READLINE_READLINE_H
10 #include <readline/readline.h>
11 #endif
12 #ifdef HAVE_READLINE_HISTORY_H
13 #include <readline/history.h>
14 #endif
15 #ifdef HAVE_EDITLINE_READLINE_H
16 #include <editline/readline.h>
17 #endif
19 #include "ruby.h"
20 #include "rubyio.h"
21 #include "rubysig.h"
23 #ifdef HAVE_UNISTD_H
24 #include <unistd.h>
25 #endif
27 static VALUE mReadline;
29 #define TOLOWER(c) (isupper(c) ? tolower(c) : c)
31 #define COMPLETION_PROC "completion_proc"
32 #define COMPLETION_CASE_FOLD "completion_case_fold"
33 static ID completion_proc, completion_case_fold;
35 #ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION
36 # define rl_filename_completion_function filename_completion_function
37 #endif
38 #ifndef HAVE_RL_USERNAME_COMPLETION_FUNCTION
39 # define rl_username_completion_function username_completion_function
40 #endif
41 #ifndef HAVE_RL_COMPLETION_MATCHES
42 # define rl_completion_matches completion_matches
43 #endif
45 static int readline_event(void);
46 static char **readline_attempted_completion_function(const char *text,
47 int start, int end);
49 static int
50 readline_event()
52 CHECK_INTS;
53 rb_thread_schedule();
54 return 0;
57 static VALUE
58 readline_readline(argc, argv, self)
59 int argc;
60 VALUE *argv;
61 VALUE self;
63 VALUE tmp, add_hist, result;
64 char *prompt = NULL;
65 char *buff;
66 int status;
67 OpenFile *ofp, *ifp;
69 rb_secure(4);
70 if (rb_scan_args(argc, argv, "02", &tmp, &add_hist) > 0) {
71 SafeStringValue(tmp);
72 prompt = RSTRING(tmp)->ptr;
75 if (!isatty(0) && errno == EBADF) rb_raise(rb_eIOError, "stdin closed");
77 Check_Type(rb_stdout, T_FILE);
78 GetOpenFile(rb_stdout, ofp);
79 rl_outstream = GetWriteFile(ofp);
80 Check_Type(rb_stdin, T_FILE);
81 GetOpenFile(rb_stdin, ifp);
82 rl_instream = GetReadFile(ifp);
83 buff = (char*)rb_protect((VALUE(*)_((VALUE)))readline, (VALUE)prompt,
84 &status);
85 if (status) {
86 #if defined HAVE_RL_CLEANUP_AFTER_SIGNAL
87 /* restore terminal mode and signal handler*/
88 rl_cleanup_after_signal();
89 #elif defined HAVE_RL_DEPREP_TERM_FUNCTION
90 /* restore terminal mode */
91 if (rl_deprep_term_function != NULL) /* NULL in libedit. [ruby-dev:29116] */
92 (*rl_deprep_term_function)();
93 else
94 #else
95 rl_deprep_terminal();
96 #endif
97 rb_jump_tag(status);
100 if (RTEST(add_hist) && buff) {
101 add_history(buff);
103 if (buff)
104 result = rb_tainted_str_new2(buff);
105 else
106 result = Qnil;
107 if (buff) free(buff);
108 return result;
111 static VALUE
112 readline_s_set_completion_proc(self, proc)
113 VALUE self;
114 VALUE proc;
116 rb_secure(4);
117 if (!rb_respond_to(proc, rb_intern("call")))
118 rb_raise(rb_eArgError, "argument must respond to `call'");
119 return rb_ivar_set(mReadline, completion_proc, proc);
122 static VALUE
123 readline_s_get_completion_proc(self)
124 VALUE self;
126 rb_secure(4);
127 return rb_attr_get(mReadline, completion_proc);
130 static VALUE
131 readline_s_set_completion_case_fold(self, val)
132 VALUE self;
133 VALUE val;
135 rb_secure(4);
136 return rb_ivar_set(mReadline, completion_case_fold, val);
139 static VALUE
140 readline_s_get_completion_case_fold(self)
141 VALUE self;
143 rb_secure(4);
144 return rb_attr_get(mReadline, completion_case_fold);
147 static char **
148 readline_attempted_completion_function(text, start, end)
149 const char *text;
150 int start;
151 int end;
153 VALUE proc, ary, temp;
154 char **result;
155 int case_fold;
156 int i, matches;
158 proc = rb_attr_get(mReadline, completion_proc);
159 if (NIL_P(proc))
160 return NULL;
161 #ifdef HAVE_RL_ATTEMPTED_COMPLETION_OVER
162 rl_attempted_completion_over = 1;
163 #endif
164 case_fold = RTEST(rb_attr_get(mReadline, completion_case_fold));
165 ary = rb_funcall(proc, rb_intern("call"), 1, rb_tainted_str_new2(text));
166 if (TYPE(ary) != T_ARRAY)
167 ary = rb_Array(ary);
168 matches = RARRAY(ary)->len;
169 if (matches == 0)
170 return NULL;
171 result = ALLOC_N(char *, matches + 2);
172 for (i = 0; i < matches; i++) {
173 temp = rb_obj_as_string(RARRAY(ary)->ptr[i]);
174 result[i + 1] = ALLOC_N(char, RSTRING(temp)->len + 1);
175 strcpy(result[i + 1], RSTRING(temp)->ptr);
177 result[matches + 1] = NULL;
179 if (matches == 1) {
180 result[0] = strdup(result[1]);
182 else {
183 register int i = 1;
184 int low = 100000;
186 while (i < matches) {
187 register int c1, c2, si;
189 if (case_fold) {
190 for (si = 0;
191 (c1 = TOLOWER(result[i][si])) &&
192 (c2 = TOLOWER(result[i + 1][si]));
193 si++)
194 if (c1 != c2) break;
195 } else {
196 for (si = 0;
197 (c1 = result[i][si]) &&
198 (c2 = result[i + 1][si]);
199 si++)
200 if (c1 != c2) break;
203 if (low > si) low = si;
204 i++;
206 result[0] = ALLOC_N(char, low + 1);
207 strncpy(result[0], result[1], low);
208 result[0][low] = '\0';
211 return result;
214 static VALUE
215 readline_s_vi_editing_mode(self)
216 VALUE self;
218 #ifdef HAVE_RL_VI_EDITING_MODE
219 rb_secure(4);
220 rl_vi_editing_mode(1,0);
221 return Qnil;
222 #else
223 rb_notimplement();
224 return Qnil; /* not reached */
225 #endif /* HAVE_RL_VI_EDITING_MODE */
228 static VALUE
229 readline_s_emacs_editing_mode(self)
230 VALUE self;
232 #ifdef HAVE_RL_EMACS_EDITING_MODE
233 rb_secure(4);
234 rl_emacs_editing_mode(1,0);
235 return Qnil;
236 #else
237 rb_notimplement();
238 return Qnil; /* not reached */
239 #endif /* HAVE_RL_EMACS_EDITING_MODE */
242 static VALUE
243 readline_s_set_completion_append_character(self, str)
244 VALUE self, str;
246 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
247 rb_secure(4);
248 if (NIL_P(str)) {
249 rl_completion_append_character = '\0';
251 else {
252 SafeStringValue(str);
253 if (RSTRING(str)->len == 0) {
254 rl_completion_append_character = '\0';
255 } else {
256 rl_completion_append_character = RSTRING(str)->ptr[0];
259 return self;
260 #else
261 rb_notimplement();
262 return Qnil; /* not reached */
263 #endif /* HAVE_RL_COMPLETION_APPEND_CHARACTER */
266 static VALUE
267 readline_s_get_completion_append_character(self)
268 VALUE self;
270 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
271 VALUE str;
273 rb_secure(4);
274 if (rl_completion_append_character == '\0')
275 return Qnil;
277 str = rb_str_new("", 1);
278 RSTRING(str)->ptr[0] = rl_completion_append_character;
279 return str;
280 #else
281 rb_notimplement();
282 return Qnil; /* not reached */
283 #endif /* HAVE_RL_COMPLETION_APPEND_CHARACTER */
286 static VALUE
287 readline_s_set_basic_word_break_characters(self, str)
288 VALUE self, str;
290 #ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS
291 static char *basic_word_break_characters = NULL;
293 rb_secure(4);
294 SafeStringValue(str);
295 if (basic_word_break_characters == NULL) {
296 basic_word_break_characters =
297 ALLOC_N(char, RSTRING(str)->len + 1);
299 else {
300 REALLOC_N(basic_word_break_characters, char, RSTRING(str)->len + 1);
302 strncpy(basic_word_break_characters,
303 RSTRING(str)->ptr, RSTRING(str)->len);
304 basic_word_break_characters[RSTRING(str)->len] = '\0';
305 rl_basic_word_break_characters = basic_word_break_characters;
306 return self;
307 #else
308 rb_notimplement();
309 return Qnil; /* not reached */
310 #endif /* HAVE_RL_BASIC_WORD_BREAK_CHARACTERS */
313 static VALUE
314 readline_s_get_basic_word_break_characters(self, str)
315 VALUE self, str;
317 #ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS
318 rb_secure(4);
319 if (rl_basic_word_break_characters == NULL)
320 return Qnil;
321 return rb_tainted_str_new2(rl_basic_word_break_characters);
322 #else
323 rb_notimplement();
324 return Qnil; /* not reached */
325 #endif /* HAVE_RL_BASIC_WORD_BREAK_CHARACTERS */
328 static VALUE
329 readline_s_set_completer_word_break_characters(self, str)
330 VALUE self, str;
332 #ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS
333 static char *completer_word_break_characters = NULL;
335 rb_secure(4);
336 SafeStringValue(str);
337 if (completer_word_break_characters == NULL) {
338 completer_word_break_characters =
339 ALLOC_N(char, RSTRING(str)->len + 1);
341 else {
342 REALLOC_N(completer_word_break_characters, char, RSTRING(str)->len + 1);
344 strncpy(completer_word_break_characters,
345 RSTRING(str)->ptr, RSTRING(str)->len);
346 completer_word_break_characters[RSTRING(str)->len] = '\0';
347 rl_completer_word_break_characters = completer_word_break_characters;
348 return self;
349 #else
350 rb_notimplement();
351 return Qnil; /* not reached */
352 #endif /* HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS */
355 static VALUE
356 readline_s_get_completer_word_break_characters(self, str)
357 VALUE self, str;
359 #ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS
360 rb_secure(4);
361 if (rl_completer_word_break_characters == NULL)
362 return Qnil;
363 return rb_tainted_str_new2(rl_completer_word_break_characters);
364 #else
365 rb_notimplement();
366 return Qnil; /* not reached */
367 #endif /* HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS */
370 static VALUE
371 readline_s_set_basic_quote_characters(self, str)
372 VALUE self, str;
374 #ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS
375 static char *basic_quote_characters = NULL;
377 rb_secure(4);
378 SafeStringValue(str);
379 if (basic_quote_characters == NULL) {
380 basic_quote_characters =
381 ALLOC_N(char, RSTRING(str)->len + 1);
383 else {
384 REALLOC_N(basic_quote_characters, char, RSTRING(str)->len + 1);
386 strncpy(basic_quote_characters,
387 RSTRING(str)->ptr, RSTRING(str)->len);
388 basic_quote_characters[RSTRING(str)->len] = '\0';
389 rl_basic_quote_characters = basic_quote_characters;
391 return self;
392 #else
393 rb_notimplement();
394 return Qnil; /* not reached */
395 #endif /* HAVE_RL_BASIC_QUOTE_CHARACTERS */
398 static VALUE
399 readline_s_get_basic_quote_characters(self, str)
400 VALUE self, str;
402 #ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS
403 rb_secure(4);
404 if (rl_basic_quote_characters == NULL)
405 return Qnil;
406 return rb_tainted_str_new2(rl_basic_quote_characters);
407 #else
408 rb_notimplement();
409 return Qnil; /* not reached */
410 #endif /* HAVE_RL_BASIC_QUOTE_CHARACTERS */
413 static VALUE
414 readline_s_set_completer_quote_characters(self, str)
415 VALUE self, str;
417 #ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS
418 static char *completer_quote_characters = NULL;
420 rb_secure(4);
421 SafeStringValue(str);
422 if (completer_quote_characters == NULL) {
423 completer_quote_characters =
424 ALLOC_N(char, RSTRING(str)->len + 1);
426 else {
427 REALLOC_N(completer_quote_characters, char, RSTRING(str)->len + 1);
429 strncpy(completer_quote_characters,
430 RSTRING(str)->ptr, RSTRING(str)->len);
431 completer_quote_characters[RSTRING(str)->len] = '\0';
432 rl_completer_quote_characters = completer_quote_characters;
434 return self;
435 #else
436 rb_notimplement();
437 return Qnil; /* not reached */
438 #endif /* HAVE_RL_COMPLETER_QUOTE_CHARACTERS */
441 static VALUE
442 readline_s_get_completer_quote_characters(self, str)
443 VALUE self, str;
445 #ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS
446 rb_secure(4);
447 if (rl_completer_quote_characters == NULL)
448 return Qnil;
449 return rb_tainted_str_new2(rl_completer_quote_characters);
450 #else
451 rb_notimplement();
452 return Qnil; /* not reached */
453 #endif /* HAVE_RL_COMPLETER_QUOTE_CHARACTERS */
456 static VALUE
457 readline_s_set_filename_quote_characters(self, str)
458 VALUE self, str;
460 #ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS
461 static char *filename_quote_characters = NULL;
463 rb_secure(4);
464 SafeStringValue(str);
465 if (filename_quote_characters == NULL) {
466 filename_quote_characters =
467 ALLOC_N(char, RSTRING(str)->len + 1);
469 else {
470 REALLOC_N(filename_quote_characters, char, RSTRING(str)->len + 1);
472 strncpy(filename_quote_characters,
473 RSTRING(str)->ptr, RSTRING(str)->len);
474 filename_quote_characters[RSTRING(str)->len] = '\0';
475 rl_filename_quote_characters = filename_quote_characters;
477 return self;
478 #else
479 rb_notimplement();
480 return Qnil; /* not reached */
481 #endif /* HAVE_RL_FILENAME_QUOTE_CHARACTERS */
484 static VALUE
485 readline_s_get_filename_quote_characters(self, str)
486 VALUE self, str;
488 #ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS
489 rb_secure(4);
490 if (rl_filename_quote_characters == NULL)
491 return Qnil;
492 return rb_tainted_str_new2(rl_filename_quote_characters);
493 #else
494 rb_notimplement();
495 return Qnil; /* not reached */
496 #endif /* HAVE_RL_FILENAME_QUOTE_CHARACTERS */
499 static VALUE
500 hist_to_s(self)
501 VALUE self;
503 return rb_str_new2("HISTORY");
506 static VALUE
507 hist_get(self, index)
508 VALUE self;
509 VALUE index;
511 HIST_ENTRY *entry;
512 int i;
514 rb_secure(4);
515 i = NUM2INT(index);
516 if (i < 0) {
517 i += history_length;
519 entry = history_get(history_base + i);
520 if (entry == NULL) {
521 rb_raise(rb_eIndexError, "invalid index");
523 return rb_tainted_str_new2(entry->line);
526 static VALUE
527 hist_set(self, index, str)
528 VALUE self;
529 VALUE index;
530 VALUE str;
532 #ifdef HAVE_REPLACE_HISTORY_ENTRY
533 HIST_ENTRY *entry;
534 int i;
536 rb_secure(4);
537 i = NUM2INT(index);
538 SafeStringValue(str);
539 if (i < 0) {
540 i += history_length;
542 entry = replace_history_entry(i, RSTRING(str)->ptr, NULL);
543 if (entry == NULL) {
544 rb_raise(rb_eIndexError, "invalid index");
546 return str;
547 #else
548 rb_notimplement();
549 return Qnil; /* not reached */
550 #endif
553 static VALUE
554 hist_push(self, str)
555 VALUE self;
556 VALUE str;
558 rb_secure(4);
559 SafeStringValue(str);
560 add_history(RSTRING(str)->ptr);
561 return self;
564 static VALUE
565 hist_push_method(argc, argv, self)
566 int argc;
567 VALUE *argv;
568 VALUE self;
570 VALUE str;
572 rb_secure(4);
573 while (argc--) {
574 str = *argv++;
575 SafeStringValue(str);
576 add_history(RSTRING(str)->ptr);
578 return self;
581 static VALUE
582 rb_remove_history(index)
583 int index;
585 #ifdef HAVE_REMOVE_HISTORY
586 HIST_ENTRY *entry;
587 VALUE val;
589 rb_secure(4);
590 entry = remove_history(index);
591 if (entry) {
592 val = rb_tainted_str_new2(entry->line);
593 free(entry->line);
594 free(entry);
595 return val;
597 return Qnil;
598 #else
599 rb_notimplement();
600 return Qnil; /* not reached */
601 #endif
604 static VALUE
605 hist_pop(self)
606 VALUE self;
608 rb_secure(4);
609 if (history_length > 0) {
610 return rb_remove_history(history_length - 1);
611 } else {
612 return Qnil;
616 static VALUE
617 hist_shift(self)
618 VALUE self;
620 rb_secure(4);
621 if (history_length > 0) {
622 return rb_remove_history(0);
623 } else {
624 return Qnil;
628 static VALUE
629 hist_each(self)
630 VALUE self;
632 HIST_ENTRY *entry;
633 int i;
635 rb_secure(4);
636 for (i = 0; i < history_length; i++) {
637 entry = history_get(history_base + i);
638 if (entry == NULL)
639 break;
640 rb_yield(rb_tainted_str_new2(entry->line));
642 return self;
645 static VALUE
646 hist_length(self)
647 VALUE self;
649 rb_secure(4);
650 return INT2NUM(history_length);
653 static VALUE
654 hist_empty_p(self)
655 VALUE self;
657 rb_secure(4);
658 return history_length == 0 ? Qtrue : Qfalse;
661 static VALUE
662 hist_delete_at(self, index)
663 VALUE self;
664 VALUE index;
666 int i;
668 rb_secure(4);
669 i = NUM2INT(index);
670 if (i < 0)
671 i += history_length;
672 if (i < 0 || i > history_length - 1) {
673 rb_raise(rb_eIndexError, "invalid index");
675 return rb_remove_history(i);
678 static VALUE
679 filename_completion_proc_call(self, str)
680 VALUE self;
681 VALUE str;
683 VALUE result;
684 char **matches;
685 int i;
687 matches = rl_completion_matches(StringValuePtr(str),
688 rl_filename_completion_function);
689 if (matches) {
690 result = rb_ary_new();
691 for (i = 0; matches[i]; i++) {
692 rb_ary_push(result, rb_tainted_str_new2(matches[i]));
693 free(matches[i]);
695 free(matches);
696 if (RARRAY(result)->len >= 2)
697 rb_ary_shift(result);
699 else {
700 result = Qnil;
702 return result;
705 static VALUE
706 username_completion_proc_call(self, str)
707 VALUE self;
708 VALUE str;
710 VALUE result;
711 char **matches;
712 int i;
714 matches = rl_completion_matches(StringValuePtr(str),
715 rl_username_completion_function);
716 if (matches) {
717 result = rb_ary_new();
718 for (i = 0; matches[i]; i++) {
719 rb_ary_push(result, rb_tainted_str_new2(matches[i]));
720 free(matches[i]);
722 free(matches);
723 if (RARRAY(result)->len >= 2)
724 rb_ary_shift(result);
726 else {
727 result = Qnil;
729 return result;
732 void
733 Init_readline()
735 VALUE history, fcomp, ucomp;
737 /* Allow conditional parsing of the ~/.inputrc file. */
738 rl_readline_name = "Ruby";
740 using_history();
742 completion_proc = rb_intern(COMPLETION_PROC);
743 completion_case_fold = rb_intern(COMPLETION_CASE_FOLD);
745 mReadline = rb_define_module("Readline");
746 rb_define_module_function(mReadline, "readline",
747 readline_readline, -1);
748 rb_define_singleton_method(mReadline, "completion_proc=",
749 readline_s_set_completion_proc, 1);
750 rb_define_singleton_method(mReadline, "completion_proc",
751 readline_s_get_completion_proc, 0);
752 rb_define_singleton_method(mReadline, "completion_case_fold=",
753 readline_s_set_completion_case_fold, 1);
754 rb_define_singleton_method(mReadline, "completion_case_fold",
755 readline_s_get_completion_case_fold, 0);
756 rb_define_singleton_method(mReadline, "vi_editing_mode",
757 readline_s_vi_editing_mode, 0);
758 rb_define_singleton_method(mReadline, "emacs_editing_mode",
759 readline_s_emacs_editing_mode, 0);
760 rb_define_singleton_method(mReadline, "completion_append_character=",
761 readline_s_set_completion_append_character, 1);
762 rb_define_singleton_method(mReadline, "completion_append_character",
763 readline_s_get_completion_append_character, 0);
764 rb_define_singleton_method(mReadline, "basic_word_break_characters=",
765 readline_s_set_basic_word_break_characters, 1);
766 rb_define_singleton_method(mReadline, "basic_word_break_characters",
767 readline_s_get_basic_word_break_characters, 0);
768 rb_define_singleton_method(mReadline, "completer_word_break_characters=",
769 readline_s_set_completer_word_break_characters, 1);
770 rb_define_singleton_method(mReadline, "completer_word_break_characters",
771 readline_s_get_completer_word_break_characters, 0);
772 rb_define_singleton_method(mReadline, "basic_quote_characters=",
773 readline_s_set_basic_quote_characters, 1);
774 rb_define_singleton_method(mReadline, "basic_quote_characters",
775 readline_s_get_basic_quote_characters, 0);
776 rb_define_singleton_method(mReadline, "completer_quote_characters=",
777 readline_s_set_completer_quote_characters, 1);
778 rb_define_singleton_method(mReadline, "completer_quote_characters",
779 readline_s_get_completer_quote_characters, 0);
780 rb_define_singleton_method(mReadline, "filename_quote_characters=",
781 readline_s_set_filename_quote_characters, 1);
782 rb_define_singleton_method(mReadline, "filename_quote_characters",
783 readline_s_get_filename_quote_characters, 0);
785 history = rb_obj_alloc(rb_cObject);
786 rb_extend_object(history, rb_mEnumerable);
787 rb_define_singleton_method(history,"to_s", hist_to_s, 0);
788 rb_define_singleton_method(history,"[]", hist_get, 1);
789 rb_define_singleton_method(history,"[]=", hist_set, 2);
790 rb_define_singleton_method(history,"<<", hist_push, 1);
791 rb_define_singleton_method(history,"push", hist_push_method, -1);
792 rb_define_singleton_method(history,"pop", hist_pop, 0);
793 rb_define_singleton_method(history,"shift", hist_shift, 0);
794 rb_define_singleton_method(history,"each", hist_each, 0);
795 rb_define_singleton_method(history,"length", hist_length, 0);
796 rb_define_singleton_method(history,"size", hist_length, 0);
797 rb_define_singleton_method(history,"empty?", hist_empty_p, 0);
798 rb_define_singleton_method(history,"delete_at", hist_delete_at, 1);
799 rb_define_const(mReadline, "HISTORY", history);
801 fcomp = rb_obj_alloc(rb_cObject);
802 rb_define_singleton_method(fcomp, "call",
803 filename_completion_proc_call, 1);
804 rb_define_const(mReadline, "FILENAME_COMPLETION_PROC", fcomp);
806 ucomp = rb_obj_alloc(rb_cObject);
807 rb_define_singleton_method(ucomp, "call",
808 username_completion_proc_call, 1);
809 rb_define_const(mReadline, "USERNAME_COMPLETION_PROC", ucomp);
810 #if defined HAVE_RL_LIBRARY_VERSION
811 rb_define_const(mReadline, "VERSION", rb_str_new2(rl_library_version));
812 #else
813 rb_define_const(mReadline, "VERSION",
814 rb_str_new2("2.0 or before version"));
815 #endif
817 rl_attempted_completion_function = readline_attempted_completion_function;
818 #ifdef HAVE_RL_EVENT_HOOK
819 rl_event_hook = readline_event;
820 #endif
821 #ifdef HAVE_RL_CLEAR_SIGNALS
822 rl_clear_signals();
823 #endif