readline.c revision 1.49.2.4 1 /* $NetBSD: readline.c,v 1.49.2.4 2005/07/12 11:35:03 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.4 2005/07/12 11:35:03 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 pwres, *pass;
1382 char *temp;
1383 size_t len = 0;
1384 char pwbuf[1024];
1385
1386 if (txt[0] != '~')
1387 return (strdup(txt));
1388
1389 temp = strchr(txt + 1, '/');
1390 if (temp == NULL) {
1391 temp = strdup(txt + 1);
1392 if (temp == NULL)
1393 return NULL;
1394 } else {
1395 len = temp - txt + 1; /* text until string after slash */
1396 temp = malloc(len);
1397 if (temp == NULL)
1398 return NULL;
1399 (void)strncpy(temp, txt + 1, len - 2);
1400 temp[len - 2] = '\0';
1401 }
1402 if (getpwnam_r(temp, &pwres, pwbuf, sizeof(pwbuf), &pass) != 0)
1403 pass = NULL;
1404 free(temp); /* value no more needed */
1405 if (pass == NULL)
1406 return (strdup(txt));
1407
1408 /* update pointer txt to point at string immedially following */
1409 /* first slash */
1410 txt += len;
1411
1412 temp = malloc(strlen(pass->pw_dir) + 1 + strlen(txt) + 1);
1413 if (temp == NULL)
1414 return NULL;
1415 (void)sprintf(temp, "%s/%s", pass->pw_dir, txt);
1416
1417 return (temp);
1418 }
1419
1420
1421 /*
1422 * return first found file name starting by the ``text'' or NULL if no
1423 * such file can be found
1424 * value of ``state'' is ignored
1425 *
1426 * it's caller's responsibility to free returned string
1427 */
1428 char *
1429 filename_completion_function(const char *text, int state)
1430 {
1431 static DIR *dir = NULL;
1432 static char *filename = NULL, *dirname = NULL;
1433 static size_t filename_len = 0;
1434 struct dirent *entry;
1435 char *temp;
1436 size_t len;
1437
1438 if (state == 0 || dir == NULL) {
1439 temp = strrchr(text, '/');
1440 if (temp) {
1441 char *nptr;
1442 temp++;
1443 nptr = realloc(filename, strlen(temp) + 1);
1444 if (nptr == NULL) {
1445 free(filename);
1446 return NULL;
1447 }
1448 filename = nptr;
1449 (void)strcpy(filename, temp);
1450 len = temp - text; /* including last slash */
1451 nptr = realloc(dirname, len + 1);
1452 if (nptr == NULL) {
1453 free(filename);
1454 return NULL;
1455 }
1456 dirname = nptr;
1457 (void)strncpy(dirname, text, len);
1458 dirname[len] = '\0';
1459 } else {
1460 if (*text == 0)
1461 filename = NULL;
1462 else {
1463 filename = strdup(text);
1464 if (filename == NULL)
1465 return NULL;
1466 }
1467 dirname = NULL;
1468 }
1469
1470 /* support for ``~user'' syntax */
1471 if (dirname && *dirname == '~') {
1472 char *nptr;
1473 temp = tilde_expand(dirname);
1474 if (temp == NULL)
1475 return NULL;
1476 nptr = realloc(dirname, strlen(temp) + 1);
1477 if (nptr == NULL) {
1478 free(dirname);
1479 return NULL;
1480 }
1481 dirname = nptr;
1482 (void)strcpy(dirname, temp); /* safe */
1483 free(temp); /* no longer needed */
1484 }
1485 /* will be used in cycle */
1486 filename_len = filename ? strlen(filename) : 0;
1487
1488 if (dir != NULL) {
1489 (void)closedir(dir);
1490 dir = NULL;
1491 }
1492 dir = opendir(dirname ? dirname : ".");
1493 if (!dir)
1494 return (NULL); /* cannot open the directory */
1495 }
1496 /* find the match */
1497 while ((entry = readdir(dir)) != NULL) {
1498 /* skip . and .. */
1499 if (entry->d_name[0] == '.' && (!entry->d_name[1]
1500 || (entry->d_name[1] == '.' && !entry->d_name[2])))
1501 continue;
1502 if (filename_len == 0)
1503 break;
1504 /* otherwise, get first entry where first */
1505 /* filename_len characters are equal */
1506 if (entry->d_name[0] == filename[0]
1507 #if defined(__SVR4) || defined(__linux__)
1508 && strlen(entry->d_name) >= filename_len
1509 #else
1510 && entry->d_namlen >= filename_len
1511 #endif
1512 && strncmp(entry->d_name, filename,
1513 filename_len) == 0)
1514 break;
1515 }
1516
1517 if (entry) { /* match found */
1518
1519 struct stat stbuf;
1520 #if defined(__SVR4) || defined(__linux__)
1521 len = strlen(entry->d_name) +
1522 #else
1523 len = entry->d_namlen +
1524 #endif
1525 ((dirname) ? strlen(dirname) : 0) + 1 + 1;
1526 temp = malloc(len);
1527 if (temp == NULL)
1528 return NULL;
1529 (void)sprintf(temp, "%s%s",
1530 dirname ? dirname : "", entry->d_name); /* safe */
1531
1532 /* test, if it's directory */
1533 if (stat(temp, &stbuf) == 0 && S_ISDIR(stbuf.st_mode))
1534 strcat(temp, "/"); /* safe */
1535 } else {
1536 (void)closedir(dir);
1537 dir = NULL;
1538 temp = NULL;
1539 }
1540
1541 return (temp);
1542 }
1543
1544
1545 /*
1546 * a completion generator for usernames; returns _first_ username
1547 * which starts with supplied text
1548 * text contains a partial username preceded by random character
1549 * (usually '~'); state is ignored
1550 * it's callers responsibility to free returned value
1551 */
1552 char *
1553 username_completion_function(const char *text, int state)
1554 {
1555 struct passwd *pwd, pwres;
1556 char pwbuf[1024];
1557
1558 if (text[0] == '\0')
1559 return (NULL);
1560
1561 if (*text == '~')
1562 text++;
1563
1564 if (state == 0)
1565 setpwent();
1566
1567 while (getpwent_r(&pwres, pwbuf, sizeof(pwbuf), &pwd) == 0
1568 && pwd != NULL && text[0] == pwd->pw_name[0]
1569 && strcmp(text, pwd->pw_name) == 0);
1570
1571 if (pwd == NULL) {
1572 endpwent();
1573 return (NULL);
1574 }
1575 return (strdup(pwd->pw_name));
1576 }
1577
1578
1579 /*
1580 * el-compatible wrapper around rl_complete; needed for key binding
1581 */
1582 /* ARGSUSED */
1583 static unsigned char
1584 _el_rl_complete(EditLine *el __attribute__((__unused__)), int ch)
1585 {
1586 return (unsigned char) rl_complete(0, ch);
1587 }
1588
1589 /*
1590 * el-compatible wrapper to send TSTP on ^Z
1591 */
1592 /* ARGSUSED */
1593 static unsigned char
1594 _el_rl_tstp(EditLine *el __attribute__((__unused__)), int ch __attribute__((__unused__)))
1595 {
1596 (void)kill(0, SIGTSTP);
1597 return CC_NORM;
1598 }
1599
1600 /*
1601 * returns list of completions for text given
1602 */
1603 char **
1604 completion_matches(const char *text, CPFunction *genfunc)
1605 {
1606 char **match_list = NULL, *retstr, *prevstr;
1607 size_t match_list_len, max_equal, which, i;
1608 size_t matches;
1609
1610 if (h == NULL || e == NULL)
1611 rl_initialize();
1612
1613 matches = 0;
1614 match_list_len = 1;
1615 while ((retstr = (*genfunc) (text, (int)matches)) != NULL) {
1616 /* allow for list terminator here */
1617 if (matches + 3 >= match_list_len) {
1618 char **nmatch_list;
1619 while (matches + 3 >= match_list_len)
1620 match_list_len <<= 1;
1621 nmatch_list = realloc(match_list,
1622 match_list_len * sizeof(char *));
1623 if (nmatch_list == NULL) {
1624 free(match_list);
1625 return NULL;
1626 }
1627 match_list = nmatch_list;
1628
1629 }
1630 match_list[++matches] = retstr;
1631 }
1632
1633 if (!match_list)
1634 return NULL; /* nothing found */
1635
1636 /* find least denominator and insert it to match_list[0] */
1637 which = 2;
1638 prevstr = match_list[1];
1639 max_equal = strlen(prevstr);
1640 for (; which <= matches; which++) {
1641 for (i = 0; i < max_equal &&
1642 prevstr[i] == match_list[which][i]; i++)
1643 continue;
1644 max_equal = i;
1645 }
1646
1647 retstr = malloc(max_equal + 1);
1648 if (retstr == NULL) {
1649 free(match_list);
1650 return NULL;
1651 }
1652 (void)strncpy(retstr, match_list[1], max_equal);
1653 retstr[max_equal] = '\0';
1654 match_list[0] = retstr;
1655
1656 /* add NULL as last pointer to the array */
1657 match_list[matches + 1] = (char *) NULL;
1658
1659 return (match_list);
1660 }
1661
1662 /*
1663 * Sort function for qsort(). Just wrapper around strcasecmp().
1664 */
1665 static int
1666 _rl_qsort_string_compare(i1, i2)
1667 const void *i1, *i2;
1668 {
1669 const char *s1 = ((const char * const *)i1)[0];
1670 const char *s2 = ((const char * const *)i2)[0];
1671
1672 return strcasecmp(s1, s2);
1673 }
1674
1675 /*
1676 * Display list of strings in columnar format on readline's output stream.
1677 * 'matches' is list of strings, 'len' is number of strings in 'matches',
1678 * 'max' is maximum length of string in 'matches'.
1679 */
1680 void
1681 rl_display_match_list (matches, len, max)
1682 char **matches;
1683 int len, max;
1684 {
1685 int i, idx, limit, count;
1686 int screenwidth = e->el_term.t_size.h;
1687
1688 /*
1689 * Find out how many entries can be put on one line, count
1690 * with two spaces between strings.
1691 */
1692 limit = screenwidth / (max + 2);
1693 if (limit == 0)
1694 limit = 1;
1695
1696 /* how many lines of output */
1697 count = len / limit;
1698 if (count * limit < len)
1699 count++;
1700
1701 /* Sort the items if they are not already sorted. */
1702 qsort(&matches[1], (size_t)(len - 1), sizeof(char *),
1703 _rl_qsort_string_compare);
1704
1705 idx = 1;
1706 for(; count > 0; count--) {
1707 for(i = 0; i < limit && matches[idx]; i++, idx++)
1708 (void)fprintf(e->el_outfile, "%-*s ", max,
1709 matches[idx]);
1710 (void)fprintf(e->el_outfile, "\n");
1711 }
1712 }
1713
1714 /*
1715 * Complete the word at or before point, called by rl_complete()
1716 * 'what_to_do' says what to do with the completion.
1717 * `?' means list the possible completions.
1718 * TAB means do standard completion.
1719 * `*' means insert all of the possible completions.
1720 * `!' means to do standard completion, and list all possible completions if
1721 * there is more than one.
1722 *
1723 * Note: '*' support is not implemented
1724 */
1725 static int
1726 _rl_complete_internal(int what_to_do)
1727 {
1728 Function *complet_func;
1729 const LineInfo *li;
1730 char *temp, **matches;
1731 const char *ctemp;
1732 size_t len;
1733
1734 rl_completion_type = what_to_do;
1735
1736 if (h == NULL || e == NULL)
1737 rl_initialize();
1738
1739 complet_func = rl_completion_entry_function;
1740 if (!complet_func)
1741 complet_func = (Function *)(void *)filename_completion_function;
1742
1743 /* We now look backwards for the start of a filename/variable word */
1744 li = el_line(e);
1745 ctemp = (const char *) li->cursor;
1746 while (ctemp > li->buffer
1747 && !strchr(rl_basic_word_break_characters, ctemp[-1])
1748 && (!rl_special_prefixes
1749 || !strchr(rl_special_prefixes, ctemp[-1]) ) )
1750 ctemp--;
1751
1752 len = li->cursor - ctemp;
1753 temp = alloca(len + 1);
1754 (void)strncpy(temp, ctemp, len);
1755 temp[len] = '\0';
1756
1757 /* these can be used by function called in completion_matches() */
1758 /* or (*rl_attempted_completion_function)() */
1759 _rl_update_pos();
1760
1761 if (rl_attempted_completion_function) {
1762 int end = li->cursor - li->buffer;
1763 matches = (*rl_attempted_completion_function) (temp, (int)
1764 (end - len), end);
1765 } else
1766 matches = 0;
1767 if (!rl_attempted_completion_function || !matches)
1768 matches = completion_matches(temp, (CPFunction *)complet_func);
1769
1770 if (matches) {
1771 int i, retval = CC_REFRESH;
1772 int matches_num, maxlen, match_len, match_display=1;
1773
1774 /*
1775 * Only replace the completed string with common part of
1776 * possible matches if there is possible completion.
1777 */
1778 if (matches[0][0] != '\0') {
1779 el_deletestr(e, (int) len);
1780 el_insertstr(e, matches[0]);
1781 }
1782
1783 if (what_to_do == '?')
1784 goto display_matches;
1785
1786 if (matches[2] == NULL && strcmp(matches[0], matches[1]) == 0) {
1787 /*
1788 * We found exact match. Add a space after
1789 * it, unless we do filename completion and the
1790 * object is a directory.
1791 */
1792 size_t alen = strlen(matches[0]);
1793 if ((complet_func !=
1794 (Function *)filename_completion_function
1795 || (alen > 0 && (matches[0])[alen - 1] != '/'))
1796 && rl_completion_append_character) {
1797 char buf[2];
1798 buf[0] = rl_completion_append_character;
1799 buf[1] = '\0';
1800 el_insertstr(e, buf);
1801 }
1802 } else if (what_to_do == '!') {
1803 display_matches:
1804 /*
1805 * More than one match and requested to list possible
1806 * matches.
1807 */
1808
1809 for(i=1, maxlen=0; matches[i]; i++) {
1810 match_len = strlen(matches[i]);
1811 if (match_len > maxlen)
1812 maxlen = match_len;
1813 }
1814 matches_num = i - 1;
1815
1816 /* newline to get on next line from command line */
1817 (void)fprintf(e->el_outfile, "\n");
1818
1819 /*
1820 * If there are too many items, ask user for display
1821 * confirmation.
1822 */
1823 if (matches_num > rl_completion_query_items) {
1824 (void)fprintf(e->el_outfile,
1825 "Display all %d possibilities? (y or n) ",
1826 matches_num);
1827 (void)fflush(e->el_outfile);
1828 if (getc(stdin) != 'y')
1829 match_display = 0;
1830 (void)fprintf(e->el_outfile, "\n");
1831 }
1832
1833 if (match_display)
1834 rl_display_match_list(matches, matches_num,
1835 maxlen);
1836 retval = CC_REDISPLAY;
1837 } else if (matches[0][0]) {
1838 /*
1839 * There was some common match, but the name was
1840 * not complete enough. Next tab will print possible
1841 * completions.
1842 */
1843 el_beep(e);
1844 } else {
1845 /* lcd is not a valid object - further specification */
1846 /* is needed */
1847 el_beep(e);
1848 retval = CC_NORM;
1849 }
1850
1851 /* free elements of array and the array itself */
1852 for (i = 0; matches[i]; i++)
1853 free(matches[i]);
1854 free(matches), matches = NULL;
1855
1856 return (retval);
1857 }
1858 return (CC_NORM);
1859 }
1860
1861
1862 /*
1863 * complete word at current point
1864 */
1865 int
1866 /*ARGSUSED*/
1867 rl_complete(int ignore, int invoking_key)
1868 {
1869 if (h == NULL || e == NULL)
1870 rl_initialize();
1871
1872 if (rl_inhibit_completion) {
1873 char arr[2];
1874 arr[0] = (char)invoking_key;
1875 arr[1] = '\0';
1876 el_insertstr(e, arr);
1877 return (CC_REFRESH);
1878 } else if (e->el_state.lastcmd == el_rl_complete_cmdnum)
1879 return _rl_complete_internal('?');
1880 else if (_rl_complete_show_all)
1881 return _rl_complete_internal('!');
1882 else
1883 return _rl_complete_internal(TAB);
1884 }
1885
1886
1887 /*
1888 * misc other functions
1889 */
1890
1891 /*
1892 * bind key c to readline-type function func
1893 */
1894 int
1895 rl_bind_key(int c, int func(int, int))
1896 {
1897 int retval = -1;
1898
1899 if (h == NULL || e == NULL)
1900 rl_initialize();
1901
1902 if (func == rl_insert) {
1903 /* XXX notice there is no range checking of ``c'' */
1904 e->el_map.key[c] = ED_INSERT;
1905 retval = 0;
1906 }
1907 return (retval);
1908 }
1909
1910
1911 /*
1912 * read one key from input - handles chars pushed back
1913 * to input stream also
1914 */
1915 int
1916 rl_read_key(void)
1917 {
1918 char fooarr[2 * sizeof(int)];
1919
1920 if (e == NULL || h == NULL)
1921 rl_initialize();
1922
1923 return (el_getc(e, fooarr));
1924 }
1925
1926
1927 /*
1928 * reset the terminal
1929 */
1930 /* ARGSUSED */
1931 void
1932 rl_reset_terminal(const char *p __attribute__((__unused__)))
1933 {
1934
1935 if (h == NULL || e == NULL)
1936 rl_initialize();
1937 el_reset(e);
1938 }
1939
1940
1941 /*
1942 * insert character ``c'' back into input stream, ``count'' times
1943 */
1944 int
1945 rl_insert(int count, int c)
1946 {
1947 char arr[2];
1948
1949 if (h == NULL || e == NULL)
1950 rl_initialize();
1951
1952 /* XXX - int -> char conversion can lose on multichars */
1953 arr[0] = c;
1954 arr[1] = '\0';
1955
1956 for (; count > 0; count--)
1957 el_push(e, arr);
1958
1959 return (0);
1960 }
1961
1962 /*ARGSUSED*/
1963 int
1964 rl_newline(int count, int c)
1965 {
1966 /*
1967 * Readline-4.0 appears to ignore the args.
1968 */
1969 return rl_insert(1, '\n');
1970 }
1971
1972 /*ARGSUSED*/
1973 static unsigned char
1974 rl_bind_wrapper(EditLine *el, unsigned char c)
1975 {
1976 if (map[c] == NULL)
1977 return CC_ERROR;
1978
1979 _rl_update_pos();
1980
1981 (*map[c])(NULL, c);
1982
1983 /* If rl_done was set by the above call, deal with it here */
1984 if (rl_done)
1985 return CC_EOF;
1986
1987 return CC_NORM;
1988 }
1989
1990 int
1991 rl_add_defun(const char *name, Function *fun, int c)
1992 {
1993 char dest[8];
1994 if (c >= sizeof(map) / sizeof(map[0]) || c < 0)
1995 return -1;
1996 map[(unsigned char)c] = fun;
1997 el_set(e, EL_ADDFN, name, name, rl_bind_wrapper);
1998 vis(dest, c, VIS_WHITE|VIS_NOSLASH, 0);
1999 el_set(e, EL_BIND, dest, name);
2000 return 0;
2001 }
2002
2003 void
2004 rl_callback_read_char()
2005 {
2006 int count = 0, done = 0;
2007 const char *buf = el_gets(e, &count);
2008 char *wbuf;
2009
2010 if (buf == NULL || count-- <= 0)
2011 return;
2012 if (count == 0 && buf[0] == CTRL('d'))
2013 done = 1;
2014 if (buf[count] == '\n' || buf[count] == '\r')
2015 done = 2;
2016
2017 if (done && rl_linefunc != NULL) {
2018 el_set(e, EL_UNBUFFERED, 0);
2019 if (done == 2) {
2020 if ((wbuf = strdup(buf)) != NULL)
2021 wbuf[count] = '\0';
2022 } else
2023 wbuf = NULL;
2024 (*(void (*)(const char *))rl_linefunc)(wbuf);
2025 el_set(e, EL_UNBUFFERED, 1);
2026 }
2027 }
2028
2029 void
2030 rl_callback_handler_install (const char *prompt, VCPFunction *linefunc)
2031 {
2032 if (e == NULL) {
2033 rl_initialize();
2034 }
2035 if (rl_prompt)
2036 free(rl_prompt);
2037 rl_prompt = prompt ? strdup(strchr(prompt, *prompt)) : NULL;
2038 rl_linefunc = linefunc;
2039 el_set(e, EL_UNBUFFERED, 1);
2040 }
2041
2042 void
2043 rl_callback_handler_remove(void)
2044 {
2045 el_set(e, EL_UNBUFFERED, 0);
2046 }
2047
2048 void
2049 rl_redisplay(void)
2050 {
2051 char a[2];
2052 a[0] = CTRL('r');
2053 a[1] = '\0';
2054 el_push(e, a);
2055 }
2056
2057 int
2058 rl_get_previous_history(int count, int key)
2059 {
2060 char a[2];
2061 a[0] = key;
2062 a[1] = '\0';
2063 while (count--)
2064 el_push(e, a);
2065 return 0;
2066 }
2067
2068 void
2069 /*ARGSUSED*/
2070 rl_prep_terminal(int meta_flag)
2071 {
2072 el_set(e, EL_PREP_TERM, 1);
2073 }
2074
2075 void
2076 rl_deprep_terminal()
2077 {
2078 el_set(e, EL_PREP_TERM, 0);
2079 }
2080
2081 int
2082 rl_read_init_file(const char *s)
2083 {
2084 return(el_source(e, s));
2085 }
2086
2087 int
2088 rl_parse_and_bind(const char *line)
2089 {
2090 const char **argv;
2091 int argc;
2092 Tokenizer *tok;
2093
2094 tok = tok_init(NULL);
2095 tok_str(tok, line, &argc, &argv);
2096 argc = el_parse(e, argc, argv);
2097 tok_end(tok);
2098 return (argc ? 1 : 0);
2099 }
2100
2101 void
2102 rl_stuff_char(int c)
2103 {
2104 char buf[2];
2105
2106 buf[0] = c;
2107 buf[1] = '\0';
2108 el_insertstr(e, buf);
2109 }
2110
2111 static int
2112 _rl_event_read_char(EditLine *el, char *cp)
2113 {
2114 int n, num_read = 0;
2115
2116 *cp = 0;
2117 while (rl_event_hook) {
2118
2119 (*rl_event_hook)();
2120
2121 #if defined(FIONREAD)
2122 if (ioctl(el->el_infd, FIONREAD, &n) < 0)
2123 return(-1);
2124 if (n)
2125 num_read = read(el->el_infd, cp, 1);
2126 else
2127 num_read = 0;
2128 #elif defined(F_SETFL) && defined(O_NDELAY)
2129 if ((n = fcntl(el->el_infd, F_GETFL, 0)) < 0)
2130 return(-1);
2131 if (fcntl(el->el_infd, F_SETFL, n|O_NDELAY) < 0)
2132 return(-1);
2133 num_read = read(el->el_infd, cp, 1);
2134 if (fcntl(el->el_infd, F_SETFL, n))
2135 return(-1);
2136 #else
2137 /* not non-blocking, but what you gonna do? */
2138 num_read = read(el->el_infd, cp, 1);
2139 return(-1);
2140 #endif
2141
2142 if (num_read < 0 && errno == EAGAIN)
2143 continue;
2144 if (num_read == 0)
2145 continue;
2146 break;
2147 }
2148 if (!rl_event_hook)
2149 el_set(el, EL_GETCFN, EL_BUILTIN_GETCFN);
2150 return(num_read);
2151 }
2152
2153 static void
2154 _rl_update_pos(void)
2155 {
2156 const LineInfo *li = el_line(e);
2157
2158 rl_point = li->cursor - li->buffer;
2159 rl_end = li->lastchar - li->buffer;
2160 }
2161