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