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