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