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