00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifdef RUBY_EXTCONF_H
00019 #include RUBY_EXTCONF_H
00020 #endif
00021
00022 #include "ruby/config.h"
00023 #include <errno.h>
00024 #include <stdio.h>
00025 #include <string.h>
00026 #ifdef HAVE_READLINE_READLINE_H
00027 #include <readline/readline.h>
00028 #endif
00029 #ifdef HAVE_READLINE_HISTORY_H
00030 #include <readline/history.h>
00031 #endif
00032 #ifdef HAVE_EDITLINE_READLINE_H
00033 #include <editline/readline.h>
00034 #endif
00035
00036 #include "ruby/ruby.h"
00037 #include "ruby/io.h"
00038 #include "ruby/thread.h"
00039
00040 #ifdef HAVE_UNISTD_H
00041 #include <unistd.h>
00042 #endif
00043
00044 #ifdef HAVE_SYS_STAT_H
00045 #include <sys/stat.h>
00046 #endif
00047
00048 static VALUE mReadline;
00049
00050 #define EDIT_LINE_LIBRARY_VERSION "EditLine wrapper"
00051 #ifndef USE_INSERT_IGNORE_ESCAPE
00052 # if !defined(HAVE_EDITLINE_READLINE_H) && defined(RL_PROMPT_START_IGNORE) && defined(RL_PROMPT_END_IGNORE)
00053 # define USE_INSERT_IGNORE_ESCAPE 1
00054 # else
00055 # define USE_INSERT_IGNORE_ESCAPE 0
00056 # endif
00057 #endif
00058
00059 #define COMPLETION_PROC "completion_proc"
00060 #define COMPLETION_CASE_FOLD "completion_case_fold"
00061 static ID completion_proc, completion_case_fold;
00062 #if USE_INSERT_IGNORE_ESCAPE
00063 static ID id_orig_prompt, id_last_prompt;
00064 #endif
00065 #if defined(HAVE_RL_PRE_INPUT_HOOK)
00066 static ID id_pre_input_hook;
00067 #endif
00068 #if defined(HAVE_RL_SPECIAL_PREFIXES)
00069 static ID id_special_prefixes;
00070 #endif
00071
00072 #ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION
00073 # define rl_filename_completion_function filename_completion_function
00074 #endif
00075 #ifndef HAVE_RL_USERNAME_COMPLETION_FUNCTION
00076 # define rl_username_completion_function username_completion_function
00077 #endif
00078 #ifndef HAVE_RL_COMPLETION_MATCHES
00079 # define rl_completion_matches completion_matches
00080 #endif
00081
00082 static int (*history_get_offset_func)(int);
00083 static int (*history_replace_offset_func)(int);
00084 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
00085 static int readline_completion_append_character;
00086 #endif
00087
00088 static char **readline_attempted_completion_function(const char *text,
00089 int start, int end);
00090
00091 #define OutputStringValue(str) do {\
00092 SafeStringValue(str);\
00093 (str) = rb_str_conv_enc((str), rb_enc_get(str), rb_locale_encoding());\
00094 } while (0)\
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 static VALUE readline_instream;
00131 static VALUE readline_outstream;
00132 static FILE *readline_rl_instream;
00133 static FILE *readline_rl_outstream;
00134
00135 #if defined HAVE_RL_GETC_FUNCTION
00136
00137 #ifndef HAVE_RL_GETC
00138 #define rl_getc(f) EOF
00139 #endif
00140
00141 struct getc_struct {
00142 FILE *input;
00143 int fd;
00144 int ret;
00145 int err;
00146 };
00147
00148 static int
00149 getc_body(struct getc_struct *p)
00150 {
00151 char ch;
00152 ssize_t ss;
00153
00154 #if defined(_WIN32)
00155 {
00156 INPUT_RECORD ir;
00157 int n;
00158 static int prior_key = '0';
00159 for (;;) {
00160 if (prior_key > 0xff) {
00161 prior_key = rl_getc(p->input);
00162 return prior_key;
00163 }
00164 if (PeekConsoleInput((HANDLE)_get_osfhandle(p->fd), &ir, 1, &n)) {
00165 if (n == 1) {
00166 if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown) {
00167 prior_key = rl_getc(p->input);
00168 return prior_key;
00169 } else {
00170 ReadConsoleInput((HANDLE)_get_osfhandle(p->fd), &ir, 1, &n);
00171 }
00172 } else {
00173 HANDLE h = (HANDLE)_get_osfhandle(p->fd);
00174 rb_w32_wait_events(&h, 1, INFINITE);
00175 }
00176 } else {
00177 break;
00178 }
00179 }
00180 }
00181 #endif
00182
00183 ss = read(p->fd, &ch, 1);
00184 if (ss == 0) {
00185 errno = 0;
00186 return EOF;
00187 }
00188 if (ss != 1)
00189 return EOF;
00190 return (unsigned char)ch;
00191 }
00192
00193 static void *
00194 getc_func(void *data1)
00195 {
00196 struct getc_struct *p = data1;
00197 errno = 0;
00198 p->ret = getc_body(p);
00199 p->err = errno;
00200 return NULL;
00201 }
00202
00203 static int
00204 readline_getc(FILE *input)
00205 {
00206 struct getc_struct data;
00207 if (input == NULL)
00208 input = stdin;
00209 data.input = input;
00210 data.fd = fileno(input);
00211 again:
00212 data.ret = EOF;
00213 data.err = EINTR;
00214 rb_thread_call_without_gvl2(getc_func, &data, RUBY_UBF_IO, NULL);
00215 if (data.ret == EOF) {
00216 if (data.err == 0) {
00217 return EOF;
00218 }
00219 if (data.err == EINTR) {
00220 rb_thread_check_ints();
00221 goto again;
00222 }
00223 if (data.err == EWOULDBLOCK || data.err == EAGAIN) {
00224 int ret;
00225 if (fileno(input) != data.fd)
00226 rb_bug("readline_getc: input closed unexpectedly or memory corrupted");
00227 ret = rb_wait_for_single_fd(data.fd, RB_WAITFD_IN, NULL);
00228 if (ret != -1 || errno == EINTR)
00229 goto again;
00230 rb_sys_fail("rb_wait_for_single_fd");
00231 }
00232 errno = data.err;
00233 rb_sys_fail("read");
00234 }
00235 return data.ret;
00236 }
00237
00238 #elif defined HAVE_RL_EVENT_HOOK
00239 #define BUSY_WAIT 0
00240
00241 static int readline_event(void);
00242 static int
00243 readline_event(void)
00244 {
00245 #if BUSY_WAIT
00246 rb_thread_schedule();
00247 #else
00248 rb_wait_for_single_fd(fileno(rl_instream), RB_WAITFD_IN, NULL);
00249 return 0;
00250 #endif
00251 }
00252 #endif
00253
00254 #if USE_INSERT_IGNORE_ESCAPE
00255 static VALUE
00256 insert_ignore_escape(VALUE self, VALUE prompt)
00257 {
00258 VALUE last_prompt, orig_prompt = rb_attr_get(self, id_orig_prompt);
00259 int ignoring = 0;
00260 const char *s0, *s, *e;
00261 long len;
00262 static const char ignore_code[2] = {RL_PROMPT_START_IGNORE, RL_PROMPT_END_IGNORE};
00263
00264 prompt = rb_str_new_shared(prompt);
00265 last_prompt = rb_attr_get(self, id_last_prompt);
00266 if (orig_prompt == prompt) return last_prompt;
00267 len = RSTRING_LEN(prompt);
00268 if (NIL_P(last_prompt)) {
00269 last_prompt = rb_str_tmp_new(len);
00270 }
00271
00272 s = s0 = RSTRING_PTR(prompt);
00273 e = s0 + len;
00274 rb_str_set_len(last_prompt, 0);
00275 while (s < e && *s) {
00276 switch (*s) {
00277 case RL_PROMPT_START_IGNORE:
00278 ignoring = -1;
00279 rb_str_cat(last_prompt, s0, ++s - s0);
00280 s0 = s;
00281 break;
00282 case RL_PROMPT_END_IGNORE:
00283 ignoring = 0;
00284 rb_str_cat(last_prompt, s0, ++s - s0);
00285 s0 = s;
00286 break;
00287 case '\033':
00288 if (++s < e && *s == '[') {
00289 rb_str_cat(last_prompt, s0, s - s0 - 1);
00290 s0 = s - 1;
00291 while (++s < e && *s) {
00292 if (ISALPHA(*(unsigned char *)s)) {
00293 if (!ignoring) {
00294 ignoring = 1;
00295 rb_str_cat(last_prompt, ignore_code+0, 1);
00296 }
00297 rb_str_cat(last_prompt, s0, ++s - s0);
00298 s0 = s;
00299 break;
00300 }
00301 else if (!(('0' <= *s && *s <= '9') || *s == ';')) {
00302 break;
00303 }
00304 }
00305 }
00306 break;
00307 default:
00308 if (ignoring > 0) {
00309 ignoring = 0;
00310 rb_str_cat(last_prompt, ignore_code+1, 1);
00311 }
00312 s++;
00313 break;
00314 }
00315 }
00316 if (ignoring > 0) {
00317 ignoring = 0;
00318 rb_str_cat(last_prompt, ignore_code+1, 1);
00319 }
00320 rb_str_cat(last_prompt, s0, s - s0);
00321
00322 rb_ivar_set(self, id_orig_prompt, prompt);
00323 rb_ivar_set(self, id_last_prompt, last_prompt);
00324
00325 return last_prompt;
00326 }
00327 #endif
00328
00329 static VALUE
00330 readline_get(VALUE prompt)
00331 {
00332 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
00333 readline_completion_append_character = rl_completion_append_character;
00334 #endif
00335 return (VALUE)readline((char *)prompt);
00336 }
00337
00338 static void
00339 clear_rl_instream(void)
00340 {
00341 if (readline_rl_instream) {
00342 fclose(readline_rl_instream);
00343 if (rl_instream == readline_rl_instream)
00344 rl_instream = NULL;
00345 readline_rl_instream = NULL;
00346 }
00347 readline_instream = Qfalse;
00348 }
00349
00350 static void
00351 clear_rl_outstream(void)
00352 {
00353 if (readline_rl_outstream) {
00354 fclose(readline_rl_outstream);
00355 if (rl_outstream == readline_rl_outstream)
00356 rl_outstream = NULL;
00357 readline_rl_outstream = NULL;
00358 }
00359 readline_outstream = Qfalse;
00360 }
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446 static VALUE
00447 readline_readline(int argc, VALUE *argv, VALUE self)
00448 {
00449 VALUE tmp, add_hist, result;
00450 char *prompt = NULL;
00451 char *buff;
00452 int status;
00453
00454 if (rb_scan_args(argc, argv, "02", &tmp, &add_hist) > 0) {
00455 OutputStringValue(tmp);
00456 #if USE_INSERT_IGNORE_ESCAPE
00457 tmp = insert_ignore_escape(self, tmp);
00458 rb_str_locktmp(tmp);
00459 #endif
00460 prompt = RSTRING_PTR(tmp);
00461 }
00462
00463 if (readline_instream) {
00464 rb_io_t *ifp;
00465 rb_io_check_initialized(ifp = RFILE(rb_io_taint_check(readline_instream))->fptr);
00466 if (ifp->fd < 0) {
00467 clear_rl_instream();
00468 rb_raise(rb_eIOError, "closed readline input");
00469 }
00470 }
00471
00472 if (readline_outstream) {
00473 rb_io_t *ofp;
00474 rb_io_check_initialized(ofp = RFILE(rb_io_taint_check(readline_outstream))->fptr);
00475 if (ofp->fd < 0) {
00476 clear_rl_outstream();
00477 rb_raise(rb_eIOError, "closed readline output");
00478 }
00479 }
00480
00481 #ifdef _WIN32
00482 rl_prep_terminal(1);
00483 #endif
00484 buff = (char*)rb_protect(readline_get, (VALUE)prompt, &status);
00485 #if USE_INSERT_IGNORE_ESCAPE
00486 if (prompt) {
00487 rb_str_unlocktmp(tmp);
00488 }
00489 #endif
00490 if (status) {
00491 #if defined HAVE_RL_CLEANUP_AFTER_SIGNAL
00492
00493 #if defined HAVE_RL_FREE_LINE_STATE
00494 rl_free_line_state();
00495 #endif
00496 rl_cleanup_after_signal();
00497 #elif defined HAVE_RL_DEPREP_TERM_FUNCTION
00498
00499 if (rl_deprep_term_function != NULL)
00500 (*rl_deprep_term_function)();
00501 else
00502 #else
00503 rl_deprep_terminal();
00504 #endif
00505 rb_jump_tag(status);
00506 }
00507
00508 if (RTEST(add_hist) && buff) {
00509 add_history(buff);
00510 }
00511 if (buff) {
00512 result = rb_locale_str_new_cstr(buff);
00513 }
00514 else
00515 result = Qnil;
00516 if (buff) free(buff);
00517 return result;
00518 }
00519
00520
00521
00522
00523
00524
00525
00526
00527 static VALUE
00528 readline_s_set_input(VALUE self, VALUE input)
00529 {
00530 rb_io_t *ifp;
00531 int fd;
00532 FILE *f;
00533
00534 if (NIL_P(input)) {
00535 clear_rl_instream();
00536 }
00537 else {
00538 Check_Type(input, T_FILE);
00539 GetOpenFile(input, ifp);
00540 clear_rl_instream();
00541 fd = rb_cloexec_dup(ifp->fd);
00542 if (fd == -1)
00543 rb_sys_fail("dup");
00544 f = fdopen(fd, "r");
00545 if (f == NULL) {
00546 int save_errno = errno;
00547 close(fd);
00548 errno = save_errno;
00549 rb_sys_fail("fdopen");
00550 }
00551 rl_instream = readline_rl_instream = f;
00552 readline_instream = input;
00553 }
00554 return input;
00555 }
00556
00557
00558
00559
00560
00561
00562
00563
00564 static VALUE
00565 readline_s_set_output(VALUE self, VALUE output)
00566 {
00567 rb_io_t *ofp;
00568 int fd;
00569 FILE *f;
00570
00571 if (NIL_P(output)) {
00572 clear_rl_outstream();
00573 }
00574 else {
00575 Check_Type(output, T_FILE);
00576 GetOpenFile(output, ofp);
00577 clear_rl_outstream();
00578 fd = rb_cloexec_dup(ofp->fd);
00579 if (fd == -1)
00580 rb_sys_fail("dup");
00581 f = fdopen(fd, "w");
00582 if (f == NULL) {
00583 int save_errno = errno;
00584 close(fd);
00585 errno = save_errno;
00586 rb_sys_fail("fdopen");
00587 }
00588 rl_outstream = readline_rl_outstream = f;
00589 readline_outstream = output;
00590 }
00591 return output;
00592 }
00593
00594 #if defined(HAVE_RL_PRE_INPUT_HOOK)
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609 static VALUE
00610 readline_s_set_pre_input_hook(VALUE self, VALUE proc)
00611 {
00612 if (!NIL_P(proc) && !rb_respond_to(proc, rb_intern("call")))
00613 rb_raise(rb_eArgError, "argument must respond to `call'");
00614 return rb_ivar_set(mReadline, id_pre_input_hook, proc);
00615 }
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627 static VALUE
00628 readline_s_get_pre_input_hook(VALUE self)
00629 {
00630 return rb_attr_get(mReadline, id_pre_input_hook);
00631 }
00632
00633 static int
00634 readline_pre_input_hook(void)
00635 {
00636 VALUE proc;
00637
00638 proc = rb_attr_get(mReadline, id_pre_input_hook);
00639 if (!NIL_P(proc))
00640 rb_funcall(proc, rb_intern("call"), 0);
00641 return 0;
00642 }
00643 #else
00644 #define readline_s_set_pre_input_hook rb_f_notimplement
00645 #define readline_s_get_pre_input_hook rb_f_notimplement
00646 #endif
00647
00648 #if defined(HAVE_RL_INSERT_TEXT)
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659 static VALUE
00660 readline_s_insert_text(VALUE self, VALUE str)
00661 {
00662 OutputStringValue(str);
00663 rl_insert_text(RSTRING_PTR(str));
00664 return self;
00665 }
00666 #else
00667 #define readline_s_insert_text rb_f_notimplement
00668 #endif
00669
00670 #if defined(HAVE_RL_DELETE_TEXT)
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683 static VALUE
00684 readline_s_delete_text(int argc, VALUE *argv, VALUE self)
00685 {
00686 rb_check_arity(argc, 0, 2);
00687 if (rl_line_buffer) {
00688 char *p, *ptr = rl_line_buffer;
00689 long beg = 0, len = strlen(rl_line_buffer);
00690 struct RString fakestr;
00691 VALUE str = (VALUE)&fakestr;
00692
00693 fakestr.basic.flags = T_STRING | RSTRING_NOEMBED;
00694 fakestr.as.heap.ptr = ptr;
00695 fakestr.as.heap.len = len;
00696 rb_enc_associate(str, rb_locale_encoding());
00697 OBJ_FREEZE(str);
00698 if (argc == 2) {
00699 beg = NUM2LONG(argv[0]);
00700 len = NUM2LONG(argv[1]);
00701 num_pos:
00702 p = rb_str_subpos(str, beg, &len);
00703 if (!p) rb_raise(rb_eArgError, "invalid index");
00704 beg = p - ptr;
00705 }
00706 else if (argc == 1) {
00707 len = rb_str_strlen(str);
00708 if (!rb_range_beg_len(argv[0], &beg, &len, len, 1)) {
00709 beg = NUM2LONG(argv[0]);
00710 goto num_pos;
00711 }
00712 }
00713 rl_delete_text(rb_long2int(beg), rb_long2int(beg + len));
00714 }
00715 return self;
00716 }
00717 #else
00718 #define readline_s_delete_text rb_f_notimplement
00719 #endif
00720
00721 #if defined(HAVE_RL_REDISPLAY)
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733 static VALUE
00734 readline_s_redisplay(VALUE self)
00735 {
00736 rl_redisplay();
00737 return self;
00738 }
00739 #else
00740 #define readline_s_redisplay rb_f_notimplement
00741 #endif
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811 static VALUE
00812 readline_s_set_completion_proc(VALUE self, VALUE proc)
00813 {
00814 if (!NIL_P(proc) && !rb_respond_to(proc, rb_intern("call")))
00815 rb_raise(rb_eArgError, "argument must respond to `call'");
00816 return rb_ivar_set(mReadline, completion_proc, proc);
00817 }
00818
00819
00820
00821
00822
00823
00824
00825 static VALUE
00826 readline_s_get_completion_proc(VALUE self)
00827 {
00828 return rb_attr_get(mReadline, completion_proc);
00829 }
00830
00831
00832
00833
00834
00835
00836
00837 static VALUE
00838 readline_s_set_completion_case_fold(VALUE self, VALUE val)
00839 {
00840 return rb_ivar_set(mReadline, completion_case_fold, val);
00841 }
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857 static VALUE
00858 readline_s_get_completion_case_fold(VALUE self)
00859 {
00860 return rb_attr_get(mReadline, completion_case_fold);
00861 }
00862
00863 #ifdef HAVE_RL_LINE_BUFFER
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877 static VALUE
00878 readline_s_get_line_buffer(VALUE self)
00879 {
00880 if (rl_line_buffer == NULL)
00881 return Qnil;
00882 return rb_locale_str_new_cstr(rl_line_buffer);
00883 }
00884 #else
00885 #define readline_s_get_line_buffer rb_f_notimplement
00886 #endif
00887
00888 #ifdef HAVE_RL_POINT
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904 static VALUE
00905 readline_s_get_point(VALUE self)
00906 {
00907 return INT2NUM(rl_point);
00908 }
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921 static VALUE
00922 readline_s_set_point(VALUE self, VALUE pos)
00923 {
00924 rl_point = NUM2INT(pos);
00925 return pos;
00926 }
00927 #else
00928 #define readline_s_get_point rb_f_notimplement
00929 #define readline_s_set_point rb_f_notimplement
00930 #endif
00931
00932 static char **
00933 readline_attempted_completion_function(const char *text, int start, int end)
00934 {
00935 VALUE proc, ary, temp;
00936 char **result;
00937 int case_fold;
00938 long i, matches;
00939 rb_encoding *enc;
00940 VALUE encobj;
00941
00942 proc = rb_attr_get(mReadline, completion_proc);
00943 if (NIL_P(proc))
00944 return NULL;
00945 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
00946 rl_completion_append_character = readline_completion_append_character;
00947 #endif
00948 #ifdef HAVE_RL_ATTEMPTED_COMPLETION_OVER
00949 rl_attempted_completion_over = 1;
00950 #endif
00951 case_fold = RTEST(rb_attr_get(mReadline, completion_case_fold));
00952 ary = rb_funcall(proc, rb_intern("call"), 1, rb_locale_str_new_cstr(text));
00953 if (!RB_TYPE_P(ary, T_ARRAY))
00954 ary = rb_Array(ary);
00955 matches = RARRAY_LEN(ary);
00956 if (matches == 0) return NULL;
00957 result = (char**)malloc((matches + 2)*sizeof(char*));
00958 if (result == NULL) rb_memerror();
00959 enc = rb_locale_encoding();
00960 encobj = rb_enc_from_encoding(enc);
00961 for (i = 0; i < matches; i++) {
00962 temp = rb_obj_as_string(RARRAY_PTR(ary)[i]);
00963 StringValueCStr(temp);
00964 rb_enc_check(encobj, temp);
00965 result[i + 1] = (char*)malloc(RSTRING_LEN(temp) + 1);
00966 if (result[i + 1] == NULL) rb_memerror();
00967 strcpy(result[i + 1], RSTRING_PTR(temp));
00968 }
00969 result[matches + 1] = NULL;
00970
00971 if (matches == 1) {
00972 result[0] = strdup(result[1]);
00973 }
00974 else {
00975 const char *result1 = result[1];
00976 long low = strlen(result1);
00977
00978 for (i = 1; i < matches; ++i) {
00979 register int c1, c2;
00980 long i1, i2, l2;
00981 int n1, n2;
00982 const char *p2 = result[i + 1];
00983
00984 l2 = strlen(p2);
00985 for (i1 = i2 = 0; i1 < low && i2 < l2; i1 += n1, i2 += n2) {
00986 c1 = rb_enc_codepoint_len(result1 + i1, result1 + low, &n1, enc);
00987 c2 = rb_enc_codepoint_len(p2 + i2, p2 + l2, &n2, enc);
00988 if (case_fold) {
00989 c1 = rb_tolower(c1);
00990 c2 = rb_tolower(c2);
00991 }
00992 if (c1 != c2) break;
00993 }
00994
00995 low = i1;
00996 }
00997 result[0] = (char*)malloc(low + 1);
00998 if (result[0] == NULL) rb_memerror();
00999 strncpy(result[0], result[1], low);
01000 result[0][low] = '\0';
01001 }
01002
01003 return result;
01004 }
01005
01006 #ifdef HAVE_RL_SET_SCREEN_SIZE
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017 static VALUE
01018 readline_s_set_screen_size(VALUE self, VALUE rows, VALUE columns)
01019 {
01020 rl_set_screen_size(NUM2INT(rows), NUM2INT(columns));
01021 return self;
01022 }
01023 #else
01024 #define readline_s_set_screen_size rb_f_notimplement
01025 #endif
01026
01027 #ifdef HAVE_RL_GET_SCREEN_SIZE
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038 static VALUE
01039 readline_s_get_screen_size(VALUE self)
01040 {
01041 int rows, columns;
01042 VALUE res;
01043
01044 rl_get_screen_size(&rows, &columns);
01045 res = rb_ary_new();
01046 rb_ary_push(res, INT2NUM(rows));
01047 rb_ary_push(res, INT2NUM(columns));
01048 return res;
01049 }
01050 #else
01051 #define readline_s_get_screen_size rb_f_notimplement
01052 #endif
01053
01054 #ifdef HAVE_RL_VI_EDITING_MODE
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064 static VALUE
01065 readline_s_vi_editing_mode(VALUE self)
01066 {
01067 rl_vi_editing_mode(1,0);
01068 return Qnil;
01069 }
01070 #else
01071 #define readline_s_vi_editing_mode rb_f_notimplement
01072 #endif
01073
01074 #ifdef HAVE_RL_EDITING_MODE
01075
01076
01077
01078
01079
01080
01081
01082
01083 static VALUE
01084 readline_s_vi_editing_mode_p(VALUE self)
01085 {
01086 return rl_editing_mode == 0 ? Qtrue : Qfalse;
01087 }
01088 #else
01089 #define readline_s_vi_editing_mode_p rb_f_notimplement
01090 #endif
01091
01092 #ifdef HAVE_RL_EMACS_EDITING_MODE
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102 static VALUE
01103 readline_s_emacs_editing_mode(VALUE self)
01104 {
01105 rl_emacs_editing_mode(1,0);
01106 return Qnil;
01107 }
01108 #else
01109 #define readline_s_emacs_editing_mode rb_f_notimplement
01110 #endif
01111
01112 #ifdef HAVE_RL_EDITING_MODE
01113
01114
01115
01116
01117
01118
01119
01120
01121 static VALUE
01122 readline_s_emacs_editing_mode_p(VALUE self)
01123 {
01124 return rl_editing_mode == 1 ? Qtrue : Qfalse;
01125 }
01126 #else
01127 #define readline_s_emacs_editing_mode_p rb_f_notimplement
01128 #endif
01129
01130 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167 static VALUE
01168 readline_s_set_completion_append_character(VALUE self, VALUE str)
01169 {
01170 if (NIL_P(str)) {
01171 rl_completion_append_character = '\0';
01172 }
01173 else {
01174 OutputStringValue(str);
01175 if (RSTRING_LEN(str) == 0) {
01176 rl_completion_append_character = '\0';
01177 } else {
01178 rl_completion_append_character = RSTRING_PTR(str)[0];
01179 }
01180 }
01181 return self;
01182 }
01183 #else
01184 #define readline_s_set_completion_append_character rb_f_notimplement
01185 #endif
01186
01187 #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197 static VALUE
01198 readline_s_get_completion_append_character(VALUE self)
01199 {
01200 char buf[1];
01201
01202 if (rl_completion_append_character == '\0')
01203 return Qnil;
01204
01205 buf[0] = (char) rl_completion_append_character;
01206 return rb_locale_str_new(buf, 1);
01207 }
01208 #else
01209 #define readline_s_get_completion_append_character rb_f_notimplement
01210 #endif
01211
01212 #ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223 static VALUE
01224 readline_s_set_basic_word_break_characters(VALUE self, VALUE str)
01225 {
01226 static char *basic_word_break_characters = NULL;
01227
01228 OutputStringValue(str);
01229 if (basic_word_break_characters == NULL) {
01230 basic_word_break_characters =
01231 ALLOC_N(char, RSTRING_LEN(str) + 1);
01232 }
01233 else {
01234 REALLOC_N(basic_word_break_characters, char, RSTRING_LEN(str) + 1);
01235 }
01236 strncpy(basic_word_break_characters,
01237 RSTRING_PTR(str), RSTRING_LEN(str));
01238 basic_word_break_characters[RSTRING_LEN(str)] = '\0';
01239 rl_basic_word_break_characters = basic_word_break_characters;
01240 return self;
01241 }
01242 #else
01243 #define readline_s_set_basic_word_break_characters rb_f_notimplement
01244 #endif
01245
01246 #ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256 static VALUE
01257 readline_s_get_basic_word_break_characters(VALUE self, VALUE str)
01258 {
01259 if (rl_basic_word_break_characters == NULL)
01260 return Qnil;
01261 return rb_locale_str_new_cstr(rl_basic_word_break_characters);
01262 }
01263 #else
01264 #define readline_s_get_basic_word_break_characters rb_f_notimplement
01265 #endif
01266
01267 #ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278 static VALUE
01279 readline_s_set_completer_word_break_characters(VALUE self, VALUE str)
01280 {
01281 static char *completer_word_break_characters = NULL;
01282
01283 OutputStringValue(str);
01284 if (completer_word_break_characters == NULL) {
01285 completer_word_break_characters =
01286 ALLOC_N(char, RSTRING_LEN(str) + 1);
01287 }
01288 else {
01289 REALLOC_N(completer_word_break_characters, char, RSTRING_LEN(str) + 1);
01290 }
01291 strncpy(completer_word_break_characters,
01292 RSTRING_PTR(str), RSTRING_LEN(str));
01293 completer_word_break_characters[RSTRING_LEN(str)] = '\0';
01294 rl_completer_word_break_characters = completer_word_break_characters;
01295 return self;
01296 }
01297 #else
01298 #define readline_s_set_completer_word_break_characters rb_f_notimplement
01299 #endif
01300
01301 #ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311 static VALUE
01312 readline_s_get_completer_word_break_characters(VALUE self, VALUE str)
01313 {
01314 if (rl_completer_word_break_characters == NULL)
01315 return Qnil;
01316 return rb_locale_str_new_cstr(rl_completer_word_break_characters);
01317 }
01318 #else
01319 #define readline_s_get_completer_word_break_characters rb_f_notimplement
01320 #endif
01321
01322 #if defined(HAVE_RL_SPECIAL_PREFIXES)
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337 static VALUE
01338 readline_s_set_special_prefixes(VALUE self, VALUE str)
01339 {
01340 if (!NIL_P(str)) {
01341 OutputStringValue(str);
01342 str = rb_str_dup_frozen(str);
01343 rb_obj_hide(str);
01344 }
01345 rb_ivar_set(mReadline, id_special_prefixes, str);
01346 if (NIL_P(str)) {
01347 rl_special_prefixes = NULL;
01348 }
01349 else {
01350 rl_special_prefixes = RSTRING_PTR(str);
01351 }
01352 return self;
01353 }
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367 static VALUE
01368 readline_s_get_special_prefixes(VALUE self)
01369 {
01370 VALUE str;
01371 if (rl_special_prefixes == NULL) return Qnil;
01372 str = rb_ivar_get(mReadline, id_special_prefixes);
01373 if (!NIL_P(str)) {
01374 str = rb_str_dup_frozen(str);
01375 rb_obj_reveal(str, rb_cString);
01376 }
01377 return str;
01378 }
01379 #else
01380 #define readline_s_set_special_prefixes rb_f_notimplement
01381 #define readline_s_get_special_prefixes rb_f_notimplement
01382 #endif
01383
01384 #ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS
01385
01386
01387
01388
01389
01390
01391
01392
01393 static VALUE
01394 readline_s_set_basic_quote_characters(VALUE self, VALUE str)
01395 {
01396 static char *basic_quote_characters = NULL;
01397
01398 OutputStringValue(str);
01399 if (basic_quote_characters == NULL) {
01400 basic_quote_characters =
01401 ALLOC_N(char, RSTRING_LEN(str) + 1);
01402 }
01403 else {
01404 REALLOC_N(basic_quote_characters, char, RSTRING_LEN(str) + 1);
01405 }
01406 strncpy(basic_quote_characters,
01407 RSTRING_PTR(str), RSTRING_LEN(str));
01408 basic_quote_characters[RSTRING_LEN(str)] = '\0';
01409 rl_basic_quote_characters = basic_quote_characters;
01410
01411 return self;
01412 }
01413 #else
01414 #define readline_s_set_basic_quote_characters rb_f_notimplement
01415 #endif
01416
01417 #ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS
01418
01419
01420
01421
01422
01423
01424
01425
01426 static VALUE
01427 readline_s_get_basic_quote_characters(VALUE self, VALUE str)
01428 {
01429 if (rl_basic_quote_characters == NULL)
01430 return Qnil;
01431 return rb_locale_str_new_cstr(rl_basic_quote_characters);
01432 }
01433 #else
01434 #define readline_s_get_basic_quote_characters rb_f_notimplement
01435 #endif
01436
01437 #ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449 static VALUE
01450 readline_s_set_completer_quote_characters(VALUE self, VALUE str)
01451 {
01452 static char *completer_quote_characters = NULL;
01453
01454 OutputStringValue(str);
01455 if (completer_quote_characters == NULL) {
01456 completer_quote_characters =
01457 ALLOC_N(char, RSTRING_LEN(str) + 1);
01458 }
01459 else {
01460 REALLOC_N(completer_quote_characters, char, RSTRING_LEN(str) + 1);
01461 }
01462 strncpy(completer_quote_characters, RSTRING_PTR(str), RSTRING_LEN(str));
01463 completer_quote_characters[RSTRING_LEN(str)] = '\0';
01464 rl_completer_quote_characters = completer_quote_characters;
01465
01466 return self;
01467 }
01468 #else
01469 #define readline_s_set_completer_quote_characters rb_f_notimplement
01470 #endif
01471
01472 #ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482 static VALUE
01483 readline_s_get_completer_quote_characters(VALUE self, VALUE str)
01484 {
01485 if (rl_completer_quote_characters == NULL)
01486 return Qnil;
01487 return rb_locale_str_new_cstr(rl_completer_quote_characters);
01488 }
01489 #else
01490 #define readline_s_get_completer_quote_characters rb_f_notimplement
01491 #endif
01492
01493 #ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503 static VALUE
01504 readline_s_set_filename_quote_characters(VALUE self, VALUE str)
01505 {
01506 static char *filename_quote_characters = NULL;
01507
01508 OutputStringValue(str);
01509 if (filename_quote_characters == NULL) {
01510 filename_quote_characters =
01511 ALLOC_N(char, RSTRING_LEN(str) + 1);
01512 }
01513 else {
01514 REALLOC_N(filename_quote_characters, char, RSTRING_LEN(str) + 1);
01515 }
01516 strncpy(filename_quote_characters, RSTRING_PTR(str), RSTRING_LEN(str));
01517 filename_quote_characters[RSTRING_LEN(str)] = '\0';
01518 rl_filename_quote_characters = filename_quote_characters;
01519
01520 return self;
01521 }
01522 #else
01523 #define readline_s_set_filename_quote_characters rb_f_notimplement
01524 #endif
01525
01526 #ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536 static VALUE
01537 readline_s_get_filename_quote_characters(VALUE self, VALUE str)
01538 {
01539 if (rl_filename_quote_characters == NULL)
01540 return Qnil;
01541 return rb_locale_str_new_cstr(rl_filename_quote_characters);
01542 }
01543 #else
01544 #define readline_s_get_filename_quote_characters rb_f_notimplement
01545 #endif
01546
01547 #ifdef HAVE_RL_REFRESH_LINE
01548
01549
01550
01551
01552
01553
01554 static VALUE
01555 readline_s_refresh_line(VALUE self)
01556 {
01557 rl_refresh_line(0, 0);
01558 return Qnil;
01559 }
01560 #else
01561 #define readline_s_refresh_line rb_f_notimplement
01562 #endif
01563
01564 static VALUE
01565 hist_to_s(VALUE self)
01566 {
01567 return rb_str_new_cstr("HISTORY");
01568 }
01569
01570 static int
01571 history_get_offset_history_base(int offset)
01572 {
01573 return history_base + offset;
01574 }
01575
01576 static int
01577 history_get_offset_0(int offset)
01578 {
01579 return offset;
01580 }
01581
01582 static VALUE
01583 hist_get(VALUE self, VALUE index)
01584 {
01585 HIST_ENTRY *entry = NULL;
01586 int i;
01587
01588 i = NUM2INT(index);
01589 if (i < 0) {
01590 i += history_length;
01591 }
01592 if (i >= 0) {
01593 entry = history_get(history_get_offset_func(i));
01594 }
01595 if (entry == NULL) {
01596 rb_raise(rb_eIndexError, "invalid index");
01597 }
01598 return rb_locale_str_new_cstr(entry->line);
01599 }
01600
01601 #ifdef HAVE_REPLACE_HISTORY_ENTRY
01602 static VALUE
01603 hist_set(VALUE self, VALUE index, VALUE str)
01604 {
01605 HIST_ENTRY *entry = NULL;
01606 int i;
01607
01608 i = NUM2INT(index);
01609 OutputStringValue(str);
01610 if (i < 0) {
01611 i += history_length;
01612 }
01613 if (i >= 0) {
01614 entry = replace_history_entry(history_replace_offset_func(i), RSTRING_PTR(str), NULL);
01615 }
01616 if (entry == NULL) {
01617 rb_raise(rb_eIndexError, "invalid index");
01618 }
01619 return str;
01620 }
01621 #else
01622 #define hist_set rb_f_notimplement
01623 #endif
01624
01625 static VALUE
01626 hist_push(VALUE self, VALUE str)
01627 {
01628 OutputStringValue(str);
01629 add_history(RSTRING_PTR(str));
01630 return self;
01631 }
01632
01633 static VALUE
01634 hist_push_method(int argc, VALUE *argv, VALUE self)
01635 {
01636 VALUE str;
01637
01638 while (argc--) {
01639 str = *argv++;
01640 OutputStringValue(str);
01641 add_history(RSTRING_PTR(str));
01642 }
01643 return self;
01644 }
01645
01646 static VALUE
01647 rb_remove_history(int index)
01648 {
01649 #ifdef HAVE_REMOVE_HISTORY
01650 HIST_ENTRY *entry;
01651 VALUE val;
01652
01653 entry = remove_history(index);
01654 if (entry) {
01655 val = rb_locale_str_new_cstr(entry->line);
01656 free((void *) entry->line);
01657 free(entry);
01658 return val;
01659 }
01660 return Qnil;
01661 #else
01662 rb_notimplement();
01663
01664 UNREACHABLE;
01665 #endif
01666 }
01667
01668 static VALUE
01669 hist_pop(VALUE self)
01670 {
01671 if (history_length > 0) {
01672 return rb_remove_history(history_length - 1);
01673 } else {
01674 return Qnil;
01675 }
01676 }
01677
01678 static VALUE
01679 hist_shift(VALUE self)
01680 {
01681 if (history_length > 0) {
01682 return rb_remove_history(0);
01683 } else {
01684 return Qnil;
01685 }
01686 }
01687
01688 static VALUE
01689 hist_each(VALUE self)
01690 {
01691 HIST_ENTRY *entry;
01692 int i;
01693
01694 RETURN_ENUMERATOR(self, 0, 0);
01695
01696 for (i = 0; i < history_length; i++) {
01697 entry = history_get(history_get_offset_func(i));
01698 if (entry == NULL)
01699 break;
01700 rb_yield(rb_locale_str_new_cstr(entry->line));
01701 }
01702 return self;
01703 }
01704
01705 static VALUE
01706 hist_length(VALUE self)
01707 {
01708 return INT2NUM(history_length);
01709 }
01710
01711 static VALUE
01712 hist_empty_p(VALUE self)
01713 {
01714 return history_length == 0 ? Qtrue : Qfalse;
01715 }
01716
01717 static VALUE
01718 hist_delete_at(VALUE self, VALUE index)
01719 {
01720 int i;
01721
01722 i = NUM2INT(index);
01723 if (i < 0)
01724 i += history_length;
01725 if (i < 0 || i > history_length - 1) {
01726 rb_raise(rb_eIndexError, "invalid index");
01727 }
01728 return rb_remove_history(i);
01729 }
01730
01731 #ifdef HAVE_CLEAR_HISTORY
01732 static VALUE
01733 hist_clear(VALUE self)
01734 {
01735 clear_history();
01736 return self;
01737 }
01738 #else
01739 #define hist_clear rb_f_notimplement
01740 #endif
01741
01742 static VALUE
01743 filename_completion_proc_call(VALUE self, VALUE str)
01744 {
01745 VALUE result;
01746 char **matches;
01747 int i;
01748
01749 matches = rl_completion_matches(StringValuePtr(str),
01750 rl_filename_completion_function);
01751 if (matches) {
01752 result = rb_ary_new();
01753 for (i = 0; matches[i]; i++) {
01754 rb_ary_push(result, rb_locale_str_new_cstr(matches[i]));
01755 free(matches[i]);
01756 }
01757 free(matches);
01758 if (RARRAY_LEN(result) >= 2)
01759 rb_ary_shift(result);
01760 }
01761 else {
01762 result = Qnil;
01763 }
01764 return result;
01765 }
01766
01767 static VALUE
01768 username_completion_proc_call(VALUE self, VALUE str)
01769 {
01770 VALUE result;
01771 char **matches;
01772 int i;
01773
01774 matches = rl_completion_matches(StringValuePtr(str),
01775 rl_username_completion_function);
01776 if (matches) {
01777 result = rb_ary_new();
01778 for (i = 0; matches[i]; i++) {
01779 rb_ary_push(result, rb_locale_str_new_cstr(matches[i]));
01780 free(matches[i]);
01781 }
01782 free(matches);
01783 if (RARRAY_LEN(result) >= 2)
01784 rb_ary_shift(result);
01785 }
01786 else {
01787 result = Qnil;
01788 }
01789 return result;
01790 }
01791
01792 void
01793 Init_readline()
01794 {
01795 VALUE history, fcomp, ucomp, version;
01796
01797
01798 rl_readline_name = (char *)"Ruby";
01799
01800 #if defined HAVE_RL_GETC_FUNCTION
01801
01802
01803
01804 rl_getc_function = readline_getc;
01805 #elif defined HAVE_RL_EVENT_HOOK
01806 rl_event_hook = readline_event;
01807 #endif
01808
01809 using_history();
01810
01811 completion_proc = rb_intern(COMPLETION_PROC);
01812 completion_case_fold = rb_intern(COMPLETION_CASE_FOLD);
01813 #if defined(HAVE_RL_PRE_INPUT_HOOK)
01814 id_pre_input_hook = rb_intern("pre_input_hook");
01815 #endif
01816 #if defined(HAVE_RL_SPECIAL_PREFIXES)
01817 id_special_prefixes = rb_intern("special_prefixes");
01818 #endif
01819
01820 mReadline = rb_define_module("Readline");
01821 rb_define_module_function(mReadline, "readline",
01822 readline_readline, -1);
01823 rb_define_singleton_method(mReadline, "input=",
01824 readline_s_set_input, 1);
01825 rb_define_singleton_method(mReadline, "output=",
01826 readline_s_set_output, 1);
01827 rb_define_singleton_method(mReadline, "completion_proc=",
01828 readline_s_set_completion_proc, 1);
01829 rb_define_singleton_method(mReadline, "completion_proc",
01830 readline_s_get_completion_proc, 0);
01831 rb_define_singleton_method(mReadline, "completion_case_fold=",
01832 readline_s_set_completion_case_fold, 1);
01833 rb_define_singleton_method(mReadline, "completion_case_fold",
01834 readline_s_get_completion_case_fold, 0);
01835 rb_define_singleton_method(mReadline, "line_buffer",
01836 readline_s_get_line_buffer, 0);
01837 rb_define_singleton_method(mReadline, "point",
01838 readline_s_get_point, 0);
01839 rb_define_singleton_method(mReadline, "point=",
01840 readline_s_set_point, 1);
01841 rb_define_singleton_method(mReadline, "set_screen_size",
01842 readline_s_set_screen_size, 2);
01843 rb_define_singleton_method(mReadline, "get_screen_size",
01844 readline_s_get_screen_size, 0);
01845 rb_define_singleton_method(mReadline, "vi_editing_mode",
01846 readline_s_vi_editing_mode, 0);
01847 rb_define_singleton_method(mReadline, "vi_editing_mode?",
01848 readline_s_vi_editing_mode_p, 0);
01849 rb_define_singleton_method(mReadline, "emacs_editing_mode",
01850 readline_s_emacs_editing_mode, 0);
01851 rb_define_singleton_method(mReadline, "emacs_editing_mode?",
01852 readline_s_emacs_editing_mode_p, 0);
01853 rb_define_singleton_method(mReadline, "completion_append_character=",
01854 readline_s_set_completion_append_character, 1);
01855 rb_define_singleton_method(mReadline, "completion_append_character",
01856 readline_s_get_completion_append_character, 0);
01857 rb_define_singleton_method(mReadline, "basic_word_break_characters=",
01858 readline_s_set_basic_word_break_characters, 1);
01859 rb_define_singleton_method(mReadline, "basic_word_break_characters",
01860 readline_s_get_basic_word_break_characters, 0);
01861 rb_define_singleton_method(mReadline, "completer_word_break_characters=",
01862 readline_s_set_completer_word_break_characters, 1);
01863 rb_define_singleton_method(mReadline, "completer_word_break_characters",
01864 readline_s_get_completer_word_break_characters, 0);
01865 rb_define_singleton_method(mReadline, "basic_quote_characters=",
01866 readline_s_set_basic_quote_characters, 1);
01867 rb_define_singleton_method(mReadline, "basic_quote_characters",
01868 readline_s_get_basic_quote_characters, 0);
01869 rb_define_singleton_method(mReadline, "completer_quote_characters=",
01870 readline_s_set_completer_quote_characters, 1);
01871 rb_define_singleton_method(mReadline, "completer_quote_characters",
01872 readline_s_get_completer_quote_characters, 0);
01873 rb_define_singleton_method(mReadline, "filename_quote_characters=",
01874 readline_s_set_filename_quote_characters, 1);
01875 rb_define_singleton_method(mReadline, "filename_quote_characters",
01876 readline_s_get_filename_quote_characters, 0);
01877 rb_define_singleton_method(mReadline, "refresh_line",
01878 readline_s_refresh_line, 0);
01879 rb_define_singleton_method(mReadline, "pre_input_hook=",
01880 readline_s_set_pre_input_hook, 1);
01881 rb_define_singleton_method(mReadline, "pre_input_hook",
01882 readline_s_get_pre_input_hook, 0);
01883 rb_define_singleton_method(mReadline, "insert_text",
01884 readline_s_insert_text, 1);
01885 rb_define_singleton_method(mReadline, "delete_text",
01886 readline_s_delete_text, -1);
01887 rb_define_singleton_method(mReadline, "redisplay",
01888 readline_s_redisplay, 0);
01889 rb_define_singleton_method(mReadline, "special_prefixes=",
01890 readline_s_set_special_prefixes, 1);
01891 rb_define_singleton_method(mReadline, "special_prefixes",
01892 readline_s_get_special_prefixes, 0);
01893
01894 #if USE_INSERT_IGNORE_ESCAPE
01895 CONST_ID(id_orig_prompt, "orig_prompt");
01896 CONST_ID(id_last_prompt, "last_prompt");
01897 #endif
01898
01899 history = rb_obj_alloc(rb_cObject);
01900 rb_extend_object(history, rb_mEnumerable);
01901 rb_define_singleton_method(history,"to_s", hist_to_s, 0);
01902 rb_define_singleton_method(history,"[]", hist_get, 1);
01903 rb_define_singleton_method(history,"[]=", hist_set, 2);
01904 rb_define_singleton_method(history,"<<", hist_push, 1);
01905 rb_define_singleton_method(history,"push", hist_push_method, -1);
01906 rb_define_singleton_method(history,"pop", hist_pop, 0);
01907 rb_define_singleton_method(history,"shift", hist_shift, 0);
01908 rb_define_singleton_method(history,"each", hist_each, 0);
01909 rb_define_singleton_method(history,"length", hist_length, 0);
01910 rb_define_singleton_method(history,"size", hist_length, 0);
01911 rb_define_singleton_method(history,"empty?", hist_empty_p, 0);
01912 rb_define_singleton_method(history,"delete_at", hist_delete_at, 1);
01913 rb_define_singleton_method(history,"clear", hist_clear, 0);
01914
01915
01916
01917
01918
01919
01920
01921 rb_define_const(mReadline, "HISTORY", history);
01922
01923 fcomp = rb_obj_alloc(rb_cObject);
01924 rb_define_singleton_method(fcomp, "call",
01925 filename_completion_proc_call, 1);
01926
01927
01928
01929
01930 rb_define_const(mReadline, "FILENAME_COMPLETION_PROC", fcomp);
01931
01932 ucomp = rb_obj_alloc(rb_cObject);
01933 rb_define_singleton_method(ucomp, "call",
01934 username_completion_proc_call, 1);
01935
01936
01937
01938
01939 rb_define_const(mReadline, "USERNAME_COMPLETION_PROC", ucomp);
01940 history_get_offset_func = history_get_offset_history_base;
01941 history_replace_offset_func = history_get_offset_0;
01942 #if defined HAVE_RL_LIBRARY_VERSION
01943 version = rb_str_new_cstr(rl_library_version);
01944 #if defined HAVE_CLEAR_HISTORY || defined HAVE_REMOVE_HISTORY
01945 if (strncmp(rl_library_version, EDIT_LINE_LIBRARY_VERSION,
01946 strlen(EDIT_LINE_LIBRARY_VERSION)) == 0) {
01947 add_history("1");
01948 if (history_get(history_get_offset_func(0)) == NULL) {
01949 history_get_offset_func = history_get_offset_0;
01950 }
01951 #ifdef HAVE_REPLACE_HISTORY_ENTRY
01952 if (replace_history_entry(0, "a", NULL) == NULL) {
01953 history_replace_offset_func = history_get_offset_history_base;
01954 }
01955 #endif
01956 #ifdef HAVE_CLEAR_HISTORY
01957 clear_history();
01958 #else
01959 {
01960 HIST_ENTRY *entry = remove_history(0);
01961 if (entry) {
01962 free((char *)entry->line);
01963 free(entry);
01964 }
01965 }
01966 #endif
01967 }
01968 #endif
01969 #else
01970 version = rb_str_new_cstr("2.0 or prior version");
01971 #endif
01972
01973 rb_define_const(mReadline, "VERSION", version);
01974
01975 rl_attempted_completion_function = readline_attempted_completion_function;
01976 #if defined(HAVE_RL_PRE_INPUT_HOOK)
01977 rl_pre_input_hook = (rl_hook_func_t *)readline_pre_input_hook;
01978 #endif
01979 #ifdef HAVE_RL_CATCH_SIGNALS
01980 rl_catch_signals = 0;
01981 #endif
01982 #ifdef HAVE_RL_CLEAR_SIGNALS
01983 rl_clear_signals();
01984 #endif
01985
01986 rb_gc_register_address(&readline_instream);
01987 rb_gc_register_address(&readline_outstream);
01988 }
01989