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