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