]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libedit/readline.c
sqlite3: Vendor import of sqlite3 3.40.1
[FreeBSD/FreeBSD.git] / contrib / libedit / readline.c
1 /*      $NetBSD: readline.c,v 1.174 2022/04/08 20:11:31 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.174 2022/04/08 20:11:31 christos Exp $");
35 #endif /* not lint && not SCCSID */
36
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <ctype.h>
40 #include <dirent.h>
41 #include <errno.h>
42 #include <fcntl.h>
43 #include <limits.h>
44 #include <pwd.h>
45 #include <setjmp.h>
46 #include <stdarg.h>
47 #include <stdint.h>
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <unistd.h>
52 #include <vis.h>
53
54 #include "readline/readline.h"
55 #include "el.h"
56 #include "fcns.h"
57 #include "filecomplete.h"
58
59 void rl_prep_terminal(int);
60 void rl_deprep_terminal(void);
61
62 /* for rl_complete() */
63 #define TAB             '\r'
64
65 /* see comment at the #ifdef for sense of this */
66 /* #define GDB_411_HACK */
67
68 /* readline compatibility stuff - look at readline sources/documentation */
69 /* to see what these variables mean */
70 const char *rl_library_version = "EditLine wrapper";
71 int rl_readline_version = RL_READLINE_VERSION;
72 static char empty[] = { '\0' };
73 static char expand_chars[] = { ' ', '\t', '\n', '=', '(', '\0' };
74 static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
75     '>', '<', '=', ';', '|', '&', '{', '(', '\0' };
76 const char *rl_readline_name = empty;
77 FILE *rl_instream = NULL;
78 FILE *rl_outstream = NULL;
79 int rl_point = 0;
80 int rl_end = 0;
81 char *rl_line_buffer = NULL;
82 rl_vcpfunc_t *rl_linefunc = NULL;
83 int rl_done = 0;
84 rl_hook_func_t *rl_event_hook = NULL;
85 KEYMAP_ENTRY_ARRAY emacs_standard_keymap,
86     emacs_meta_keymap,
87     emacs_ctlx_keymap;
88 /*
89  * The following is not implemented; we always catch signals in the
90  * libedit fashion: set handlers on entry to el_gets() and clear them
91  * on the way out. This simplistic approach works for most cases; if
92  * it does not work for your application, please let us know.
93  */
94 int rl_catch_signals = 1;
95 int rl_catch_sigwinch = 1;
96
97 int history_base = 1;           /* probably never subject to change */
98 int history_length = 0;
99 int history_offset = 0;
100 int max_input_history = 0;
101 char history_expansion_char = '!';
102 char history_subst_char = '^';
103 char *history_no_expand_chars = expand_chars;
104 Function *history_inhibit_expansion_function = NULL;
105 char *history_arg_extract(int start, int end, const char *str);
106
107 int rl_inhibit_completion = 0;
108 int rl_attempted_completion_over = 0;
109 const char *rl_basic_word_break_characters = break_chars;
110 char *rl_completer_word_break_characters = NULL;
111 const char *rl_completer_quote_characters = NULL;
112 const char *rl_basic_quote_characters = "\"'";
113 rl_compentry_func_t *rl_completion_entry_function = NULL;
114 char *(*rl_completion_word_break_hook)(void) = NULL;
115 rl_completion_func_t *rl_attempted_completion_function = NULL;
116 rl_hook_func_t *rl_pre_input_hook = NULL;
117 rl_hook_func_t *rl_startup1_hook = NULL;
118 int (*rl_getc_function)(FILE *) = NULL;
119 char *rl_terminal_name = NULL;
120 int rl_already_prompted = 0;
121 int rl_filename_completion_desired = 0;
122 int rl_ignore_completion_duplicates = 0;
123 int readline_echoing_p = 1;
124 int _rl_print_completions_horizontally = 0;
125 VFunction *rl_redisplay_function = NULL;
126 rl_hook_func_t *rl_startup_hook = NULL;
127 VFunction *rl_completion_display_matches_hook = NULL;
128 VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal;
129 VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal;
130 KEYMAP_ENTRY_ARRAY emacs_meta_keymap;
131 unsigned long rl_readline_state = RL_STATE_NONE;
132 int _rl_complete_mark_directories;
133 rl_icppfunc_t *rl_directory_completion_hook;
134 int rl_completion_suppress_append;
135 int rl_sort_completion_matches;
136 int _rl_completion_prefix_display_length;
137 int _rl_echoing_p;
138 int history_max_entries;
139 char *rl_display_prompt;
140 int rl_erase_empty_line;
141
142 /*
143  * The current prompt string.
144  */
145 char *rl_prompt = NULL;
146 char *rl_prompt_saved = NULL;
147 /*
148  * This is set to character indicating type of completion being done by
149  * rl_complete_internal(); this is available for application completion
150  * functions.
151  */
152 int rl_completion_type = 0;
153
154 /*
155  * If more than this number of items results from query for possible
156  * completions, we ask user if they are sure to really display the list.
157  */
158 int rl_completion_query_items = 100;
159
160 /*
161  * List of characters which are word break characters, but should be left
162  * in the parsed text when it is passed to the completion function.
163  * Shell uses this to help determine what kind of completing to do.
164  */
165 const char *rl_special_prefixes = NULL;
166
167 /*
168  * This is the character appended to the completed words if at the end of
169  * the line. Default is ' ' (a space).
170  */
171 int rl_completion_append_character = ' ';
172
173 /* stuff below is used internally by libedit for readline emulation */
174
175 static History *h = NULL;
176 static EditLine *e = NULL;
177 static rl_command_func_t *map[256];
178 static jmp_buf topbuf;
179
180 /* internal functions */
181 static unsigned char     _el_rl_complete(EditLine *, int);
182 static unsigned char     _el_rl_tstp(EditLine *, int);
183 static char             *_get_prompt(EditLine *);
184 static int               _getc_function(EditLine *, wchar_t *);
185 static int               _history_expand_command(const char *, size_t, size_t,
186     char **);
187 static char             *_rl_compat_sub(const char *, const char *,
188     const char *, int);
189 static int               _rl_event_read_char(EditLine *, wchar_t *);
190 static void              _rl_update_pos(void);
191
192 static HIST_ENTRY rl_he;
193
194 /* ARGSUSED */
195 static char *
196 _get_prompt(EditLine *el __attribute__((__unused__)))
197 {
198         rl_already_prompted = 1;
199         return rl_prompt;
200 }
201
202
203 /*
204  * read one key from user defined input function
205  */
206 static int
207 /*ARGSUSED*/
208 _getc_function(EditLine *el __attribute__((__unused__)), wchar_t *c)
209 {
210         int i;
211
212         i = (*rl_getc_function)(rl_instream);
213         if (i == -1)
214                 return 0;
215         *c = (wchar_t)i;
216         return 1;
217 }
218
219 static void
220 _resize_fun(EditLine *el, void *a)
221 {
222         const LineInfo *li;
223         const char **ap = a;
224
225         li = el_line(el);
226         *ap = li->buffer;
227 }
228
229 static const char *
230 _default_history_file(void)
231 {
232         struct passwd *p;
233         static char *path;
234         size_t len;
235
236         if (path)
237                 return path;
238
239         if ((p = getpwuid(getuid())) == NULL)
240                 return NULL;
241
242         len = strlen(p->pw_dir) + sizeof("/.history");
243         if ((path = malloc(len)) == NULL)
244                 return NULL;
245
246         (void)snprintf(path, len, "%s/.history", p->pw_dir);
247         return path;
248 }
249
250 /*
251  * READLINE compatibility stuff
252  */
253
254 /*
255  * Set the prompt
256  */
257 int
258 rl_set_prompt(const char *prompt)
259 {
260         char *p;
261
262         if (!prompt)
263                 prompt = "";
264         if (rl_prompt != NULL && strcmp(rl_prompt, prompt) == 0)
265                 return 0;
266         if (rl_prompt)
267                 el_free(rl_prompt);
268         rl_prompt = strdup(prompt);
269         if (rl_prompt == NULL)
270                 return -1;
271
272         while ((p = strchr(rl_prompt, RL_PROMPT_END_IGNORE)) != NULL) {
273                 /* Remove adjacent end/start markers to avoid double-escapes. */
274                 if (p[1] == RL_PROMPT_START_IGNORE) {
275                         memmove(p, p + 2, 1 + strlen(p + 2));
276                 } else {
277                         *p = RL_PROMPT_START_IGNORE;
278                 }
279         }
280
281         return 0;
282 }
283
284 void
285 rl_save_prompt(void)
286 {
287         rl_prompt_saved = strdup(rl_prompt);
288 }
289
290 void
291 rl_restore_prompt(void)
292 {
293         if (!rl_prompt_saved)
294                 return;
295         rl_prompt = rl_prompt_saved;
296         rl_prompt_saved = NULL;
297 }
298
299 /*
300  * initialize rl compat stuff
301  */
302 int
303 rl_initialize(void)
304 {
305         HistEvent ev;
306         int editmode = 1;
307         struct termios t;
308
309         if (e != NULL)
310                 el_end(e);
311         if (h != NULL)
312                 history_end(h);
313
314         RL_UNSETSTATE(RL_STATE_DONE);
315
316         if (!rl_instream)
317                 rl_instream = stdin;
318         if (!rl_outstream)
319                 rl_outstream = stdout;
320
321         /*
322          * See if we don't really want to run the editor
323          */
324         if (tcgetattr(fileno(rl_instream), &t) != -1 && (t.c_lflag & ECHO) == 0)
325                 editmode = 0;
326
327         e = el_init_internal(rl_readline_name, rl_instream, rl_outstream,
328             stderr, fileno(rl_instream), fileno(rl_outstream), fileno(stderr),
329             NO_RESET);
330
331         if (!editmode)
332                 el_set(e, EL_EDITMODE, 0);
333
334         h = history_init();
335         if (!e || !h)
336                 return -1;
337
338         history(h, &ev, H_SETSIZE, INT_MAX);    /* unlimited */
339         history_length = 0;
340         max_input_history = INT_MAX;
341         el_set(e, EL_HIST, history, h);
342
343         /* Setup resize function */
344         el_set(e, EL_RESIZE, _resize_fun, &rl_line_buffer);
345
346         /* setup getc function if valid */
347         if (rl_getc_function)
348                 el_set(e, EL_GETCFN, _getc_function);
349
350         /* for proper prompt printing in readline() */
351         if (rl_set_prompt("") == -1) {
352                 history_end(h);
353                 el_end(e);
354                 return -1;
355         }
356         el_set(e, EL_PROMPT_ESC, _get_prompt, RL_PROMPT_START_IGNORE);
357         el_set(e, EL_SIGNAL, rl_catch_signals);
358
359         /* set default mode to "emacs"-style and read setting afterwards */
360         /* so this can be overridden */
361         el_set(e, EL_EDITOR, "emacs");
362         if (rl_terminal_name != NULL)
363                 el_set(e, EL_TERMINAL, rl_terminal_name);
364         else
365                 el_get(e, EL_TERMINAL, &rl_terminal_name);
366
367         /*
368          * Word completion - this has to go AFTER rebinding keys
369          * to emacs-style.
370          */
371         el_set(e, EL_ADDFN, "rl_complete",
372             "ReadLine compatible completion function",
373             _el_rl_complete);
374         el_set(e, EL_BIND, "^I", "rl_complete", NULL);
375
376         /*
377          * Send TSTP when ^Z is pressed.
378          */
379         el_set(e, EL_ADDFN, "rl_tstp",
380             "ReadLine compatible suspend function",
381             _el_rl_tstp);
382         el_set(e, EL_BIND, "^Z", "rl_tstp", NULL);
383
384         /*
385          * Set some readline compatible key-bindings.
386          */
387         el_set(e, EL_BIND, "^R", "em-inc-search-prev", NULL);
388
389         /*
390          * Allow the use of Home/End keys.
391          */
392         el_set(e, EL_BIND, "\\e[1~", "ed-move-to-beg", NULL);
393         el_set(e, EL_BIND, "\\e[4~", "ed-move-to-end", NULL);
394         el_set(e, EL_BIND, "\\e[7~", "ed-move-to-beg", NULL);
395         el_set(e, EL_BIND, "\\e[8~", "ed-move-to-end", NULL);
396         el_set(e, EL_BIND, "\\e[H", "ed-move-to-beg", NULL);
397         el_set(e, EL_BIND, "\\e[F", "ed-move-to-end", NULL);
398
399         /*
400          * Allow the use of the Delete/Insert keys.
401          */
402         el_set(e, EL_BIND, "\\e[3~", "ed-delete-next-char", NULL);
403         el_set(e, EL_BIND, "\\e[2~", "ed-quoted-insert", NULL);
404
405         /*
406          * Ctrl-left-arrow and Ctrl-right-arrow for word moving.
407          */
408         el_set(e, EL_BIND, "\\e[1;5C", "em-next-word", NULL);
409         el_set(e, EL_BIND, "\\e[1;5D", "ed-prev-word", NULL);
410         el_set(e, EL_BIND, "\\e[5C", "em-next-word", NULL);
411         el_set(e, EL_BIND, "\\e[5D", "ed-prev-word", NULL);
412         el_set(e, EL_BIND, "\\e\\e[C", "em-next-word", NULL);
413         el_set(e, EL_BIND, "\\e\\e[D", "ed-prev-word", NULL);
414
415         /* read settings from configuration file */
416         el_source(e, NULL);
417
418         /*
419          * Unfortunately, some applications really do use rl_point
420          * and rl_line_buffer directly.
421          */
422         _resize_fun(e, &rl_line_buffer);
423         _rl_update_pos();
424
425         tty_end(e, TCSADRAIN);
426
427         return 0;
428 }
429
430
431 /*
432  * read one line from input stream and return it, chomping
433  * trailing newline (if there is any)
434  */
435 char *
436 readline(const char *p)
437 {
438         HistEvent ev;
439         const char * volatile prompt = p;
440         int count;
441         const char *ret;
442         char *buf;
443         static int used_event_hook;
444
445         if (e == NULL || h == NULL)
446                 rl_initialize();
447         if (rl_startup_hook) {
448                 (*rl_startup_hook)();
449         }
450         tty_init(e);
451
452
453         rl_done = 0;
454
455         (void)setjmp(topbuf);
456         buf = NULL;
457
458         /* update prompt accordingly to what has been passed */
459         if (rl_set_prompt(prompt) == -1)
460                 goto out;
461
462         if (rl_pre_input_hook)
463                 (*rl_pre_input_hook)();
464
465         if (rl_event_hook && !(e->el_flags & NO_TTY)) {
466                 el_set(e, EL_GETCFN, _rl_event_read_char);
467                 used_event_hook = 1;
468         }
469
470         if (!rl_event_hook && used_event_hook) {
471                 el_set(e, EL_GETCFN, EL_BUILTIN_GETCFN);
472                 used_event_hook = 0;
473         }
474
475         rl_already_prompted = 0;
476
477         /* get one line from input stream */
478         ret = el_gets(e, &count);
479
480         if (ret && count > 0) {
481                 buf = strdup(ret);
482                 if (buf == NULL)
483                         goto out;
484                 buf[strcspn(buf, "\n")] = '\0';
485         } else
486                 buf = NULL;
487
488         history(h, &ev, H_GETSIZE);
489         history_length = ev.num;
490
491 out:
492         tty_end(e, TCSADRAIN);
493         return buf;
494 }
495
496 /*
497  * history functions
498  */
499
500 /*
501  * is normally called before application starts to use
502  * history expansion functions
503  */
504 void
505 using_history(void)
506 {
507         if (h == NULL || e == NULL)
508                 rl_initialize();
509         history_offset = history_length;
510 }
511
512
513 /*
514  * substitute ``what'' with ``with'', returning resulting string; if
515  * globally == 1, substitutes all occurrences of what, otherwise only the
516  * first one
517  */
518 static char *
519 _rl_compat_sub(const char *str, const char *what, const char *with,
520     int globally)
521 {
522         const   char    *s;
523         char    *r, *result;
524         size_t  len, with_len, what_len;
525
526         len = strlen(str);
527         with_len = strlen(with);
528         what_len = strlen(what);
529
530         /* calculate length we need for result */
531         s = str;
532         while (*s) {
533                 if (*s == *what && !strncmp(s, what, what_len)) {
534                         len += with_len - what_len;
535                         if (!globally)
536                                 break;
537                         s += what_len;
538                 } else
539                         s++;
540         }
541         r = result = el_calloc(len + 1, sizeof(*r));
542         if (result == NULL)
543                 return NULL;
544         s = str;
545         while (*s) {
546                 if (*s == *what && !strncmp(s, what, what_len)) {
547                         memcpy(r, with, with_len);
548                         r += with_len;
549                         s += what_len;
550                         if (!globally) {
551                                 (void)strcpy(r, s);
552                                 return result;
553                         }
554                 } else
555                         *r++ = *s++;
556         }
557         *r = '\0';
558         return result;
559 }
560
561 static  char    *last_search_pat;       /* last !?pat[?] search pattern */
562 static  char    *last_search_match;     /* last !?pat[?] that matched */
563
564 const char *
565 get_history_event(const char *cmd, int *cindex, int qchar)
566 {
567         int idx, sign, sub, num, begin, ret;
568         size_t len;
569         char    *pat;
570         const char *rptr;
571         HistEvent ev;
572
573         idx = *cindex;
574         if (cmd[idx++] != history_expansion_char)
575                 return NULL;
576
577         /* find out which event to take */
578         if (cmd[idx] == history_expansion_char || cmd[idx] == '\0') {
579                 if (history(h, &ev, H_FIRST) != 0)
580                         return NULL;
581                 *cindex = cmd[idx]? (idx + 1):idx;
582                 return ev.str;
583         }
584         sign = 0;
585         if (cmd[idx] == '-') {
586                 sign = 1;
587                 idx++;
588         }
589
590         if ('0' <= cmd[idx] && cmd[idx] <= '9') {
591                 HIST_ENTRY *he;
592
593                 num = 0;
594                 while (cmd[idx] && '0' <= cmd[idx] && cmd[idx] <= '9') {
595                         num = num * 10 + cmd[idx] - '0';
596                         idx++;
597                 }
598                 if (sign)
599                         num = history_length - num + history_base;
600
601                 if (!(he = history_get(num)))
602                         return NULL;
603
604                 *cindex = idx;
605                 return he->line;
606         }
607         sub = 0;
608         if (cmd[idx] == '?') {
609                 sub = 1;
610                 idx++;
611         }
612         begin = idx;
613         while (cmd[idx]) {
614                 if (cmd[idx] == '\n')
615                         break;
616                 if (sub && cmd[idx] == '?')
617                         break;
618                 if (!sub && (cmd[idx] == ':' || cmd[idx] == ' '
619                     || cmd[idx] == '\t' || cmd[idx] == qchar))
620                         break;
621                 idx++;
622         }
623         len = (size_t)idx - (size_t)begin;
624         if (sub && cmd[idx] == '?')
625                 idx++;
626         if (sub && len == 0 && last_search_pat && *last_search_pat)
627                 pat = last_search_pat;
628         else if (len == 0)
629                 return NULL;
630         else {
631                 if ((pat = el_calloc(len + 1, sizeof(*pat))) == NULL)
632                         return NULL;
633                 (void)strlcpy(pat, cmd + begin, len + 1);
634         }
635
636         if (history(h, &ev, H_CURR) != 0) {
637                 if (pat != last_search_pat)
638                         el_free(pat);
639                 return NULL;
640         }
641         num = ev.num;
642
643         if (sub) {
644                 if (pat != last_search_pat) {
645                         el_free(last_search_pat);
646                         last_search_pat = pat;
647                 }
648                 ret = history_search(pat, -1);
649         } else
650                 ret = history_search_prefix(pat, -1);
651
652         if (ret == -1) {
653                 /* restore to end of list on failed search */
654                 history(h, &ev, H_FIRST);
655                 (void)fprintf(rl_outstream, "%s: Event not found\n", pat);
656                 if (pat != last_search_pat)
657                         el_free(pat);
658                 return NULL;
659         }
660
661         if (sub && len) {
662                 el_free(last_search_match);
663                 last_search_match = strdup(pat);
664         }
665
666         if (pat != last_search_pat)
667                 el_free(pat);
668
669         if (history(h, &ev, H_CURR) != 0)
670                 return NULL;
671         *cindex = idx;
672         rptr = ev.str;
673
674         /* roll back to original position */
675         (void)history(h, &ev, H_SET, num);
676
677         return rptr;
678 }
679
680 static int
681 getfrom(const char **cmdp, char **fromp, const char *search, int delim)
682 {
683         size_t size = 16;
684         size_t len = 0;
685         const char *cmd = *cmdp;
686         char *what = el_realloc(*fromp, size * sizeof(*what));
687         if (what == NULL){
688                 el_free(*fromp);
689                 *fromp = NULL;
690                 return 0;
691         }
692         for (; *cmd && *cmd != delim; cmd++) {
693                 if (*cmd == '\\' && cmd[1] == delim)
694                         cmd++;
695                 if (len - 1 >= size) {
696                         char *nwhat;
697                         nwhat = el_realloc(what, (size <<= 1) * sizeof(*nwhat));
698                         if (nwhat == NULL) {
699                                 el_free(what);
700                                 el_free(*fromp);
701                                 *cmdp = cmd;
702                                 *fromp = NULL;
703                                 return 0;
704                         }
705                         what = nwhat;
706                 }
707                 what[len++] = *cmd;
708         }
709         what[len] = '\0';
710         *fromp = what;
711         *cmdp = cmd;
712         if (*what == '\0') {
713                 el_free(what);
714                 if (search) {
715                         *fromp = strdup(search);
716                         if (*fromp == NULL) {
717                                 return 0;
718                         }
719                 } else {
720                         *fromp = NULL;
721                         return -1;
722                 }
723         }
724         if (!*cmd) {
725                 el_free(what);
726                 *fromp = NULL;
727                 return -1;
728         }
729
730         cmd++;  /* shift after delim */
731         *cmdp = cmd;
732
733         if (!*cmd) {
734                 el_free(what);
735                 *fromp = NULL;
736                 return -1;
737         }
738         return 1;
739 }
740
741 static int
742 getto(const char **cmdp, char **top, const char *from, int delim)
743 {
744         size_t size = 16;
745         size_t len = 0;
746         size_t from_len = strlen(from);
747         const char *cmd = *cmdp;
748         char *with = el_realloc(*top, size * sizeof(*with));
749         *top = NULL;
750         if (with == NULL)
751                 goto out;
752
753         for (; *cmd && *cmd != delim; cmd++) {
754                 if (len + from_len + 1 >= size) {
755                         char *nwith;
756                         size += from_len + 1;
757                         nwith = el_realloc(with, size * sizeof(*nwith));
758                         if (nwith == NULL)
759                                 goto out;
760                         with = nwith;
761                 }
762                 if (*cmd == '&') {
763                         /* safe */
764                         strcpy(&with[len], from);
765                         len += from_len;
766                         continue;
767                 }
768                 if (*cmd == '\\' && (*(cmd + 1) == delim || *(cmd + 1) == '&'))
769                         cmd++;
770                 with[len++] = *cmd;
771         }
772         if (!*cmd)
773                 goto out;
774         with[len] = '\0';
775         *top = with;
776         *cmdp = cmd;
777         return 1;
778 out:
779         el_free(with);
780         el_free(*top);
781         *top = NULL;
782         *cmdp = cmd;
783         return -1;
784 }
785
786 static void
787 replace(char **tmp, int c)
788 {
789         char *aptr;
790         if ((aptr = strrchr(*tmp, c)) == NULL)
791                 return;
792         aptr = strdup(aptr + 1); // XXX: check
793         el_free(*tmp);
794         *tmp = aptr;
795 }
796
797 /*
798  * the real function doing history expansion - takes as argument command
799  * to do and data upon which the command should be executed
800  * does expansion the way I've understood readline documentation
801  *
802  * returns 0 if data was not modified, 1 if it was and 2 if the string
803  * should be only printed and not executed; in case of error,
804  * returns -1 and *result points to NULL
805  * it's the caller's responsibility to free() the string returned in *result
806  */
807 static int
808 _history_expand_command(const char *command, size_t offs, size_t cmdlen,
809     char **result)
810 {
811         char *tmp, *search = NULL, *aptr, delim;
812         const char *ptr, *cmd;
813         static char *from = NULL, *to = NULL;
814         int start, end, idx, has_mods = 0;
815         int p_on = 0, g_on = 0, ev;
816
817         *result = NULL;
818         aptr = NULL;
819         ptr = NULL;
820
821         /* First get event specifier */
822         idx = 0;
823
824         if (strchr(":^*$", command[offs + 1])) {
825                 char str[4];
826                 /*
827                 * "!:" is shorthand for "!!:".
828                 * "!^", "!*" and "!$" are shorthand for
829                 * "!!:^", "!!:*" and "!!:$" respectively.
830                 */
831                 str[0] = str[1] = '!';
832                 str[2] = '0';
833                 ptr = get_history_event(str, &idx, 0);
834                 idx = (command[offs + 1] == ':')? 1:0;
835                 has_mods = 1;
836         } else {
837                 if (command[offs + 1] == '#') {
838                         /* use command so far */
839                         if ((aptr = el_calloc(offs + 1, sizeof(*aptr)))
840                             == NULL)
841                                 return -1;
842                         (void)strlcpy(aptr, command, offs + 1);
843                         idx = 1;
844                 } else {
845                         int     qchar;
846
847                         qchar = (offs > 0 && command[offs - 1] == '"')
848                             ? '"' : '\0';
849                         ptr = get_history_event(command + offs, &idx, qchar);
850                 }
851                 has_mods = command[offs + (size_t)idx] == ':';
852         }
853
854         if (ptr == NULL && aptr == NULL)
855                 return -1;
856
857         if (!has_mods) {
858                 *result = strdup(aptr ? aptr : ptr);
859                 if (aptr)
860                         el_free(aptr);
861                 if (*result == NULL)
862                         return -1;
863                 return 1;
864         }
865
866         cmd = command + offs + idx + 1;
867
868         /* Now parse any word designators */
869
870         if (*cmd == '%')        /* last word matched by ?pat? */
871                 tmp = strdup(last_search_match ? last_search_match : "");
872         else if (strchr("^*$-0123456789", *cmd)) {
873                 start = end = -1;
874                 if (*cmd == '^')
875                         start = end = 1, cmd++;
876                 else if (*cmd == '$')
877                         start = -1, cmd++;
878                 else if (*cmd == '*')
879                         start = 1, cmd++;
880                 else if (*cmd == '-' || isdigit((unsigned char) *cmd)) {
881                         start = 0;
882                         while (*cmd && '0' <= *cmd && *cmd <= '9')
883                                 start = start * 10 + *cmd++ - '0';
884
885                         if (*cmd == '-') {
886                                 if (isdigit((unsigned char) cmd[1])) {
887                                         cmd++;
888                                         end = 0;
889                                         while (*cmd && '0' <= *cmd && *cmd <= '9')
890                                                 end = end * 10 + *cmd++ - '0';
891                                 } else if (cmd[1] == '$') {
892                                         cmd += 2;
893                                         end = -1;
894                                 } else {
895                                         cmd++;
896                                         end = -2;
897                                 }
898                         } else if (*cmd == '*')
899                                 end = -1, cmd++;
900                         else
901                                 end = start;
902                 }
903                 tmp = history_arg_extract(start, end, aptr? aptr:ptr);
904                 if (tmp == NULL) {
905                         (void)fprintf(rl_outstream, "%s: Bad word specifier",
906                             command + offs + idx);
907                         if (aptr)
908                                 el_free(aptr);
909                         return -1;
910                 }
911         } else
912                 tmp = strdup(aptr? aptr:ptr);
913
914         if (aptr)
915                 el_free(aptr);
916
917         if (*cmd == '\0' || ((size_t)(cmd - (command + offs)) >= cmdlen)) {
918                 *result = tmp;
919                 return 1;
920         }
921
922         for (; *cmd; cmd++) {
923                 switch (*cmd) {
924                 case ':':
925                         continue;
926                 case 'h':       /* remove trailing path */
927                         if ((aptr = strrchr(tmp, '/')) != NULL)
928                                 *aptr = '\0';
929                         continue;
930                 case 't':       /* remove leading path */
931                         replace(&tmp, '/');
932                         continue;
933                 case 'r':       /* remove trailing suffix */
934                         if ((aptr = strrchr(tmp, '.')) != NULL)
935                                 *aptr = '\0';
936                         continue;
937                 case 'e':       /* remove all but suffix */
938                         replace(&tmp, '.');
939                         continue;
940                 case 'p':       /* print only */
941                         p_on = 1;
942                         continue;
943                 case 'g':
944                         g_on = 2;
945                         continue;
946                 case '&':
947                         if (from == NULL || to == NULL)
948                                 continue;
949                         /*FALLTHROUGH*/
950                 case 's':
951                         ev = -1;
952                         delim = *++cmd;
953                         if (delim == '\0' || *++cmd == '\0')
954                                 goto out;
955                         if ((ev = getfrom(&cmd, &from, search, delim)) != 1)
956                                 goto out;
957                         if ((ev = getto(&cmd, &to, from, delim)) != 1)
958                                 goto out;
959                         aptr = _rl_compat_sub(tmp, from, to, g_on);
960                         if (aptr) {
961                                 el_free(tmp);
962                                 tmp = aptr;
963                         }
964                         g_on = 0;
965                         cmd--;
966                         continue;
967                 }
968         }
969         *result = tmp;
970         return p_on ? 2 : 1;
971 out:
972         el_free(tmp);
973         return ev;
974         
975 }
976
977
978 /*
979  * csh-style history expansion
980  */
981 int
982 history_expand(char *str, char **output)
983 {
984         int ret = 0;
985         size_t idx, i, size;
986         char *tmp, *result;
987
988         if (h == NULL || e == NULL)
989                 rl_initialize();
990
991         if (history_expansion_char == 0) {
992                 *output = strdup(str);
993                 return 0;
994         }
995
996         *output = NULL;
997         if (str[0] == history_subst_char) {
998                 /* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */
999                 *output = el_calloc(strlen(str) + 4 + 1, sizeof(**output));
1000                 if (*output == NULL)
1001                         return 0;
1002                 (*output)[0] = (*output)[1] = history_expansion_char;
1003                 (*output)[2] = ':';
1004                 (*output)[3] = 's';
1005                 (void)strcpy((*output) + 4, str);
1006                 str = *output;
1007         } else {
1008                 *output = strdup(str);
1009                 if (*output == NULL)
1010                         return 0;
1011         }
1012
1013 #define ADD_STRING(what, len, fr)                                       \
1014         {                                                               \
1015                 if (idx + len + 1 > size) {                             \
1016                         char *nresult = el_realloc(result,              \
1017                             (size += len + 1) * sizeof(*nresult));      \
1018                         if (nresult == NULL) {                          \
1019                                 el_free(*output);                       \
1020                                 el_free(fr);                            \
1021                                 return 0;                               \
1022                         }                                               \
1023                         result = nresult;                               \
1024                 }                                                       \
1025                 (void)strlcpy(&result[idx], what, len + 1);             \
1026                 idx += len;                                             \
1027         }
1028
1029         result = NULL;
1030         size = idx = 0;
1031         tmp = NULL;
1032         for (i = 0; str[i];) {
1033                 int qchar, loop_again;
1034                 size_t len, start, j;
1035
1036                 qchar = 0;
1037                 loop_again = 1;
1038                 start = j = i;
1039 loop:
1040                 for (; str[j]; j++) {
1041                         if (str[j] == '\\' &&
1042                             str[j + 1] == history_expansion_char) {
1043                                 len = strlen(&str[j + 1]) + 1;
1044                                 memmove(&str[j], &str[j + 1], len);
1045                                 continue;
1046                         }
1047                         if (!loop_again) {
1048                                 if (isspace((unsigned char) str[j])
1049                                     || str[j] == qchar)
1050                                         break;
1051                         }
1052                         if (str[j] == history_expansion_char
1053                             && !strchr(history_no_expand_chars, str[j + 1])
1054                             && (!history_inhibit_expansion_function ||
1055                             (*history_inhibit_expansion_function)(str,
1056                             (int)j) == 0))
1057                                 break;
1058                 }
1059
1060                 if (str[j] && loop_again) {
1061                         i = j;
1062                         qchar = (j > 0 && str[j - 1] == '"' )? '"':0;
1063                         j++;
1064                         if (str[j] == history_expansion_char)
1065                                 j++;
1066                         loop_again = 0;
1067                         goto loop;
1068                 }
1069                 len = i - start;
1070                 ADD_STRING(&str[start], len, NULL);
1071
1072                 if (str[i] == '\0' || str[i] != history_expansion_char) {
1073                         len = j - i;
1074                         ADD_STRING(&str[i], len, NULL);
1075                         if (start == 0)
1076                                 ret = 0;
1077                         else
1078                                 ret = 1;
1079                         break;
1080                 }
1081                 ret = _history_expand_command (str, i, (j - i), &tmp);
1082                 if (ret > 0 && tmp) {
1083                         len = strlen(tmp);
1084                         ADD_STRING(tmp, len, tmp);
1085                 }
1086                 if (tmp) {
1087                         el_free(tmp);
1088                         tmp = NULL;
1089                 }
1090                 i = j;
1091         }
1092
1093         /* ret is 2 for "print only" option */
1094         if (ret == 2) {
1095                 add_history(result);
1096 #ifdef GDB_411_HACK
1097                 /* gdb 4.11 has been shipped with readline, where */
1098                 /* history_expand() returned -1 when the line     */
1099                 /* should not be executed; in readline 2.1+       */
1100                 /* it should return 2 in such a case              */
1101                 ret = -1;
1102 #endif
1103         }
1104         el_free(*output);
1105         *output = result;
1106
1107         return ret;
1108 }
1109
1110 /*
1111 * Return a string consisting of arguments of "str" from "start" to "end".
1112 */
1113 char *
1114 history_arg_extract(int start, int end, const char *str)
1115 {
1116         size_t  i, len, max;
1117         char    **arr, *result = NULL;
1118
1119         arr = history_tokenize(str);
1120         if (!arr)
1121                 return NULL;
1122         if (arr && *arr == NULL)
1123                 goto out;
1124
1125         for (max = 0; arr[max]; max++)
1126                 continue;
1127         max--;
1128
1129         if (start == '$')
1130                 start = (int)max;
1131         if (end == '$')
1132                 end = (int)max;
1133         if (end < 0)
1134                 end = (int)max + end + 1;
1135         if (start < 0)
1136                 start = end;
1137
1138         if (start < 0 || end < 0 || (size_t)start > max ||
1139             (size_t)end > max || start > end)
1140                 goto out;
1141
1142         for (i = (size_t)start, len = 0; i <= (size_t)end; i++)
1143                 len += strlen(arr[i]) + 1;
1144         len++;
1145         result = el_calloc(len, sizeof(*result));
1146         if (result == NULL)
1147                 goto out;
1148
1149         for (i = (size_t)start, len = 0; i <= (size_t)end; i++) {
1150                 (void)strcpy(result + len, arr[i]);
1151                 len += strlen(arr[i]);
1152                 if (i < (size_t)end)
1153                         result[len++] = ' ';
1154         }
1155         result[len] = '\0';
1156
1157 out:
1158         for (i = 0; arr[i]; i++)
1159                 el_free(arr[i]);
1160         el_free(arr);
1161
1162         return result;
1163 }
1164
1165 /*
1166  * Parse the string into individual tokens,
1167  * similar to how shell would do it.
1168  */
1169 char **
1170 history_tokenize(const char *str)
1171 {
1172         int size = 1, idx = 0, i, start;
1173         size_t len;
1174         char **result = NULL, *temp, delim = '\0';
1175
1176         for (i = 0; str[i];) {
1177                 while (isspace((unsigned char) str[i]))
1178                         i++;
1179                 start = i;
1180                 for (; str[i];) {
1181                         if (str[i] == '\\') {
1182                                 if (str[i+1] != '\0')
1183                                         i++;
1184                         } else if (str[i] == delim)
1185                                 delim = '\0';
1186                         else if (!delim &&
1187                                     (isspace((unsigned char) str[i]) ||
1188                                 strchr("()<>;&|$", str[i])))
1189                                 break;
1190                         else if (!delim && strchr("'`\"", str[i]))
1191                                 delim = str[i];
1192                         if (str[i])
1193                                 i++;
1194                 }
1195
1196                 if (idx + 2 >= size) {
1197                         char **nresult;
1198                         size <<= 1;
1199                         nresult = el_realloc(result, (size_t)size * sizeof(*nresult));
1200                         if (nresult == NULL) {
1201                                 el_free(result);
1202                                 return NULL;
1203                         }
1204                         result = nresult;
1205                 }
1206                 len = (size_t)i - (size_t)start;
1207                 temp = el_calloc(len + 1, sizeof(*temp));
1208                 if (temp == NULL) {
1209                         for (i = 0; i < idx; i++)
1210                                 el_free(result[i]);
1211                         el_free(result);
1212                         return NULL;
1213                 }
1214                 (void)strlcpy(temp, &str[start], len + 1);
1215                 result[idx++] = temp;
1216                 result[idx] = NULL;
1217                 if (str[i])
1218                         i++;
1219         }
1220         return result;
1221 }
1222
1223
1224 /*
1225  * limit size of history record to ``max'' events
1226  */
1227 void
1228 stifle_history(int max)
1229 {
1230         HistEvent ev;
1231         HIST_ENTRY *he;
1232
1233         if (h == NULL || e == NULL)
1234                 rl_initialize();
1235
1236         if (history(h, &ev, H_SETSIZE, max) == 0) {
1237                 max_input_history = max;
1238                 if (history_length > max)
1239                         history_base = history_length - max;
1240                 while (history_length > max) {
1241                         he = remove_history(0);
1242                         el_free(he->data);
1243                         el_free((void *)(unsigned long)he->line);
1244                         el_free(he);
1245                 }
1246         }
1247 }
1248
1249
1250 /*
1251  * "unlimit" size of history - set the limit to maximum allowed int value
1252  */
1253 int
1254 unstifle_history(void)
1255 {
1256         HistEvent ev;
1257         int omax;
1258
1259         history(h, &ev, H_SETSIZE, INT_MAX);
1260         omax = max_input_history;
1261         max_input_history = INT_MAX;
1262         return omax;            /* some value _must_ be returned */
1263 }
1264
1265
1266 int
1267 history_is_stifled(void)
1268 {
1269
1270         /* cannot return true answer */
1271         return max_input_history != INT_MAX;
1272 }
1273
1274 static const char _history_tmp_template[] = "/tmp/.historyXXXXXX";
1275
1276 int
1277 history_truncate_file (const char *filename, int nlines)
1278 {
1279         int ret = 0;
1280         FILE *fp, *tp;
1281         char template[sizeof(_history_tmp_template)];
1282         char buf[4096];
1283         int fd;
1284         char *cp;
1285         off_t off;
1286         int count = 0;
1287         ssize_t left = 0;
1288
1289         if (filename == NULL && (filename = _default_history_file()) == NULL)
1290                 return errno;
1291         if ((fp = fopen(filename, "r+")) == NULL)
1292                 return errno;
1293         strcpy(template, _history_tmp_template);
1294         if ((fd = mkstemp(template)) == -1) {
1295                 ret = errno;
1296                 goto out1;
1297         }
1298
1299         if ((tp = fdopen(fd, "r+")) == NULL) {
1300                 close(fd);
1301                 ret = errno;
1302                 goto out2;
1303         }
1304
1305         for(;;) {
1306                 if (fread(buf, sizeof(buf), (size_t)1, fp) != 1) {
1307                         if (ferror(fp)) {
1308                                 ret = errno;
1309                                 break;
1310                         }
1311                         if (fseeko(fp, (off_t)sizeof(buf) * count, SEEK_SET) ==
1312                             (off_t)-1) {
1313                                 ret = errno;
1314                                 break;
1315                         }
1316                         left = (ssize_t)fread(buf, (size_t)1, sizeof(buf), fp);
1317                         if (ferror(fp)) {
1318                                 ret = errno;
1319                                 break;
1320                         }
1321                         if (left == 0) {
1322                                 count--;
1323                                 left = sizeof(buf);
1324                         } else if (fwrite(buf, (size_t)left, (size_t)1, tp)
1325                             != 1) {
1326                                 ret = errno;
1327                                 break;
1328                         }
1329                         fflush(tp);
1330                         break;
1331                 }
1332                 if (fwrite(buf, sizeof(buf), (size_t)1, tp) != 1) {
1333                         ret = errno;
1334                         break;
1335                 }
1336                 count++;
1337         }
1338         if (ret)
1339                 goto out3;
1340         cp = buf + left - 1;
1341         if(*cp != '\n')
1342                 cp++;
1343         for(;;) {
1344                 while (--cp >= buf) {
1345                         if (*cp == '\n') {
1346                                 if (--nlines == 0) {
1347                                         if (++cp >= buf + sizeof(buf)) {
1348                                                 count++;
1349                                                 cp = buf;
1350                                         }
1351                                         break;
1352                                 }
1353                         }
1354                 }
1355                 if (nlines <= 0 || count == 0)
1356                         break;
1357                 count--;
1358                 if (fseeko(tp, (off_t)sizeof(buf) * count, SEEK_SET) < 0) {
1359                         ret = errno;
1360                         break;
1361                 }
1362                 if (fread(buf, sizeof(buf), (size_t)1, tp) != 1) {
1363                         if (ferror(tp)) {
1364                                 ret = errno;
1365                                 break;
1366                         }
1367                         ret = EAGAIN;
1368                         break;
1369                 }
1370                 cp = buf + sizeof(buf);
1371         }
1372
1373         if (ret || nlines > 0)
1374                 goto out3;
1375
1376         if (fseeko(fp, (off_t)0, SEEK_SET) == (off_t)-1) {
1377                 ret = errno;
1378                 goto out3;
1379         }
1380
1381         if (fseeko(tp, (off_t)sizeof(buf) * count + (cp - buf), SEEK_SET) ==
1382             (off_t)-1) {
1383                 ret = errno;
1384                 goto out3;
1385         }
1386
1387         for(;;) {
1388                 if ((left = (ssize_t)fread(buf, (size_t)1, sizeof(buf), tp)) == 0) {
1389                         if (ferror(fp))
1390                                 ret = errno;
1391                         break;
1392                 }
1393                 if (fwrite(buf, (size_t)left, (size_t)1, fp) != 1) {
1394                         ret = errno;
1395                         break;
1396                 }
1397         }
1398         fflush(fp);
1399         if((off = ftello(fp)) > 0)
1400                 (void)ftruncate(fileno(fp), off);
1401 out3:
1402         fclose(tp);
1403 out2:
1404         unlink(template);
1405 out1:
1406         fclose(fp);
1407
1408         return ret;
1409 }
1410
1411
1412 /*
1413  * read history from a file given
1414  */
1415 int
1416 read_history(const char *filename)
1417 {
1418         HistEvent ev;
1419
1420         if (h == NULL || e == NULL)
1421                 rl_initialize();
1422         if (filename == NULL && (filename = _default_history_file()) == NULL)
1423                 return errno;
1424         errno = 0;
1425         if (history(h, &ev, H_LOAD, filename) == -1)
1426                 return errno ? errno : EINVAL;
1427         if (history(h, &ev, H_GETSIZE) == 0)
1428                 history_length = ev.num;
1429         if (history_length < 0)
1430                 return EINVAL;
1431         return 0;
1432 }
1433
1434
1435 /*
1436  * write history to a file given
1437  */
1438 int
1439 write_history(const char *filename)
1440 {
1441         HistEvent ev;
1442
1443         if (h == NULL || e == NULL)
1444                 rl_initialize();
1445         if (filename == NULL && (filename = _default_history_file()) == NULL)
1446                 return errno;
1447         return history(h, &ev, H_SAVE, filename) == -1 ?
1448             (errno ? errno : EINVAL) : 0;
1449 }
1450
1451 int
1452 append_history(int n, const char *filename)
1453 {
1454         HistEvent ev;
1455         FILE *fp;
1456
1457         if (h == NULL || e == NULL)
1458                 rl_initialize();
1459         if (filename == NULL && (filename = _default_history_file()) == NULL)
1460                 return errno;
1461
1462         if ((fp = fopen(filename, "a")) == NULL)
1463                 return errno;
1464
1465         if (history(h, &ev, H_NSAVE_FP, (size_t)n,  fp) == -1) {
1466                 int serrno = errno ? errno : EINVAL;
1467                 fclose(fp);
1468                 return serrno;
1469         }
1470         fclose(fp);
1471         return 0;
1472 }
1473
1474 /*
1475  * returns history ``num''th event
1476  *
1477  * returned pointer points to static variable
1478  */
1479 HIST_ENTRY *
1480 history_get(int num)
1481 {
1482         static HIST_ENTRY she;
1483         HistEvent ev;
1484         int curr_num;
1485
1486         if (h == NULL || e == NULL)
1487                 rl_initialize();
1488
1489         if (num < history_base)
1490                 return NULL;
1491
1492         /* save current position */
1493         if (history(h, &ev, H_CURR) != 0)
1494                 return NULL;
1495         curr_num = ev.num;
1496
1497         /*
1498          * use H_DELDATA to set to nth history (without delete) by passing
1499          * (void **)-1  -- as in history_set_pos
1500          */
1501         if (history(h, &ev, H_DELDATA, num - history_base, (void **)-1) != 0)
1502                 goto out;
1503
1504         /* get current entry */
1505         if (history(h, &ev, H_CURR) != 0)
1506                 goto out;
1507         if (history(h, &ev, H_NEXT_EVDATA, ev.num, &she.data) != 0)
1508                 goto out;
1509         she.line = ev.str;
1510
1511         /* restore pointer to where it was */
1512         (void)history(h, &ev, H_SET, curr_num);
1513
1514         return &she;
1515
1516 out:
1517         /* restore pointer to where it was */
1518         (void)history(h, &ev, H_SET, curr_num);
1519         return NULL;
1520 }
1521
1522
1523 /*
1524  * add the line to history table
1525  */
1526 int
1527 add_history(const char *line)
1528 {
1529         HistEvent ev;
1530
1531         if (h == NULL || e == NULL)
1532                 rl_initialize();
1533
1534         if (history(h, &ev, H_ENTER, line) == -1)
1535                 return 0;
1536
1537         (void)history(h, &ev, H_GETSIZE);
1538         if (ev.num == history_length)
1539                 history_base++;
1540         else {
1541                 history_offset++;
1542                 history_length = ev.num;
1543         }
1544         return 0;
1545 }
1546
1547
1548 /*
1549  * remove the specified entry from the history list and return it.
1550  */
1551 HIST_ENTRY *
1552 remove_history(int num)
1553 {
1554         HIST_ENTRY *he;
1555         HistEvent ev;
1556
1557         if (h == NULL || e == NULL)
1558                 rl_initialize();
1559
1560         if ((he = el_malloc(sizeof(*he))) == NULL)
1561                 return NULL;
1562
1563         if (history(h, &ev, H_DELDATA, num, &he->data) != 0) {
1564                 el_free(he);
1565                 return NULL;
1566         }
1567
1568         he->line = ev.str;
1569         if (history(h, &ev, H_GETSIZE) == 0)
1570                 history_length = ev.num;
1571
1572         return he;
1573 }
1574
1575
1576 /*
1577  * replace the line and data of the num-th entry
1578  */
1579 HIST_ENTRY *
1580 replace_history_entry(int num, const char *line, histdata_t data)
1581 {
1582         HIST_ENTRY *he;
1583         HistEvent ev;
1584         int curr_num;
1585
1586         if (h == NULL || e == NULL)
1587                 rl_initialize();
1588
1589         /* save current position */
1590         if (history(h, &ev, H_CURR) != 0)
1591                 return NULL;
1592         curr_num = ev.num;
1593
1594         /* start from the oldest */
1595         if (history(h, &ev, H_LAST) != 0)
1596                 return NULL;    /* error */
1597
1598         if ((he = el_malloc(sizeof(*he))) == NULL)
1599                 return NULL;
1600
1601         /* look forwards for event matching specified offset */
1602         if (history(h, &ev, H_NEXT_EVDATA, num, &he->data))
1603                 goto out;
1604
1605         he->line = strdup(ev.str);
1606         if (he->line == NULL)
1607                 goto out;
1608
1609         if (history(h, &ev, H_REPLACE, line, data))
1610                 goto out;
1611
1612         /* restore pointer to where it was */
1613         if (history(h, &ev, H_SET, curr_num))
1614                 goto out;
1615
1616         return he;
1617 out:
1618         el_free(he);
1619         return NULL;
1620 }
1621
1622 /*
1623  * clear the history list - delete all entries
1624  */
1625 void
1626 clear_history(void)
1627 {
1628         HistEvent ev;
1629
1630         if (h == NULL || e == NULL)
1631                 rl_initialize();
1632
1633         (void)history(h, &ev, H_CLEAR);
1634         history_offset = history_length = 0;
1635 }
1636
1637
1638 /*
1639  * returns offset of the current history event
1640  */
1641 int
1642 where_history(void)
1643 {
1644         return history_offset;
1645 }
1646
1647 static HIST_ENTRY **_history_listp;
1648 static HIST_ENTRY *_history_list;
1649
1650 HIST_ENTRY **
1651 history_list(void)
1652 {
1653         HistEvent ev;
1654         HIST_ENTRY **nlp, *nl;
1655         int i;
1656
1657         if (history(h, &ev, H_LAST) != 0)
1658                 return NULL;
1659
1660         if ((nlp = el_realloc(_history_listp,
1661             ((size_t)history_length + 1) * sizeof(*nlp))) == NULL)
1662                 return NULL;
1663         _history_listp = nlp;
1664
1665         if ((nl = el_realloc(_history_list,
1666             (size_t)history_length * sizeof(*nl))) == NULL)
1667                 return NULL;
1668         _history_list = nl;
1669
1670         i = 0;
1671         do {
1672                 _history_listp[i] = &_history_list[i];
1673                 _history_list[i].line = ev.str;
1674                 _history_list[i].data = NULL;
1675                 if (i++ == history_length)
1676                         abort();
1677         } while (history(h, &ev, H_PREV) == 0);
1678         _history_listp[i] = NULL;
1679         return _history_listp;
1680 }
1681
1682 /*
1683  * returns current history event or NULL if there is no such event
1684  */
1685 HIST_ENTRY *
1686 current_history(void)
1687 {
1688         HistEvent ev;
1689
1690         if (history(h, &ev, H_PREV_EVENT, history_offset + 1) != 0)
1691                 return NULL;
1692
1693         rl_he.line = ev.str;
1694         rl_he.data = NULL;
1695         return &rl_he;
1696 }
1697
1698
1699 /*
1700  * returns total number of bytes history events' data are using
1701  */
1702 int
1703 history_total_bytes(void)
1704 {
1705         HistEvent ev;
1706         int curr_num;
1707         size_t size;
1708
1709         if (history(h, &ev, H_CURR) != 0)
1710                 return -1;
1711         curr_num = ev.num;
1712
1713         (void)history(h, &ev, H_FIRST);
1714         size = 0;
1715         do
1716                 size += strlen(ev.str) * sizeof(*ev.str);
1717         while (history(h, &ev, H_NEXT) == 0);
1718
1719         /* get to the same position as before */
1720         history(h, &ev, H_PREV_EVENT, curr_num);
1721
1722         return (int)size;
1723 }
1724
1725
1726 /*
1727  * sets the position in the history list to ``pos''
1728  */
1729 int
1730 history_set_pos(int pos)
1731 {
1732         if (pos >= history_length || pos < 0)
1733                 return 0;
1734
1735         history_offset = pos;
1736         return 1;
1737 }
1738
1739
1740 /*
1741  * returns previous event in history and shifts pointer accordingly
1742  * Note that readline and editline define directions in opposite ways.
1743  */
1744 HIST_ENTRY *
1745 previous_history(void)
1746 {
1747         HistEvent ev;
1748
1749         if (history_offset == 0)
1750                 return NULL;
1751
1752         if (history(h, &ev, H_LAST) != 0)
1753                 return NULL;
1754
1755         history_offset--;
1756         return current_history();
1757 }
1758
1759
1760 /*
1761  * returns next event in history and shifts pointer accordingly
1762  */
1763 HIST_ENTRY *
1764 next_history(void)
1765 {
1766         HistEvent ev;
1767
1768         if (history_offset >= history_length)
1769                 return NULL;
1770
1771         if (history(h, &ev, H_LAST) != 0)
1772                 return NULL;
1773
1774         history_offset++;
1775         return current_history();
1776 }
1777
1778
1779 /*
1780  * searches for first history event containing the str
1781  */
1782 int
1783 history_search(const char *str, int direction)
1784 {
1785         HistEvent ev;
1786         const char *strp;
1787         int curr_num;
1788
1789         if (history(h, &ev, H_CURR) != 0)
1790                 return -1;
1791         curr_num = ev.num;
1792
1793         for (;;) {
1794                 if ((strp = strstr(ev.str, str)) != NULL)
1795                         return (int)(strp - ev.str);
1796                 if (history(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0)
1797                         break;
1798         }
1799         (void)history(h, &ev, H_SET, curr_num);
1800         return -1;
1801 }
1802
1803
1804 /*
1805  * searches for first history event beginning with str
1806  */
1807 int
1808 history_search_prefix(const char *str, int direction)
1809 {
1810         HistEvent ev;
1811
1812         return (history(h, &ev, direction < 0 ?
1813             H_PREV_STR : H_NEXT_STR, str));
1814 }
1815
1816
1817 /*
1818  * search for event in history containing str, starting at offset
1819  * abs(pos); continue backward, if pos<0, forward otherwise
1820  */
1821 /* ARGSUSED */
1822 int
1823 history_search_pos(const char *str,
1824                    int direction __attribute__((__unused__)), int pos)
1825 {
1826         HistEvent ev;
1827         int curr_num, off;
1828
1829         off = (pos > 0) ? pos : -pos;
1830         pos = (pos > 0) ? 1 : -1;
1831
1832         if (history(h, &ev, H_CURR) != 0)
1833                 return -1;
1834         curr_num = ev.num;
1835
1836         if (!history_set_pos(off) || history(h, &ev, H_CURR) != 0)
1837                 return -1;
1838
1839         for (;;) {
1840                 if (strstr(ev.str, str))
1841                         return off;
1842                 if (history(h, &ev, (pos < 0) ? H_PREV : H_NEXT) != 0)
1843                         break;
1844         }
1845
1846         /* set "current" pointer back to previous state */
1847         (void)history(h, &ev,
1848             pos < 0 ? H_NEXT_EVENT : H_PREV_EVENT, curr_num);
1849
1850         return -1;
1851 }
1852
1853
1854 /********************************/
1855 /* completion functions */
1856
1857 char *
1858 tilde_expand(char *name)
1859 {
1860         return fn_tilde_expand(name);
1861 }
1862
1863 char *
1864 filename_completion_function(const char *name, int state)
1865 {
1866         return fn_filename_completion_function(name, state);
1867 }
1868
1869 /*
1870  * a completion generator for usernames; returns _first_ username
1871  * which starts with supplied text
1872  * text contains a partial username preceded by random character
1873  * (usually '~'); state resets search from start (??? should we do that anyway)
1874  * it's the caller's responsibility to free the returned value
1875  */
1876 char *
1877 username_completion_function(const char *text, int state)
1878 {
1879 #if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT)
1880         struct passwd pwres;
1881         char pwbuf[1024];
1882 #endif
1883         struct passwd *pass = NULL;
1884
1885         if (text[0] == '\0')
1886                 return NULL;
1887
1888         if (*text == '~')
1889                 text++;
1890
1891         if (state == 0)
1892                 setpwent();
1893
1894         while (
1895 #if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT)
1896             getpwent_r(&pwres, pwbuf, sizeof(pwbuf), &pass) == 0 && pass != NULL
1897 #else
1898             (pass = getpwent()) != NULL
1899 #endif
1900             && text[0] == pass->pw_name[0]
1901             && strcmp(text, pass->pw_name) == 0)
1902                 continue;
1903
1904         if (pass == NULL) {
1905                 endpwent();
1906                 return NULL;
1907         }
1908         return strdup(pass->pw_name);
1909 }
1910
1911
1912 /*
1913  * el-compatible wrapper to send TSTP on ^Z
1914  */
1915 /* ARGSUSED */
1916 static unsigned char
1917 _el_rl_tstp(EditLine *el __attribute__((__unused__)), int ch __attribute__((__unused__)))
1918 {
1919         (void)kill(0, SIGTSTP);
1920         return CC_NORM;
1921 }
1922
1923 static const char *
1924 /*ARGSUSED*/
1925 _rl_completion_append_character_function(const char *dummy
1926     __attribute__((__unused__)))
1927 {
1928         static char buf[2];
1929         buf[0] = (char)rl_completion_append_character;
1930         buf[1] = '\0';
1931         return buf;
1932 }
1933
1934
1935 /*
1936  * Display list of strings in columnar format on readline's output stream.
1937  * 'matches' is list of strings, 'len' is number of strings in 'matches',
1938  * 'max' is maximum length of string in 'matches'.
1939  */
1940 void
1941 rl_display_match_list(char **matches, int len, int max)
1942 {
1943
1944         fn_display_match_list(e, matches, (size_t)len, (size_t)max,
1945                 _rl_completion_append_character_function);
1946 }
1947
1948 /*
1949  * complete word at current point
1950  */
1951 /* ARGSUSED */
1952 int
1953 rl_complete(int ignore __attribute__((__unused__)), int invoking_key)
1954 {
1955         static ct_buffer_t wbreak_conv, sprefix_conv;
1956         const char *breakchars;
1957
1958         if (h == NULL || e == NULL)
1959                 rl_initialize();
1960
1961         if (rl_inhibit_completion) {
1962                 char arr[2];
1963                 arr[0] = (char)invoking_key;
1964                 arr[1] = '\0';
1965                 el_insertstr(e, arr);
1966                 return CC_REFRESH;
1967         }
1968
1969         if (rl_completion_word_break_hook != NULL)
1970                 breakchars = (*rl_completion_word_break_hook)();
1971         else
1972                 breakchars = rl_basic_word_break_characters;
1973
1974         _rl_update_pos();
1975
1976         /* Just look at how many global variables modify this operation! */
1977         return fn_complete(e,
1978             (rl_compentry_func_t *)rl_completion_entry_function,
1979             rl_attempted_completion_function,
1980             ct_decode_string(rl_basic_word_break_characters, &wbreak_conv),
1981             ct_decode_string(breakchars, &sprefix_conv),
1982             _rl_completion_append_character_function,
1983             (size_t)rl_completion_query_items,
1984             &rl_completion_type, &rl_attempted_completion_over,
1985             &rl_point, &rl_end);
1986
1987
1988 }
1989
1990
1991 /* ARGSUSED */
1992 static unsigned char
1993 _el_rl_complete(EditLine *el __attribute__((__unused__)), int ch)
1994 {
1995         return (unsigned char)rl_complete(0, ch);
1996 }
1997
1998 /*
1999  * misc other functions
2000  */
2001
2002 /*
2003  * bind key c to readline-type function func
2004  */
2005 int
2006 rl_bind_key(int c, rl_command_func_t *func)
2007 {
2008         int retval = -1;
2009
2010         if (h == NULL || e == NULL)
2011                 rl_initialize();
2012
2013         if (func == rl_insert) {
2014                 /* XXX notice there is no range checking of ``c'' */
2015                 e->el_map.key[c] = ED_INSERT;
2016                 retval = 0;
2017         }
2018         return retval;
2019 }
2020
2021
2022 /*
2023  * read one key from input - handles chars pushed back
2024  * to input stream also
2025  */
2026 int
2027 rl_read_key(void)
2028 {
2029         char fooarr[2 * sizeof(int)];
2030
2031         if (e == NULL || h == NULL)
2032                 rl_initialize();
2033
2034         return el_getc(e, fooarr);
2035 }
2036
2037
2038 /*
2039  * reset the terminal
2040  */
2041 /* ARGSUSED */
2042 int
2043 rl_reset_terminal(const char *p __attribute__((__unused__)))
2044 {
2045
2046         if (h == NULL || e == NULL)
2047                 rl_initialize();
2048         el_reset(e);
2049         return 0;
2050 }
2051
2052
2053 /*
2054  * insert character ``c'' back into input stream, ``count'' times
2055  */
2056 int
2057 rl_insert(int count, int c)
2058 {
2059         char arr[2];
2060
2061         if (h == NULL || e == NULL)
2062                 rl_initialize();
2063
2064         /* XXX - int -> char conversion can lose on multichars */
2065         arr[0] = (char)c;
2066         arr[1] = '\0';
2067
2068         for (; count > 0; count--)
2069                 el_push(e, arr);
2070
2071         return 0;
2072 }
2073
2074 int
2075 rl_insert_text(const char *text)
2076 {
2077         if (!text || *text == 0)
2078                 return 0;
2079
2080         if (h == NULL || e == NULL)
2081                 rl_initialize();
2082
2083         if (el_insertstr(e, text) < 0)
2084                 return 0;
2085         return (int)strlen(text);
2086 }
2087
2088 /*ARGSUSED*/
2089 int
2090 rl_newline(int count __attribute__((__unused__)),
2091     int c __attribute__((__unused__)))
2092 {
2093         /*
2094          * Readline-4.0 appears to ignore the args.
2095          */
2096         return rl_insert(1, '\n');
2097 }
2098
2099 /*ARGSUSED*/
2100 static unsigned char
2101 rl_bind_wrapper(EditLine *el __attribute__((__unused__)), unsigned char c)
2102 {
2103         if (map[c] == NULL)
2104                 return CC_ERROR;
2105
2106         _rl_update_pos();
2107
2108         (*map[c])(1, c);
2109
2110         /* If rl_done was set by the above call, deal with it here */
2111         if (rl_done)
2112                 return CC_EOF;
2113
2114         return CC_NORM;
2115 }
2116
2117 int
2118 rl_add_defun(const char *name, rl_command_func_t *fun, int c)
2119 {
2120         char dest[8];
2121         if ((size_t)c >= sizeof(map) / sizeof(map[0]) || c < 0)
2122                 return -1;
2123         map[(unsigned char)c] = fun;
2124         el_set(e, EL_ADDFN, name, name, rl_bind_wrapper);
2125         vis(dest, c, VIS_WHITE|VIS_NOSLASH, 0);
2126         el_set(e, EL_BIND, dest, name, NULL);
2127         return 0;
2128 }
2129
2130 void
2131 rl_callback_read_char(void)
2132 {
2133         int count = 0, done = 0;
2134         const char *buf = el_gets(e, &count);
2135         char *wbuf;
2136
2137         el_set(e, EL_UNBUFFERED, 1);
2138         if (buf == NULL || count-- <= 0)
2139                 return;
2140         if (count == 0 && buf[0] == e->el_tty.t_c[TS_IO][C_EOF])
2141                 done = 1;
2142         if (buf[count] == '\n' || buf[count] == '\r')
2143                 done = 2;
2144
2145         if (done && rl_linefunc != NULL) {
2146                 el_set(e, EL_UNBUFFERED, 0);
2147                 if (done == 2) {
2148                         if ((wbuf = strdup(buf)) != NULL)
2149                                 wbuf[count] = '\0';
2150                         RL_SETSTATE(RL_STATE_DONE);
2151                 } else
2152                         wbuf = NULL;
2153                 (*(void (*)(const char *))rl_linefunc)(wbuf);
2154         }
2155         _rl_update_pos();
2156 }
2157
2158 void
2159 rl_callback_handler_install(const char *prompt, rl_vcpfunc_t *linefunc)
2160 {
2161         if (e == NULL) {
2162                 rl_initialize();
2163         }
2164         (void)rl_set_prompt(prompt);
2165         rl_linefunc = linefunc;
2166         el_set(e, EL_UNBUFFERED, 1);
2167 }
2168
2169 void
2170 rl_callback_handler_remove(void)
2171 {
2172         el_set(e, EL_UNBUFFERED, 0);
2173         rl_linefunc = NULL;
2174 }
2175
2176 void
2177 rl_redisplay(void)
2178 {
2179         char a[2];
2180         a[0] = (char)e->el_tty.t_c[TS_IO][C_REPRINT];
2181         a[1] = '\0';
2182         el_push(e, a);
2183         rl_forced_update_display();
2184 }
2185
2186 int
2187 rl_get_previous_history(int count, int key)
2188 {
2189         char a[2];
2190         a[0] = (char)key;
2191         a[1] = '\0';
2192         while (count--)
2193                 el_push(e, a);
2194         return 0;
2195 }
2196
2197 void
2198 /*ARGSUSED*/
2199 rl_prep_terminal(int meta_flag __attribute__((__unused__)))
2200 {
2201         el_set(e, EL_PREP_TERM, 1);
2202 }
2203
2204 void
2205 rl_deprep_terminal(void)
2206 {
2207         el_set(e, EL_PREP_TERM, 0);
2208 }
2209
2210 int
2211 rl_read_init_file(const char *s)
2212 {
2213         return el_source(e, s);
2214 }
2215
2216 int
2217 rl_parse_and_bind(const char *line)
2218 {
2219         const char **argv;
2220         int argc;
2221         Tokenizer *tok;
2222
2223         tok = tok_init(NULL);
2224         tok_str(tok, line, &argc, &argv);
2225         argc = el_parse(e, argc, argv);
2226         tok_end(tok);
2227         return argc ? 1 : 0;
2228 }
2229
2230 int
2231 rl_variable_bind(const char *var, const char *value)
2232 {
2233         /*
2234          * The proper return value is undocument, but this is what the
2235          * readline source seems to do.
2236          */
2237         return el_set(e, EL_BIND, "", var, value, NULL) == -1 ? 1 : 0;
2238 }
2239
2240 int
2241 rl_stuff_char(int c)
2242 {
2243         char buf[2];
2244
2245         buf[0] = (char)c;
2246         buf[1] = '\0';
2247         el_insertstr(e, buf);
2248         return 1;
2249 }
2250
2251 static int
2252 _rl_event_read_char(EditLine *el, wchar_t *wc)
2253 {
2254         char    ch;
2255         int     n;
2256         ssize_t num_read = 0;
2257
2258         ch = '\0';
2259         *wc = L'\0';
2260         while (rl_event_hook) {
2261
2262                 (*rl_event_hook)();
2263
2264 #if defined(FIONREAD)
2265                 if (ioctl(el->el_infd, FIONREAD, &n) < 0)
2266                         return -1;
2267                 if (n)
2268                         num_read = read(el->el_infd, &ch, (size_t)1);
2269                 else
2270                         num_read = 0;
2271 #elif defined(F_SETFL) && defined(O_NDELAY)
2272                 if ((n = fcntl(el->el_infd, F_GETFL, 0)) < 0)
2273                         return -1;
2274                 if (fcntl(el->el_infd, F_SETFL, n|O_NDELAY) < 0)
2275                         return -1;
2276                 num_read = read(el->el_infd, &ch, 1);
2277                 if (fcntl(el->el_infd, F_SETFL, n))
2278                         return -1;
2279 #else
2280                 /* not non-blocking, but what you gonna do? */
2281                 num_read = read(el->el_infd, &ch, 1);
2282                 return -1;
2283 #endif
2284
2285                 if (num_read < 0 && errno == EAGAIN)
2286                         continue;
2287                 if (num_read == 0)
2288                         continue;
2289                 break;
2290         }
2291         if (!rl_event_hook)
2292                 el_set(el, EL_GETCFN, EL_BUILTIN_GETCFN);
2293         *wc = (wchar_t)ch;
2294         return (int)num_read;
2295 }
2296
2297 static void
2298 _rl_update_pos(void)
2299 {
2300         const LineInfo *li = el_line(e);
2301
2302         rl_point = (int)(li->cursor - li->buffer);
2303         rl_end = (int)(li->lastchar - li->buffer);
2304         rl_line_buffer[rl_end] = '\0';
2305 }
2306
2307 char *
2308 rl_copy_text(int from, int to)
2309 {
2310         const LineInfo *li;
2311         size_t len;
2312         char * out;
2313
2314         if (h == NULL || e == NULL)
2315                 rl_initialize();
2316
2317         li = el_line(e);
2318
2319         if (from > to)
2320                 return NULL;
2321
2322         if (li->buffer + from > li->lastchar)
2323                 from = (int)(li->lastchar - li->buffer);
2324
2325         if (li->buffer + to > li->lastchar)
2326                 to = (int)(li->lastchar - li->buffer);
2327
2328         len = (size_t)(to - from);
2329         out = el_malloc((size_t)len + 1);
2330         (void)strlcpy(out, li->buffer + from , len);
2331
2332         return out;
2333 }
2334
2335 void
2336 rl_replace_line(const char * text, int clear_undo __attribute__((__unused__)))
2337 {
2338         if (!text || *text == 0)
2339                 return;
2340
2341         if (h == NULL || e == NULL)
2342                 rl_initialize();
2343
2344         el_replacestr(e, text);
2345 }
2346
2347 int
2348 rl_delete_text(int start, int end)
2349 {
2350
2351         if (h == NULL || e == NULL)
2352                 rl_initialize();
2353
2354         return el_deletestr1(e, start, end);
2355 }
2356
2357 void
2358 rl_get_screen_size(int *rows, int *cols)
2359 {
2360         if (rows)
2361                 el_get(e, EL_GETTC, "li", rows);
2362         if (cols)
2363                 el_get(e, EL_GETTC, "co", cols);
2364 }
2365
2366 #define MAX_MESSAGE 160
2367 void
2368 rl_message(const char *format, ...)
2369 {
2370         char msg[MAX_MESSAGE];
2371         va_list args;
2372
2373         va_start(args, format);
2374         vsnprintf(msg, sizeof(msg), format, args);
2375         va_end(args);
2376
2377         rl_set_prompt(msg);
2378         rl_forced_update_display();
2379 }
2380
2381 void
2382 rl_set_screen_size(int rows, int cols)
2383 {
2384         char buf[64];
2385         (void)snprintf(buf, sizeof(buf), "%d", rows);
2386         el_set(e, EL_SETTC, "li", buf, NULL);
2387         (void)snprintf(buf, sizeof(buf), "%d", cols);
2388         el_set(e, EL_SETTC, "co", buf, NULL);
2389 }
2390
2391 char **
2392 rl_completion_matches(const char *str, rl_compentry_func_t *fun)
2393 {
2394         size_t len, max, i, j, min;
2395         char **list, *match, *a, *b;
2396
2397         len = 1;
2398         max = 10;
2399         if ((list = el_calloc(max, sizeof(*list))) == NULL)
2400                 return NULL;
2401
2402         while ((match = (*fun)(str, (int)(len - 1))) != NULL) {
2403                 list[len++] = match;
2404                 if (len == max) {
2405                         char **nl;
2406                         max += 10;
2407                         if ((nl = el_realloc(list, max * sizeof(*nl))) == NULL)
2408                                 goto out;
2409                         list = nl;
2410                 }
2411         }
2412         if (len == 1)
2413                 goto out;
2414         list[len] = NULL;
2415         if (len == 2) {
2416                 if ((list[0] = strdup(list[1])) == NULL)
2417                         goto out;
2418                 return list;
2419         }
2420         qsort(&list[1], len - 1, sizeof(*list),
2421             (int (*)(const void *, const void *)) strcmp);
2422         min = SIZE_MAX;
2423         for (i = 1, a = list[i]; i < len - 1; i++, a = b) {
2424                 b = list[i + 1];
2425                 for (j = 0; a[j] && a[j] == b[j]; j++)
2426                         continue;
2427                 if (min > j)
2428                         min = j;
2429         }
2430         if (min == 0 && *str) {
2431                 if ((list[0] = strdup(str)) == NULL)
2432                         goto out;
2433         } else {
2434                 if ((list[0] = el_calloc(min + 1, sizeof(*list[0]))) == NULL)
2435                         goto out;
2436                 (void)memcpy(list[0], list[1], min);
2437                 list[0][min] = '\0';
2438         }
2439         return list;
2440
2441 out:
2442         el_free(list);
2443         return NULL;
2444 }
2445
2446 char *
2447 rl_filename_completion_function (const char *text, int state)
2448 {
2449         return fn_filename_completion_function(text, state);
2450 }
2451
2452 void
2453 rl_forced_update_display(void)
2454 {
2455         el_set(e, EL_REFRESH);
2456 }
2457
2458 int
2459 _rl_abort_internal(void)
2460 {
2461         el_beep(e);
2462         longjmp(topbuf, 1);
2463         /*NOTREACHED*/
2464 }
2465
2466 int
2467 _rl_qsort_string_compare(char **s1, char **s2)
2468 {
2469         return strcoll(*s1, *s2);
2470 }
2471
2472 HISTORY_STATE *
2473 history_get_history_state(void)
2474 {
2475         HISTORY_STATE *hs;
2476
2477         if ((hs = el_malloc(sizeof(*hs))) == NULL)
2478                 return NULL;
2479         hs->length = history_length;
2480         return hs;
2481 }
2482
2483 int
2484 /*ARGSUSED*/
2485 rl_kill_text(int from __attribute__((__unused__)),
2486     int to __attribute__((__unused__)))
2487 {
2488         return 0;
2489 }
2490
2491 Keymap
2492 rl_make_bare_keymap(void)
2493 {
2494         return NULL;
2495 }
2496
2497 Keymap
2498 rl_get_keymap(void)
2499 {
2500         return NULL;
2501 }
2502
2503 void
2504 /*ARGSUSED*/
2505 rl_set_keymap(Keymap k __attribute__((__unused__)))
2506 {
2507 }
2508
2509 int
2510 /*ARGSUSED*/
2511 rl_generic_bind(int type __attribute__((__unused__)),
2512     const char * keyseq __attribute__((__unused__)),
2513     const char * data __attribute__((__unused__)),
2514     Keymap k __attribute__((__unused__)))
2515 {
2516         return 0;
2517 }
2518
2519 int
2520 /*ARGSUSED*/
2521 rl_bind_key_in_map(int key __attribute__((__unused__)),
2522     rl_command_func_t *fun __attribute__((__unused__)),
2523     Keymap k __attribute__((__unused__)))
2524 {
2525         return 0;
2526 }
2527
2528 int
2529 rl_set_key(const char *keyseq  __attribute__((__unused__)),
2530         rl_command_func_t *function __attribute__((__unused__)),
2531         Keymap k __attribute__((__unused__)))
2532 {
2533         return 0;
2534 }
2535
2536 /* unsupported, but needed by python */
2537 void
2538 rl_cleanup_after_signal(void)
2539 {
2540 }
2541
2542 int
2543 rl_on_new_line(void)
2544 {
2545         return 0;
2546 }
2547
2548 void
2549 rl_free_line_state(void)
2550 {
2551 }
2552
2553 int
2554 /*ARGSUSED*/
2555 rl_set_keyboard_input_timeout(int u __attribute__((__unused__)))
2556 {
2557         return 0;
2558 }
2559
2560 void
2561 rl_resize_terminal(void)
2562 {
2563         el_resize(e);
2564 }
2565
2566 void
2567 rl_reset_after_signal(void)
2568 {
2569         if (rl_prep_term_function)
2570                 (*rl_prep_term_function)();
2571 }
2572
2573 void
2574 rl_echo_signal_char(int sig)
2575 {
2576         int c = tty_get_signal_character(e, sig);
2577         if (c == -1)
2578                 return;
2579         re_putc(e, c, 0);
2580 }
2581
2582 int
2583 rl_crlf(void)
2584 {
2585         re_putc(e, '\n', 0);
2586         return 0;
2587 }
2588
2589 int
2590 rl_ding(void)
2591 {
2592         re_putc(e, '\a', 0);
2593         return 0;
2594 }
2595
2596 int
2597 rl_abort(int count, int key)
2598 {
2599         return count && key ? 0 : 0;
2600 }
2601
2602 int
2603 rl_set_keymap_name(const char *name, Keymap k)
2604 {
2605         return name && k ? 0 : 0;
2606 }
2607
2608 histdata_t
2609 free_history_entry(HIST_ENTRY *he)
2610 {
2611         return he ? NULL : NULL;
2612 }
2613
2614 void
2615 _rl_erase_entire_line(void)
2616 {
2617 }