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