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