Merge commit 'dfc115332c94a2f62058ac7f2bce7631fbd20b3d'
[unleashed/tickless.git] / lib / libedit / readline.c
blobaf13ec54946b77ff069afc65aeac18211862c276
1 /* $OpenBSD: readline.c,v 1.27 2016/05/31 16:12:00 schwarze Exp $ */
2 /* $NetBSD: readline.c,v 1.91 2010/08/28 15:44:59 christos Exp $ */
4 /*-
5 * Copyright (c) 1997 The NetBSD Foundation, Inc.
6 * All rights reserved.
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jaromir Dolecek.
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.
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
33 #include "config.h"
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <ctype.h>
38 #include <dirent.h>
39 #include <errno.h>
40 #include <fcntl.h>
41 #include <limits.h>
42 #include <pwd.h>
43 #include <setjmp.h>
44 #include <stdint.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <unistd.h>
49 #ifdef HAVE_VIS_H
50 #include <vis.h>
51 #else
52 #include "np/vis.h"
53 #endif
54 #include "readline/readline.h"
55 #include "el.h"
56 #include "fcns.h"
57 #include "filecomplete.h"
59 void rl_prep_terminal(int);
60 void rl_deprep_terminal(void);
62 /* for rl_complete() */
63 #define TAB '\r'
65 /* see comment at the #ifdef for sense of this */
66 /* #define GDB_411_HACK */
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 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 VCPFunction *rl_linefunc = NULL;
83 int rl_done = 0;
84 VFunction *rl_event_hook = NULL;
85 KEYMAP_ENTRY_ARRAY emacs_standard_keymap,
86 emacs_meta_keymap,
87 emacs_ctlx_keymap;
89 int history_base = 1; /* probably never subject to change */
90 int history_length = 0;
91 int max_input_history = 0;
92 char history_expansion_char = '!';
93 char history_subst_char = '^';
94 char *history_no_expand_chars = expand_chars;
95 Function *history_inhibit_expansion_function = NULL;
96 char *history_arg_extract(int start, int end, const char *str);
98 int rl_inhibit_completion = 0;
99 int rl_attempted_completion_over = 0;
100 char *rl_basic_word_break_characters = break_chars;
101 char *rl_completer_word_break_characters = NULL;
102 char *rl_completer_quote_characters = NULL;
103 Function *rl_completion_entry_function = NULL;
104 CPPFunction *rl_attempted_completion_function = NULL;
105 Function *rl_pre_input_hook = NULL;
106 Function *rl_startup1_hook = NULL;
107 int (*rl_getc_function)(FILE *) = NULL;
108 char *rl_terminal_name = NULL;
109 int rl_already_prompted = 0;
110 int rl_filename_completion_desired = 0;
111 int rl_ignore_completion_duplicates = 0;
112 int rl_catch_signals = 1;
113 int readline_echoing_p = 1;
114 int _rl_print_completions_horizontally = 0;
115 VFunction *rl_redisplay_function = NULL;
116 Function *rl_startup_hook = NULL;
117 VFunction *rl_completion_display_matches_hook = NULL;
118 VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal;
119 VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal;
120 KEYMAP_ENTRY_ARRAY emacs_meta_keymap;
123 * The current prompt string.
125 char *rl_prompt = NULL;
127 * This is set to character indicating type of completion being done by
128 * rl_complete_internal(); this is available for application completion
129 * functions.
131 int rl_completion_type = 0;
134 * If more than this number of items results from query for possible
135 * completions, we ask user if they are sure to really display the list.
137 int rl_completion_query_items = 100;
140 * List of characters which are word break characters, but should be left
141 * in the parsed text when it is passed to the completion function.
142 * Shell uses this to help determine what kind of completing to do.
144 char *rl_special_prefixes = NULL;
147 * This is the character appended to the completed words if at the end of
148 * the line. Default is ' ' (a space).
150 int rl_completion_append_character = ' ';
153 * When the history cursor is on the newest element and next_history()
154 * is called, GNU readline moves the cursor beyond the newest element.
155 * The editline library does not provide data structures to express
156 * that state, so we need a local flag.
158 static int current_history_valid = 1;
160 /* stuff below is used internally by libedit for readline emulation */
162 static History *h = NULL;
163 static EditLine *e = NULL;
164 static Function *map[256];
165 static jmp_buf topbuf;
167 /* internal functions */
168 static unsigned char _el_rl_complete(EditLine *, int);
169 static unsigned char _el_rl_tstp(EditLine *, int);
170 static char *_get_prompt(EditLine *);
171 static int _getc_function(EditLine *, wchar_t *);
172 static HIST_ENTRY *_move_history(int);
173 static int _history_expand_command(const char *, size_t, size_t,
174 char **);
175 static char *_rl_compat_sub(const char *, const char *,
176 const char *, int);
177 static int _rl_event_read_char(EditLine *, wchar_t *);
178 static void _rl_update_pos(void);
181 /* ARGSUSED */
182 static char *
183 _get_prompt(EditLine *el __attribute__((__unused__)))
185 rl_already_prompted = 1;
186 return rl_prompt;
191 * generic function for moving around history
193 static HIST_ENTRY *
194 _move_history(int op)
196 HistEvent ev;
197 static HIST_ENTRY rl_he;
199 if (history(h, &ev, op) != 0)
200 return NULL;
202 rl_he.line = ev.str;
203 rl_he.data = NULL;
205 return &rl_he;
210 * read one key from user defined input function
212 static int
213 /*ARGSUSED*/
214 _getc_function(EditLine *el __attribute__((__unused__)), wchar_t *c)
216 int i;
218 i = (*rl_getc_function)(NULL);
219 if (i == -1)
220 return 0;
221 *c = (wchar_t)i;
222 return 1;
225 static void
226 _resize_fun(EditLine *el, void *a)
228 const LineInfo *li;
229 char **ap = a;
231 li = el_line(el);
232 /* a cheesy way to get rid of const cast. */
233 *ap = memchr(li->buffer, *li->buffer, 1);
236 static const char _dothistory[] = "/.history";
238 static const char *
239 _default_history_file(void)
241 struct passwd *p;
242 static char path[PATH_MAX];
244 if (*path)
245 return path;
246 if ((p = getpwuid(getuid())) == NULL)
247 return NULL;
248 strlcpy(path, p->pw_dir, PATH_MAX);
249 strlcat(path, _dothistory, PATH_MAX);
250 return path;
254 * READLINE compatibility stuff
258 * Set the prompt
261 rl_set_prompt(const char *prompt)
263 char *p;
265 if (!prompt)
266 prompt = "";
267 if (rl_prompt != NULL && strcmp(rl_prompt, prompt) == 0)
268 return 0;
269 if (rl_prompt)
270 free(rl_prompt);
271 rl_prompt = strdup(prompt);
272 if (rl_prompt == NULL)
273 return -1;
275 while ((p = strchr(rl_prompt, RL_PROMPT_END_IGNORE)) != NULL)
276 *p = RL_PROMPT_START_IGNORE;
278 return 0;
282 * initialize rl compat stuff
285 rl_initialize(void)
287 HistEvent ev;
288 int editmode = 1;
289 struct termios t;
291 current_history_valid = 1;
293 if (e != NULL)
294 el_end(e);
295 if (h != NULL)
296 history_end(h);
298 if (!rl_instream)
299 rl_instream = stdin;
300 if (!rl_outstream)
301 rl_outstream = stdout;
304 * See if we don't really want to run the editor
306 if (tcgetattr(fileno(rl_instream), &t) != -1 && (t.c_lflag & ECHO) == 0)
307 editmode = 0;
309 e = el_init(rl_readline_name, rl_instream, rl_outstream, stderr);
311 if (!editmode)
312 el_set(e, EL_EDITMODE, 0);
314 h = history_init();
315 if (!e || !h)
316 return -1;
318 history(h, &ev, H_SETSIZE, INT_MAX); /* unlimited */
319 history_length = 0;
320 max_input_history = INT_MAX;
321 el_set(e, EL_HIST, history, h);
323 /* Setup resize function */
324 el_set(e, EL_RESIZE, _resize_fun, &rl_line_buffer);
326 /* setup getc function if valid */
327 if (rl_getc_function)
328 el_set(e, EL_GETCFN, _getc_function);
330 /* for proper prompt printing in readline() */
331 if (rl_set_prompt("") == -1) {
332 history_end(h);
333 el_end(e);
334 return -1;
336 el_set(e, EL_PROMPT, _get_prompt, RL_PROMPT_START_IGNORE);
337 el_set(e, EL_SIGNAL, rl_catch_signals);
339 /* set default mode to "emacs"-style and read setting afterwards */
340 /* so this can be overriden */
341 el_set(e, EL_EDITOR, "emacs");
342 if (rl_terminal_name != NULL)
343 el_set(e, EL_TERMINAL, rl_terminal_name);
344 else
345 el_get(e, EL_TERMINAL, &rl_terminal_name);
348 * Word completion - this has to go AFTER rebinding keys
349 * to emacs-style.
351 el_set(e, EL_ADDFN, "rl_complete",
352 "ReadLine compatible completion function",
353 _el_rl_complete);
354 el_set(e, EL_BIND, "^I", "rl_complete", NULL);
357 * Send TSTP when ^Z is pressed.
359 el_set(e, EL_ADDFN, "rl_tstp",
360 "ReadLine compatible suspend function",
361 _el_rl_tstp);
362 el_set(e, EL_BIND, "^Z", "rl_tstp", NULL);
364 /* read settings from configuration file */
365 el_source(e, NULL);
368 * Unfortunately, some applications really do use rl_point
369 * and rl_line_buffer directly.
371 _resize_fun(e, &rl_line_buffer);
372 _rl_update_pos();
374 if (rl_startup_hook)
375 (*rl_startup_hook)(NULL, 0);
377 return 0;
382 * read one line from input stream and return it, chomping
383 * trailing newline (if there is any)
385 char *
386 readline(const char *p)
388 HistEvent ev;
389 const char * volatile prompt = p;
390 int count;
391 const char *ret;
392 char *buf;
393 static int used_event_hook;
395 if (e == NULL || h == NULL)
396 rl_initialize();
398 rl_done = 0;
400 (void)setjmp(topbuf);
402 /* update prompt accordingly to what has been passed */
403 if (rl_set_prompt(prompt) == -1)
404 return NULL;
406 if (rl_pre_input_hook)
407 (*rl_pre_input_hook)(NULL, 0);
409 if (rl_event_hook && !(e->el_flags&NO_TTY)) {
410 el_set(e, EL_GETCFN, _rl_event_read_char);
411 used_event_hook = 1;
414 if (!rl_event_hook && used_event_hook) {
415 el_set(e, EL_GETCFN, EL_BUILTIN_GETCFN);
416 used_event_hook = 0;
419 rl_already_prompted = 0;
421 /* get one line from input stream */
422 ret = el_gets(e, &count);
424 if (ret && count > 0) {
425 int lastidx;
427 buf = strdup(ret);
428 if (buf == NULL)
429 return NULL;
430 lastidx = count - 1;
431 if (buf[lastidx] == '\n')
432 buf[lastidx] = '\0';
433 } else
434 buf = NULL;
436 history(h, &ev, H_GETSIZE);
437 history_length = ev.num;
439 return buf;
443 * history functions
447 * is normally called before application starts to use
448 * history expansion functions
450 void
451 using_history(void)
453 if (h == NULL || e == NULL)
454 rl_initialize();
459 * substitute ``what'' with ``with'', returning resulting string; if
460 * globally == 1, substitutes all occurrences of what, otherwise only the
461 * first one
463 static char *
464 _rl_compat_sub(const char *str, const char *what, const char *with,
465 int globally)
467 const char *s;
468 char *r, *result;
469 size_t len, with_len, what_len;
471 len = strlen(str);
472 with_len = strlen(with);
473 what_len = strlen(what);
475 /* calculate length we need for result */
476 s = str;
477 while (*s) {
478 if (*s == *what && !strncmp(s, what, what_len)) {
479 len += with_len - what_len;
480 if (!globally)
481 break;
482 s += what_len;
483 } else
484 s++;
486 r = result = malloc(len + 1);
487 if (result == NULL)
488 return NULL;
489 s = str;
490 while (*s) {
491 if (*s == *what && !strncmp(s, what, what_len)) {
492 (void)strncpy(r, with, with_len);
493 r += with_len;
494 s += what_len;
495 if (!globally) {
496 (void)strlcpy(r, s, len);
497 return result;
499 } else
500 *r++ = *s++;
502 *r = '\0';
503 return result;
506 static char *last_search_pat; /* last !?pat[?] search pattern */
507 static char *last_search_match; /* last !?pat[?] that matched */
509 const char *
510 get_history_event(const char *cmd, int *cindex, int qchar)
512 int idx, sign, sub, num, begin, ret;
513 size_t len;
514 char *pat;
515 const char *rptr;
516 HistEvent ev;
518 idx = *cindex;
519 if (cmd[idx++] != history_expansion_char)
520 return NULL;
522 /* find out which event to take */
523 if (cmd[idx] == history_expansion_char || cmd[idx] == '\0') {
524 if (history(h, &ev, H_FIRST) != 0)
525 return NULL;
526 *cindex = cmd[idx]? (idx + 1):idx;
527 return ev.str;
529 sign = 0;
530 if (cmd[idx] == '-') {
531 sign = 1;
532 idx++;
535 if ('0' <= cmd[idx] && cmd[idx] <= '9') {
536 HIST_ENTRY *rl_he;
538 num = 0;
539 while (cmd[idx] && '0' <= cmd[idx] && cmd[idx] <= '9') {
540 num = num * 10 + cmd[idx] - '0';
541 idx++;
543 if (sign)
544 num = history_length - num + 1;
546 if (!(rl_he = history_get(num)))
547 return NULL;
549 *cindex = idx;
550 return rl_he->line;
552 sub = 0;
553 if (cmd[idx] == '?') {
554 sub = 1;
555 idx++;
557 begin = idx;
558 while (cmd[idx]) {
559 if (cmd[idx] == '\n')
560 break;
561 if (sub && cmd[idx] == '?')
562 break;
563 if (!sub && (cmd[idx] == ':' || cmd[idx] == ' '
564 || cmd[idx] == '\t' || cmd[idx] == qchar))
565 break;
566 idx++;
568 len = idx - begin;
569 if (sub && cmd[idx] == '?')
570 idx++;
571 if (sub && len == 0 && last_search_pat && *last_search_pat)
572 pat = last_search_pat;
573 else if (len == 0)
574 return NULL;
575 else {
576 if ((pat = malloc(len + 1)) == NULL)
577 return NULL;
578 (void)strncpy(pat, cmd + begin, len);
579 pat[len] = '\0';
582 if (history(h, &ev, H_CURR) != 0) {
583 if (pat != last_search_pat)
584 free(pat);
585 return NULL;
587 num = ev.num;
589 if (sub) {
590 if (pat != last_search_pat) {
591 if (last_search_pat)
592 free(last_search_pat);
593 last_search_pat = pat;
595 ret = history_search(pat, -1);
596 } else
597 ret = history_search_prefix(pat, -1);
599 if (ret == -1) {
600 /* restore to end of list on failed search */
601 history(h, &ev, H_FIRST);
602 (void)fprintf(rl_outstream, "%s: Event not found\n", pat);
603 if (pat != last_search_pat)
604 free(pat);
605 return NULL;
608 if (sub && len) {
609 if (last_search_match && last_search_match != pat)
610 free(last_search_match);
611 last_search_match = pat;
614 if (pat != last_search_pat)
615 free(pat);
617 if (history(h, &ev, H_CURR) != 0)
618 return NULL;
619 *cindex = idx;
620 rptr = ev.str;
622 /* roll back to original position */
623 (void)history(h, &ev, H_SET, num);
625 return rptr;
629 * the real function doing history expansion - takes as argument command
630 * to do and data upon which the command should be executed
631 * does expansion the way I've understood readline documentation
633 * returns 0 if data was not modified, 1 if it was and 2 if the string
634 * should be only printed and not executed; in case of error,
635 * returns -1 and *result points to NULL
636 * it's the caller's responsibility to free() the string returned in *result
638 static int
639 _history_expand_command(const char *command, size_t offs, size_t cmdlen,
640 char **result)
642 char *tmp, *search = NULL, *aptr;
643 const char *ptr, *cmd;
644 static char *from = NULL, *to = NULL;
645 int start, end, idx, has_mods = 0;
646 int p_on = 0, g_on = 0;
648 *result = NULL;
649 aptr = NULL;
650 ptr = NULL;
652 /* First get event specifier */
653 idx = 0;
655 if (strchr(":^*$", command[offs + 1])) {
656 char str[4];
658 * "!:" is shorthand for "!!:".
659 * "!^", "!*" and "!$" are shorthand for
660 * "!!:^", "!!:*" and "!!:$" respectively.
662 str[0] = str[1] = '!';
663 str[2] = '0';
664 ptr = get_history_event(str, &idx, 0);
665 idx = (command[offs + 1] == ':')? 1:0;
666 has_mods = 1;
667 } else {
668 if (command[offs + 1] == '#') {
669 /* use command so far */
670 if ((aptr = malloc(offs + 1)) == NULL)
671 return -1;
672 (void)strncpy(aptr, command, offs);
673 aptr[offs] = '\0';
674 idx = 1;
675 } else {
676 int qchar;
678 qchar = (offs > 0 && command[offs - 1] == '"')? '"':0;
679 ptr = get_history_event(command + offs, &idx, qchar);
681 has_mods = command[offs + idx] == ':';
684 if (ptr == NULL && aptr == NULL)
685 return -1;
687 if (!has_mods) {
688 *result = strdup(aptr ? aptr : ptr);
689 if (aptr)
690 free(aptr);
691 if (*result == NULL)
692 return -1;
693 return 1;
696 cmd = command + offs + idx + 1;
698 /* Now parse any word designators */
700 if (*cmd == '%') /* last word matched by ?pat? */
701 tmp = strdup(last_search_match? last_search_match:"");
702 else if (strchr("^*$-0123456789", *cmd)) {
703 start = end = -1;
704 if (*cmd == '^')
705 start = end = 1, cmd++;
706 else if (*cmd == '$')
707 start = -1, cmd++;
708 else if (*cmd == '*')
709 start = 1, cmd++;
710 else if (*cmd == '-' || isdigit((unsigned char) *cmd)) {
711 start = 0;
712 while (*cmd && '0' <= *cmd && *cmd <= '9')
713 start = start * 10 + *cmd++ - '0';
715 if (*cmd == '-') {
716 if (isdigit((unsigned char) cmd[1])) {
717 cmd++;
718 end = 0;
719 while (*cmd && '0' <= *cmd && *cmd <= '9')
720 end = end * 10 + *cmd++ - '0';
721 } else if (cmd[1] == '$') {
722 cmd += 2;
723 end = -1;
724 } else {
725 cmd++;
726 end = -2;
728 } else if (*cmd == '*')
729 end = -1, cmd++;
730 else
731 end = start;
733 tmp = history_arg_extract(start, end, aptr? aptr:ptr);
734 if (tmp == NULL) {
735 (void)fprintf(rl_outstream, "%s: Bad word specifier",
736 command + offs + idx);
737 if (aptr)
738 free(aptr);
739 return -1;
741 } else
742 tmp = strdup(aptr? aptr:ptr);
744 if (aptr)
745 free(aptr);
747 if (*cmd == '\0' || ((size_t)(cmd - (command + offs)) >= cmdlen)) {
748 *result = tmp;
749 return 1;
752 for (; *cmd; cmd++) {
753 if (*cmd == ':')
754 continue;
755 else if (*cmd == 'h') { /* remove trailing path */
756 if ((aptr = strrchr(tmp, '/')) != NULL)
757 *aptr = '\0';
758 } else if (*cmd == 't') { /* remove leading path */
759 if ((aptr = strrchr(tmp, '/')) != NULL) {
760 aptr = strdup(aptr + 1);
761 free(tmp);
762 tmp = aptr;
764 } else if (*cmd == 'r') { /* remove trailing suffix */
765 if ((aptr = strrchr(tmp, '.')) != NULL)
766 *aptr = '\0';
767 } else if (*cmd == 'e') { /* remove all but suffix */
768 if ((aptr = strrchr(tmp, '.')) != NULL) {
769 aptr = strdup(aptr);
770 free(tmp);
771 tmp = aptr;
773 } else if (*cmd == 'p') /* print only */
774 p_on = 1;
775 else if (*cmd == 'g')
776 g_on = 2;
777 else if (*cmd == 's' || *cmd == '&') {
778 char *what, *with, delim;
779 size_t len, from_len;
780 size_t size;
782 if (*cmd == '&' && (from == NULL || to == NULL))
783 continue;
784 else if (*cmd == 's') {
785 delim = *(++cmd), cmd++;
786 size = 16;
787 what = realloc(from, size);
788 if (what == NULL) {
789 free(from);
790 free(tmp);
791 return 0;
793 len = 0;
794 for (; *cmd && *cmd != delim; cmd++) {
795 if (*cmd == '\\' && cmd[1] == delim)
796 cmd++;
797 if (len >= size) {
798 char *nwhat;
799 nwhat = reallocarray(what,
800 size, 2);
801 if (nwhat == NULL) {
802 free(what);
803 free(tmp);
804 return 0;
806 size *= 2;
807 what = nwhat;
809 what[len++] = *cmd;
811 what[len] = '\0';
812 from = what;
813 if (*what == '\0') {
814 free(what);
815 if (search) {
816 from = strdup(search);
817 if (from == NULL) {
818 free(tmp);
819 return 0;
821 } else {
822 from = NULL;
823 free(tmp);
824 return -1;
827 cmd++; /* shift after delim */
828 if (!*cmd)
829 continue;
831 size = 16;
832 with = realloc(to, size);
833 if (with == NULL) {
834 free(to);
835 free(tmp);
836 return -1;
838 len = 0;
839 from_len = strlen(from);
840 for (; *cmd && *cmd != delim; cmd++) {
841 if (len + from_len + 1 >= size) {
842 char *nwith;
843 size += from_len + 1;
844 nwith = realloc(with, size);
845 if (nwith == NULL) {
846 free(with);
847 free(tmp);
848 return -1;
850 with = nwith;
852 if (*cmd == '&') {
853 /* safe */
854 (void)strlcpy(&with[len], from,
855 size - len);
856 len += from_len;
857 continue;
859 if (*cmd == '\\'
860 && (*(cmd + 1) == delim
861 || *(cmd + 1) == '&'))
862 cmd++;
863 with[len++] = *cmd;
865 with[len] = '\0';
866 to = with;
869 aptr = _rl_compat_sub(tmp, from, to, g_on);
870 if (aptr) {
871 free(tmp);
872 tmp = aptr;
874 g_on = 0;
877 *result = tmp;
878 return p_on? 2:1;
883 * csh-style history expansion
886 history_expand(char *str, char **output)
888 int ret = 0;
889 size_t idx, i, size;
890 char *tmp, *result;
892 if (h == NULL || e == NULL)
893 rl_initialize();
895 if (history_expansion_char == 0) {
896 *output = strdup(str);
897 return 0;
900 *output = NULL;
901 if (str[0] == history_subst_char) {
902 /* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */
903 size_t sz = 4 + strlen(str) + 1;
904 *output = malloc(sz);
905 if (*output == NULL)
906 return 0;
907 (*output)[0] = (*output)[1] = history_expansion_char;
908 (*output)[2] = ':';
909 (*output)[3] = 's';
910 (void)strlcpy((*output) + 4, str, sz - 4);
911 str = *output;
912 } else {
913 *output = strdup(str);
914 if (*output == NULL)
915 return 0;
918 #define ADD_STRING(what, len, fr) \
920 if (idx + len + 1 > size) { \
921 char *nresult = realloc(result, (size += len + 1));\
922 if (nresult == NULL) { \
923 free(*output); \
924 if (/*CONSTCOND*/fr) \
925 free(tmp); \
926 return 0; \
928 result = nresult; \
930 (void)strncpy(&result[idx], what, len); \
931 idx += len; \
932 result[idx] = '\0'; \
935 result = NULL;
936 size = idx = 0;
937 tmp = NULL;
938 for (i = 0; str[i];) {
939 int qchar, loop_again;
940 size_t len, start, j;
942 qchar = 0;
943 loop_again = 1;
944 start = j = i;
945 loop:
946 for (; str[j]; j++) {
947 if (str[j] == '\\' &&
948 str[j + 1] == history_expansion_char) {
949 size_t sz = strlen(&str[j]) + 1;
950 (void)strlcpy(&str[j], &str[j + 1], sz);
951 continue;
953 if (!loop_again) {
954 if (isspace((unsigned char) str[j])
955 || str[j] == qchar)
956 break;
958 if (str[j] == history_expansion_char
959 && !strchr(history_no_expand_chars, str[j + 1])
960 && (!history_inhibit_expansion_function ||
961 (*history_inhibit_expansion_function)(str,
962 (int)j) == 0))
963 break;
966 if (str[j] && loop_again) {
967 i = j;
968 qchar = (j > 0 && str[j - 1] == '"' )? '"':0;
969 j++;
970 if (str[j] == history_expansion_char)
971 j++;
972 loop_again = 0;
973 goto loop;
975 len = i - start;
976 ADD_STRING(&str[start], len, 0);
978 if (str[i] == '\0' || str[i] != history_expansion_char) {
979 len = j - i;
980 ADD_STRING(&str[i], len, 0);
981 if (start == 0)
982 ret = 0;
983 else
984 ret = 1;
985 break;
987 ret = _history_expand_command (str, i, (j - i), &tmp);
988 if (ret > 0 && tmp) {
989 len = strlen(tmp);
990 ADD_STRING(tmp, len, 1);
992 if (tmp) {
993 free(tmp);
994 tmp = NULL;
996 i = j;
999 /* ret is 2 for "print only" option */
1000 if (ret == 2) {
1001 add_history(result);
1002 #ifdef GDB_411_HACK
1003 /* gdb 4.11 has been shipped with readline, where */
1004 /* history_expand() returned -1 when the line */
1005 /* should not be executed; in readline 2.1+ */
1006 /* it should return 2 in such a case */
1007 ret = -1;
1008 #endif
1010 free(*output);
1011 *output = result;
1013 return ret;
1017 * Return a string consisting of arguments of "str" from "start" to "end".
1019 char *
1020 history_arg_extract(int start, int end, const char *str)
1022 size_t i, len, max;
1023 char **arr, *result = NULL;
1025 arr = history_tokenize(str);
1026 if (!arr)
1027 return NULL;
1028 if (arr && *arr == NULL)
1029 goto out;
1031 for (max = 0; arr[max]; max++)
1032 continue;
1033 max--;
1035 if (start == '$')
1036 start = (int)max;
1037 if (end == '$')
1038 end = (int)max;
1039 if (end < 0)
1040 end = (int)max + end + 1;
1041 if (start < 0)
1042 start = end;
1044 if (start < 0 || end < 0 || (size_t)start > max ||
1045 (size_t)end > max || start > end)
1046 goto out;
1048 for (i = start, len = 0; i <= (size_t)end; i++)
1049 len += strlen(arr[i]) + 1;
1050 len++;
1051 max = len;
1052 result = malloc(len);
1053 if (result == NULL)
1054 goto out;
1056 for (i = start, len = 0; i <= (size_t)end; i++) {
1057 (void)strlcpy(result + len, arr[i], max - len);
1058 len += strlen(arr[i]);
1059 if (i < (size_t)end)
1060 result[len++] = ' ';
1062 result[len] = '\0';
1064 out:
1065 for (i = 0; arr[i]; i++)
1066 free(arr[i]);
1067 free(arr);
1069 return result;
1073 * Parse the string into individual tokens,
1074 * similar to how shell would do it.
1076 char **
1077 history_tokenize(const char *str)
1079 int size = 1, idx = 0, i, start;
1080 size_t len;
1081 char **result = NULL, *temp, delim = '\0';
1083 for (i = 0; str[i];) {
1084 while (isspace((unsigned char) str[i]))
1085 i++;
1086 start = i;
1087 for (; str[i];) {
1088 if (str[i] == '\\') {
1089 if (str[i+1] != '\0')
1090 i++;
1091 } else if (str[i] == delim)
1092 delim = '\0';
1093 else if (!delim &&
1094 (isspace((unsigned char) str[i]) ||
1095 strchr("()<>;&|$", str[i])))
1096 break;
1097 else if (!delim && strchr("'`\"", str[i]))
1098 delim = str[i];
1099 if (str[i])
1100 i++;
1103 if (idx + 2 >= size) {
1104 char **nresult;
1105 nresult = reallocarray(result, size,
1106 2 * sizeof(char *));
1107 if (nresult == NULL) {
1108 free(result);
1109 return NULL;
1111 size *= 2;
1112 result = nresult;
1114 len = i - start;
1115 temp = malloc(len + 1);
1116 if (temp == NULL) {
1117 for (i = 0; i < idx; i++)
1118 free(result[i]);
1119 free(result);
1120 return NULL;
1122 (void)strncpy(temp, &str[start], len);
1123 temp[len] = '\0';
1124 result[idx++] = temp;
1125 result[idx] = NULL;
1126 if (str[i])
1127 i++;
1129 return result;
1134 * limit size of history record to ``max'' events
1136 void
1137 stifle_history(int max)
1139 HistEvent ev;
1140 HIST_ENTRY *he;
1141 int i, len;
1143 if (h == NULL || e == NULL)
1144 rl_initialize();
1146 len = history_length;
1147 if (history(h, &ev, H_SETSIZE, max) == 0) {
1148 max_input_history = max;
1149 if (max < len)
1150 history_base += len - max;
1151 for (i = 0; i < len - max; i++) {
1152 he = remove_history(0);
1153 free(he->data);
1154 free((void *)he->line);
1155 free(he);
1162 * "unlimit" size of history - set the limit to maximum allowed int value
1165 unstifle_history(void)
1167 HistEvent ev;
1168 int omax;
1170 history(h, &ev, H_SETSIZE, INT_MAX);
1171 omax = max_input_history;
1172 max_input_history = INT_MAX;
1173 return omax; /* some value _must_ be returned */
1178 history_is_stifled(void)
1181 /* cannot return true answer */
1182 return max_input_history != INT_MAX;
1185 static const char _history_tmp_template[] = "/tmp/.historyXXXXXX";
1188 history_truncate_file (const char *filename, int nlines)
1190 int ret = 0;
1191 FILE *fp, *tp;
1192 char template[sizeof(_history_tmp_template)];
1193 char buf[4096];
1194 int fd;
1195 char *cp;
1196 off_t off;
1197 int count = 0;
1198 ssize_t left = 0;
1200 if (filename == NULL && (filename = _default_history_file()) == NULL)
1201 return errno;
1202 if ((fp = fopen(filename, "r+")) == NULL)
1203 return errno;
1204 strlcpy(template, _history_tmp_template, sizeof(template));
1205 if ((fd = mkstemp(template)) == -1) {
1206 ret = errno;
1207 goto out1;
1210 if ((tp = fdopen(fd, "r+")) == NULL) {
1211 close(fd);
1212 ret = errno;
1213 goto out2;
1216 for(;;) {
1217 if (fread(buf, sizeof(buf), 1, fp) != 1) {
1218 if (ferror(fp)) {
1219 ret = errno;
1220 break;
1222 if (fseeko(fp, (off_t)sizeof(buf) * count, SEEK_SET) ==
1223 (off_t)-1) {
1224 ret = errno;
1225 break;
1227 left = fread(buf, 1, sizeof(buf), fp);
1228 if (ferror(fp)) {
1229 ret = errno;
1230 break;
1232 if (left == 0) {
1233 count--;
1234 left = sizeof(buf);
1235 } else if (fwrite(buf, (size_t)left, 1, tp) != 1) {
1236 ret = errno;
1237 break;
1239 fflush(tp);
1240 break;
1242 if (fwrite(buf, sizeof(buf), 1, tp) != 1) {
1243 ret = errno;
1244 break;
1246 count++;
1248 if (ret)
1249 goto out3;
1250 cp = buf + left - 1;
1251 if(*cp != '\n')
1252 cp++;
1253 for(;;) {
1254 while (--cp >= buf) {
1255 if (*cp == '\n') {
1256 if (--nlines == 0) {
1257 if (++cp >= buf + sizeof(buf)) {
1258 count++;
1259 cp = buf;
1261 break;
1265 if (nlines <= 0 || count == 0)
1266 break;
1267 count--;
1268 if (fseeko(tp, (off_t)sizeof(buf) * count, SEEK_SET) < 0) {
1269 ret = errno;
1270 break;
1272 if (fread(buf, sizeof(buf), 1, tp) != 1) {
1273 if (ferror(tp)) {
1274 ret = errno;
1275 break;
1277 ret = EAGAIN;
1278 break;
1280 cp = buf + sizeof(buf);
1283 if (ret || nlines > 0)
1284 goto out3;
1286 if (fseeko(fp, 0, SEEK_SET) == (off_t)-1) {
1287 ret = errno;
1288 goto out3;
1291 if (fseeko(tp, (off_t)sizeof(buf) * count + (cp - buf), SEEK_SET) ==
1292 (off_t)-1) {
1293 ret = errno;
1294 goto out3;
1297 for(;;) {
1298 if ((left = fread(buf, 1, sizeof(buf), tp)) == 0) {
1299 if (ferror(fp))
1300 ret = errno;
1301 break;
1303 if (fwrite(buf, (size_t)left, 1, fp) != 1) {
1304 ret = errno;
1305 break;
1308 fflush(fp);
1309 if((off = ftello(fp)) > 0)
1310 (void)ftruncate(fileno(fp), off);
1311 out3:
1312 fclose(tp);
1313 out2:
1314 unlink(template);
1315 out1:
1316 fclose(fp);
1318 return ret;
1323 * read history from a file given
1326 read_history(const char *filename)
1328 HistEvent ev;
1330 if (h == NULL || e == NULL)
1331 rl_initialize();
1332 if (filename == NULL && (filename = _default_history_file()) == NULL)
1333 return errno;
1334 return history(h, &ev, H_LOAD, filename) == -1 ?
1335 (errno ? errno : EINVAL) : 0;
1340 * write history to a file given
1343 write_history(const char *filename)
1345 HistEvent ev;
1347 if (h == NULL || e == NULL)
1348 rl_initialize();
1349 if (filename == NULL && (filename = _default_history_file()) == NULL)
1350 return errno;
1351 return history(h, &ev, H_SAVE, filename) == -1 ?
1352 (errno ? errno : EINVAL) : 0;
1357 * returns history ``num''th event
1359 * returned pointer points to static variable
1361 HIST_ENTRY *
1362 history_get(int num)
1364 static HIST_ENTRY she;
1365 HistEvent ev;
1366 int curr_num;
1368 if (h == NULL || e == NULL)
1369 rl_initialize();
1371 if (num < history_base)
1372 return NULL;
1374 /* save current position */
1375 if (history(h, &ev, H_CURR) != 0)
1376 return NULL;
1377 curr_num = ev.num;
1380 * use H_DELDATA to set to nth history (without delete) by passing
1381 * (void **)-1 -- as in history_set_pos
1383 if (history(h, &ev, H_DELDATA, num - history_base, (void **)-1) != 0)
1384 goto out;
1386 /* get current entry */
1387 if (history(h, &ev, H_CURR) != 0)
1388 goto out;
1389 if (history(h, &ev, H_NEXT_EVDATA, ev.num, &she.data) != 0)
1390 goto out;
1391 she.line = ev.str;
1393 /* restore pointer to where it was */
1394 (void)history(h, &ev, H_SET, curr_num);
1396 return &she;
1398 out:
1399 /* restore pointer to where it was */
1400 (void)history(h, &ev, H_SET, curr_num);
1401 return NULL;
1406 * add the line to history table
1409 add_history(const char *line)
1411 HistEvent ev;
1413 if (h == NULL || e == NULL)
1414 rl_initialize();
1416 (void)history(h, &ev, H_ENTER, line);
1417 if (history(h, &ev, H_GETSIZE) == 0)
1418 history_length = ev.num;
1419 current_history_valid = 1;
1421 return !(history_length > 0); /* return 0 if all is okay */
1426 * remove the specified entry from the history list and return it.
1428 HIST_ENTRY *
1429 remove_history(int num)
1431 HIST_ENTRY *he;
1432 HistEvent ev;
1434 if (h == NULL || e == NULL)
1435 rl_initialize();
1437 if ((he = malloc(sizeof(*he))) == NULL)
1438 return NULL;
1440 if (history(h, &ev, H_DELDATA, num, &he->data) != 0) {
1441 free(he);
1442 return NULL;
1445 he->line = ev.str;
1446 if (history(h, &ev, H_GETSIZE) == 0)
1447 history_length = ev.num;
1449 return he;
1454 * replace the line and data of the num-th entry
1456 HIST_ENTRY *
1457 replace_history_entry(int num, const char *line, histdata_t data)
1459 HIST_ENTRY *he;
1460 HistEvent ev;
1461 int curr_num;
1463 if (h == NULL || e == NULL)
1464 rl_initialize();
1466 /* save current position */
1467 if (history(h, &ev, H_CURR) != 0)
1468 return NULL;
1469 curr_num = ev.num;
1471 /* start from the oldest */
1472 if (history(h, &ev, H_LAST) != 0)
1473 return NULL; /* error */
1475 if ((he = malloc(sizeof(*he))) == NULL)
1476 return NULL;
1478 /* look forwards for event matching specified offset */
1479 if (history(h, &ev, H_NEXT_EVDATA, num, &he->data))
1480 goto out;
1482 he->line = strdup(ev.str);
1483 if (he->line == NULL)
1484 goto out;
1486 if (history(h, &ev, H_REPLACE, line, data))
1487 goto out;
1489 /* restore pointer to where it was */
1490 if (history(h, &ev, H_SET, curr_num))
1491 goto out;
1493 return he;
1494 out:
1495 free(he);
1496 return NULL;
1500 * clear the history list - delete all entries
1502 void
1503 clear_history(void)
1505 HistEvent ev;
1507 (void)history(h, &ev, H_CLEAR);
1508 history_length = 0;
1509 current_history_valid = 1;
1514 * returns offset of the current history event
1517 where_history(void)
1519 HistEvent ev;
1520 int curr_num, off;
1522 if (history(h, &ev, H_CURR) != 0)
1523 return 0;
1524 curr_num = ev.num;
1526 /* start from the oldest */
1527 (void)history(h, &ev, H_LAST);
1529 /* position is zero-based */
1530 off = 0;
1531 while (ev.num != curr_num && history(h, &ev, H_PREV) == 0)
1532 off++;
1534 return off;
1539 * returns current history event or NULL if there is no such event
1541 HIST_ENTRY *
1542 current_history(void)
1545 return current_history_valid ? _move_history(H_CURR) : NULL;
1550 * returns total number of bytes history events' data are using
1553 history_total_bytes(void)
1555 HistEvent ev;
1556 int curr_num;
1557 size_t size;
1559 if (history(h, &ev, H_CURR) != 0)
1560 return -1;
1561 curr_num = ev.num;
1563 (void)history(h, &ev, H_FIRST);
1564 size = 0;
1566 size += strlen(ev.str) * sizeof(*ev.str);
1567 while (history(h, &ev, H_NEXT) == 0);
1569 /* get to the same position as before */
1570 history(h, &ev, H_PREV_EVENT, curr_num);
1572 return (int)size;
1577 * sets the position in the history list to ``pos''
1580 history_set_pos(int pos)
1582 HistEvent ev;
1583 int curr_num;
1585 if (pos >= history_length || pos < 0)
1586 return 0;
1588 (void)history(h, &ev, H_CURR);
1589 curr_num = ev.num;
1590 current_history_valid = 1;
1593 * use H_DELDATA to set to nth history (without delete) by passing
1594 * (void **)-1
1596 if (history(h, &ev, H_DELDATA, pos, (void **)-1)) {
1597 (void)history(h, &ev, H_SET, curr_num);
1598 return 0;
1600 return 1;
1605 * returns previous event in history and shifts pointer accordingly
1606 * Note that readline and editline define directions in opposite ways.
1608 HIST_ENTRY *
1609 previous_history(void)
1612 if (current_history_valid == 0) {
1613 current_history_valid = 1;
1614 return _move_history(H_CURR);
1616 return _move_history(H_NEXT);
1621 * returns next event in history and shifts pointer accordingly
1623 HIST_ENTRY *
1624 next_history(void)
1626 HIST_ENTRY *he;
1628 he = _move_history(H_PREV);
1629 if (he == NULL)
1630 current_history_valid = 0;
1631 return he;
1636 * searches for first history event containing the str
1639 history_search(const char *str, int direction)
1641 HistEvent ev;
1642 const char *strp;
1643 int curr_num;
1645 if (history(h, &ev, H_CURR) != 0)
1646 return -1;
1647 curr_num = ev.num;
1649 for (;;) {
1650 if ((strp = strstr(ev.str, str)) != NULL)
1651 return (int)(strp - ev.str);
1652 if (history(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0)
1653 break;
1655 (void)history(h, &ev, H_SET, curr_num);
1656 return -1;
1661 * searches for first history event beginning with str
1664 history_search_prefix(const char *str, int direction)
1666 HistEvent ev;
1668 return (history(h, &ev, direction < 0 ?
1669 H_PREV_STR : H_NEXT_STR, str));
1674 * search for event in history containing str, starting at offset
1675 * abs(pos); continue backward, if pos<0, forward otherwise
1677 /* ARGSUSED */
1679 history_search_pos(const char *str,
1680 int direction __attribute__((__unused__)), int pos)
1682 HistEvent ev;
1683 int curr_num, off;
1685 off = (pos > 0) ? pos : -pos;
1686 pos = (pos > 0) ? 1 : -1;
1688 if (history(h, &ev, H_CURR) != 0)
1689 return -1;
1690 curr_num = ev.num;
1692 if (!history_set_pos(off) || history(h, &ev, H_CURR) != 0)
1693 return -1;
1695 for (;;) {
1696 if (strstr(ev.str, str))
1697 return off;
1698 if (history(h, &ev, (pos < 0) ? H_PREV : H_NEXT) != 0)
1699 break;
1702 /* set "current" pointer back to previous state */
1703 (void)history(h, &ev,
1704 pos < 0 ? H_NEXT_EVENT : H_PREV_EVENT, curr_num);
1706 return -1;
1710 /********************************/
1711 /* completion functions */
1713 char *
1714 tilde_expand(char *name)
1716 return fn_tilde_expand(name);
1719 char *
1720 filename_completion_function(const char *name, int state)
1722 return fn_filename_completion_function(name, state);
1726 * a completion generator for usernames; returns _first_ username
1727 * which starts with supplied text
1728 * text contains a partial username preceded by random character
1729 * (usually '~'); state is ignored
1730 * it's the caller's responsibility to free the returned value
1732 char *
1733 username_completion_function(const char *text, int state)
1735 struct passwd *pwd;
1737 if (text[0] == '\0')
1738 return NULL;
1740 if (*text == '~')
1741 text++;
1743 if (state == 0)
1744 setpwent();
1746 while ((pwd = getpwent()) != NULL && text[0] == pwd->pw_name[0]
1747 && strcmp(text, pwd->pw_name) == 0);
1749 if (pwd == NULL) {
1750 endpwent();
1751 return NULL;
1753 return strdup(pwd->pw_name);
1758 * el-compatible wrapper to send TSTP on ^Z
1760 /* ARGSUSED */
1761 static unsigned char
1762 _el_rl_tstp(EditLine *el __attribute__((__unused__)), int ch __attribute__((__unused__)))
1764 (void)kill(0, SIGTSTP);
1765 return CC_NORM;
1769 * Display list of strings in columnar format on readline's output stream.
1770 * 'matches' is list of strings, 'len' is number of strings in 'matches',
1771 * 'max' is maximum length of string in 'matches'.
1773 void
1774 rl_display_match_list(char **matches, int len, int max)
1777 fn_display_match_list(e, matches, (size_t)len, (size_t)max);
1780 static const char *
1781 /*ARGSUSED*/
1782 _rl_completion_append_character_function(const char *dummy
1783 __attribute__((__unused__)))
1785 static char buf[2];
1786 buf[0] = rl_completion_append_character;
1787 buf[1] = '\0';
1788 return buf;
1793 * complete word at current point
1795 /* ARGSUSED */
1797 rl_complete(int ignore __attribute__((__unused__)), int invoking_key)
1799 static ct_buffer_t wbreak_conv, sprefix_conv;
1801 if (h == NULL || e == NULL)
1802 rl_initialize();
1804 if (rl_inhibit_completion) {
1805 char arr[2];
1806 arr[0] = (char)invoking_key;
1807 arr[1] = '\0';
1808 el_insertstr(e, arr);
1809 return CC_REFRESH;
1812 /* Just look at how many global variables modify this operation! */
1813 return fn_complete(e,
1814 (CPFunction *)rl_completion_entry_function,
1815 rl_attempted_completion_function,
1816 ct_decode_string(rl_basic_word_break_characters, &wbreak_conv),
1817 ct_decode_string(rl_special_prefixes, &sprefix_conv),
1818 _rl_completion_append_character_function,
1819 (size_t)rl_completion_query_items,
1820 &rl_completion_type, &rl_attempted_completion_over,
1821 &rl_point, &rl_end);
1827 /* ARGSUSED */
1828 static unsigned char
1829 _el_rl_complete(EditLine *el __attribute__((__unused__)), int ch)
1831 return (unsigned char)rl_complete(0, ch);
1835 * misc other functions
1839 * bind key c to readline-type function func
1842 rl_bind_key(int c, rl_command_func_t *func)
1844 int retval = -1;
1846 if (h == NULL || e == NULL)
1847 rl_initialize();
1849 if (func == rl_insert) {
1850 /* XXX notice there is no range checking of ``c'' */
1851 e->el_map.key[c] = ED_INSERT;
1852 retval = 0;
1854 return retval;
1859 * read one key from input - handles chars pushed back
1860 * to input stream also
1863 rl_read_key(void)
1865 char fooarr[2 * sizeof(int)];
1867 if (e == NULL || h == NULL)
1868 rl_initialize();
1870 return el_getc(e, fooarr);
1875 * reset the terminal
1877 /* ARGSUSED */
1878 void
1879 rl_reset_terminal(const char *p __attribute__((__unused__)))
1882 if (h == NULL || e == NULL)
1883 rl_initialize();
1884 el_reset(e);
1889 * insert character ``c'' back into input stream, ``count'' times
1892 rl_insert(int count, int c)
1894 char arr[2];
1896 if (h == NULL || e == NULL)
1897 rl_initialize();
1899 /* XXX - int -> char conversion can lose on multichars */
1900 arr[0] = c;
1901 arr[1] = '\0';
1903 for (; count > 0; count--)
1904 el_push(e, arr);
1906 return 0;
1910 rl_insert_text(const char *text)
1912 if (!text || *text == 0)
1913 return 0;
1915 if (h == NULL || e == NULL)
1916 rl_initialize();
1918 if (el_insertstr(e, text) < 0)
1919 return 0;
1920 return (int)strlen(text);
1923 /*ARGSUSED*/
1925 rl_newline(int count, int c)
1928 * Readline-4.0 appears to ignore the args.
1930 return rl_insert(1, '\n');
1933 /*ARGSUSED*/
1934 static unsigned char
1935 rl_bind_wrapper(EditLine *el, unsigned char c)
1937 if (map[c] == NULL)
1938 return CC_ERROR;
1940 _rl_update_pos();
1942 (*map[c])(NULL, c);
1944 /* If rl_done was set by the above call, deal with it here */
1945 if (rl_done)
1946 return CC_EOF;
1948 return CC_NORM;
1952 rl_add_defun(const char *name, Function *fun, int c)
1954 char dest[8];
1955 if ((size_t)c >= sizeof(map) / sizeof(map[0]) || c < 0)
1956 return -1;
1957 map[(unsigned char)c] = fun;
1958 el_set(e, EL_ADDFN, name, name, rl_bind_wrapper);
1959 vis(dest, c, VIS_WHITE|VIS_NOSLASH, 0);
1960 el_set(e, EL_BIND, dest, name, NULL);
1961 return 0;
1964 void
1965 rl_callback_read_char()
1967 int count = 0, done = 0;
1968 const char *buf = el_gets(e, &count);
1969 char *wbuf;
1971 if (buf == NULL || count-- <= 0)
1972 return;
1973 if (count == 0 && buf[0] == e->el_tty.t_c[TS_IO][C_EOF])
1974 done = 1;
1975 if (buf[count] == '\n' || buf[count] == '\r')
1976 done = 2;
1978 if (done && rl_linefunc != NULL) {
1979 el_set(e, EL_UNBUFFERED, 0);
1980 if (done == 2) {
1981 if ((wbuf = strdup(buf)) != NULL)
1982 wbuf[count] = '\0';
1983 } else
1984 wbuf = NULL;
1985 (*(void (*)(const char *))rl_linefunc)(wbuf);
1986 //el_set(e, EL_UNBUFFERED, 1);
1990 void
1991 rl_callback_handler_install(const char *prompt, VCPFunction *linefunc)
1993 if (e == NULL) {
1994 rl_initialize();
1996 (void)rl_set_prompt(prompt);
1997 rl_linefunc = linefunc;
1998 el_set(e, EL_UNBUFFERED, 1);
2001 void
2002 rl_callback_handler_remove(void)
2004 el_set(e, EL_UNBUFFERED, 0);
2005 rl_linefunc = NULL;
2008 void
2009 rl_redisplay(void)
2011 char a[2];
2012 a[0] = e->el_tty.t_c[TS_IO][C_REPRINT];
2013 a[1] = '\0';
2014 el_push(e, a);
2018 rl_get_previous_history(int count, int key)
2020 char a[2];
2021 a[0] = key;
2022 a[1] = '\0';
2023 while (count--)
2024 el_push(e, a);
2025 return 0;
2028 void
2029 /*ARGSUSED*/
2030 rl_prep_terminal(int meta_flag)
2032 el_set(e, EL_PREP_TERM, 1);
2035 void
2036 rl_deprep_terminal(void)
2038 el_set(e, EL_PREP_TERM, 0);
2042 rl_read_init_file(const char *s)
2044 return el_source(e, s);
2048 rl_parse_and_bind(const char *line)
2050 const char **argv;
2051 int argc;
2052 Tokenizer *tok;
2054 tok = tok_init(NULL);
2055 tok_str(tok, line, &argc, &argv);
2056 argc = el_parse(e, argc, argv);
2057 tok_end(tok);
2058 return argc ? 1 : 0;
2062 rl_variable_bind(const char *var, const char *value)
2065 * The proper return value is undocument, but this is what the
2066 * readline source seems to do.
2068 return el_set(e, EL_BIND, "", var, value, NULL) == -1 ? 1 : 0;
2071 void
2072 rl_stuff_char(int c)
2074 char buf[2];
2076 buf[0] = c;
2077 buf[1] = '\0';
2078 el_insertstr(e, buf);
2081 static int
2082 _rl_event_read_char(EditLine *el, wchar_t *wc)
2084 char ch;
2085 int n;
2086 ssize_t num_read = 0;
2088 ch = '\0';
2089 *wc = L'\0';
2090 while (rl_event_hook) {
2092 (*rl_event_hook)();
2094 #if defined(FIONREAD)
2095 if (ioctl(el->el_infd, FIONREAD, &n) < 0)
2096 return -1;
2097 if (n)
2098 num_read = read(el->el_infd, &ch, 1);
2099 else
2100 num_read = 0;
2101 #elif defined(F_SETFL) && defined(O_NDELAY)
2102 if ((n = fcntl(el->el_infd, F_GETFL)) < 0)
2103 return -1;
2104 if (fcntl(el->el_infd, F_SETFL, n|O_NDELAY) < 0)
2105 return -1;
2106 num_read = read(el->el_infd, &ch, 1);
2107 if (fcntl(el->el_infd, F_SETFL, n))
2108 return -1;
2109 #else
2110 /* not non-blocking, but what you gonna do? */
2111 num_read = read(el->el_infd, &ch, 1);
2112 return -1;
2113 #endif
2115 if (num_read < 0 && errno == EAGAIN)
2116 continue;
2117 if (num_read == 0)
2118 continue;
2119 break;
2121 if (!rl_event_hook)
2122 el_set(el, EL_GETCFN, EL_BUILTIN_GETCFN);
2123 *wc = (wchar_t)ch;
2124 return (int)num_read;
2127 static void
2128 _rl_update_pos(void)
2130 const LineInfo *li = el_line(e);
2132 rl_point = (int)(li->cursor - li->buffer);
2133 rl_end = (int)(li->lastchar - li->buffer);
2136 void
2137 rl_get_screen_size(int *rows, int *cols)
2139 if (rows)
2140 el_get(e, EL_GETTC, "li", rows);
2141 if (cols)
2142 el_get(e, EL_GETTC, "co", cols);
2145 void
2146 rl_set_screen_size(int rows, int cols)
2148 char buf[64];
2149 (void)snprintf(buf, sizeof(buf), "%d", rows);
2150 el_set(e, EL_SETTC, "li", buf, NULL);
2151 (void)snprintf(buf, sizeof(buf), "%d", cols);
2152 el_set(e, EL_SETTC, "co", buf, NULL);
2155 char **
2156 rl_completion_matches(const char *str, rl_compentry_func_t *fun)
2158 size_t len, max, i, j, min;
2159 char **list, *match, *a, *b;
2161 len = 1;
2162 max = 10;
2163 if ((list = reallocarray(NULL, max, sizeof(*list))) == NULL)
2164 return NULL;
2166 while ((match = (*fun)(str, (int)(len - 1))) != NULL) {
2167 list[len++] = match;
2168 if (len == max) {
2169 char **nl;
2170 max += 10;
2171 if ((nl = reallocarray(list, max, sizeof(*nl))) == NULL)
2172 goto out;
2173 list = nl;
2176 if (len == 1)
2177 goto out;
2178 list[len] = NULL;
2179 if (len == 2) {
2180 if ((list[0] = strdup(list[1])) == NULL)
2181 goto out;
2182 return list;
2184 qsort(&list[1], len - 1, sizeof(*list),
2185 (int (*)(const void *, const void *)) strcmp);
2186 min = SIZE_MAX;
2187 for (i = 1, a = list[i]; i < len - 1; i++, a = b) {
2188 b = list[i + 1];
2189 for (j = 0; a[j] && a[j] == b[j]; j++)
2190 continue;
2191 if (min > j)
2192 min = j;
2194 if (min == 0 && *str) {
2195 if ((list[0] = strdup(str)) == NULL)
2196 goto out;
2197 } else {
2198 if ((list[0] = malloc(min + 1)) == NULL)
2199 goto out;
2200 (void)memcpy(list[0], list[1], min);
2201 list[0][min] = '\0';
2203 return list;
2205 out:
2206 free(list);
2207 return NULL;
2210 char *
2211 rl_filename_completion_function (const char *text, int state)
2213 return fn_filename_completion_function(text, state);
2216 void
2217 rl_forced_update_display(void)
2219 el_set(e, EL_REFRESH);
2223 _rl_abort_internal(void)
2225 el_beep(e);
2226 longjmp(topbuf, 1);
2227 /*NOTREACHED*/
2231 _rl_qsort_string_compare(char **s1, char **s2)
2233 return strcoll(*s1, *s2);
2236 HISTORY_STATE *
2237 history_get_history_state(void)
2239 HISTORY_STATE *hs;
2241 if ((hs = malloc(sizeof(HISTORY_STATE))) == NULL)
2242 return NULL;
2243 hs->length = history_length;
2244 return hs;
2248 /*ARGSUSED*/
2249 rl_kill_text(int from, int to)
2251 return 0;
2254 Keymap
2255 rl_make_bare_keymap(void)
2257 return NULL;
2260 Keymap
2261 rl_get_keymap(void)
2263 return NULL;
2266 void
2267 /*ARGSUSED*/
2268 rl_set_keymap(Keymap k)
2273 /*ARGSUSED*/
2274 rl_generic_bind(int type, const char * keyseq, const char * data, Keymap k)
2276 return 0;
2280 /*ARGSUSED*/
2281 rl_bind_key_in_map(int key, rl_command_func_t *fun, Keymap k)
2283 return 0;
2286 /* unsupported, but needed by python */
2287 void
2288 rl_cleanup_after_signal(void)
2293 rl_on_new_line(void)
2295 return 0;
2299 /*ARGSUSED*/
2300 rl_set_keyboard_input_timeout(int u __attribute__((__unused__)))
2302 return 0;