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