1 /* $NetBSD: readline.c,v 1.21 2002/03/18 16:20:36 christos Exp $ */
4 * Copyright (c) 1997 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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.
40 #if !defined(lint) && !defined(SCCSID)
41 __RCSID("$NetBSD: readline.c,v 1.21 2002/03/18 16:20:36 christos Exp $");
42 #endif /* not lint && not SCCSID */
44 #include <sys/types.h>
60 #include "readline/readline.h"
62 #include "fcns.h" /* for EL_NUM_FCNS */
64 /* for rl_complete() */
67 /* see comment at the #ifdef for sense of this */
70 /* readline compatibility stuff - look at readline sources/documentation */
71 /* to see what these variables mean */
72 const char *rl_library_version
= "EditLine wrapper";
73 static char empty
[] = { '\0' };
74 static char expand_chars
[] = { ' ', '\t', '\n', '=', '(', '\0' };
75 static char break_chars
[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
76 '>', '<', '=', ';', '|', '&', '{', '(', '\0' };
77 char *rl_readline_name
= empty
;
78 FILE *rl_instream
= NULL
;
79 FILE *rl_outstream
= NULL
;
82 char *rl_line_buffer
= NULL
;
84 int history_base
= 1; /* probably never subject to change */
85 int history_length
= 0;
86 int max_input_history
= 0;
87 char history_expansion_char
= '!';
88 char history_subst_char
= '^';
89 char *history_no_expand_chars
= expand_chars
;
90 Function
*history_inhibit_expansion_function
= NULL
;
92 int rl_inhibit_completion
= 0;
93 int rl_attempted_completion_over
= 0;
94 char *rl_basic_word_break_characters
= break_chars
;
95 char *rl_completer_word_break_characters
= NULL
;
96 char *rl_completer_quote_characters
= NULL
;
97 CPFunction
*rl_completion_entry_function
= NULL
;
98 CPPFunction
*rl_attempted_completion_function
= NULL
;
101 * This is set to character indicating type of completion being done by
102 * rl_complete_internal(); this is available for application completion
105 int rl_completion_type
= 0;
108 * If more than this number of items results from query for possible
109 * completions, we ask user if they are sure to really display the list.
111 int rl_completion_query_items
= 100;
114 * List of characters which are word break characters, but should be left
115 * in the parsed text when it is passed to the completion function.
116 * Shell uses this to help determine what kind of completing to do.
118 char *rl_special_prefixes
= (char *)NULL
;
121 * This is the character appended to the completed words if at the end of
122 * the line. Default is ' ' (a space).
124 int rl_completion_append_character
= ' ';
126 /* stuff below is used internally by libedit for readline emulation */
128 /* if not zero, non-unique completions always show list of possible matches */
129 static int _rl_complete_show_all
= 0;
131 static History
*h
= NULL
;
132 static EditLine
*e
= NULL
;
133 static int el_rl_complete_cmdnum
= 0;
135 /* internal functions */
136 static unsigned char _el_rl_complete(EditLine
*, int);
137 static char *_get_prompt(EditLine
*);
138 static HIST_ENTRY
*_move_history(int);
139 static int _history_search_gen(const char *, int, int);
140 static int _history_expand_command(const char *, size_t, char **);
141 static char *_rl_compat_sub(const char *, const char *,
143 static int rl_complete_internal(int);
144 static int _rl_qsort_string_compare(const void *, const void *);
147 * needed for prompt switching in readline()
149 static char *el_rl_prompt
= NULL
;
154 _get_prompt(EditLine
*el
)
156 return (el_rl_prompt
);
161 * generic function for moving around history
164 _move_history(int op
)
167 static HIST_ENTRY rl_he
;
169 if (history(h
, &ev
, op
) != 0)
170 return (HIST_ENTRY
*) NULL
;
180 * READLINE compatibility stuff
184 * initialize rl compat stuff
203 rl_outstream
= stdout
;
206 * See if we don't really want to run the editor
208 if (tcgetattr(fileno(rl_instream
), &t
) != -1 && (t
.c_lflag
& ECHO
) == 0)
211 e
= el_init(rl_readline_name
, rl_instream
, rl_outstream
, stderr
);
214 el_set(e
, EL_EDITMODE
, 0);
220 history(h
, &ev
, H_SETSIZE
, INT_MAX
); /* unlimited */
222 max_input_history
= INT_MAX
;
223 el_set(e
, EL_HIST
, history
, h
);
225 /* for proper prompt printing in readline() */
226 el_rl_prompt
= strdup("");
227 el_set(e
, EL_PROMPT
, _get_prompt
);
228 el_set(e
, EL_SIGNAL
, 1);
230 /* set default mode to "emacs"-style and read setting afterwards */
231 /* so this can be overriden */
232 el_set(e
, EL_EDITOR
, "emacs");
235 * Word completition - this has to go AFTER rebinding keys
238 el_set(e
, EL_ADDFN
, "rl_complete",
239 "ReadLine compatible completition function",
241 el_set(e
, EL_BIND
, "^I", "rl_complete", NULL
);
244 * Find out where the rl_complete function was added; this is
245 * used later to detect that lastcmd was also rl_complete.
247 for(i
=EL_NUM_FCNS
; i
< e
->el_map
.nfunc
; i
++) {
248 if (e
->el_map
.func
[i
] == _el_rl_complete
) {
249 el_rl_complete_cmdnum
= i
;
254 /* read settings from configuration file */
258 * Unfortunately, some applications really do use rl_point
259 * and rl_line_buffer directly.
262 /* a cheesy way to get rid of const cast. */
263 rl_line_buffer
= memchr(li
->buffer
, *li
->buffer
, 1);
264 rl_point
= rl_end
= 0;
271 * read one line from input stream and return it, chomping
272 * trailing newline (if there is any)
275 readline(const char *prompt
)
282 if (e
== NULL
|| h
== NULL
)
285 /* update prompt accordingly to what has been passed */
288 if (strcmp(el_rl_prompt
, prompt
) != 0) {
290 el_rl_prompt
= strdup(prompt
);
292 /* get one line from input stream */
293 ret
= el_gets(e
, &count
);
295 if (ret
&& count
> 0) {
300 if (buf
[lastidx
] == '\n')
305 history(h
, &ev
, H_GETSIZE
);
306 history_length
= ev
.num
;
316 * is normally called before application starts to use
317 * history expansion functions
322 if (h
== NULL
|| e
== NULL
)
328 * substitute ``what'' with ``with'', returning resulting string; if
329 * globally == 1, substitutes all occurences of what, otherwise only the
333 _rl_compat_sub(const char *str
, const char *what
, const char *with
,
337 const char *temp
, *new;
338 int len
, with_len
, what_len
, add
;
341 result
= malloc((size
= 16));
343 with_len
= strlen(with
);
344 what_len
= strlen(what
);
347 new = strstr(temp
, what
);
351 if (i
+ add
+ 1 >= size
) {
353 result
= realloc(result
, size
);
355 (void) strncpy(&result
[len
], temp
, i
);
357 (void) strcpy(&result
[len
], with
); /* safe */
359 temp
= new + what_len
;
362 if (len
+ add
+ 1 >= size
) {
364 result
= realloc(result
, size
);
366 (void) strcpy(&result
[len
], temp
); /* safe */
370 } while (temp
&& globally
);
378 * the real function doing history expansion - takes as argument command
379 * to do and data upon which the command should be executed
380 * does expansion the way I've understood readline documentation
381 * word designator ``%'' isn't supported (yet ?)
383 * returns 0 if data was not modified, 1 if it was and 2 if the string
384 * should be only printed and not executed; in case of error,
385 * returns -1 and *result points to NULL
386 * it's callers responsibility to free() string returned in *result
389 _history_expand_command(const char *command
, size_t cmdlen
, char **result
)
391 char **arr
, *tempcmd
, *line
, *search
= NULL
, *cmd
;
392 const char *event_data
= NULL
;
393 static char *from
= NULL
, *to
= NULL
;
394 int start
= -1, end
= -1, max
, i
, idx
;
395 int h_on
= 0, t_on
= 0, r_on
= 0, e_on
= 0, p_on
= 0, g_on
= 0;
396 int event_num
= 0, retval
;
401 cmd
= alloca(cmdlen
+ 1);
402 (void) strncpy(cmd
, command
, cmdlen
);
406 /* find out which event to take */
407 if (cmd
[idx
] == history_expansion_char
) {
408 event_num
= history_length
;
414 while (cmd
[off
] && !strchr(":^$*-%", cmd
[off
]))
416 num
= atoi(&cmd
[idx
]);
420 event_num
+= history_length
+ 1;
422 int prefix
= 1, curr_num
;
426 if (cmd
[idx
] == '?') {
428 if (cmd
[off
- 1] == '?')
430 else if (cmd
[off
] != '\n' && cmd
[off
] != '\0')
434 search
= alloca(len
+ 1);
435 (void) strncpy(search
, &cmd
[idx
], len
);
438 if (history(h
, &ev
, H_CURR
) != 0)
443 retval
= history_search_prefix(search
, -1);
445 retval
= history_search(search
, -1);
448 fprintf(rl_outstream
, "%s: Event not found\n",
452 if (history(h
, &ev
, H_CURR
) != 0)
456 /* roll back to original position */
457 history(h
, &ev
, H_NEXT_EVENT
, curr_num
);
462 if (!event_data
&& event_num
>= 0) {
464 rl_he
= history_get(event_num
);
467 event_data
= rl_he
->line
;
477 start
= end
= 1, cmd
++;
478 else if (*cmd
== '$')
479 start
= end
= -1, cmd
++;
480 else if (*cmd
== '*')
481 start
= 1, end
= -1, cmd
++;
482 else if (isdigit((unsigned char) *cmd
)) {
488 for (; isdigit((unsigned char) *cmd
); cmd
++);
491 if (shifted
&& *cmd
== '-') {
492 if (!isdigit((unsigned char) *(cmd
+ 1)))
496 for (; isdigit((unsigned char) *cmd
); cmd
++);
498 } else if (shifted
&& *cmd
== '*')
506 line
= strdup(event_data
);
507 for (; *cmd
; cmd
++) {
510 else if (*cmd
== 'h')
511 h_on
= 1 | g_on
, g_on
= 0;
512 else if (*cmd
== 't')
513 t_on
= 1 | g_on
, g_on
= 0;
514 else if (*cmd
== 'r')
515 r_on
= 1 | g_on
, g_on
= 0;
516 else if (*cmd
== 'e')
517 e_on
= 1 | g_on
, g_on
= 0;
518 else if (*cmd
== 'p')
519 p_on
= 1 | g_on
, g_on
= 0;
520 else if (*cmd
== 'g')
522 else if (*cmd
== 's' || *cmd
== '&') {
523 char *what
, *with
, delim
;
527 if (*cmd
== '&' && (from
== NULL
|| to
== NULL
))
529 else if (*cmd
== 's') {
530 delim
= *(++cmd
), cmd
++;
532 what
= realloc(from
, size
);
534 for (; *cmd
&& *cmd
!= delim
; cmd
++) {
536 && *(cmd
+ 1) == delim
)
548 from
= strdup(search
);
554 cmd
++; /* shift after delim */
559 with
= realloc(to
, size
);
561 from_len
= strlen(from
);
562 for (; *cmd
&& *cmd
!= delim
; cmd
++) {
563 if (len
+ from_len
+ 1 >= size
) {
564 size
+= from_len
+ 1;
565 with
= realloc(with
, size
);
569 (void) strcpy(&with
[len
], from
);
574 && (*(cmd
+ 1) == delim
575 || *(cmd
+ 1) == '&'))
582 tempcmd
= _rl_compat_sub(line
, from
, to
,
591 arr
= history_tokenize(line
);
592 free(line
); /* no more needed */
593 if (arr
&& *arr
== NULL
)
594 free(arr
), arr
= NULL
;
598 /* find out max valid idx to array of array */
600 for (i
= 0; arr
[i
]; i
++)
604 /* set boundaries to something relevant */
608 end
= max
- ((end
< -1) ? 1 : 0);
610 /* check boundaries ... */
611 if (start
> max
|| end
> max
|| start
> end
)
614 for (i
= 0; i
<= max
; i
++) {
616 if (h_on
&& (i
== 1 || h_on
> 1) &&
617 (temp
= strrchr(arr
[i
], '/')))
619 if (t_on
&& (i
== 1 || t_on
> 1) &&
620 (temp
= strrchr(arr
[i
], '/')))
621 (void) strcpy(arr
[i
], temp
+ 1);
622 if (r_on
&& (i
== 1 || r_on
> 1) &&
623 (temp
= strrchr(arr
[i
], '.')))
625 if (e_on
&& (i
== 1 || e_on
> 1) &&
626 (temp
= strrchr(arr
[i
], '.')))
627 (void) strcpy(arr
[i
], temp
);
630 cmdsize
= 1, cmdlen
= 0;
631 tempcmd
= malloc(cmdsize
);
632 for (i
= start
; start
<= i
&& i
<= end
; i
++) {
635 arr_len
= strlen(arr
[i
]);
636 if (cmdlen
+ arr_len
+ 1 >= cmdsize
) {
637 cmdsize
+= arr_len
+ 1;
638 tempcmd
= realloc(tempcmd
, cmdsize
);
640 (void) strcpy(&tempcmd
[cmdlen
], arr
[i
]); /* safe */
642 tempcmd
[cmdlen
++] = ' '; /* add a space */
644 while (cmdlen
> 0 && isspace((unsigned char) tempcmd
[cmdlen
- 1]))
646 tempcmd
[cmdlen
] = '\0';
650 for (i
= 0; i
<= max
; i
++)
652 free(arr
), arr
= (char **) NULL
;
653 return (p_on
) ? 2 : 1;
658 * csh-style history expansion
661 history_expand(char *str
, char **output
)
663 int i
, retval
= 0, idx
;
667 if (h
== NULL
|| e
== NULL
)
670 *output
= strdup(str
); /* do it early */
672 if (str
[0] == history_subst_char
) {
673 /* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */
674 temp
= alloca(4 + strlen(str
) + 1);
675 temp
[0] = temp
[1] = history_expansion_char
;
678 (void) strcpy(temp
+ 4, str
);
681 #define ADD_STRING(what, len) \
683 if (idx + len + 1 > size) \
684 result = realloc(result, (size += len + 1)); \
685 (void)strncpy(&result[idx], what, len); \
687 result[idx] = '\0'; \
692 for (i
= 0; str
[i
];) {
693 int start
, j
, loop_again
;
699 for (; str
[j
]; j
++) {
700 if (str
[j
] == '\\' &&
701 str
[j
+ 1] == history_expansion_char
) {
702 (void) strcpy(&str
[j
], &str
[j
+ 1]);
707 while (str
[j
] && str
[++j
] != '?');
710 } else if (isspace((unsigned char) str
[j
]))
713 if (str
[j
] == history_expansion_char
714 && !strchr(history_no_expand_chars
, str
[j
+ 1])
715 && (!history_inhibit_expansion_function
||
716 (*history_inhibit_expansion_function
)(str
, j
) == 0))
720 if (str
[j
] && str
[j
+ 1] != '#' && loop_again
) {
723 if (str
[j
] == history_expansion_char
)
730 ADD_STRING(temp
, len
);
732 if (str
[i
] == '\0' || str
[i
] != history_expansion_char
733 || str
[i
+ 1] == '#') {
736 ADD_STRING(temp
, len
);
743 retval
= _history_expand_command(&str
[i
], (size_t) (j
- i
),
747 ADD_STRING(temp
, len
);
755 /* gdb 4.11 has been shipped with readline, where */
756 /* history_expand() returned -1 when the line */
757 /* should not be executed; in readline 2.1+ */
758 /* it should return 2 in such a case */
770 * Parse the string into individual tokens, similarily to how shell would do it.
773 history_tokenize(const char *str
)
775 int size
= 1, result_idx
= 0, i
, start
;
777 char **result
= NULL
, *temp
, delim
= '\0';
779 for (i
= 0; str
[i
]; i
++) {
780 while (isspace((unsigned char) str
[i
]))
783 for (; str
[i
]; i
++) {
784 if (str
[i
] == '\\') {
785 if (str
[i
+1] != '\0')
787 } else if (str
[i
] == delim
)
790 (isspace((unsigned char) str
[i
]) ||
791 strchr("()<>;&|$", str
[i
])))
793 else if (!delim
&& strchr("'`\"", str
[i
]))
797 if (result_idx
+ 2 >= size
) {
799 result
= realloc(result
, size
* sizeof(char *));
802 temp
= malloc(len
+ 1);
803 (void) strncpy(temp
, &str
[start
], len
);
805 result
[result_idx
++] = temp
;
806 result
[result_idx
] = NULL
;
814 * limit size of history record to ``max'' events
817 stifle_history(int max
)
821 if (h
== NULL
|| e
== NULL
)
824 if (history(h
, &ev
, H_SETSIZE
, max
) == 0)
825 max_input_history
= max
;
830 * "unlimit" size of history - set the limit to maximum allowed int value
833 unstifle_history(void)
838 history(h
, &ev
, H_SETSIZE
, INT_MAX
);
839 omax
= max_input_history
;
840 max_input_history
= INT_MAX
;
841 return (omax
); /* some value _must_ be returned */
846 history_is_stifled(void)
849 /* cannot return true answer */
850 return (max_input_history
!= INT_MAX
);
855 * read history from a file given
858 read_history(const char *filename
)
862 if (h
== NULL
|| e
== NULL
)
864 return (history(h
, &ev
, H_LOAD
, filename
));
869 * write history to a file given
872 write_history(const char *filename
)
876 if (h
== NULL
|| e
== NULL
)
878 return (history(h
, &ev
, H_SAVE
, filename
));
883 * returns history ``num''th event
885 * returned pointer points to static variable
890 static HIST_ENTRY she
;
894 if (h
== NULL
|| e
== NULL
)
897 /* rewind to beginning */
898 if (history(h
, &ev
, H_CURR
) != 0)
901 if (history(h
, &ev
, H_LAST
) != 0)
902 return (NULL
); /* error */
903 while (i
< num
&& history(h
, &ev
, H_PREV
) == 0)
906 return (NULL
); /* not so many entries */
911 /* rewind history to the same event it was before */
912 (void) history(h
, &ev
, H_FIRST
);
913 (void) history(h
, &ev
, H_NEXT_EVENT
, curr_num
);
920 * add the line to history table
923 add_history(const char *line
)
927 if (h
== NULL
|| e
== NULL
)
930 (void) history(h
, &ev
, H_ENTER
, line
);
931 if (history(h
, &ev
, H_GETSIZE
) == 0)
932 history_length
= ev
.num
;
934 return (!(history_length
> 0)); /* return 0 if all is okay */
939 * clear the history list - delete all entries
946 history(h
, &ev
, H_CLEAR
);
951 * returns offset of the current history event
959 if (history(h
, &ev
, H_CURR
) != 0)
963 history(h
, &ev
, H_FIRST
);
965 while (ev
.num
!= curr_num
&& history(h
, &ev
, H_NEXT
) == 0)
973 * returns current history event or NULL if there is no such event
976 current_history(void)
979 return (_move_history(H_CURR
));
984 * returns total number of bytes history events' data are using
987 history_total_bytes(void)
992 if (history(h
, &ev
, H_CURR
) != 0)
996 history(h
, &ev
, H_FIRST
);
999 size
+= strlen(ev
.str
);
1000 while (history(h
, &ev
, H_NEXT
) == 0);
1002 /* get to the same position as before */
1003 history(h
, &ev
, H_PREV_EVENT
, curr_num
);
1010 * sets the position in the history list to ``pos''
1013 history_set_pos(int pos
)
1018 if (pos
> history_length
|| pos
< 0)
1021 history(h
, &ev
, H_CURR
);
1023 history(h
, &ev
, H_FIRST
);
1025 while (off
< pos
&& history(h
, &ev
, H_NEXT
) == 0)
1028 if (off
!= pos
) { /* do a rollback in case of error */
1029 history(h
, &ev
, H_FIRST
);
1030 history(h
, &ev
, H_NEXT_EVENT
, curr_num
);
1038 * returns previous event in history and shifts pointer accordingly
1041 previous_history(void)
1044 return (_move_history(H_PREV
));
1049 * returns next event in history and shifts pointer accordingly
1055 return (_move_history(H_NEXT
));
1060 * generic history search function
1063 _history_search_gen(const char *str
, int direction
, int pos
)
1069 if (history(h
, &ev
, H_CURR
) != 0)
1074 strp
= strstr(ev
.str
, str
);
1075 if (strp
&& (pos
< 0 || &ev
.str
[pos
] == strp
))
1076 return (int) (strp
- ev
.str
);
1077 if (history(h
, &ev
, direction
< 0 ? H_PREV
: H_NEXT
) != 0)
1081 history(h
, &ev
, direction
< 0 ? H_NEXT_EVENT
: H_PREV_EVENT
, curr_num
);
1088 * searches for first history event containing the str
1091 history_search(const char *str
, int direction
)
1094 return (_history_search_gen(str
, direction
, -1));
1099 * searches for first history event beginning with str
1102 history_search_prefix(const char *str
, int direction
)
1105 return (_history_search_gen(str
, direction
, 0));
1110 * search for event in history containing str, starting at offset
1111 * abs(pos); continue backward, if pos<0, forward otherwise
1115 history_search_pos(const char *str
, int direction
, int pos
)
1120 off
= (pos
> 0) ? pos
: -pos
;
1121 pos
= (pos
> 0) ? 1 : -1;
1123 if (history(h
, &ev
, H_CURR
) != 0)
1127 if (history_set_pos(off
) != 0 || history(h
, &ev
, H_CURR
) != 0)
1132 if (strstr(ev
.str
, str
))
1134 if (history(h
, &ev
, (pos
< 0) ? H_PREV
: H_NEXT
) != 0)
1138 /* set "current" pointer back to previous state */
1139 history(h
, &ev
, (pos
< 0) ? H_NEXT_EVENT
: H_PREV_EVENT
, curr_num
);
1145 /********************************/
1146 /* completition functions */
1149 * does tilde expansion of strings of type ``~user/foo''
1150 * if ``user'' isn't valid user name or ``txt'' doesn't start
1151 * w/ '~', returns pointer to strdup()ed copy of ``txt''
1153 * it's callers's responsibility to free() returned string
1156 tilde_expand(char *txt
)
1158 struct passwd
*pass
;
1163 return (strdup(txt
));
1165 temp
= strchr(txt
+ 1, '/');
1167 temp
= strdup(txt
+ 1);
1169 len
= temp
- txt
+ 1; /* text until string after slash */
1171 (void) strncpy(temp
, txt
+ 1, len
- 2);
1172 temp
[len
- 2] = '\0';
1174 pass
= getpwnam(temp
);
1175 free(temp
); /* value no more needed */
1177 return (strdup(txt
));
1179 /* update pointer txt to point at string immedially following */
1183 temp
= malloc(strlen(pass
->pw_dir
) + 1 + strlen(txt
) + 1);
1184 (void) sprintf(temp
, "%s/%s", pass
->pw_dir
, txt
);
1191 * return first found file name starting by the ``text'' or NULL if no
1192 * such file can be found
1193 * value of ``state'' is ignored
1195 * it's caller's responsibility to free returned string
1198 filename_completion_function(const char *text
, int state
)
1200 static DIR *dir
= NULL
;
1201 static char *filename
= NULL
, *dirname
= NULL
;
1202 static size_t filename_len
= 0;
1203 struct dirent
*entry
;
1207 if (state
== 0 || dir
== NULL
) {
1212 temp
= strrchr(text
, '/');
1215 filename
= realloc(filename
, strlen(temp
) + 1);
1216 (void) strcpy(filename
, temp
);
1217 len
= temp
- text
; /* including last slash */
1218 dirname
= realloc(dirname
, len
+ 1);
1219 (void) strncpy(dirname
, text
, len
);
1220 dirname
[len
] = '\0';
1222 filename
= strdup(text
);
1226 /* support for ``~user'' syntax */
1227 if (dirname
&& *dirname
== '~') {
1228 temp
= tilde_expand(dirname
);
1229 dirname
= realloc(dirname
, strlen(temp
) + 1);
1230 (void) strcpy(dirname
, temp
); /* safe */
1231 free(temp
); /* no longer needed */
1233 /* will be used in cycle */
1234 filename_len
= strlen(filename
);
1235 if (filename_len
== 0)
1236 return (NULL
); /* no expansion possible */
1238 dir
= opendir(dirname
? dirname
: ".");
1240 return (NULL
); /* cannot open the directory */
1242 /* find the match */
1243 while ((entry
= readdir(dir
)) != NULL
) {
1244 /* otherwise, get first entry where first */
1245 /* filename_len characters are equal */
1246 if (entry
->d_name
[0] == filename
[0]
1247 #if defined(__SVR4) || defined(__linux__)
1248 && strlen(entry
->d_name
) >= filename_len
1250 && entry
->d_namlen
>= filename_len
1252 && strncmp(entry
->d_name
, filename
,
1257 if (entry
) { /* match found */
1260 #if defined(__SVR4) || defined(__linux__)
1261 len
= strlen(entry
->d_name
) +
1263 len
= entry
->d_namlen
+
1265 ((dirname
) ? strlen(dirname
) : 0) + 1 + 1;
1267 (void) sprintf(temp
, "%s%s",
1268 dirname
? dirname
: "", entry
->d_name
); /* safe */
1270 /* test, if it's directory */
1271 if (stat(temp
, &stbuf
) == 0 && S_ISDIR(stbuf
.st_mode
))
1272 strcat(temp
, "/"); /* safe */
1281 * a completion generator for usernames; returns _first_ username
1282 * which starts with supplied text
1283 * text contains a partial username preceded by random character
1284 * (usually '~'); state is ignored
1285 * it's callers responsibility to free returned value
1288 username_completion_function(const char *text
, int state
)
1292 if (text
[0] == '\0')
1301 while ((pwd
= getpwent()) && text
[0] == pwd
->pw_name
[0]
1302 && strcmp(text
, pwd
->pw_name
) == 0);
1308 return (strdup(pwd
->pw_name
));
1313 * el-compatible wrapper around rl_complete; needed for key binding
1316 static unsigned char
1317 _el_rl_complete(EditLine
*el
, int ch
)
1319 return (unsigned char) rl_complete(0, ch
);
1324 * returns list of completitions for text given
1327 completion_matches(const char *text
, CPFunction
*genfunc
)
1329 char **match_list
= NULL
, *retstr
, *prevstr
;
1330 size_t match_list_len
, max_equal
, which
, i
;
1333 if (h
== NULL
|| e
== NULL
)
1338 while ((retstr
= (*genfunc
) (text
, matches
)) != NULL
) {
1339 if (matches
+ 1 >= match_list_len
) {
1340 match_list_len
<<= 1;
1341 match_list
= realloc(match_list
,
1342 match_list_len
* sizeof(char *));
1344 match_list
[++matches
] = retstr
;
1348 return (char **) NULL
; /* nothing found */
1350 /* find least denominator and insert it to match_list[0] */
1352 prevstr
= match_list
[1];
1353 max_equal
= strlen(prevstr
);
1354 for (; which
<= matches
; which
++) {
1355 for (i
= 0; i
< max_equal
&&
1356 prevstr
[i
] == match_list
[which
][i
]; i
++)
1361 retstr
= malloc(max_equal
+ 1);
1362 (void) strncpy(retstr
, match_list
[1], max_equal
);
1363 retstr
[max_equal
] = '\0';
1364 match_list
[0] = retstr
;
1366 /* add NULL as last pointer to the array */
1367 if (matches
+ 1 >= match_list_len
)
1368 match_list
= realloc(match_list
,
1369 (match_list_len
+ 1) * sizeof(char *));
1370 match_list
[matches
+ 1] = (char *) NULL
;
1372 return (match_list
);
1376 * Sort function for qsort(). Just wrapper around strcasecmp().
1379 _rl_qsort_string_compare(i1
, i2
)
1380 const void *i1
, *i2
;
1382 /* LINTED const castaway */
1383 const char *s1
= ((const char **)i1
)[0];
1384 /* LINTED const castaway */
1385 const char *s2
= ((const char **)i2
)[0];
1387 return strcasecmp(s1
, s2
);
1391 * Display list of strings in columnar format on readline's output stream.
1392 * 'matches' is list of strings, 'len' is number of strings in 'matches',
1393 * 'max' is maximum length of string in 'matches'.
1396 rl_display_match_list (matches
, len
, max
)
1400 int i
, idx
, limit
, count
;
1401 int screenwidth
= e
->el_term
.t_size
.h
;
1404 * Find out how many entries can be put on one line, count
1405 * with two spaces between strings.
1407 limit
= screenwidth
/ (max
+ 2);
1411 /* how many lines of output */
1412 count
= len
/ limit
;
1413 if (count
* limit
< len
)
1416 /* Sort the items if they are not already sorted. */
1417 qsort(&matches
[1], (size_t)(len
- 1), sizeof(char *),
1418 _rl_qsort_string_compare
);
1421 for(; count
> 0; count
--) {
1422 for(i
=0; i
< limit
&& matches
[idx
]; i
++, idx
++)
1423 fprintf(e
->el_outfile
, "%-*s ", max
, matches
[idx
]);
1424 fprintf(e
->el_outfile
, "\n");
1429 * Complete the word at or before point, called by rl_complete()
1430 * 'what_to_do' says what to do with the completion.
1431 * `?' means list the possible completions.
1432 * TAB means do standard completion.
1433 * `*' means insert all of the possible completions.
1434 * `!' means to do standard completion, and list all possible completions if
1435 * there is more than one.
1437 * Note: '*' support is not implemented
1440 rl_complete_internal(int what_to_do
)
1442 CPFunction
*complet_func
;
1444 char *temp
, **matches
;
1448 rl_completion_type
= what_to_do
;
1450 if (h
== NULL
|| e
== NULL
)
1453 complet_func
= rl_completion_entry_function
;
1455 complet_func
= filename_completion_function
;
1457 /* We now look backwards for the start of a filename/variable word */
1459 ctemp
= (const char *) li
->cursor
;
1460 while (ctemp
> li
->buffer
1461 && !strchr(rl_basic_word_break_characters
, ctemp
[-1])
1462 && (!rl_special_prefixes
1463 || !strchr(rl_special_prefixes
, ctemp
[-1]) ) )
1466 len
= li
->cursor
- ctemp
;
1467 temp
= alloca(len
+ 1);
1468 (void) strncpy(temp
, ctemp
, len
);
1471 /* these can be used by function called in completion_matches() */
1472 /* or (*rl_attempted_completion_function)() */
1473 rl_point
= li
->cursor
- li
->buffer
;
1474 rl_end
= li
->lastchar
- li
->buffer
;
1476 if (!rl_attempted_completion_function
)
1477 matches
= completion_matches(temp
, complet_func
);
1479 int end
= li
->cursor
- li
->buffer
;
1480 matches
= (*rl_attempted_completion_function
) (temp
, (int)
1485 int i
, retval
= CC_REFRESH
;
1486 int matches_num
, maxlen
, match_len
, match_display
=1;
1489 * Only replace the completed string with common part of
1490 * possible matches if there is possible completion.
1492 if (matches
[0][0] != '\0') {
1493 el_deletestr(e
, (int) len
);
1494 el_insertstr(e
, matches
[0]);
1497 if (what_to_do
== '?')
1498 goto display_matches
;
1500 if (matches
[2] == NULL
&& strcmp(matches
[0], matches
[1]) == 0) {
1502 * We found exact match. Add a space after
1503 * it, unless we do filename completition and the
1504 * object is a directory.
1506 size_t alen
= strlen(matches
[0]);
1507 if ((complet_func
!= filename_completion_function
1508 || (alen
> 0 && (matches
[0])[alen
- 1] != '/'))
1509 && rl_completion_append_character
) {
1511 buf
[0] = rl_completion_append_character
;
1513 el_insertstr(e
, buf
);
1515 } else if (what_to_do
== '!') {
1518 * More than one match and requested to list possible
1522 for(i
=1, maxlen
=0; matches
[i
]; i
++) {
1523 match_len
= strlen(matches
[i
]);
1524 if (match_len
> maxlen
)
1527 matches_num
= i
- 1;
1529 /* newline to get on next line from command line */
1530 fprintf(e
->el_outfile
, "\n");
1533 * If there are too many items, ask user for display
1536 if (matches_num
> rl_completion_query_items
) {
1537 fprintf(e
->el_outfile
,
1538 "Display all %d possibilities? (y or n) ",
1540 fflush(e
->el_outfile
);
1541 if (getc(stdin
) != 'y')
1543 fprintf(e
->el_outfile
, "\n");
1547 rl_display_match_list(matches
, matches_num
,
1549 retval
= CC_REDISPLAY
;
1550 } else if (matches
[0][0]) {
1552 * There was some common match, but the name was
1553 * not complete enough. Next tab will print possible
1558 /* lcd is not a valid object - further specification */
1564 /* free elements of array and the array itself */
1565 for (i
= 0; matches
[i
]; i
++)
1567 free(matches
), matches
= NULL
;
1576 * complete word at current point
1579 rl_complete(int ignore
, int invoking_key
)
1581 if (h
== NULL
|| e
== NULL
)
1584 if (rl_inhibit_completion
) {
1585 rl_insert(ignore
, invoking_key
);
1586 return (CC_REFRESH
);
1587 } else if (e
->el_state
.lastcmd
== el_rl_complete_cmdnum
)
1588 return rl_complete_internal('?');
1589 else if (_rl_complete_show_all
)
1590 return rl_complete_internal('!');
1592 return (rl_complete_internal(TAB
));
1597 * misc other functions
1601 * bind key c to readline-type function func
1604 rl_bind_key(int c
, int func(int, int))
1608 if (h
== NULL
|| e
== NULL
)
1611 if (func
== rl_insert
) {
1612 /* XXX notice there is no range checking of ``c'' */
1613 e
->el_map
.key
[c
] = ED_INSERT
;
1621 * read one key from input - handles chars pushed back
1622 * to input stream also
1627 char fooarr
[2 * sizeof(int)];
1629 if (e
== NULL
|| h
== NULL
)
1632 return (el_getc(e
, fooarr
));
1637 * reset the terminal
1641 rl_reset_terminal(const char *p
)
1644 if (h
== NULL
|| e
== NULL
)
1651 * insert character ``c'' back into input stream, ``count'' times
1654 rl_insert(int count
, int c
)
1658 if (h
== NULL
|| e
== NULL
)
1661 /* XXX - int -> char conversion can lose on multichars */
1665 for (; count
> 0; count
--)