1 /* $NetBSD: readline.c,v 1.75 2008/04/29 06:53:01 martin Exp $ */ 2 3 /*- 4 * Copyright (c) 1997 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jaromir Dolecek. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include "config.h" 33 #if !defined(lint) && !defined(SCCSID) 34 __RCSID("$NetBSD: readline.c,v 1.75 2008/04/29 06:53:01 martin Exp $"); 35 #endif /* not lint && not SCCSID */ 36 37 #include <sys/types.h> 38 #include <sys/stat.h> 39 #include <stdio.h> 40 #include <dirent.h> 41 #include <string.h> 42 #include <pwd.h> 43 #include <ctype.h> 44 #include <stdlib.h> 45 #include <unistd.h> 46 #include <limits.h> 47 #include <errno.h> 48 #include <fcntl.h> 49 #include <setjmp.h> 50 #ifdef HAVE_VIS_H 51 #include <vis.h> 52 #else 53 #include "np/vis.h" 54 #endif 55 #ifdef HAVE_ALLOCA_H 56 #include <alloca.h> 57 #endif 58 #include "el.h" 59 #include "fcns.h" /* for EL_NUM_FCNS */ 60 #include "histedit.h" 61 #include "readline/readline.h" 62 #include "filecomplete.h" 63 64 void rl_prep_terminal(int); 65 void rl_deprep_terminal(void); 66 67 /* for rl_complete() */ 68 #define TAB '\r' 69 70 /* see comment at the #ifdef for sense of this */ 71 /* #define GDB_411_HACK */ 72 73 /* readline compatibility stuff - look at readline sources/documentation */ 74 /* to see what these variables mean */ 75 const char *rl_library_version = "EditLine wrapper"; 76 static char empty[] = { '\0' }; 77 static char expand_chars[] = { ' ', '\t', '\n', '=', '(', '\0' }; 78 static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$', 79 '>', '<', '=', ';', '|', '&', '{', '(', '\0' }; 80 char *rl_readline_name = empty; 81 FILE *rl_instream = NULL; 82 FILE *rl_outstream = NULL; 83 int rl_point = 0; 84 int rl_end = 0; 85 char *rl_line_buffer = NULL; 86 VCPFunction *rl_linefunc = NULL; 87 int rl_done = 0; 88 VFunction *rl_event_hook = NULL; 89 KEYMAP_ENTRY_ARRAY emacs_standard_keymap, 90 emacs_meta_keymap, 91 emacs_ctlx_keymap; 92 93 int history_base = 1; /* probably never subject to change */ 94 int history_length = 0; 95 int max_input_history = 0; 96 char history_expansion_char = '!'; 97 char history_subst_char = '^'; 98 char *history_no_expand_chars = expand_chars; 99 Function *history_inhibit_expansion_function = NULL; 100 char *history_arg_extract(int start, int end, const char *str); 101 102 int rl_inhibit_completion = 0; 103 int rl_attempted_completion_over = 0; 104 char *rl_basic_word_break_characters = break_chars; 105 char *rl_completer_word_break_characters = NULL; 106 char *rl_completer_quote_characters = NULL; 107 Function *rl_completion_entry_function = NULL; 108 CPPFunction *rl_attempted_completion_function = NULL; 109 Function *rl_pre_input_hook = NULL; 110 Function *rl_startup1_hook = NULL; 111 int (*rl_getc_function)(FILE *) = NULL; 112 char *rl_terminal_name = NULL; 113 int rl_already_prompted = 0; 114 int rl_filename_completion_desired = 0; 115 int rl_ignore_completion_duplicates = 0; 116 int rl_catch_signals = 1; 117 int readline_echoing_p = 1; 118 int _rl_print_completions_horizontally = 0; 119 VFunction *rl_redisplay_function = NULL; 120 Function *rl_startup_hook = NULL; 121 VFunction *rl_completion_display_matches_hook = NULL; 122 VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal; 123 VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal; 124 125 /* 126 * The current prompt string. 127 */ 128 char *rl_prompt = NULL; 129 /* 130 * This is set to character indicating type of completion being done by 131 * rl_complete_internal(); this is available for application completion 132 * functions. 133 */ 134 int rl_completion_type = 0; 135 136 /* 137 * If more than this number of items results from query for possible 138 * completions, we ask user if they are sure to really display the list. 139 */ 140 int rl_completion_query_items = 100; 141 142 /* 143 * List of characters which are word break characters, but should be left 144 * in the parsed text when it is passed to the completion function. 145 * Shell uses this to help determine what kind of completing to do. 146 */ 147 char *rl_special_prefixes = NULL; 148 149 /* 150 * This is the character appended to the completed words if at the end of 151 * the line. Default is ' ' (a space). 152 */ 153 int rl_completion_append_character = ' '; 154 155 /* stuff below is used internally by libedit for readline emulation */ 156 157 static History *h = NULL; 158 static EditLine *e = NULL; 159 static Function *map[256]; 160 static jmp_buf topbuf; 161 162 /* internal functions */ 163 static unsigned char _el_rl_complete(EditLine *, int); 164 static unsigned char _el_rl_tstp(EditLine *, int); 165 static char *_get_prompt(EditLine *); 166 static int _getc_function(EditLine *, char *); 167 static HIST_ENTRY *_move_history(int); 168 static int _history_expand_command(const char *, size_t, size_t, 169 char **); 170 static char *_rl_compat_sub(const char *, const char *, 171 const char *, int); 172 static int _rl_event_read_char(EditLine *, char *); 173 static void _rl_update_pos(void); 174 175 176 /* ARGSUSED */ 177 static char * 178 _get_prompt(EditLine *el __attribute__((__unused__))) 179 { 180 rl_already_prompted = 1; 181 return (rl_prompt); 182 } 183 184 185 /* 186 * generic function for moving around history 187 */ 188 static HIST_ENTRY * 189 _move_history(int op) 190 { 191 HistEvent ev; 192 static HIST_ENTRY rl_he; 193 194 if (history(h, &ev, op) != 0) 195 return (HIST_ENTRY *) NULL; 196 197 rl_he.line = ev.str; 198 rl_he.data = NULL; 199 200 return (&rl_he); 201 } 202 203 204 /* 205 * read one key from user defined input function 206 */ 207 static int 208 /*ARGSUSED*/ 209 _getc_function(EditLine *el, char *c) 210 { 211 int i; 212 213 i = (*rl_getc_function)(NULL); 214 if (i == -1) 215 return 0; 216 *c = i; 217 return 1; 218 } 219 220 221 /* 222 * READLINE compatibility stuff 223 */ 224 225 /* 226 * initialize rl compat stuff 227 */ 228 int 229 rl_initialize(void) 230 { 231 HistEvent ev; 232 const LineInfo *li; 233 int editmode = 1; 234 struct termios t; 235 236 if (e != NULL) 237 el_end(e); 238 if (h != NULL) 239 history_end(h); 240 241 if (!rl_instream) 242 rl_instream = stdin; 243 if (!rl_outstream) 244 rl_outstream = stdout; 245 246 /* 247 * See if we don't really want to run the editor 248 */ 249 if (tcgetattr(fileno(rl_instream), &t) != -1 && (t.c_lflag & ECHO) == 0) 250 editmode = 0; 251 252 e = el_init(rl_readline_name, rl_instream, rl_outstream, stderr); 253 254 if (!editmode) 255 el_set(e, EL_EDITMODE, 0); 256 257 h = history_init(); 258 if (!e || !h) 259 return (-1); 260 261 history(h, &ev, H_SETSIZE, INT_MAX); /* unlimited */ 262 history_length = 0; 263 max_input_history = INT_MAX; 264 el_set(e, EL_HIST, history, h); 265 266 /* setup getc function if valid */ 267 if (rl_getc_function) 268 el_set(e, EL_GETCFN, _getc_function); 269 270 /* for proper prompt printing in readline() */ 271 rl_prompt = strdup(""); 272 if (rl_prompt == NULL) { 273 history_end(h); 274 el_end(e); 275 return -1; 276 } 277 el_set(e, EL_PROMPT, _get_prompt); 278 el_set(e, EL_SIGNAL, rl_catch_signals); 279 280 /* set default mode to "emacs"-style and read setting afterwards */ 281 /* so this can be overriden */ 282 el_set(e, EL_EDITOR, "emacs"); 283 if (rl_terminal_name != NULL) 284 el_set(e, EL_TERMINAL, rl_terminal_name); 285 else 286 el_get(e, EL_TERMINAL, &rl_terminal_name); 287 288 /* 289 * Word completion - this has to go AFTER rebinding keys 290 * to emacs-style. 291 */ 292 el_set(e, EL_ADDFN, "rl_complete", 293 "ReadLine compatible completion function", 294 _el_rl_complete); 295 el_set(e, EL_BIND, "^I", "rl_complete", NULL); 296 297 /* 298 * Send TSTP when ^Z is pressed. 299 */ 300 el_set(e, EL_ADDFN, "rl_tstp", 301 "ReadLine compatible suspend function", 302 _el_rl_tstp); 303 el_set(e, EL_BIND, "^Z", "rl_tstp", NULL); 304 305 /* read settings from configuration file */ 306 el_source(e, NULL); 307 308 /* 309 * Unfortunately, some applications really do use rl_point 310 * and rl_line_buffer directly. 311 */ 312 li = el_line(e); 313 /* a cheesy way to get rid of const cast. */ 314 rl_line_buffer = memchr(li->buffer, *li->buffer, 1); 315 _rl_update_pos(); 316 317 if (rl_startup_hook) 318 (*rl_startup_hook)(NULL, 0); 319 320 return (0); 321 } 322 323 324 /* 325 * read one line from input stream and return it, chomping 326 * trailing newline (if there is any) 327 */ 328 char * 329 readline(const char *p) 330 { 331 HistEvent ev; 332 const char * volatile prompt = p; 333 int count; 334 const char *ret; 335 char *buf; 336 static int used_event_hook; 337 338 if (e == NULL || h == NULL) 339 rl_initialize(); 340 341 rl_done = 0; 342 343 (void)setjmp(topbuf); 344 345 /* update prompt accordingly to what has been passed */ 346 if (!prompt) 347 prompt = ""; 348 if (strcmp(rl_prompt, prompt) != 0) { 349 free(rl_prompt); 350 rl_prompt = strdup(prompt); 351 if (rl_prompt == NULL) 352 return NULL; 353 } 354 355 if (rl_pre_input_hook) 356 (*rl_pre_input_hook)(NULL, 0); 357 358 if (rl_event_hook && !(e->el_flags&NO_TTY)) { 359 el_set(e, EL_GETCFN, _rl_event_read_char); 360 used_event_hook = 1; 361 } 362 363 if (!rl_event_hook && used_event_hook) { 364 el_set(e, EL_GETCFN, EL_BUILTIN_GETCFN); 365 used_event_hook = 0; 366 } 367 368 rl_already_prompted = 0; 369 370 /* get one line from input stream */ 371 ret = el_gets(e, &count); 372 373 if (ret && count > 0) { 374 int lastidx; 375 376 buf = strdup(ret); 377 if (buf == NULL) 378 return NULL; 379 lastidx = count - 1; 380 if (buf[lastidx] == '\n') 381 buf[lastidx] = '\0'; 382 } else 383 buf = NULL; 384 385 history(h, &ev, H_GETSIZE); 386 history_length = ev.num; 387 388 return buf; 389 } 390 391 /* 392 * history functions 393 */ 394 395 /* 396 * is normally called before application starts to use 397 * history expansion functions 398 */ 399 void 400 using_history(void) 401 { 402 if (h == NULL || e == NULL) 403 rl_initialize(); 404 } 405 406 407 /* 408 * substitute ``what'' with ``with'', returning resulting string; if 409 * globally == 1, substitutes all occurrences of what, otherwise only the 410 * first one 411 */ 412 static char * 413 _rl_compat_sub(const char *str, const char *what, const char *with, 414 int globally) 415 { 416 const char *s; 417 char *r, *result; 418 size_t len, with_len, what_len; 419 420 len = strlen(str); 421 with_len = strlen(with); 422 what_len = strlen(what); 423 424 /* calculate length we need for result */ 425 s = str; 426 while (*s) { 427 if (*s == *what && !strncmp(s, what, what_len)) { 428 len += with_len - what_len; 429 if (!globally) 430 break; 431 s += what_len; 432 } else 433 s++; 434 } 435 r = result = malloc(len + 1); 436 if (result == NULL) 437 return NULL; 438 s = str; 439 while (*s) { 440 if (*s == *what && !strncmp(s, what, what_len)) { 441 (void)strncpy(r, with, with_len); 442 r += with_len; 443 s += what_len; 444 if (!globally) { 445 (void)strcpy(r, s); 446 return(result); 447 } 448 } else 449 *r++ = *s++; 450 } 451 *r = 0; 452 return(result); 453 } 454 455 static char *last_search_pat; /* last !?pat[?] search pattern */ 456 static char *last_search_match; /* last !?pat[?] that matched */ 457 458 const char * 459 get_history_event(const char *cmd, int *cindex, int qchar) 460 { 461 int idx, sign, sub, num, begin, ret; 462 size_t len; 463 char *pat; 464 const char *rptr; 465 HistEvent ev; 466 467 idx = *cindex; 468 if (cmd[idx++] != history_expansion_char) 469 return(NULL); 470 471 /* find out which event to take */ 472 if (cmd[idx] == history_expansion_char || cmd[idx] == 0) { 473 if (history(h, &ev, H_FIRST) != 0) 474 return(NULL); 475 *cindex = cmd[idx]? (idx + 1):idx; 476 return(ev.str); 477 } 478 sign = 0; 479 if (cmd[idx] == '-') { 480 sign = 1; 481 idx++; 482 } 483 484 if ('0' <= cmd[idx] && cmd[idx] <= '9') { 485 HIST_ENTRY *rl_he; 486 487 num = 0; 488 while (cmd[idx] && '0' <= cmd[idx] && cmd[idx] <= '9') { 489 num = num * 10 + cmd[idx] - '0'; 490 idx++; 491 } 492 if (sign) 493 num = history_length - num + 1; 494 495 if (!(rl_he = history_get(num))) 496 return(NULL); 497 498 *cindex = idx; 499 return(rl_he->line); 500 } 501 sub = 0; 502 if (cmd[idx] == '?') { 503 sub = 1; 504 idx++; 505 } 506 begin = idx; 507 while (cmd[idx]) { 508 if (cmd[idx] == '\n') 509 break; 510 if (sub && cmd[idx] == '?') 511 break; 512 if (!sub && (cmd[idx] == ':' || cmd[idx] == ' ' 513 || cmd[idx] == '\t' || cmd[idx] == qchar)) 514 break; 515 idx++; 516 } 517 len = idx - begin; 518 if (sub && cmd[idx] == '?') 519 idx++; 520 if (sub && len == 0 && last_search_pat && *last_search_pat) 521 pat = last_search_pat; 522 else if (len == 0) 523 return(NULL); 524 else { 525 if ((pat = malloc(len + 1)) == NULL) 526 return NULL; 527 (void)strncpy(pat, cmd + begin, len); 528 pat[len] = '\0'; 529 } 530 531 if (history(h, &ev, H_CURR) != 0) { 532 if (pat != last_search_pat) 533 free(pat); 534 return (NULL); 535 } 536 num = ev.num; 537 538 if (sub) { 539 if (pat != last_search_pat) { 540 if (last_search_pat) 541 free(last_search_pat); 542 last_search_pat = pat; 543 } 544 ret = history_search(pat, -1); 545 } else 546 ret = history_search_prefix(pat, -1); 547 548 if (ret == -1) { 549 /* restore to end of list on failed search */ 550 history(h, &ev, H_FIRST); 551 (void)fprintf(rl_outstream, "%s: Event not found\n", pat); 552 if (pat != last_search_pat) 553 free(pat); 554 return(NULL); 555 } 556 557 if (sub && len) { 558 if (last_search_match && last_search_match != pat) 559 free(last_search_match); 560 last_search_match = pat; 561 } 562 563 if (pat != last_search_pat) 564 free(pat); 565 566 if (history(h, &ev, H_CURR) != 0) 567 return(NULL); 568 *cindex = idx; 569 rptr = ev.str; 570 571 /* roll back to original position */ 572 (void)history(h, &ev, H_SET, num); 573 574 return rptr; 575 } 576 577 /* 578 * the real function doing history expansion - takes as argument command 579 * to do and data upon which the command should be executed 580 * does expansion the way I've understood readline documentation 581 * 582 * returns 0 if data was not modified, 1 if it was and 2 if the string 583 * should be only printed and not executed; in case of error, 584 * returns -1 and *result points to NULL 585 * it's callers responsibility to free() string returned in *result 586 */ 587 static int 588 _history_expand_command(const char *command, size_t offs, size_t cmdlen, 589 char **result) 590 { 591 char *tmp, *search = NULL, *aptr; 592 const char *ptr, *cmd; 593 static char *from = NULL, *to = NULL; 594 int start, end, idx, has_mods = 0; 595 int p_on = 0, g_on = 0; 596 597 *result = NULL; 598 aptr = NULL; 599 ptr = NULL; 600 601 /* First get event specifier */ 602 idx = 0; 603 604 if (strchr(":^*$", command[offs + 1])) { 605 char str[4]; 606 /* 607 * "!:" is shorthand for "!!:". 608 * "!^", "!*" and "!$" are shorthand for 609 * "!!:^", "!!:*" and "!!:$" respectively. 610 */ 611 str[0] = str[1] = '!'; 612 str[2] = '0'; 613 ptr = get_history_event(str, &idx, 0); 614 idx = (command[offs + 1] == ':')? 1:0; 615 has_mods = 1; 616 } else { 617 if (command[offs + 1] == '#') { 618 /* use command so far */ 619 if ((aptr = malloc(offs + 1)) == NULL) 620 return -1; 621 (void)strncpy(aptr, command, offs); 622 aptr[offs] = '\0'; 623 idx = 1; 624 } else { 625 int qchar; 626 627 qchar = (offs > 0 && command[offs - 1] == '"')? '"':0; 628 ptr = get_history_event(command + offs, &idx, qchar); 629 } 630 has_mods = command[offs + idx] == ':'; 631 } 632 633 if (ptr == NULL && aptr == NULL) 634 return(-1); 635 636 if (!has_mods) { 637 *result = strdup(aptr? aptr : ptr); 638 if (aptr) 639 free(aptr); 640 return(1); 641 } 642 643 cmd = command + offs + idx + 1; 644 645 /* Now parse any word designators */ 646 647 if (*cmd == '%') /* last word matched by ?pat? */ 648 tmp = strdup(last_search_match? last_search_match:""); 649 else if (strchr("^*$-0123456789", *cmd)) { 650 start = end = -1; 651 if (*cmd == '^') 652 start = end = 1, cmd++; 653 else if (*cmd == '$') 654 start = -1, cmd++; 655 else if (*cmd == '*') 656 start = 1, cmd++; 657 else if (*cmd == '-' || isdigit((unsigned char) *cmd)) { 658 start = 0; 659 while (*cmd && '0' <= *cmd && *cmd <= '9') 660 start = start * 10 + *cmd++ - '0'; 661 662 if (*cmd == '-') { 663 if (isdigit((unsigned char) cmd[1])) { 664 cmd++; 665 end = 0; 666 while (*cmd && '0' <= *cmd && *cmd <= '9') 667 end = end * 10 + *cmd++ - '0'; 668 } else if (cmd[1] == '$') { 669 cmd += 2; 670 end = -1; 671 } else { 672 cmd++; 673 end = -2; 674 } 675 } else if (*cmd == '*') 676 end = -1, cmd++; 677 else 678 end = start; 679 } 680 tmp = history_arg_extract(start, end, aptr? aptr:ptr); 681 if (tmp == NULL) { 682 (void)fprintf(rl_outstream, "%s: Bad word specifier", 683 command + offs + idx); 684 if (aptr) 685 free(aptr); 686 return(-1); 687 } 688 } else 689 tmp = strdup(aptr? aptr:ptr); 690 691 if (aptr) 692 free(aptr); 693 694 if (*cmd == 0 || (cmd - (command + offs) >= cmdlen)) { 695 *result = tmp; 696 return(1); 697 } 698 699 for (; *cmd; cmd++) { 700 if (*cmd == ':') 701 continue; 702 else if (*cmd == 'h') { /* remove trailing path */ 703 if ((aptr = strrchr(tmp, '/')) != NULL) 704 *aptr = 0; 705 } else if (*cmd == 't') { /* remove leading path */ 706 if ((aptr = strrchr(tmp, '/')) != NULL) { 707 aptr = strdup(aptr + 1); 708 free(tmp); 709 tmp = aptr; 710 } 711 } else if (*cmd == 'r') { /* remove trailing suffix */ 712 if ((aptr = strrchr(tmp, '.')) != NULL) 713 *aptr = 0; 714 } else if (*cmd == 'e') { /* remove all but suffix */ 715 if ((aptr = strrchr(tmp, '.')) != NULL) { 716 aptr = strdup(aptr); 717 free(tmp); 718 tmp = aptr; 719 } 720 } else if (*cmd == 'p') /* print only */ 721 p_on = 1; 722 else if (*cmd == 'g') 723 g_on = 2; 724 else if (*cmd == 's' || *cmd == '&') { 725 char *what, *with, delim; 726 size_t len, from_len; 727 size_t size; 728 729 if (*cmd == '&' && (from == NULL || to == NULL)) 730 continue; 731 else if (*cmd == 's') { 732 delim = *(++cmd), cmd++; 733 size = 16; 734 what = realloc(from, size); 735 if (what == NULL) { 736 free(from); 737 free(tmp); 738 return 0; 739 } 740 len = 0; 741 for (; *cmd && *cmd != delim; cmd++) { 742 if (*cmd == '\\' && cmd[1] == delim) 743 cmd++; 744 if (len >= size) { 745 char *nwhat; 746 nwhat = realloc(what, 747 (size <<= 1)); 748 if (nwhat == NULL) { 749 free(what); 750 free(tmp); 751 return 0; 752 } 753 what = nwhat; 754 } 755 what[len++] = *cmd; 756 } 757 what[len] = '\0'; 758 from = what; 759 if (*what == '\0') { 760 free(what); 761 if (search) { 762 from = strdup(search); 763 if (from == NULL) { 764 free(tmp); 765 return 0; 766 } 767 } else { 768 from = NULL; 769 free(tmp); 770 return (-1); 771 } 772 } 773 cmd++; /* shift after delim */ 774 if (!*cmd) 775 continue; 776 777 size = 16; 778 with = realloc(to, size); 779 if (with == NULL) { 780 free(to); 781 free(tmp); 782 return -1; 783 } 784 len = 0; 785 from_len = strlen(from); 786 for (; *cmd && *cmd != delim; cmd++) { 787 if (len + from_len + 1 >= size) { 788 char *nwith; 789 size += from_len + 1; 790 nwith = realloc(with, size); 791 if (nwith == NULL) { 792 free(with); 793 free(tmp); 794 return -1; 795 } 796 with = nwith; 797 } 798 if (*cmd == '&') { 799 /* safe */ 800 (void)strcpy(&with[len], from); 801 len += from_len; 802 continue; 803 } 804 if (*cmd == '\\' 805 && (*(cmd + 1) == delim 806 || *(cmd + 1) == '&')) 807 cmd++; 808 with[len++] = *cmd; 809 } 810 with[len] = '\0'; 811 to = with; 812 } 813 814 aptr = _rl_compat_sub(tmp, from, to, g_on); 815 if (aptr) { 816 free(tmp); 817 tmp = aptr; 818 } 819 g_on = 0; 820 } 821 } 822 *result = tmp; 823 return (p_on? 2:1); 824 } 825 826 827 /* 828 * csh-style history expansion 829 */ 830 int 831 history_expand(char *str, char **output) 832 { 833 int ret = 0; 834 size_t idx, i, size; 835 char *tmp, *result; 836 837 if (h == NULL || e == NULL) 838 rl_initialize(); 839 840 if (history_expansion_char == 0) { 841 *output = strdup(str); 842 return(0); 843 } 844 845 *output = NULL; 846 if (str[0] == history_subst_char) { 847 /* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */ 848 *output = malloc(strlen(str) + 4 + 1); 849 if (*output == NULL) 850 return 0; 851 (*output)[0] = (*output)[1] = history_expansion_char; 852 (*output)[2] = ':'; 853 (*output)[3] = 's'; 854 (void)strcpy((*output) + 4, str); 855 str = *output; 856 } else { 857 *output = strdup(str); 858 if (*output == NULL) 859 return 0; 860 } 861 862 #define ADD_STRING(what, len, fr) \ 863 { \ 864 if (idx + len + 1 > size) { \ 865 char *nresult = realloc(result, (size += len + 1));\ 866 if (nresult == NULL) { \ 867 free(*output); \ 868 if (/*CONSTCOND*/fr) \ 869 free(tmp); \ 870 return 0; \ 871 } \ 872 result = nresult; \ 873 } \ 874 (void)strncpy(&result[idx], what, len); \ 875 idx += len; \ 876 result[idx] = '\0'; \ 877 } 878 879 result = NULL; 880 size = idx = 0; 881 tmp = NULL; 882 for (i = 0; str[i];) { 883 int qchar, loop_again; 884 size_t len, start, j; 885 886 qchar = 0; 887 loop_again = 1; 888 start = j = i; 889 loop: 890 for (; str[j]; j++) { 891 if (str[j] == '\\' && 892 str[j + 1] == history_expansion_char) { 893 (void)strcpy(&str[j], &str[j + 1]); 894 continue; 895 } 896 if (!loop_again) { 897 if (isspace((unsigned char) str[j]) 898 || str[j] == qchar) 899 break; 900 } 901 if (str[j] == history_expansion_char 902 && !strchr(history_no_expand_chars, str[j + 1]) 903 && (!history_inhibit_expansion_function || 904 (*history_inhibit_expansion_function)(str, 905 (int)j) == 0)) 906 break; 907 } 908 909 if (str[j] && loop_again) { 910 i = j; 911 qchar = (j > 0 && str[j - 1] == '"' )? '"':0; 912 j++; 913 if (str[j] == history_expansion_char) 914 j++; 915 loop_again = 0; 916 goto loop; 917 } 918 len = i - start; 919 ADD_STRING(&str[start], len, 0); 920 921 if (str[i] == '\0' || str[i] != history_expansion_char) { 922 len = j - i; 923 ADD_STRING(&str[i], len, 0); 924 if (start == 0) 925 ret = 0; 926 else 927 ret = 1; 928 break; 929 } 930 ret = _history_expand_command (str, i, (j - i), &tmp); 931 if (ret > 0 && tmp) { 932 len = strlen(tmp); 933 ADD_STRING(tmp, len, 1); 934 } 935 if (tmp) { 936 free(tmp); 937 tmp = NULL; 938 } 939 i = j; 940 } 941 942 /* ret is 2 for "print only" option */ 943 if (ret == 2) { 944 add_history(result); 945 #ifdef GDB_411_HACK 946 /* gdb 4.11 has been shipped with readline, where */ 947 /* history_expand() returned -1 when the line */ 948 /* should not be executed; in readline 2.1+ */ 949 /* it should return 2 in such a case */ 950 ret = -1; 951 #endif 952 } 953 free(*output); 954 *output = result; 955 956 return (ret); 957 } 958 959 /* 960 * Return a string consisting of arguments of "str" from "start" to "end". 961 */ 962 char * 963 history_arg_extract(int start, int end, const char *str) 964 { 965 size_t i, len, max; 966 char **arr, *result; 967 968 arr = history_tokenize(str); 969 if (!arr) 970 return(NULL); 971 if (arr && *arr == NULL) { 972 free(arr); 973 return(NULL); 974 } 975 976 for (max = 0; arr[max]; max++) 977 continue; 978 max--; 979 980 if (start == '$') 981 start = max; 982 if (end == '$') 983 end = max; 984 if (end < 0) 985 end = max + end + 1; 986 if (start < 0) 987 start = end; 988 989 if (start < 0 || end < 0 || start > max || end > max || start > end) 990 return(NULL); 991 992 for (i = start, len = 0; i <= end; i++) 993 len += strlen(arr[i]) + 1; 994 len++; 995 result = malloc(len); 996 if (result == NULL) 997 return NULL; 998 999 for (i = start, len = 0; i <= end; i++) { 1000 (void)strcpy(result + len, arr[i]); 1001 len += strlen(arr[i]); 1002 if (i < end) 1003 result[len++] = ' '; 1004 } 1005 result[len] = 0; 1006 1007 for (i = 0; arr[i]; i++) 1008 free(arr[i]); 1009 free(arr); 1010 1011 return(result); 1012 } 1013 1014 /* 1015 * Parse the string into individual tokens, 1016 * similar to how shell would do it. 1017 */ 1018 char ** 1019 history_tokenize(const char *str) 1020 { 1021 int size = 1, idx = 0, i, start; 1022 size_t len; 1023 char **result = NULL, *temp, delim = '\0'; 1024 1025 for (i = 0; str[i];) { 1026 while (isspace((unsigned char) str[i])) 1027 i++; 1028 start = i; 1029 for (; str[i];) { 1030 if (str[i] == '\\') { 1031 if (str[i+1] != '\0') 1032 i++; 1033 } else if (str[i] == delim) 1034 delim = '\0'; 1035 else if (!delim && 1036 (isspace((unsigned char) str[i]) || 1037 strchr("()<>;&|$", str[i]))) 1038 break; 1039 else if (!delim && strchr("'`\"", str[i])) 1040 delim = str[i]; 1041 if (str[i]) 1042 i++; 1043 } 1044 1045 if (idx + 2 >= size) { 1046 char **nresult; 1047 size <<= 1; 1048 nresult = realloc(result, size * sizeof(char *)); 1049 if (nresult == NULL) { 1050 free(result); 1051 return NULL; 1052 } 1053 result = nresult; 1054 } 1055 len = i - start; 1056 temp = malloc(len + 1); 1057 if (temp == NULL) { 1058 for (i = 0; i < idx; i++) 1059 free(result[i]); 1060 free(result); 1061 return NULL; 1062 } 1063 (void)strncpy(temp, &str[start], len); 1064 temp[len] = '\0'; 1065 result[idx++] = temp; 1066 result[idx] = NULL; 1067 if (str[i]) 1068 i++; 1069 } 1070 return (result); 1071 } 1072 1073 1074 /* 1075 * limit size of history record to ``max'' events 1076 */ 1077 void 1078 stifle_history(int max) 1079 { 1080 HistEvent ev; 1081 1082 if (h == NULL || e == NULL) 1083 rl_initialize(); 1084 1085 if (history(h, &ev, H_SETSIZE, max) == 0) 1086 max_input_history = max; 1087 } 1088 1089 1090 /* 1091 * "unlimit" size of history - set the limit to maximum allowed int value 1092 */ 1093 int 1094 unstifle_history(void) 1095 { 1096 HistEvent ev; 1097 int omax; 1098 1099 history(h, &ev, H_SETSIZE, INT_MAX); 1100 omax = max_input_history; 1101 max_input_history = INT_MAX; 1102 return (omax); /* some value _must_ be returned */ 1103 } 1104 1105 1106 int 1107 history_is_stifled(void) 1108 { 1109 1110 /* cannot return true answer */ 1111 return (max_input_history != INT_MAX); 1112 } 1113 1114 1115 /* 1116 * read history from a file given 1117 */ 1118 int 1119 read_history(const char *filename) 1120 { 1121 HistEvent ev; 1122 1123 if (h == NULL || e == NULL) 1124 rl_initialize(); 1125 return (history(h, &ev, H_LOAD, filename) == -1); 1126 } 1127 1128 1129 /* 1130 * write history to a file given 1131 */ 1132 int 1133 write_history(const char *filename) 1134 { 1135 HistEvent ev; 1136 1137 if (h == NULL || e == NULL) 1138 rl_initialize(); 1139 return (history(h, &ev, H_SAVE, filename) == -1); 1140 } 1141 1142 1143 /* 1144 * returns history ``num''th event 1145 * 1146 * returned pointer points to static variable 1147 */ 1148 HIST_ENTRY * 1149 history_get(int num) 1150 { 1151 static HIST_ENTRY she; 1152 HistEvent ev; 1153 int curr_num; 1154 1155 if (h == NULL || e == NULL) 1156 rl_initialize(); 1157 1158 /* save current position */ 1159 if (history(h, &ev, H_CURR) != 0) 1160 return (NULL); 1161 curr_num = ev.num; 1162 1163 /* start from most recent */ 1164 if (history(h, &ev, H_FIRST) != 0) 1165 return (NULL); /* error */ 1166 1167 /* look backwards for event matching specified offset */ 1168 if (history(h, &ev, H_NEXT_EVENT, num + 1)) 1169 return (NULL); 1170 1171 she.line = ev.str; 1172 she.data = NULL; 1173 1174 /* restore pointer to where it was */ 1175 (void)history(h, &ev, H_SET, curr_num); 1176 1177 return (&she); 1178 } 1179 1180 1181 /* 1182 * add the line to history table 1183 */ 1184 int 1185 add_history(const char *line) 1186 { 1187 HistEvent ev; 1188 1189 if (h == NULL || e == NULL) 1190 rl_initialize(); 1191 1192 (void)history(h, &ev, H_ENTER, line); 1193 if (history(h, &ev, H_GETSIZE) == 0) 1194 history_length = ev.num; 1195 1196 return (!(history_length > 0)); /* return 0 if all is okay */ 1197 } 1198 1199 1200 /* 1201 * remove the specified entry from the history list and return it. 1202 */ 1203 HIST_ENTRY * 1204 remove_history(int num) 1205 { 1206 HIST_ENTRY *she; 1207 HistEvent ev; 1208 1209 if (h == NULL || e == NULL) 1210 rl_initialize(); 1211 1212 if (history(h, &ev, H_DEL, num) != 0) 1213 return NULL; 1214 1215 if ((she = malloc(sizeof(*she))) == NULL) 1216 return NULL; 1217 1218 she->line = ev.str; 1219 she->data = NULL; 1220 1221 return she; 1222 } 1223 1224 1225 /* 1226 * clear the history list - delete all entries 1227 */ 1228 void 1229 clear_history(void) 1230 { 1231 HistEvent ev; 1232 1233 history(h, &ev, H_CLEAR); 1234 } 1235 1236 1237 /* 1238 * returns offset of the current history event 1239 */ 1240 int 1241 where_history(void) 1242 { 1243 HistEvent ev; 1244 int curr_num, off; 1245 1246 if (history(h, &ev, H_CURR) != 0) 1247 return (0); 1248 curr_num = ev.num; 1249 1250 history(h, &ev, H_FIRST); 1251 off = 1; 1252 while (ev.num != curr_num && history(h, &ev, H_NEXT) == 0) 1253 off++; 1254 1255 return (off); 1256 } 1257 1258 1259 /* 1260 * returns current history event or NULL if there is no such event 1261 */ 1262 HIST_ENTRY * 1263 current_history(void) 1264 { 1265 1266 return (_move_history(H_CURR)); 1267 } 1268 1269 1270 /* 1271 * returns total number of bytes history events' data are using 1272 */ 1273 int 1274 history_total_bytes(void) 1275 { 1276 HistEvent ev; 1277 int curr_num, size; 1278 1279 if (history(h, &ev, H_CURR) != 0) 1280 return (-1); 1281 curr_num = ev.num; 1282 1283 history(h, &ev, H_FIRST); 1284 size = 0; 1285 do 1286 size += strlen(ev.str); 1287 while (history(h, &ev, H_NEXT) == 0); 1288 1289 /* get to the same position as before */ 1290 history(h, &ev, H_PREV_EVENT, curr_num); 1291 1292 return (size); 1293 } 1294 1295 1296 /* 1297 * sets the position in the history list to ``pos'' 1298 */ 1299 int 1300 history_set_pos(int pos) 1301 { 1302 HistEvent ev; 1303 int curr_num; 1304 1305 if (pos > history_length || pos < 0) 1306 return (-1); 1307 1308 history(h, &ev, H_CURR); 1309 curr_num = ev.num; 1310 1311 if (history(h, &ev, H_SET, pos)) { 1312 history(h, &ev, H_SET, curr_num); 1313 return(-1); 1314 } 1315 return (0); 1316 } 1317 1318 1319 /* 1320 * returns previous event in history and shifts pointer accordingly 1321 */ 1322 HIST_ENTRY * 1323 previous_history(void) 1324 { 1325 1326 return (_move_history(H_PREV)); 1327 } 1328 1329 1330 /* 1331 * returns next event in history and shifts pointer accordingly 1332 */ 1333 HIST_ENTRY * 1334 next_history(void) 1335 { 1336 1337 return (_move_history(H_NEXT)); 1338 } 1339 1340 1341 /* 1342 * searches for first history event containing the str 1343 */ 1344 int 1345 history_search(const char *str, int direction) 1346 { 1347 HistEvent ev; 1348 const char *strp; 1349 int curr_num; 1350 1351 if (history(h, &ev, H_CURR) != 0) 1352 return (-1); 1353 curr_num = ev.num; 1354 1355 for (;;) { 1356 if ((strp = strstr(ev.str, str)) != NULL) 1357 return (int) (strp - ev.str); 1358 if (history(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0) 1359 break; 1360 } 1361 history(h, &ev, H_SET, curr_num); 1362 return (-1); 1363 } 1364 1365 1366 /* 1367 * searches for first history event beginning with str 1368 */ 1369 int 1370 history_search_prefix(const char *str, int direction) 1371 { 1372 HistEvent ev; 1373 1374 return (history(h, &ev, direction < 0? H_PREV_STR:H_NEXT_STR, str)); 1375 } 1376 1377 1378 /* 1379 * search for event in history containing str, starting at offset 1380 * abs(pos); continue backward, if pos<0, forward otherwise 1381 */ 1382 /* ARGSUSED */ 1383 int 1384 history_search_pos(const char *str, 1385 int direction __attribute__((__unused__)), int pos) 1386 { 1387 HistEvent ev; 1388 int curr_num, off; 1389 1390 off = (pos > 0) ? pos : -pos; 1391 pos = (pos > 0) ? 1 : -1; 1392 1393 if (history(h, &ev, H_CURR) != 0) 1394 return (-1); 1395 curr_num = ev.num; 1396 1397 if (history_set_pos(off) != 0 || history(h, &ev, H_CURR) != 0) 1398 return (-1); 1399 1400 1401 for (;;) { 1402 if (strstr(ev.str, str)) 1403 return (off); 1404 if (history(h, &ev, (pos < 0) ? H_PREV : H_NEXT) != 0) 1405 break; 1406 } 1407 1408 /* set "current" pointer back to previous state */ 1409 history(h, &ev, (pos < 0) ? H_NEXT_EVENT : H_PREV_EVENT, curr_num); 1410 1411 return (-1); 1412 } 1413 1414 1415 /********************************/ 1416 /* completion functions */ 1417 1418 char * 1419 tilde_expand(char *name) 1420 { 1421 return fn_tilde_expand(name); 1422 } 1423 1424 char * 1425 filename_completion_function(const char *name, int state) 1426 { 1427 return fn_filename_completion_function(name, state); 1428 } 1429 1430 /* 1431 * a completion generator for usernames; returns _first_ username 1432 * which starts with supplied text 1433 * text contains a partial username preceded by random character 1434 * (usually '~'); state is ignored 1435 * it's callers responsibility to free returned value 1436 */ 1437 char * 1438 username_completion_function(const char *text, int state) 1439 { 1440 struct passwd *pwd, pwres; 1441 char pwbuf[1024]; 1442 1443 if (text[0] == '\0') 1444 return (NULL); 1445 1446 if (*text == '~') 1447 text++; 1448 1449 if (state == 0) 1450 setpwent(); 1451 1452 while (getpwent_r(&pwres, pwbuf, sizeof(pwbuf), &pwd) == 0 1453 && pwd != NULL && text[0] == pwd->pw_name[0] 1454 && strcmp(text, pwd->pw_name) == 0); 1455 1456 if (pwd == NULL) { 1457 endpwent(); 1458 return (NULL); 1459 } 1460 return (strdup(pwd->pw_name)); 1461 } 1462 1463 1464 /* 1465 * el-compatible wrapper to send TSTP on ^Z 1466 */ 1467 /* ARGSUSED */ 1468 static unsigned char 1469 _el_rl_tstp(EditLine *el __attribute__((__unused__)), int ch __attribute__((__unused__))) 1470 { 1471 (void)kill(0, SIGTSTP); 1472 return CC_NORM; 1473 } 1474 1475 /* 1476 * Display list of strings in columnar format on readline's output stream. 1477 * 'matches' is list of strings, 'len' is number of strings in 'matches', 1478 * 'max' is maximum length of string in 'matches'. 1479 */ 1480 void 1481 rl_display_match_list(char **matches, int len, int max) 1482 { 1483 1484 fn_display_match_list(e, matches, len, max); 1485 } 1486 1487 static const char * 1488 /*ARGSUSED*/ 1489 _rl_completion_append_character_function(const char *dummy 1490 __attribute__((__unused__))) 1491 { 1492 static char buf[2]; 1493 buf[1] = rl_completion_append_character; 1494 return buf; 1495 } 1496 1497 1498 /* 1499 * complete word at current point 1500 */ 1501 /* ARGSUSED */ 1502 int 1503 rl_complete(int ignore __attribute__((__unused__)), int invoking_key) 1504 { 1505 if (h == NULL || e == NULL) 1506 rl_initialize(); 1507 1508 if (rl_inhibit_completion) { 1509 char arr[2]; 1510 arr[0] = (char)invoking_key; 1511 arr[1] = '\0'; 1512 el_insertstr(e, arr); 1513 return (CC_REFRESH); 1514 } 1515 1516 /* Just look at how many global variables modify this operation! */ 1517 return fn_complete(e, 1518 (CPFunction *)rl_completion_entry_function, 1519 rl_attempted_completion_function, 1520 rl_basic_word_break_characters, rl_special_prefixes, 1521 _rl_completion_append_character_function, rl_completion_query_items, 1522 &rl_completion_type, &rl_attempted_completion_over, 1523 &rl_point, &rl_end); 1524 } 1525 1526 1527 /* ARGSUSED */ 1528 static unsigned char 1529 _el_rl_complete(EditLine *el __attribute__((__unused__)), int ch) 1530 { 1531 return (unsigned char)rl_complete(0, ch); 1532 } 1533 1534 /* 1535 * misc other functions 1536 */ 1537 1538 /* 1539 * bind key c to readline-type function func 1540 */ 1541 int 1542 rl_bind_key(int c, int func(int, int)) 1543 { 1544 int retval = -1; 1545 1546 if (h == NULL || e == NULL) 1547 rl_initialize(); 1548 1549 if (func == rl_insert) { 1550 /* XXX notice there is no range checking of ``c'' */ 1551 e->el_map.key[c] = ED_INSERT; 1552 retval = 0; 1553 } 1554 return (retval); 1555 } 1556 1557 1558 /* 1559 * read one key from input - handles chars pushed back 1560 * to input stream also 1561 */ 1562 int 1563 rl_read_key(void) 1564 { 1565 char fooarr[2 * sizeof(int)]; 1566 1567 if (e == NULL || h == NULL) 1568 rl_initialize(); 1569 1570 return (el_getc(e, fooarr)); 1571 } 1572 1573 1574 /* 1575 * reset the terminal 1576 */ 1577 /* ARGSUSED */ 1578 void 1579 rl_reset_terminal(const char *p __attribute__((__unused__))) 1580 { 1581 1582 if (h == NULL || e == NULL) 1583 rl_initialize(); 1584 el_reset(e); 1585 } 1586 1587 1588 /* 1589 * insert character ``c'' back into input stream, ``count'' times 1590 */ 1591 int 1592 rl_insert(int count, int c) 1593 { 1594 char arr[2]; 1595 1596 if (h == NULL || e == NULL) 1597 rl_initialize(); 1598 1599 /* XXX - int -> char conversion can lose on multichars */ 1600 arr[0] = c; 1601 arr[1] = '\0'; 1602 1603 for (; count > 0; count--) 1604 el_push(e, arr); 1605 1606 return (0); 1607 } 1608 1609 /*ARGSUSED*/ 1610 int 1611 rl_newline(int count, int c) 1612 { 1613 /* 1614 * Readline-4.0 appears to ignore the args. 1615 */ 1616 return rl_insert(1, '\n'); 1617 } 1618 1619 /*ARGSUSED*/ 1620 static unsigned char 1621 rl_bind_wrapper(EditLine *el, unsigned char c) 1622 { 1623 if (map[c] == NULL) 1624 return CC_ERROR; 1625 1626 _rl_update_pos(); 1627 1628 (*map[c])(NULL, c); 1629 1630 /* If rl_done was set by the above call, deal with it here */ 1631 if (rl_done) 1632 return CC_EOF; 1633 1634 return CC_NORM; 1635 } 1636 1637 int 1638 rl_add_defun(const char *name, Function *fun, int c) 1639 { 1640 char dest[8]; 1641 if (c >= sizeof(map) / sizeof(map[0]) || c < 0) 1642 return -1; 1643 map[(unsigned char)c] = fun; 1644 el_set(e, EL_ADDFN, name, name, rl_bind_wrapper); 1645 vis(dest, c, VIS_WHITE|VIS_NOSLASH, 0); 1646 el_set(e, EL_BIND, dest, name); 1647 return 0; 1648 } 1649 1650 void 1651 rl_callback_read_char() 1652 { 1653 int count = 0, done = 0; 1654 const char *buf = el_gets(e, &count); 1655 char *wbuf; 1656 1657 if (buf == NULL || count-- <= 0) 1658 return; 1659 if (count == 0 && buf[0] == e->el_tty.t_c[TS_IO][C_EOF]) 1660 done = 1; 1661 if (buf[count] == '\n' || buf[count] == '\r') 1662 done = 2; 1663 1664 if (done && rl_linefunc != NULL) { 1665 el_set(e, EL_UNBUFFERED, 0); 1666 if (done == 2) { 1667 if ((wbuf = strdup(buf)) != NULL) 1668 wbuf[count] = '\0'; 1669 } else 1670 wbuf = NULL; 1671 (*(void (*)(const char *))rl_linefunc)(wbuf); 1672 el_set(e, EL_UNBUFFERED, 1); 1673 } 1674 } 1675 1676 void 1677 rl_callback_handler_install(const char *prompt, VCPFunction *linefunc) 1678 { 1679 if (e == NULL) { 1680 rl_initialize(); 1681 } 1682 if (rl_prompt) 1683 free(rl_prompt); 1684 rl_prompt = prompt ? strdup(strchr(prompt, *prompt)) : NULL; 1685 rl_linefunc = linefunc; 1686 el_set(e, EL_UNBUFFERED, 1); 1687 } 1688 1689 void 1690 rl_callback_handler_remove(void) 1691 { 1692 el_set(e, EL_UNBUFFERED, 0); 1693 rl_linefunc = NULL; 1694 } 1695 1696 void 1697 rl_redisplay(void) 1698 { 1699 char a[2]; 1700 a[0] = e->el_tty.t_c[TS_IO][C_REPRINT]; 1701 a[1] = '\0'; 1702 el_push(e, a); 1703 } 1704 1705 int 1706 rl_get_previous_history(int count, int key) 1707 { 1708 char a[2]; 1709 a[0] = key; 1710 a[1] = '\0'; 1711 while (count--) 1712 el_push(e, a); 1713 return 0; 1714 } 1715 1716 void 1717 /*ARGSUSED*/ 1718 rl_prep_terminal(int meta_flag) 1719 { 1720 el_set(e, EL_PREP_TERM, 1); 1721 } 1722 1723 void 1724 rl_deprep_terminal(void) 1725 { 1726 el_set(e, EL_PREP_TERM, 0); 1727 } 1728 1729 int 1730 rl_read_init_file(const char *s) 1731 { 1732 return(el_source(e, s)); 1733 } 1734 1735 int 1736 rl_parse_and_bind(const char *line) 1737 { 1738 const char **argv; 1739 int argc; 1740 Tokenizer *tok; 1741 1742 tok = tok_init(NULL); 1743 tok_str(tok, line, &argc, &argv); 1744 argc = el_parse(e, argc, argv); 1745 tok_end(tok); 1746 return (argc ? 1 : 0); 1747 } 1748 1749 int 1750 rl_variable_bind(const char *var, const char *value) 1751 { 1752 /* 1753 * The proper return value is undocument, but this is what the 1754 * readline source seems to do. 1755 */ 1756 return ((el_set(e, EL_BIND, "", var, value) == -1) ? 1 : 0); 1757 } 1758 1759 void 1760 rl_stuff_char(int c) 1761 { 1762 char buf[2]; 1763 1764 buf[0] = c; 1765 buf[1] = '\0'; 1766 el_insertstr(e, buf); 1767 } 1768 1769 static int 1770 _rl_event_read_char(EditLine *el, char *cp) 1771 { 1772 int n, num_read = 0; 1773 1774 *cp = 0; 1775 while (rl_event_hook) { 1776 1777 (*rl_event_hook)(); 1778 1779 #if defined(FIONREAD) 1780 if (ioctl(el->el_infd, FIONREAD, &n) < 0) 1781 return(-1); 1782 if (n) 1783 num_read = read(el->el_infd, cp, 1); 1784 else 1785 num_read = 0; 1786 #elif defined(F_SETFL) && defined(O_NDELAY) 1787 if ((n = fcntl(el->el_infd, F_GETFL, 0)) < 0) 1788 return(-1); 1789 if (fcntl(el->el_infd, F_SETFL, n|O_NDELAY) < 0) 1790 return(-1); 1791 num_read = read(el->el_infd, cp, 1); 1792 if (fcntl(el->el_infd, F_SETFL, n)) 1793 return(-1); 1794 #else 1795 /* not non-blocking, but what you gonna do? */ 1796 num_read = read(el->el_infd, cp, 1); 1797 return(-1); 1798 #endif 1799 1800 if (num_read < 0 && errno == EAGAIN) 1801 continue; 1802 if (num_read == 0) 1803 continue; 1804 break; 1805 } 1806 if (!rl_event_hook) 1807 el_set(el, EL_GETCFN, EL_BUILTIN_GETCFN); 1808 return(num_read); 1809 } 1810 1811 static void 1812 _rl_update_pos(void) 1813 { 1814 const LineInfo *li = el_line(e); 1815 1816 rl_point = li->cursor - li->buffer; 1817 rl_end = li->lastchar - li->buffer; 1818 } 1819 1820 void 1821 rl_get_screen_size(int *rows, int *cols) 1822 { 1823 if (rows) 1824 el_get(e, EL_GETTC, "li", rows); 1825 if (cols) 1826 el_get(e, EL_GETTC, "co", cols); 1827 } 1828 1829 void 1830 rl_set_screen_size(int rows, int cols) 1831 { 1832 char buf[64]; 1833 (void)snprintf(buf, sizeof(buf), "%d", rows); 1834 el_set(e, EL_SETTC, "li", buf); 1835 (void)snprintf(buf, sizeof(buf), "%d", cols); 1836 el_set(e, EL_SETTC, "co", buf); 1837 } 1838 1839 char ** 1840 rl_completion_matches(const char *str, rl_compentry_func_t *fun) 1841 { 1842 size_t len, max, i, j, min; 1843 char **list, *match, *a, *b; 1844 1845 len = 1; 1846 max = 10; 1847 if ((list = malloc(max * sizeof(*list))) == NULL) 1848 return NULL; 1849 1850 while ((match = (*fun)(str, (int)(len - 1))) != NULL) { 1851 if (len == max) { 1852 char **nl; 1853 max += 10; 1854 if ((nl = realloc(list, max * sizeof(*nl))) == NULL) 1855 goto out; 1856 list = nl; 1857 } 1858 list[len++] = match; 1859 } 1860 if (len == 1) 1861 goto out; 1862 list[len] = NULL; 1863 if (len == 2) { 1864 if ((list[0] = strdup(list[1])) == NULL) 1865 goto out; 1866 return list; 1867 } 1868 qsort(&list[1], len - 1, sizeof(*list), 1869 (int (*)(const void *, const void *)) strcmp); 1870 min = SIZE_T_MAX; 1871 for (i = 1, a = list[i]; i < len - 1; i++, a = b) { 1872 b = list[i + 1]; 1873 for (j = 0; a[j] && a[j] == b[j]; j++) 1874 continue; 1875 if (min > j) 1876 min = j; 1877 } 1878 if (min == 0 && *str) { 1879 if ((list[0] = strdup(str)) == NULL) 1880 goto out; 1881 } else { 1882 if ((list[0] = malloc(min + 1)) == NULL) 1883 goto out; 1884 (void)memcpy(list[0], list[1], min); 1885 list[0][min] = '\0'; 1886 } 1887 return list; 1888 1889 out: 1890 free(list); 1891 return NULL; 1892 } 1893 1894 char * 1895 rl_filename_completion_function (const char *text, int state) 1896 { 1897 return fn_filename_completion_function(text, state); 1898 } 1899 1900 void 1901 rl_forced_update_display(void) 1902 { 1903 el_set(e, EL_REFRESH); 1904 } 1905 1906 int 1907 _rl_abort_internal(void) 1908 { 1909 el_beep(e); 1910 longjmp(topbuf, 1); 1911 /*NOTREACHED*/ 1912 } 1913 1914 int 1915 _rl_qsort_string_compare(char **s1, char **s2) 1916 { 1917 return strcoll(*s1, *s2); 1918 } 1919 1920 int 1921 /*ARGSUSED*/ 1922 rl_kill_text(int from, int to) 1923 { 1924 return 0; 1925 } 1926 1927 Keymap 1928 rl_make_bare_keymap(void) 1929 { 1930 return NULL; 1931 } 1932 1933 Keymap 1934 rl_get_keymap(void) 1935 { 1936 return NULL; 1937 } 1938 1939 void 1940 /*ARGSUSED*/ 1941 rl_set_keymap(Keymap k) 1942 { 1943 } 1944 1945 int 1946 /*ARGSUSED*/ 1947 rl_generic_bind(int type, const char * keyseq, const char * data, Keymap k) 1948 { 1949 return 0; 1950 } 1951 1952 int 1953 /*ARGSUSED*/ 1954 rl_bind_key_in_map(int key, Function *fun, Keymap k) 1955 { 1956 return 0; 1957 } 1958