Line data Source code
1 : /* bashline.c -- Bash's interface to the readline library. */
2 :
3 : /* Copyright (C) 1987-2016 Free Software Foundation, Inc.
4 :
5 : This file is part of GNU Bash, the Bourne Again SHell.
6 :
7 : Bash is free software: you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation, either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : Bash is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with Bash. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include "config.h"
22 :
23 : #if defined (READLINE)
24 :
25 : #include "bashtypes.h"
26 : #include "posixstat.h"
27 :
28 : #if defined (HAVE_UNISTD_H)
29 : # include <unistd.h>
30 : #endif
31 :
32 : #if defined (HAVE_GRP_H)
33 : # include <grp.h>
34 : #endif
35 :
36 : #if defined (HAVE_NETDB_H)
37 : # include <netdb.h>
38 : #endif
39 :
40 : #include <signal.h>
41 :
42 : #include <stdio.h>
43 : #include "chartypes.h"
44 : #include "bashansi.h"
45 : #include "bashintl.h"
46 :
47 : #include "shell.h"
48 : #include "input.h"
49 : #include "builtins.h"
50 : #include "bashhist.h"
51 : #include "bashline.h"
52 : #include "execute_cmd.h"
53 : #include "findcmd.h"
54 : #include "pathexp.h"
55 : #include "shmbutil.h"
56 : #include "trap.h"
57 : #include "flags.h"
58 :
59 : #if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR)
60 : # include <mbstr.h> /* mbschr */
61 : #endif
62 :
63 : #include "builtins/common.h"
64 :
65 : #include <readline/rlconf.h>
66 : #include <readline/readline.h>
67 : #include <readline/history.h>
68 :
69 : #include <glob/glob.h>
70 :
71 : #if defined (ALIAS)
72 : # include "alias.h"
73 : #endif
74 :
75 : #if defined (PROGRAMMABLE_COMPLETION)
76 : # include "pcomplete.h"
77 : #endif
78 :
79 : /* These should agree with the defines for emacs_mode and vi_mode in
80 : rldefs.h, even though that's not a public readline header file. */
81 : #ifndef EMACS_EDITING_MODE
82 : # define NO_EDITING_MODE -1
83 : # define EMACS_EDITING_MODE 1
84 : # define VI_EDITING_MODE 0
85 : #endif
86 :
87 : #define RL_BOOLEAN_VARIABLE_VALUE(s) ((s)[0] == 'o' && (s)[1] == 'n' && (s)[2] == '\0')
88 :
89 : #if defined (BRACE_COMPLETION)
90 : extern int bash_brace_completion __P((int, int));
91 : #endif /* BRACE_COMPLETION */
92 :
93 : /* To avoid including curses.h/term.h/termcap.h and that whole mess. */
94 : #ifdef _MINIX
95 : extern int tputs __P((const char *string, int nlines, void (*outx)(int)));
96 : #else
97 : extern int tputs __P((const char *string, int nlines, int (*outx)(int)));
98 : #endif
99 :
100 : /* Forward declarations */
101 :
102 : /* Functions bound to keys in Readline for Bash users. */
103 : static int shell_expand_line __P((int, int));
104 : static int display_shell_version __P((int, int));
105 : static int operate_and_get_next __P((int, int));
106 :
107 : static int bash_ignore_filenames __P((char **));
108 : static int bash_ignore_everything __P((char **));
109 :
110 : #if defined (BANG_HISTORY)
111 : static char *history_expand_line_internal __P((char *));
112 : static int history_expand_line __P((int, int));
113 : static int tcsh_magic_space __P((int, int));
114 : #endif /* BANG_HISTORY */
115 : #ifdef ALIAS
116 : static int alias_expand_line __P((int, int));
117 : #endif
118 : #if defined (BANG_HISTORY) && defined (ALIAS)
119 : static int history_and_alias_expand_line __P((int, int));
120 : #endif
121 :
122 : static int bash_forward_shellword __P((int, int));
123 : static int bash_backward_shellword __P((int, int));
124 : static int bash_kill_shellword __P((int, int));
125 : static int bash_backward_kill_shellword __P((int, int));
126 :
127 : /* Helper functions for Readline. */
128 : static char *restore_tilde __P((char *, char *));
129 : static char *maybe_restore_tilde __P((char *, char *));
130 :
131 : static char *bash_filename_rewrite_hook __P((char *, int));
132 :
133 : static void bash_directory_expansion __P((char **));
134 : static int bash_filename_stat_hook __P((char **));
135 : static int bash_command_name_stat_hook __P((char **));
136 : static int bash_directory_completion_hook __P((char **));
137 : static int filename_completion_ignore __P((char **));
138 : static int bash_push_line __P((void));
139 :
140 : static int executable_completion __P((const char *, int));
141 :
142 : static rl_icppfunc_t *save_directory_hook __P((void));
143 : static void restore_directory_hook __P((rl_icppfunc_t));
144 :
145 : static int directory_exists __P((const char *, int));
146 :
147 : static void cleanup_expansion_error __P((void));
148 : static void maybe_make_readline_line __P((char *));
149 : static void set_up_new_line __P((char *));
150 :
151 : static int check_redir __P((int));
152 : static char **attempt_shell_completion __P((const char *, int, int));
153 : static char *variable_completion_function __P((const char *, int));
154 : static char *hostname_completion_function __P((const char *, int));
155 : static char *command_subst_completion_function __P((const char *, int));
156 :
157 : static void build_history_completion_array __P((void));
158 : static char *history_completion_generator __P((const char *, int));
159 : static int dynamic_complete_history __P((int, int));
160 : static int bash_dabbrev_expand __P((int, int));
161 :
162 : static void initialize_hostname_list __P((void));
163 : static void add_host_name __P((char *));
164 : static void snarf_hosts_from_file __P((char *));
165 : static char **hostnames_matching __P((char *));
166 :
167 : static void _ignore_completion_names __P((char **, sh_ignore_func_t *));
168 : static int name_is_acceptable __P((const char *));
169 : static int test_for_directory __P((const char *));
170 : static int return_zero __P((const char *));
171 :
172 : static char *bash_dequote_filename __P((char *, int));
173 : static char *quote_word_break_chars __P((char *));
174 : static void set_filename_bstab __P((const char *));
175 : static char *bash_quote_filename __P((char *, int, char *));
176 :
177 : #if 0
178 : #ifdef _MINIX
179 : static void putx __P((int));
180 : #else
181 : static int putx __P((int));
182 : #endif
183 : #endif
184 : static int bash_execute_unix_command __P((int, int));
185 : static void init_unix_command_map __P((void));
186 : static int isolate_sequence __P((char *, int, int, int *));
187 :
188 : static int set_saved_history __P((void));
189 :
190 : #if defined (ALIAS)
191 : static int posix_edit_macros __P((int, int));
192 : #endif
193 :
194 : static int bash_event_hook __P((void));
195 :
196 : #if defined (PROGRAMMABLE_COMPLETION)
197 : static int find_cmd_start __P((int));
198 : static int find_cmd_end __P((int));
199 : static char *find_cmd_name __P((int, int *, int *));
200 : static char *prog_complete_return __P((const char *, int));
201 :
202 : static char **prog_complete_matches;
203 : #endif
204 :
205 : /* Variables used here but defined in other files. */
206 : #if defined (BANG_HISTORY)
207 : extern int hist_verify;
208 : #endif
209 :
210 : extern int current_command_line_count, saved_command_line_count;
211 : extern int last_command_exit_value;
212 : extern int array_needs_making;
213 : extern int posixly_correct, no_symbolic_links;
214 : extern int sigalrm_seen;
215 : extern char *current_prompt_string, *ps1_prompt;
216 : extern STRING_INT_ALIST word_token_alist[];
217 : extern sh_builtin_func_t *last_shell_builtin, *this_shell_builtin;
218 :
219 : /* SPECIFIC_COMPLETION_FUNCTIONS specifies that we have individual
220 : completion functions which indicate what type of completion should be
221 : done (at or before point) that can be bound to key sequences with
222 : the readline library. */
223 : #define SPECIFIC_COMPLETION_FUNCTIONS
224 :
225 : #if defined (SPECIFIC_COMPLETION_FUNCTIONS)
226 : static int bash_specific_completion __P((int, rl_compentry_func_t *));
227 :
228 : static int bash_complete_filename_internal __P((int));
229 : static int bash_complete_username_internal __P((int));
230 : static int bash_complete_hostname_internal __P((int));
231 : static int bash_complete_variable_internal __P((int));
232 : static int bash_complete_command_internal __P((int));
233 :
234 : static int bash_complete_filename __P((int, int));
235 : static int bash_possible_filename_completions __P((int, int));
236 : static int bash_complete_username __P((int, int));
237 : static int bash_possible_username_completions __P((int, int));
238 : static int bash_complete_hostname __P((int, int));
239 : static int bash_possible_hostname_completions __P((int, int));
240 : static int bash_complete_variable __P((int, int));
241 : static int bash_possible_variable_completions __P((int, int));
242 : static int bash_complete_command __P((int, int));
243 : static int bash_possible_command_completions __P((int, int));
244 :
245 : static char *glob_complete_word __P((const char *, int));
246 : static int bash_glob_completion_internal __P((int));
247 : static int bash_glob_complete_word __P((int, int));
248 : static int bash_glob_expand_word __P((int, int));
249 : static int bash_glob_list_expansions __P((int, int));
250 :
251 : #endif /* SPECIFIC_COMPLETION_FUNCTIONS */
252 :
253 : static int edit_and_execute_command __P((int, int, int, char *));
254 : #if defined (VI_MODE)
255 : static int vi_edit_and_execute_command __P((int, int));
256 : static int bash_vi_complete __P((int, int));
257 : #endif
258 : static int emacs_edit_and_execute_command __P((int, int));
259 :
260 : /* Non-zero once initalize_readline () has been called. */
261 : int bash_readline_initialized = 0;
262 :
263 : /* If non-zero, we do hostname completion, breaking words at `@' and
264 : trying to complete the stuff after the `@' from our own internal
265 : host list. */
266 : int perform_hostname_completion = 1;
267 :
268 : /* If non-zero, we don't do command completion on an empty line. */
269 : int no_empty_command_completion;
270 :
271 : /* Set FORCE_FIGNORE if you want to honor FIGNORE even if it ignores the
272 : only possible matches. Set to 0 if you want to match filenames if they
273 : are the only possible matches, even if FIGNORE says to. */
274 : int force_fignore = 1;
275 :
276 : /* Perform spelling correction on directory names during word completion */
277 : int dircomplete_spelling = 0;
278 :
279 : /* Expand directory names during word/filename completion. */
280 : #if DIRCOMPLETE_EXPAND_DEFAULT
281 : int dircomplete_expand = 1;
282 : int dircomplete_expand_relpath = 1;
283 : #else
284 : int dircomplete_expand = 0;
285 : int dircomplete_expand_relpath = 0;
286 : #endif
287 :
288 : /* When non-zero, perform `normal' shell quoting on completed filenames
289 : even when the completed name contains a directory name with a shell
290 : variable referene, so dollar signs in a filename get quoted appropriately.
291 : Set to zero to remove dollar sign (and braces or parens as needed) from
292 : the set of characters that will be quoted. */
293 : int complete_fullquote = 1;
294 :
295 : static char *bash_completer_word_break_characters = " \t\n\"'@><=;|&(:";
296 : static char *bash_nohostname_word_break_characters = " \t\n\"'><=;|&(:";
297 : /* )) */
298 :
299 : static const char *default_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{~"; /*}*/
300 : static char *custom_filename_quote_characters = 0;
301 : static char filename_bstab[256];
302 :
303 : static rl_hook_func_t *old_rl_startup_hook = (rl_hook_func_t *)NULL;
304 :
305 : static int dot_in_path = 0;
306 :
307 : /* Set to non-zero when dabbrev-expand is running */
308 : static int dabbrev_expand_active = 0;
309 :
310 : /* What kind of quoting is performed by bash_quote_filename:
311 : COMPLETE_DQUOTE = double-quoting the filename
312 : COMPLETE_SQUOTE = single_quoting the filename
313 : COMPLETE_BSQUOTE = backslash-quoting special chars in the filename
314 : */
315 : #define COMPLETE_DQUOTE 1
316 : #define COMPLETE_SQUOTE 2
317 : #define COMPLETE_BSQUOTE 3
318 : static int completion_quoting_style = COMPLETE_BSQUOTE;
319 :
320 : /* Flag values for the final argument to bash_default_completion */
321 : #define DEFCOMP_CMDPOS 1
322 :
323 : /* Change the readline VI-mode keymaps into or out of Posix.2 compliance.
324 : Called when the shell is put into or out of `posix' mode. */
325 : void
326 0 : posix_readline_initialize (on_or_off)
327 : int on_or_off;
328 : {
329 0 : if (on_or_off)
330 0 : rl_variable_bind ("comment-begin", "#");
331 : #if defined (VI_MODE)
332 0 : rl_bind_key_in_map (CTRL ('I'), on_or_off ? rl_insert : rl_complete, vi_insertion_keymap);
333 : #endif
334 0 : }
335 :
336 : void
337 9 : reset_completer_word_break_chars ()
338 : {
339 9 : rl_completer_word_break_characters = perform_hostname_completion ? savestring (bash_completer_word_break_characters) : savestring (bash_nohostname_word_break_characters);
340 9 : }
341 :
342 : /* When this function returns, rl_completer_word_break_characters points to
343 : dynamically allocated memory. */
344 : int
345 75 : enable_hostname_completion (on_or_off)
346 : int on_or_off;
347 : {
348 75 : int old_value;
349 75 : char *at, *nv, *nval;
350 :
351 75 : old_value = perform_hostname_completion;
352 :
353 75 : if (on_or_off)
354 : {
355 75 : perform_hostname_completion = 1;
356 75 : rl_special_prefixes = "$@";
357 : }
358 : else
359 : {
360 0 : perform_hostname_completion = 0;
361 0 : rl_special_prefixes = "$";
362 : }
363 :
364 : /* Now we need to figure out how to appropriately modify and assign
365 : rl_completer_word_break_characters depending on whether we want
366 : hostname completion on or off. */
367 :
368 : /* If this is the first time this has been called
369 : (bash_readline_initialized == 0), use the sames values as before, but
370 : allocate new memory for rl_completer_word_break_characters. */
371 :
372 75 : if (bash_readline_initialized == 0 &&
373 75 : (rl_completer_word_break_characters == 0 ||
374 75 : rl_completer_word_break_characters == rl_basic_word_break_characters))
375 : {
376 75 : if (on_or_off)
377 75 : rl_completer_word_break_characters = savestring (bash_completer_word_break_characters);
378 : else
379 0 : rl_completer_word_break_characters = savestring (bash_nohostname_word_break_characters);
380 : }
381 : else
382 : {
383 : /* See if we have anything to do. */
384 0 : at = strchr (rl_completer_word_break_characters, '@');
385 0 : if ((at == 0 && on_or_off == 0) || (at != 0 && on_or_off != 0))
386 : return old_value;
387 :
388 : /* We have something to do. Do it. */
389 0 : nval = (char *)xmalloc (strlen (rl_completer_word_break_characters) + 1 + on_or_off);
390 :
391 0 : if (on_or_off == 0)
392 : {
393 : /* Turn it off -- just remove `@' from word break chars. We want
394 : to remove all occurrences of `@' from the char list, so we loop
395 : rather than just copy the rest of the list over AT. */
396 0 : for (nv = nval, at = rl_completer_word_break_characters; *at; )
397 0 : if (*at != '@')
398 0 : *nv++ = *at++;
399 : else
400 0 : at++;
401 0 : *nv = '\0';
402 : }
403 : else
404 : {
405 0 : nval[0] = '@';
406 0 : strcpy (nval + 1, rl_completer_word_break_characters);
407 : }
408 :
409 0 : free (rl_completer_word_break_characters);
410 0 : rl_completer_word_break_characters = nval;
411 : }
412 :
413 : return (old_value);
414 : }
415 :
416 : /* Called once from parse.y if we are going to use readline. */
417 : void
418 75 : initialize_readline ()
419 : {
420 75 : rl_command_func_t *func;
421 75 : char kseq[2];
422 :
423 75 : if (bash_readline_initialized)
424 0 : return;
425 :
426 75 : rl_terminal_name = get_string_value ("TERM");
427 75 : rl_instream = stdin;
428 75 : rl_outstream = stderr;
429 :
430 : /* Allow conditional parsing of the ~/.inputrc file. */
431 75 : rl_readline_name = "Bash";
432 :
433 : /* Add bindable names before calling rl_initialize so they may be
434 : referenced in the various inputrc files. */
435 75 : rl_add_defun ("shell-expand-line", shell_expand_line, -1);
436 : #ifdef BANG_HISTORY
437 75 : rl_add_defun ("history-expand-line", history_expand_line, -1);
438 75 : rl_add_defun ("magic-space", tcsh_magic_space, -1);
439 : #endif
440 :
441 75 : rl_add_defun ("shell-forward-word", bash_forward_shellword, -1);
442 75 : rl_add_defun ("shell-backward-word", bash_backward_shellword, -1);
443 75 : rl_add_defun ("shell-kill-word", bash_kill_shellword, -1);
444 75 : rl_add_defun ("shell-backward-kill-word", bash_backward_kill_shellword, -1);
445 :
446 : #ifdef ALIAS
447 75 : rl_add_defun ("alias-expand-line", alias_expand_line, -1);
448 : # ifdef BANG_HISTORY
449 75 : rl_add_defun ("history-and-alias-expand-line", history_and_alias_expand_line, -1);
450 : # endif
451 : #endif
452 :
453 : /* Backwards compatibility. */
454 75 : rl_add_defun ("insert-last-argument", rl_yank_last_arg, -1);
455 :
456 75 : rl_add_defun ("operate-and-get-next", operate_and_get_next, -1);
457 75 : rl_add_defun ("display-shell-version", display_shell_version, -1);
458 75 : rl_add_defun ("edit-and-execute-command", emacs_edit_and_execute_command, -1);
459 :
460 : #if defined (BRACE_COMPLETION)
461 75 : rl_add_defun ("complete-into-braces", bash_brace_completion, -1);
462 : #endif
463 :
464 : #if defined (SPECIFIC_COMPLETION_FUNCTIONS)
465 75 : rl_add_defun ("complete-filename", bash_complete_filename, -1);
466 75 : rl_add_defun ("possible-filename-completions", bash_possible_filename_completions, -1);
467 75 : rl_add_defun ("complete-username", bash_complete_username, -1);
468 75 : rl_add_defun ("possible-username-completions", bash_possible_username_completions, -1);
469 75 : rl_add_defun ("complete-hostname", bash_complete_hostname, -1);
470 75 : rl_add_defun ("possible-hostname-completions", bash_possible_hostname_completions, -1);
471 75 : rl_add_defun ("complete-variable", bash_complete_variable, -1);
472 75 : rl_add_defun ("possible-variable-completions", bash_possible_variable_completions, -1);
473 75 : rl_add_defun ("complete-command", bash_complete_command, -1);
474 75 : rl_add_defun ("possible-command-completions", bash_possible_command_completions, -1);
475 75 : rl_add_defun ("glob-complete-word", bash_glob_complete_word, -1);
476 75 : rl_add_defun ("glob-expand-word", bash_glob_expand_word, -1);
477 75 : rl_add_defun ("glob-list-expansions", bash_glob_list_expansions, -1);
478 : #endif
479 :
480 75 : rl_add_defun ("dynamic-complete-history", dynamic_complete_history, -1);
481 75 : rl_add_defun ("dabbrev-expand", bash_dabbrev_expand, -1);
482 :
483 : /* Bind defaults before binding our custom shell keybindings. */
484 75 : if (RL_ISSTATE(RL_STATE_INITIALIZED) == 0)
485 75 : rl_initialize ();
486 :
487 : /* Bind up our special shell functions. */
488 75 : rl_bind_key_if_unbound_in_map (CTRL('E'), shell_expand_line, emacs_meta_keymap);
489 :
490 : #ifdef BANG_HISTORY
491 75 : rl_bind_key_if_unbound_in_map ('^', history_expand_line, emacs_meta_keymap);
492 : #endif
493 :
494 75 : rl_bind_key_if_unbound_in_map (CTRL ('O'), operate_and_get_next, emacs_standard_keymap);
495 75 : rl_bind_key_if_unbound_in_map (CTRL ('V'), display_shell_version, emacs_ctlx_keymap);
496 :
497 : /* In Bash, the user can switch editing modes with "set -o [vi emacs]",
498 : so it is not necessary to allow C-M-j for context switching. Turn
499 : off this occasionally confusing behaviour. */
500 75 : kseq[0] = CTRL('J');
501 75 : kseq[1] = '\0';
502 75 : func = rl_function_of_keyseq (kseq, emacs_meta_keymap, (int *)NULL);
503 75 : if (func == rl_vi_editing_mode)
504 75 : rl_unbind_key_in_map (CTRL('J'), emacs_meta_keymap);
505 75 : kseq[0] = CTRL('M');
506 75 : func = rl_function_of_keyseq (kseq, emacs_meta_keymap, (int *)NULL);
507 75 : if (func == rl_vi_editing_mode)
508 75 : rl_unbind_key_in_map (CTRL('M'), emacs_meta_keymap);
509 : #if defined (VI_MODE)
510 75 : rl_unbind_key_in_map (CTRL('E'), vi_movement_keymap);
511 : #endif
512 :
513 : #if defined (BRACE_COMPLETION)
514 75 : rl_bind_key_if_unbound_in_map ('{', bash_brace_completion, emacs_meta_keymap); /*}*/
515 : #endif /* BRACE_COMPLETION */
516 :
517 : #if defined (SPECIFIC_COMPLETION_FUNCTIONS)
518 75 : rl_bind_key_if_unbound_in_map ('/', bash_complete_filename, emacs_meta_keymap);
519 75 : rl_bind_key_if_unbound_in_map ('/', bash_possible_filename_completions, emacs_ctlx_keymap);
520 :
521 : /* Have to jump through hoops here because there is a default binding for
522 : M-~ (rl_tilde_expand) */
523 75 : kseq[0] = '~';
524 75 : kseq[1] = '\0';
525 75 : func = rl_function_of_keyseq (kseq, emacs_meta_keymap, (int *)NULL);
526 75 : if (func == 0 || func == rl_tilde_expand)
527 75 : rl_bind_keyseq_in_map (kseq, bash_complete_username, emacs_meta_keymap);
528 :
529 75 : rl_bind_key_if_unbound_in_map ('~', bash_possible_username_completions, emacs_ctlx_keymap);
530 :
531 75 : rl_bind_key_if_unbound_in_map ('@', bash_complete_hostname, emacs_meta_keymap);
532 75 : rl_bind_key_if_unbound_in_map ('@', bash_possible_hostname_completions, emacs_ctlx_keymap);
533 :
534 75 : rl_bind_key_if_unbound_in_map ('$', bash_complete_variable, emacs_meta_keymap);
535 75 : rl_bind_key_if_unbound_in_map ('$', bash_possible_variable_completions, emacs_ctlx_keymap);
536 :
537 75 : rl_bind_key_if_unbound_in_map ('!', bash_complete_command, emacs_meta_keymap);
538 75 : rl_bind_key_if_unbound_in_map ('!', bash_possible_command_completions, emacs_ctlx_keymap);
539 :
540 75 : rl_bind_key_if_unbound_in_map ('g', bash_glob_complete_word, emacs_meta_keymap);
541 75 : rl_bind_key_if_unbound_in_map ('*', bash_glob_expand_word, emacs_ctlx_keymap);
542 75 : rl_bind_key_if_unbound_in_map ('g', bash_glob_list_expansions, emacs_ctlx_keymap);
543 :
544 : #endif /* SPECIFIC_COMPLETION_FUNCTIONS */
545 :
546 75 : kseq[0] = TAB;
547 75 : kseq[1] = '\0';
548 75 : func = rl_function_of_keyseq (kseq, emacs_meta_keymap, (int *)NULL);
549 75 : if (func == 0 || func == rl_tab_insert)
550 75 : rl_bind_key_in_map (TAB, dynamic_complete_history, emacs_meta_keymap);
551 :
552 : /* Tell the completer that we want a crack first. */
553 75 : rl_attempted_completion_function = attempt_shell_completion;
554 :
555 : /* Tell the completer that we might want to follow symbolic links or
556 : do other expansion on directory names. */
557 75 : set_directory_hook ();
558 :
559 75 : rl_filename_rewrite_hook = bash_filename_rewrite_hook;
560 :
561 75 : rl_filename_stat_hook = bash_filename_stat_hook;
562 :
563 : /* Tell the filename completer we want a chance to ignore some names. */
564 75 : rl_ignore_some_completions_function = filename_completion_ignore;
565 :
566 : /* Bind C-xC-e to invoke emacs and run result as commands. */
567 75 : rl_bind_key_if_unbound_in_map (CTRL ('E'), emacs_edit_and_execute_command, emacs_ctlx_keymap);
568 : #if defined (VI_MODE)
569 75 : rl_bind_key_if_unbound_in_map ('v', vi_edit_and_execute_command, vi_movement_keymap);
570 : # if defined (ALIAS)
571 75 : rl_bind_key_if_unbound_in_map ('@', posix_edit_macros, vi_movement_keymap);
572 : # endif
573 :
574 75 : rl_bind_key_in_map ('\\', bash_vi_complete, vi_movement_keymap);
575 75 : rl_bind_key_in_map ('*', bash_vi_complete, vi_movement_keymap);
576 75 : rl_bind_key_in_map ('=', bash_vi_complete, vi_movement_keymap);
577 : #endif
578 :
579 75 : rl_completer_quote_characters = "'\"";
580 :
581 : /* This sets rl_completer_word_break_characters and rl_special_prefixes
582 : to the appropriate values, depending on whether or not hostname
583 : completion is enabled. */
584 75 : enable_hostname_completion (perform_hostname_completion);
585 :
586 : /* characters that need to be quoted when appearing in filenames. */
587 75 : rl_filename_quote_characters = default_filename_quote_characters;
588 75 : set_filename_bstab (rl_filename_quote_characters);
589 :
590 75 : rl_filename_quoting_function = bash_quote_filename;
591 75 : rl_filename_dequoting_function = bash_dequote_filename;
592 75 : rl_char_is_quoted_p = char_is_quoted;
593 :
594 : #if 0
595 : /* This is superfluous and makes it impossible to use tab completion in
596 : vi mode even when explicitly binding it in ~/.inputrc. sv_strict_posix()
597 : should already have called posix_readline_initialize() when
598 : posixly_correct was set. */
599 : if (posixly_correct)
600 : posix_readline_initialize (1);
601 : #endif
602 :
603 75 : bash_readline_initialized = 1;
604 : }
605 :
606 : void
607 9 : bashline_reinitialize ()
608 : {
609 9 : bash_readline_initialized = 0;
610 9 : }
611 :
612 : void
613 0 : bashline_set_event_hook ()
614 : {
615 0 : rl_signal_event_hook = bash_event_hook;
616 0 : }
617 :
618 : void
619 0 : bashline_reset_event_hook ()
620 : {
621 0 : rl_signal_event_hook = 0;
622 0 : }
623 :
624 : /* On Sun systems at least, rl_attempted_completion_function can end up
625 : getting set to NULL, and rl_completion_entry_function set to do command
626 : word completion if Bash is interrupted while trying to complete a command
627 : word. This just resets all the completion functions to the right thing.
628 : It's called from throw_to_top_level(). */
629 : void
630 0 : bashline_reset ()
631 : {
632 0 : tilde_initialize ();
633 0 : rl_attempted_completion_function = attempt_shell_completion;
634 0 : rl_completion_entry_function = NULL;
635 0 : rl_ignore_some_completions_function = filename_completion_ignore;
636 0 : rl_filename_quote_characters = default_filename_quote_characters;
637 0 : set_filename_bstab (rl_filename_quote_characters);
638 :
639 0 : set_directory_hook ();
640 0 : rl_filename_stat_hook = bash_filename_stat_hook;
641 :
642 0 : bashline_reset_event_hook ();
643 :
644 0 : rl_sort_completion_matches = 1;
645 0 : }
646 :
647 : /* Contains the line to push into readline. */
648 : static char *push_to_readline = (char *)NULL;
649 :
650 : /* Push the contents of push_to_readline into the
651 : readline buffer. */
652 : static int
653 0 : bash_push_line ()
654 : {
655 0 : if (push_to_readline)
656 : {
657 0 : rl_insert_text (push_to_readline);
658 0 : free (push_to_readline);
659 0 : push_to_readline = (char *)NULL;
660 0 : rl_startup_hook = old_rl_startup_hook;
661 : }
662 0 : return 0;
663 : }
664 :
665 : /* Call this to set the initial text for the next line to read
666 : from readline. */
667 : int
668 0 : bash_re_edit (line)
669 : char *line;
670 : {
671 0 : FREE (push_to_readline);
672 :
673 0 : push_to_readline = savestring (line);
674 0 : old_rl_startup_hook = rl_startup_hook;
675 0 : rl_startup_hook = bash_push_line;
676 :
677 0 : return (0);
678 : }
679 :
680 : static int
681 0 : display_shell_version (count, c)
682 : int count, c;
683 : {
684 0 : rl_crlf ();
685 0 : show_shell_version (0);
686 0 : putc ('\r', rl_outstream);
687 0 : fflush (rl_outstream);
688 0 : rl_on_new_line ();
689 0 : rl_redisplay ();
690 0 : return 0;
691 : }
692 :
693 : /* **************************************************************** */
694 : /* */
695 : /* Readline Stuff */
696 : /* */
697 : /* **************************************************************** */
698 :
699 : /* If the user requests hostname completion, then simply build a list
700 : of hosts, and complete from that forever more, or at least until
701 : HOSTFILE is unset. */
702 :
703 : /* THIS SHOULD BE A STRINGLIST. */
704 : /* The kept list of hostnames. */
705 : static char **hostname_list = (char **)NULL;
706 :
707 : /* The physical size of the above list. */
708 : static int hostname_list_size;
709 :
710 : /* The number of hostnames in the above list. */
711 : static int hostname_list_length;
712 :
713 : /* Whether or not HOSTNAME_LIST has been initialized. */
714 : int hostname_list_initialized = 0;
715 :
716 : /* Initialize the hostname completion table. */
717 : static void
718 0 : initialize_hostname_list ()
719 : {
720 0 : char *temp;
721 :
722 0 : temp = get_string_value ("HOSTFILE");
723 0 : if (temp == 0)
724 0 : temp = get_string_value ("hostname_completion_file");
725 0 : if (temp == 0)
726 0 : temp = DEFAULT_HOSTS_FILE;
727 :
728 0 : snarf_hosts_from_file (temp);
729 :
730 0 : if (hostname_list)
731 0 : hostname_list_initialized++;
732 0 : }
733 :
734 : /* Add NAME to the list of hosts. */
735 : static void
736 0 : add_host_name (name)
737 : char *name;
738 : {
739 0 : if (hostname_list_length + 2 > hostname_list_size)
740 : {
741 0 : hostname_list_size = (hostname_list_size + 32) - (hostname_list_size % 32);
742 0 : hostname_list = strvec_resize (hostname_list, hostname_list_size);
743 : }
744 :
745 0 : hostname_list[hostname_list_length++] = savestring (name);
746 0 : hostname_list[hostname_list_length] = (char *)NULL;
747 0 : }
748 :
749 : #define cr_whitespace(c) ((c) == '\r' || (c) == '\n' || whitespace(c))
750 :
751 : static void
752 0 : snarf_hosts_from_file (filename)
753 : char *filename;
754 : {
755 0 : FILE *file;
756 0 : char *temp, buffer[256], name[256];
757 0 : register int i, start;
758 :
759 0 : file = fopen (filename, "r");
760 0 : if (file == 0)
761 0 : return;
762 :
763 0 : while (temp = fgets (buffer, 255, file))
764 : {
765 : /* Skip to first character. */
766 0 : for (i = 0; buffer[i] && cr_whitespace (buffer[i]); i++)
767 0 : ;
768 :
769 : /* If comment or blank line, ignore. */
770 0 : if (buffer[i] == '\0' || buffer[i] == '#')
771 : continue;
772 :
773 : /* If `preprocessor' directive, do the include. */
774 0 : if (strncmp (buffer + i, "$include ", 9) == 0)
775 : {
776 0 : char *incfile, *t;
777 :
778 : /* Find start of filename. */
779 0 : for (incfile = buffer + i + 9; *incfile && whitespace (*incfile); incfile++)
780 0 : ;
781 :
782 : /* Find end of filename. */
783 0 : for (t = incfile; *t && cr_whitespace (*t) == 0; t++)
784 0 : ;
785 :
786 0 : *t = '\0';
787 :
788 0 : snarf_hosts_from_file (incfile);
789 0 : continue;
790 : }
791 :
792 : /* Skip internet address if present. */
793 0 : if (DIGIT (buffer[i]))
794 0 : for (; buffer[i] && cr_whitespace (buffer[i]) == 0; i++);
795 :
796 : /* Gobble up names. Each name is separated with whitespace. */
797 0 : while (buffer[i])
798 : {
799 0 : for (; cr_whitespace (buffer[i]); i++)
800 0 : ;
801 0 : if (buffer[i] == '\0' || buffer[i] == '#')
802 : break;
803 :
804 : /* Isolate the current word. */
805 0 : for (start = i; buffer[i] && cr_whitespace (buffer[i]) == 0; i++)
806 0 : ;
807 0 : if (i == start)
808 : continue;
809 0 : strncpy (name, buffer + start, i - start);
810 0 : name[i - start] = '\0';
811 0 : add_host_name (name);
812 : }
813 : }
814 0 : fclose (file);
815 : }
816 :
817 : /* Return the hostname list. */
818 : char **
819 0 : get_hostname_list ()
820 : {
821 0 : if (hostname_list_initialized == 0)
822 0 : initialize_hostname_list ();
823 0 : return (hostname_list);
824 : }
825 :
826 : void
827 0 : clear_hostname_list ()
828 : {
829 0 : register int i;
830 :
831 0 : if (hostname_list_initialized == 0)
832 : return;
833 0 : for (i = 0; i < hostname_list_length; i++)
834 0 : free (hostname_list[i]);
835 0 : hostname_list_length = hostname_list_initialized = 0;
836 : }
837 :
838 : /* Return a NULL terminated list of hostnames which begin with TEXT.
839 : Initialize the hostname list the first time if necessary.
840 : The array is malloc ()'ed, but not the individual strings. */
841 : static char **
842 0 : hostnames_matching (text)
843 : char *text;
844 : {
845 0 : register int i, len, nmatch, rsize;
846 0 : char **result;
847 :
848 0 : if (hostname_list_initialized == 0)
849 0 : initialize_hostname_list ();
850 :
851 0 : if (hostname_list_initialized == 0)
852 : return ((char **)NULL);
853 :
854 : /* Special case. If TEXT consists of nothing, then the whole list is
855 : what is desired. */
856 0 : if (*text == '\0')
857 : {
858 0 : result = strvec_create (1 + hostname_list_length);
859 0 : for (i = 0; i < hostname_list_length; i++)
860 0 : result[i] = hostname_list[i];
861 0 : result[i] = (char *)NULL;
862 0 : return (result);
863 : }
864 :
865 : /* Scan until found, or failure. */
866 0 : len = strlen (text);
867 0 : result = (char **)NULL;
868 0 : for (i = nmatch = rsize = 0; i < hostname_list_length; i++)
869 : {
870 0 : if (STREQN (text, hostname_list[i], len) == 0)
871 : continue;
872 :
873 : /* OK, it matches. Add it to the list. */
874 0 : if (nmatch >= (rsize - 1))
875 : {
876 0 : rsize = (rsize + 16) - (rsize % 16);
877 0 : result = strvec_resize (result, rsize);
878 : }
879 :
880 0 : result[nmatch++] = hostname_list[i];
881 : }
882 0 : if (nmatch)
883 0 : result[nmatch] = (char *)NULL;
884 : return (result);
885 : }
886 :
887 : /* The equivalent of the Korn shell C-o operate-and-get-next-history-line
888 : editing command. */
889 : static int saved_history_line_to_use = -1;
890 : static int last_saved_history_line = -1;
891 :
892 : #define HISTORY_FULL() (history_is_stifled () && history_length >= history_max_entries)
893 :
894 : static int
895 0 : set_saved_history ()
896 : {
897 : /* XXX - compensate for assumption that history was `shuffled' if it was
898 : actually not. */
899 0 : if (HISTORY_FULL () &&
900 0 : hist_last_line_added == 0 &&
901 0 : saved_history_line_to_use < history_length - 1)
902 0 : saved_history_line_to_use++;
903 :
904 0 : if (saved_history_line_to_use >= 0)
905 : {
906 0 : rl_get_previous_history (history_length - saved_history_line_to_use, 0);
907 0 : last_saved_history_line = saved_history_line_to_use;
908 : }
909 0 : saved_history_line_to_use = -1;
910 0 : rl_startup_hook = old_rl_startup_hook;
911 0 : return (0);
912 : }
913 :
914 : static int
915 0 : operate_and_get_next (count, c)
916 : int count, c;
917 : {
918 0 : int where;
919 :
920 : /* Accept the current line. */
921 0 : rl_newline (1, c);
922 :
923 : /* Find the current line, and find the next line to use. */
924 0 : where = where_history ();
925 :
926 0 : if (HISTORY_FULL () || (where >= history_length - 1))
927 0 : saved_history_line_to_use = where;
928 : else
929 0 : saved_history_line_to_use = where + 1;
930 :
931 0 : old_rl_startup_hook = rl_startup_hook;
932 0 : rl_startup_hook = set_saved_history;
933 :
934 0 : return 0;
935 : }
936 :
937 : /* This vi mode command causes VI_EDIT_COMMAND to be run on the current
938 : command being entered (if no explicit argument is given), otherwise on
939 : a command from the history file. */
940 :
941 : #define VI_EDIT_COMMAND "fc -e \"${VISUAL:-${EDITOR:-vitmp}}\""
942 : #define EMACS_EDIT_COMMAND "fc -e \"${VISUAL:-${EDITOR:-emacs}}\""
943 : #define POSIX_VI_EDIT_COMMAND "fc -e vi"
944 :
945 : static int
946 0 : edit_and_execute_command (count, c, editing_mode, edit_command)
947 : int count, c, editing_mode;
948 : char *edit_command;
949 : {
950 0 : char *command, *metaval;
951 0 : int r, rrs, metaflag;
952 0 : sh_parser_state_t ps;
953 :
954 0 : rrs = rl_readline_state;
955 0 : saved_command_line_count = current_command_line_count;
956 :
957 : /* Accept the current line. */
958 0 : rl_newline (1, c);
959 :
960 0 : if (rl_explicit_arg)
961 : {
962 0 : command = (char *)xmalloc (strlen (edit_command) + 8);
963 0 : sprintf (command, "%s %d", edit_command, count);
964 : }
965 : else
966 : {
967 : /* Take the command we were just editing, add it to the history file,
968 : then call fc to operate on it. We have to add a dummy command to
969 : the end of the history because fc ignores the last command (assumes
970 : it's supposed to deal with the command before the `fc'). */
971 : /* This breaks down when using command-oriented history and are not
972 : finished with the command, so we should not ignore the last command */
973 0 : using_history ();
974 0 : current_command_line_count++; /* for rl_newline above */
975 0 : bash_add_history (rl_line_buffer);
976 0 : current_command_line_count = 0; /* for dummy history entry */
977 0 : bash_add_history ("");
978 0 : history_lines_this_session++;
979 0 : using_history ();
980 0 : command = savestring (edit_command);
981 : }
982 :
983 0 : metaval = rl_variable_value ("input-meta");
984 0 : metaflag = RL_BOOLEAN_VARIABLE_VALUE (metaval);
985 :
986 0 : if (rl_deprep_term_function)
987 0 : (*rl_deprep_term_function) ();
988 0 : save_parser_state (&ps);
989 0 : r = parse_and_execute (command, (editing_mode == VI_EDITING_MODE) ? "v" : "C-xC-e", SEVAL_NOHIST);
990 0 : restore_parser_state (&ps);
991 0 : if (rl_prep_term_function)
992 0 : (*rl_prep_term_function) (metaflag);
993 :
994 0 : current_command_line_count = saved_command_line_count;
995 :
996 : /* Now erase the contents of the current line and undo the effects of the
997 : rl_accept_line() above. We don't even want to make the text we just
998 : executed available for undoing. */
999 0 : rl_line_buffer[0] = '\0'; /* XXX */
1000 0 : rl_point = rl_end = 0;
1001 0 : rl_done = 0;
1002 0 : rl_readline_state = rrs;
1003 :
1004 0 : rl_forced_update_display ();
1005 :
1006 0 : return r;
1007 : }
1008 :
1009 : #if defined (VI_MODE)
1010 : static int
1011 0 : vi_edit_and_execute_command (count, c)
1012 : int count, c;
1013 : {
1014 0 : if (posixly_correct)
1015 0 : return (edit_and_execute_command (count, c, VI_EDITING_MODE, POSIX_VI_EDIT_COMMAND));
1016 : else
1017 0 : return (edit_and_execute_command (count, c, VI_EDITING_MODE, VI_EDIT_COMMAND));
1018 : }
1019 : #endif /* VI_MODE */
1020 :
1021 : static int
1022 0 : emacs_edit_and_execute_command (count, c)
1023 : int count, c;
1024 : {
1025 0 : return (edit_and_execute_command (count, c, EMACS_EDITING_MODE, EMACS_EDIT_COMMAND));
1026 : }
1027 :
1028 : #if defined (ALIAS)
1029 : static int
1030 0 : posix_edit_macros (count, key)
1031 : int count, key;
1032 : {
1033 0 : int c;
1034 0 : char alias_name[3], *alias_value, *macro;
1035 :
1036 0 : c = rl_read_key ();
1037 0 : alias_name[0] = '_';
1038 0 : alias_name[1] = c;
1039 0 : alias_name[2] = '\0';
1040 :
1041 0 : alias_value = get_alias_value (alias_name);
1042 0 : if (alias_value && *alias_value)
1043 : {
1044 0 : macro = savestring (alias_value);
1045 0 : rl_push_macro_input (macro);
1046 : }
1047 0 : return 0;
1048 : }
1049 : #endif
1050 :
1051 : /* Bindable commands that move `shell-words': that is, sequences of
1052 : non-unquoted-metacharacters. */
1053 :
1054 : #define WORDDELIM(c) (shellmeta(c) || shellblank(c))
1055 :
1056 : static int
1057 0 : bash_forward_shellword (count, key)
1058 : int count, key;
1059 : {
1060 0 : size_t slen;
1061 0 : int c, p;
1062 0 : DECLARE_MBSTATE;
1063 :
1064 0 : if (count < 0)
1065 0 : return (bash_backward_shellword (-count, key));
1066 :
1067 : /* The tricky part of this is deciding whether or not the first character
1068 : we're on is an unquoted metacharacter. Not completely handled yet. */
1069 : /* XXX - need to test this stuff with backslash-escaped shell
1070 : metacharacters and unclosed single- and double-quoted strings. */
1071 :
1072 0 : p = rl_point;
1073 0 : slen = rl_end;
1074 :
1075 0 : while (count)
1076 : {
1077 0 : if (p == rl_end)
1078 : {
1079 0 : rl_point = rl_end;
1080 0 : return 0;
1081 : }
1082 :
1083 : /* Are we in a quoted string? If we are, move to the end of the quoted
1084 : string and continue the outer loop. We only want quoted strings, not
1085 : backslash-escaped characters, but char_is_quoted doesn't
1086 : differentiate. */
1087 0 : if (char_is_quoted (rl_line_buffer, p) && p > 0 && rl_line_buffer[p-1] != '\\')
1088 : {
1089 0 : do
1090 0 : ADVANCE_CHAR (rl_line_buffer, slen, p);
1091 0 : while (p < rl_end && char_is_quoted (rl_line_buffer, p));
1092 0 : count--;
1093 0 : continue;
1094 : }
1095 :
1096 : /* Rest of code assumes we are not in a quoted string. */
1097 : /* Move forward until we hit a non-metacharacter. */
1098 0 : while (p < rl_end && (c = rl_line_buffer[p]) && WORDDELIM (c))
1099 : {
1100 0 : switch (c)
1101 : {
1102 0 : default:
1103 0 : ADVANCE_CHAR (rl_line_buffer, slen, p);
1104 0 : continue; /* straight back to loop, don't increment p */
1105 : case '\\':
1106 0 : if (p < rl_end && rl_line_buffer[p])
1107 0 : ADVANCE_CHAR (rl_line_buffer, slen, p);
1108 : break;
1109 0 : case '\'':
1110 0 : p = skip_to_delim (rl_line_buffer, ++p, "'", SD_NOJMP);
1111 0 : break;
1112 0 : case '"':
1113 0 : p = skip_to_delim (rl_line_buffer, ++p, "\"", SD_NOJMP);
1114 0 : break;
1115 : }
1116 :
1117 0 : if (p < rl_end)
1118 0 : p++;
1119 : }
1120 :
1121 0 : if (rl_line_buffer[p] == 0 || p == rl_end)
1122 : {
1123 0 : rl_point = rl_end;
1124 0 : rl_ding ();
1125 0 : return 0;
1126 : }
1127 :
1128 : /* Now move forward until we hit a non-quoted metacharacter or EOL */
1129 0 : while (p < rl_end && (c = rl_line_buffer[p]) && WORDDELIM (c) == 0)
1130 : {
1131 0 : switch (c)
1132 : {
1133 0 : default:
1134 0 : ADVANCE_CHAR (rl_line_buffer, slen, p);
1135 0 : continue; /* straight back to loop, don't increment p */
1136 : case '\\':
1137 0 : if (p < rl_end && rl_line_buffer[p])
1138 0 : ADVANCE_CHAR (rl_line_buffer, slen, p);
1139 : break;
1140 0 : case '\'':
1141 0 : p = skip_to_delim (rl_line_buffer, ++p, "'", SD_NOJMP);
1142 0 : break;
1143 0 : case '"':
1144 0 : p = skip_to_delim (rl_line_buffer, ++p, "\"", SD_NOJMP);
1145 0 : break;
1146 : }
1147 :
1148 0 : if (p < rl_end)
1149 0 : p++;
1150 : }
1151 :
1152 0 : if (p == rl_end || rl_line_buffer[p] == 0)
1153 : {
1154 0 : rl_point = rl_end;
1155 0 : return (0);
1156 : }
1157 :
1158 0 : count--;
1159 : }
1160 :
1161 0 : rl_point = p;
1162 0 : return (0);
1163 : }
1164 :
1165 : static int
1166 0 : bash_backward_shellword (count, key)
1167 : int count, key;
1168 : {
1169 0 : size_t slen;
1170 0 : int c, p;
1171 0 : DECLARE_MBSTATE;
1172 :
1173 0 : if (count < 0)
1174 0 : return (bash_forward_shellword (-count, key));
1175 :
1176 0 : p = rl_point;
1177 0 : slen = rl_end;
1178 :
1179 0 : while (count)
1180 : {
1181 0 : if (p == 0)
1182 : {
1183 0 : rl_point = 0;
1184 0 : return 0;
1185 : }
1186 :
1187 : /* Move backward until we hit a non-metacharacter. */
1188 0 : while (p > 0)
1189 : {
1190 0 : c = rl_line_buffer[p];
1191 0 : if (WORDDELIM (c) && char_is_quoted (rl_line_buffer, p) == 0)
1192 0 : BACKUP_CHAR (rl_line_buffer, slen, p);
1193 : break;
1194 : }
1195 :
1196 0 : if (p == 0)
1197 : {
1198 0 : rl_point = 0;
1199 0 : return 0;
1200 : }
1201 :
1202 : /* Now move backward until we hit a metacharacter or BOL. */
1203 0 : while (p > 0)
1204 : {
1205 0 : c = rl_line_buffer[p];
1206 0 : if (WORDDELIM (c) && char_is_quoted (rl_line_buffer, p) == 0)
1207 : break;
1208 0 : BACKUP_CHAR (rl_line_buffer, slen, p);
1209 : }
1210 :
1211 0 : count--;
1212 : }
1213 :
1214 0 : rl_point = p;
1215 0 : return 0;
1216 : }
1217 :
1218 : static int
1219 0 : bash_kill_shellword (count, key)
1220 : int count, key;
1221 : {
1222 0 : int p;
1223 :
1224 0 : if (count < 0)
1225 0 : return (bash_backward_kill_shellword (-count, key));
1226 :
1227 0 : p = rl_point;
1228 0 : bash_forward_shellword (count, key);
1229 :
1230 0 : if (rl_point != p)
1231 0 : rl_kill_text (p, rl_point);
1232 :
1233 0 : rl_point = p;
1234 0 : if (rl_editing_mode == 1) /* 1 == emacs_mode */
1235 0 : rl_mark = rl_point;
1236 :
1237 : return 0;
1238 : }
1239 :
1240 : static int
1241 0 : bash_backward_kill_shellword (count, key)
1242 : int count, key;
1243 : {
1244 0 : int p;
1245 :
1246 0 : if (count < 0)
1247 0 : return (bash_kill_shellword (-count, key));
1248 :
1249 0 : p = rl_point;
1250 0 : bash_backward_shellword (count, key);
1251 :
1252 0 : if (rl_point != p)
1253 0 : rl_kill_text (p, rl_point);
1254 :
1255 0 : if (rl_editing_mode == 1) /* 1 == emacs_mode */
1256 0 : rl_mark = rl_point;
1257 :
1258 : return 0;
1259 : }
1260 :
1261 :
1262 : /* **************************************************************** */
1263 : /* */
1264 : /* How To Do Shell Completion */
1265 : /* */
1266 : /* **************************************************************** */
1267 :
1268 : #define COMMAND_SEPARATORS ";|&{(`"
1269 : /* )} */
1270 : #define COMMAND_SEPARATORS_PLUS_WS ";|&{(` \t"
1271 : /* )} */
1272 :
1273 : /* check for redirections and other character combinations that are not
1274 : command separators */
1275 : static int
1276 0 : check_redir (ti)
1277 : int ti;
1278 : {
1279 0 : register int this_char, prev_char;
1280 :
1281 : /* Handle the two character tokens `>&', `<&', and `>|'.
1282 : We are not in a command position after one of these. */
1283 0 : this_char = rl_line_buffer[ti];
1284 0 : prev_char = (ti > 0) ? rl_line_buffer[ti - 1] : 0;
1285 :
1286 0 : if ((this_char == '&' && (prev_char == '<' || prev_char == '>')) ||
1287 0 : (this_char == '|' && prev_char == '>'))
1288 : return (1);
1289 0 : else if (this_char == '{' && prev_char == '$') /*}*/
1290 : return (1);
1291 : #if 0 /* Not yet */
1292 : else if (this_char == '(' && prev_char == '$') /*)*/
1293 : return (1);
1294 : else if (this_char == '(' && prev_char == '<') /*)*/
1295 : return (1);
1296 : #if defined (EXTENDED_GLOB)
1297 : else if (extended_glob && this_char == '(' && prev_char == '!') /*)*/
1298 : return (1);
1299 : #endif
1300 : #endif
1301 0 : else if (char_is_quoted (rl_line_buffer, ti))
1302 0 : return (1);
1303 : return (0);
1304 : }
1305 :
1306 : #if defined (PROGRAMMABLE_COMPLETION)
1307 : /*
1308 : * XXX - because of the <= start test, and setting os = s+1, this can
1309 : * potentially return os > start. This is probably not what we want to
1310 : * happen, but fix later after 2.05a-release.
1311 : */
1312 : static int
1313 0 : find_cmd_start (start)
1314 : int start;
1315 : {
1316 0 : register int s, os, ns;
1317 :
1318 0 : os = 0;
1319 : /* Flags == SD_NOJMP only because we want to skip over command substitutions
1320 : in assignment statements. Have to test whether this affects `standalone'
1321 : command substitutions as individual words. */
1322 0 : while (((s = skip_to_delim (rl_line_buffer, os, COMMAND_SEPARATORS, SD_NOJMP|SD_COMPLETE/*|SD_NOSKIPCMD*/)) <= start) &&
1323 0 : rl_line_buffer[s])
1324 : {
1325 : /* Handle >| token crudely; treat as > not | */
1326 0 : if (rl_line_buffer[s] == '|' && rl_line_buffer[s-1] == '>')
1327 : {
1328 0 : ns = skip_to_delim (rl_line_buffer, s+1, COMMAND_SEPARATORS, SD_NOJMP|SD_COMPLETE/*|SD_NOSKIPCMD*/);
1329 0 : if (ns > start || rl_line_buffer[ns] == 0)
1330 0 : return os;
1331 0 : os = ns+1;
1332 0 : continue;
1333 : }
1334 0 : os = s+1;
1335 : }
1336 : return os;
1337 : }
1338 :
1339 : static int
1340 : find_cmd_end (end)
1341 : int end;
1342 : {
1343 0 : register int e;
1344 :
1345 0 : e = skip_to_delim (rl_line_buffer, end, COMMAND_SEPARATORS, SD_NOJMP|SD_COMPLETE);
1346 0 : return e;
1347 : }
1348 :
1349 : static char *
1350 0 : find_cmd_name (start, sp, ep)
1351 : int start;
1352 : int *sp, *ep;
1353 : {
1354 0 : char *name;
1355 0 : register int s, e;
1356 :
1357 0 : for (s = start; whitespace (rl_line_buffer[s]); s++)
1358 0 : ;
1359 :
1360 : /* skip until a shell break character */
1361 0 : e = skip_to_delim (rl_line_buffer, s, "()<>;&| \t\n", SD_NOJMP|SD_COMPLETE);
1362 :
1363 0 : name = substring (rl_line_buffer, s, e);
1364 :
1365 0 : if (sp)
1366 0 : *sp = s;
1367 0 : if (ep)
1368 0 : *ep = e;
1369 :
1370 0 : return (name);
1371 : }
1372 :
1373 : static char *
1374 0 : prog_complete_return (text, matchnum)
1375 : const char *text;
1376 : int matchnum;
1377 : {
1378 0 : static int ind;
1379 :
1380 0 : if (matchnum == 0)
1381 0 : ind = 0;
1382 :
1383 0 : if (prog_complete_matches == 0 || prog_complete_matches[ind] == 0)
1384 : return (char *)NULL;
1385 0 : return (prog_complete_matches[ind++]);
1386 : }
1387 :
1388 : #endif /* PROGRAMMABLE_COMPLETION */
1389 :
1390 : /* Try and catch completion attempts that are syntax errors or otherwise
1391 : invalid. */
1392 : static int
1393 0 : invalid_completion (text, ind)
1394 : const char *text;
1395 : int ind;
1396 : {
1397 0 : int pind;
1398 :
1399 : /* If we don't catch these here, the next clause will */
1400 0 : if (ind > 0 && rl_line_buffer[ind] == '(' && /*)*/
1401 0 : member (rl_line_buffer[ind-1], "$<>"))
1402 0 : return 0;
1403 :
1404 0 : pind = ind - 1;
1405 0 : while (pind > 0 && whitespace (rl_line_buffer[pind]))
1406 0 : pind--;
1407 : /* If we have only whitespace preceding a paren, it's valid */
1408 0 : if (ind >= 0 && pind <= 0 && rl_line_buffer[ind] == '(') /*)*/
1409 0 : return 0;
1410 : /* Flag the invalid completions, which are mostly syntax errors */
1411 0 : if (ind > 0 && rl_line_buffer[ind] == '(' && /*)*/
1412 0 : member (rl_line_buffer[pind], COMMAND_SEPARATORS) == 0)
1413 0 : return 1;
1414 :
1415 : return 0;
1416 : }
1417 :
1418 : /* Do some completion on TEXT. The indices of TEXT in RL_LINE_BUFFER are
1419 : at START and END. Return an array of matches, or NULL if none. */
1420 : static char **
1421 0 : attempt_shell_completion (text, start, end)
1422 : const char *text;
1423 : int start, end;
1424 : {
1425 0 : int in_command_position, ti, qc = 0, dflags;
1426 0 : char **matches, *command_separator_chars;
1427 : #if defined (PROGRAMMABLE_COMPLETION)
1428 0 : int have_progcomps, was_assignment;
1429 : #endif
1430 :
1431 0 : command_separator_chars = COMMAND_SEPARATORS;
1432 0 : matches = (char **)NULL;
1433 0 : rl_ignore_some_completions_function = filename_completion_ignore;
1434 :
1435 0 : rl_filename_quote_characters = default_filename_quote_characters;
1436 0 : set_filename_bstab (rl_filename_quote_characters);
1437 0 : set_directory_hook ();
1438 0 : rl_filename_stat_hook = bash_filename_stat_hook;
1439 :
1440 0 : rl_sort_completion_matches = 1; /* sort by default */
1441 :
1442 : /* Determine if this could be a command word. It is if it appears at
1443 : the start of the line (ignoring preceding whitespace), or if it
1444 : appears after a character that separates commands. It cannot be a
1445 : command word if we aren't at the top-level prompt. */
1446 0 : ti = start - 1;
1447 :
1448 0 : while ((ti > -1) && (whitespace (rl_line_buffer[ti])))
1449 0 : ti--;
1450 :
1451 : #if 1
1452 : /* If this is an open quote, maybe we're trying to complete a quoted
1453 : command name. */
1454 0 : if (ti >= 0 && (rl_line_buffer[ti] == '"' || rl_line_buffer[ti] == '\''))
1455 : {
1456 0 : qc = rl_line_buffer[ti];
1457 0 : while (ti > -1 && (whitespace (rl_line_buffer[ti])))
1458 0 : ti--;
1459 : }
1460 : #endif
1461 :
1462 0 : in_command_position = 0;
1463 0 : if (ti < 0)
1464 : {
1465 : /* Only do command completion at the start of a line when we
1466 : are prompting at the top level. */
1467 0 : if (current_prompt_string == ps1_prompt)
1468 : in_command_position++;
1469 0 : else if (parser_in_command_position ())
1470 : in_command_position++;
1471 : }
1472 0 : else if (member (rl_line_buffer[ti], command_separator_chars))
1473 : {
1474 0 : in_command_position++;
1475 :
1476 0 : if (check_redir (ti) == 1)
1477 : in_command_position = 0;
1478 : }
1479 : else
1480 : {
1481 : /* This still could be in command position. It is possible
1482 : that all of the previous words on the line are variable
1483 : assignments. */
1484 : }
1485 :
1486 0 : if (in_command_position && invalid_completion (text, ti))
1487 : {
1488 0 : rl_attempted_completion_over = 1;
1489 0 : return ((char **)NULL);
1490 : }
1491 :
1492 : /* Check that we haven't incorrectly flagged a closed command substitution
1493 : as indicating we're in a command position. */
1494 0 : if (in_command_position && ti >= 0 && rl_line_buffer[ti] == '`' &&
1495 0 : *text != '`' && unclosed_pair (rl_line_buffer, end, "`") == 0)
1496 0 : in_command_position = 0;
1497 :
1498 : /* Special handling for command substitution. If *TEXT is a backquote,
1499 : it can be the start or end of an old-style command substitution, or
1500 : unmatched. If it's unmatched, both calls to unclosed_pair will
1501 : succeed. Don't bother if readline found a single quote and we are
1502 : completing on the substring. */
1503 0 : if (*text == '`' && rl_completion_quote_character != '\'' &&
1504 0 : (in_command_position || (unclosed_pair (rl_line_buffer, start, "`") &&
1505 0 : unclosed_pair (rl_line_buffer, end, "`"))))
1506 0 : matches = rl_completion_matches (text, command_subst_completion_function);
1507 :
1508 : #if defined (PROGRAMMABLE_COMPLETION)
1509 : /* Attempt programmable completion. */
1510 0 : have_progcomps = prog_completion_enabled && (progcomp_size () > 0);
1511 0 : if (matches == 0 && (in_command_position == 0 || text[0] == '\0') &&
1512 0 : current_prompt_string == ps1_prompt)
1513 : {
1514 0 : int s, e, s1, e1 = 0, os, foundcs;
1515 0 : char *n;
1516 :
1517 : /* XXX - don't free the members */
1518 0 : if (prog_complete_matches)
1519 0 : free (prog_complete_matches);
1520 0 : prog_complete_matches = (char **)NULL;
1521 :
1522 0 : os = start;
1523 0 : n = 0;
1524 0 : was_assignment = 0;
1525 0 : s = find_cmd_start (os);
1526 0 : e = find_cmd_end (end);
1527 0 : do
1528 : {
1529 : /* Don't read past the end of rl_line_buffer */
1530 0 : if (s > rl_end)
1531 : {
1532 0 : s1 = s = e1;
1533 0 : break;
1534 : }
1535 : /* Or past point if point is within an assignment statement */
1536 0 : else if (was_assignment && s > rl_point)
1537 : {
1538 0 : s1 = s = e1;
1539 0 : break;
1540 : }
1541 : /* Skip over assignment statements preceding a command name. If we
1542 : don't find a command name at all, we can perform command name
1543 : completion. If we find a partial command name, we should perform
1544 : command name completion on it. */
1545 0 : FREE (n);
1546 0 : n = find_cmd_name (s, &s1, &e1);
1547 0 : s = e1 + 1;
1548 : }
1549 0 : while (was_assignment = assignment (n, 0));
1550 0 : s = s1; /* reset to index where name begins */
1551 :
1552 : /* s == index of where command name begins (reset above)
1553 : e == end of current command, may be end of line
1554 : s1 = index of where command name begins
1555 : e1 == index of where command name ends
1556 : start == index of where word to be completed begins
1557 : end == index of where word to be completed ends
1558 : if (s == start) we are doing command word completion for sure
1559 : if (e1 == end) we are at the end of the command name and completing it */
1560 0 : if (start == 0 && end == 0 && e != 0 && text[0] == '\0') /* beginning of non-empty line */
1561 0 : foundcs = 0;
1562 0 : else if (start == end && start == s1 && e != 0 && e1 > end) /* beginning of command name, leading whitespace */
1563 0 : foundcs = 0;
1564 0 : else if (e == 0 && e == s && text[0] == '\0' && have_progcomps) /* beginning of empty line */
1565 0 : prog_complete_matches = programmable_completions ("_EmptycmD_", text, s, e, &foundcs);
1566 0 : else if (start == end && text[0] == '\0' && s1 > start && whitespace (rl_line_buffer[start]))
1567 0 : foundcs = 0; /* whitespace before command name */
1568 0 : else if (e > s && was_assignment == 0 && e1 == end && rl_line_buffer[e] == 0 && whitespace (rl_line_buffer[e-1]) == 0)
1569 : {
1570 : /* not assignment statement, but still want to perform command
1571 : completion if we are composing command word. */
1572 0 : foundcs = 0;
1573 0 : in_command_position = s == start && STREQ (n, text); /* XXX */
1574 : }
1575 0 : else if (e > s && was_assignment == 0 && have_progcomps)
1576 : {
1577 0 : prog_complete_matches = programmable_completions (n, text, s, e, &foundcs);
1578 : /* command completion if programmable completion fails */
1579 0 : in_command_position = s == start && STREQ (n, text); /* XXX */
1580 : }
1581 : /* empty command name following command separator */
1582 0 : else if (s >= e && n[0] == '\0' && text[0] == '\0' && start > 0 &&
1583 0 : was_assignment == 0 && member (rl_line_buffer[start-1], COMMAND_SEPARATORS))
1584 : {
1585 0 : foundcs = 0;
1586 0 : in_command_position = 1;
1587 : }
1588 0 : else if (s >= e && n[0] == '\0' && text[0] == '\0' && start > 0)
1589 : {
1590 0 : foundcs = 0; /* empty command name following assignments */
1591 0 : in_command_position = was_assignment;
1592 : }
1593 0 : else if (s == start && e == end && STREQ (n, text) && start > 0)
1594 : {
1595 0 : foundcs = 0; /* partial command name following assignments */
1596 0 : in_command_position = 1;
1597 : }
1598 : else
1599 0 : foundcs = 0;
1600 0 : FREE (n);
1601 : /* XXX - if we found a COMPSPEC for the command, just return whatever
1602 : the programmable completion code returns, and disable the default
1603 : filename completion that readline will do unless the COPT_DEFAULT
1604 : option has been set with the `-o default' option to complete or
1605 : compopt. */
1606 0 : if (foundcs)
1607 : {
1608 0 : pcomp_set_readline_variables (foundcs, 1);
1609 : /* Turn what the programmable completion code returns into what
1610 : readline wants. I should have made compute_lcd_of_matches
1611 : external... */
1612 0 : matches = rl_completion_matches (text, prog_complete_return);
1613 0 : if ((foundcs & COPT_DEFAULT) == 0)
1614 0 : rl_attempted_completion_over = 1; /* no default */
1615 0 : if (matches || ((foundcs & COPT_BASHDEFAULT) == 0))
1616 0 : return (matches);
1617 : }
1618 : }
1619 : #endif
1620 :
1621 0 : if (matches == 0)
1622 : {
1623 0 : dflags = 0;
1624 0 : if (in_command_position)
1625 0 : dflags |= DEFCOMP_CMDPOS;
1626 0 : matches = bash_default_completion (text, start, end, qc, dflags);
1627 : }
1628 :
1629 : return matches;
1630 : }
1631 :
1632 : char **
1633 0 : bash_default_completion (text, start, end, qc, compflags)
1634 : const char *text;
1635 : int start, end, qc, compflags;
1636 : {
1637 0 : char **matches, *t;
1638 :
1639 0 : matches = (char **)NULL;
1640 :
1641 : /* New posix-style command substitution or variable name? */
1642 0 : if (!matches && *text == '$')
1643 : {
1644 0 : if (qc != '\'' && text[1] == '(') /* ) */
1645 0 : matches = rl_completion_matches (text, command_subst_completion_function);
1646 : else
1647 : {
1648 0 : matches = rl_completion_matches (text, variable_completion_function);
1649 : /* If a single match, see if it expands to a directory name and append
1650 : a slash if it does. This requires us to expand the variable name,
1651 : so we don't want to display errors if the variable is unset. This
1652 : can happen with dynamic variables whose value has never been
1653 : requested. */
1654 0 : if (matches && matches[0] && matches[1] == 0)
1655 : {
1656 0 : t = savestring (matches[0]);
1657 0 : bash_filename_stat_hook (&t);
1658 : /* doesn't use test_for_directory because that performs tilde
1659 : expansion */
1660 0 : if (file_isdir (t))
1661 0 : rl_completion_append_character = '/';
1662 0 : free (t);
1663 : }
1664 : }
1665 : }
1666 :
1667 : /* If the word starts in `~', and there is no slash in the word, then
1668 : try completing this word as a username. */
1669 0 : if (matches == 0 && *text == '~' && mbschr (text, '/') == 0)
1670 0 : matches = rl_completion_matches (text, rl_username_completion_function);
1671 :
1672 : /* Another one. Why not? If the word starts in '@', then look through
1673 : the world of known hostnames for completion first. */
1674 0 : if (matches == 0 && perform_hostname_completion && *text == '@')
1675 0 : matches = rl_completion_matches (text, hostname_completion_function);
1676 :
1677 : /* And last, (but not least) if this word is in a command position, then
1678 : complete over possible command names, including aliases, functions,
1679 : and command names. */
1680 0 : if (matches == 0 && (compflags & DEFCOMP_CMDPOS))
1681 : {
1682 : /* If END == START and text[0] == 0, we are trying to complete an empty
1683 : command word. */
1684 0 : if (no_empty_command_completion && end == start && text[0] == '\0')
1685 : {
1686 0 : matches = (char **)NULL;
1687 0 : rl_ignore_some_completions_function = bash_ignore_everything;
1688 : }
1689 : else
1690 : {
1691 : #define CMD_IS_DIR(x) (absolute_pathname(x) == 0 && absolute_program(x) == 0 && *(x) != '~' && test_for_directory (x))
1692 :
1693 0 : dot_in_path = 0;
1694 0 : matches = rl_completion_matches (text, command_word_completion_function);
1695 :
1696 : /* If we are attempting command completion and nothing matches, we
1697 : do not want readline to perform filename completion for us. We
1698 : still want to be able to complete partial pathnames, so set the
1699 : completion ignore function to something which will remove
1700 : filenames and leave directories in the match list. */
1701 0 : if (matches == (char **)NULL)
1702 0 : rl_ignore_some_completions_function = bash_ignore_filenames;
1703 0 : else if (matches[1] == 0 && CMD_IS_DIR(matches[0]) && dot_in_path == 0)
1704 : /* If we found a single match, without looking in the current
1705 : directory (because it's not in $PATH), but the found name is
1706 : also a command in the current directory, suppress appending any
1707 : terminating character, since it's ambiguous. */
1708 : {
1709 0 : rl_completion_suppress_append = 1;
1710 0 : rl_filename_completion_desired = 0;
1711 : }
1712 0 : else if (matches[0] && matches[1] && STREQ (matches[0], matches[1]) && CMD_IS_DIR (matches[0]))
1713 : /* There are multiple instances of the same match (duplicate
1714 : completions haven't yet been removed). In this case, all of
1715 : the matches will be the same, and the duplicate removal code
1716 : will distill them all down to one. We turn on
1717 : rl_completion_suppress_append for the same reason as above.
1718 : Remember: we only care if there's eventually a single unique
1719 : completion. If there are multiple completions this won't
1720 : make a difference and the problem won't occur. */
1721 : {
1722 0 : rl_completion_suppress_append = 1;
1723 0 : rl_filename_completion_desired = 0;
1724 : }
1725 : }
1726 : }
1727 :
1728 : /* This could be a globbing pattern, so try to expand it using pathname
1729 : expansion. */
1730 0 : if (!matches && glob_pattern_p (text))
1731 : {
1732 0 : matches = rl_completion_matches (text, glob_complete_word);
1733 : /* A glob expression that matches more than one filename is problematic.
1734 : If we match more than one filename, punt. */
1735 0 : if (matches && matches[1] && rl_completion_type == TAB)
1736 : {
1737 0 : strvec_dispose (matches);
1738 0 : matches = (char **)0;
1739 : }
1740 0 : else if (matches && matches[1] && rl_completion_type == '!')
1741 : {
1742 0 : rl_completion_suppress_append = 1;
1743 0 : rl_filename_completion_desired = 0;
1744 : }
1745 : }
1746 :
1747 0 : return (matches);
1748 : }
1749 :
1750 : static int
1751 0 : bash_command_name_stat_hook (name)
1752 : char **name;
1753 : {
1754 0 : char *cname, *result;
1755 :
1756 : /* If it's not something we're going to look up in $PATH, just call the
1757 : normal filename stat hook. */
1758 0 : if (absolute_program (*name))
1759 0 : return (bash_filename_stat_hook (name));
1760 :
1761 0 : cname = *name;
1762 : /* XXX - we could do something here with converting aliases, builtins,
1763 : and functions into something that came out as executable, but we don't. */
1764 0 : result = search_for_command (cname, 0);
1765 0 : if (result)
1766 : {
1767 0 : *name = result;
1768 0 : return 1;
1769 : }
1770 : return 0;
1771 : }
1772 :
1773 : static int
1774 0 : executable_completion (filename, searching_path)
1775 : const char *filename;
1776 : int searching_path;
1777 : {
1778 0 : char *f;
1779 0 : int r;
1780 :
1781 0 : f = savestring (filename);
1782 0 : bash_directory_completion_hook (&f);
1783 :
1784 0 : r = searching_path ? executable_file (f) : executable_or_directory (f);
1785 0 : free (f);
1786 0 : return r;
1787 : }
1788 :
1789 : /* This is the function to call when the word to complete is in a position
1790 : where a command word can be found. It grovels $PATH, looking for commands
1791 : that match. It also scans aliases, function names, and the shell_builtin
1792 : table. */
1793 : char *
1794 0 : command_word_completion_function (hint_text, state)
1795 : const char *hint_text;
1796 : int state;
1797 : {
1798 0 : static char *hint = (char *)NULL;
1799 0 : static char *path = (char *)NULL;
1800 0 : static char *val = (char *)NULL;
1801 0 : static char *filename_hint = (char *)NULL;
1802 0 : static char *fnhint = (char *)NULL;
1803 0 : static char *dequoted_hint = (char *)NULL;
1804 0 : static char *directory_part = (char *)NULL;
1805 0 : static char **glob_matches = (char **)NULL;
1806 0 : static int path_index, hint_len, istate, igncase;
1807 0 : static int mapping_over, local_index, searching_path, hint_is_dir;
1808 0 : static int old_glob_ignore_case, globpat;
1809 0 : static SHELL_VAR **varlist = (SHELL_VAR **)NULL;
1810 : #if defined (ALIAS)
1811 0 : static alias_t **alias_list = (alias_t **)NULL;
1812 : #endif /* ALIAS */
1813 0 : char *temp, *cval;
1814 :
1815 : /* We have to map over the possibilities for command words. If we have
1816 : no state, then make one just for that purpose. */
1817 0 : if (state == 0)
1818 : {
1819 0 : rl_filename_stat_hook = bash_command_name_stat_hook;
1820 :
1821 0 : if (dequoted_hint && dequoted_hint != hint)
1822 0 : free (dequoted_hint);
1823 0 : if (hint)
1824 0 : free (hint);
1825 :
1826 0 : mapping_over = searching_path = 0;
1827 0 : hint_is_dir = CMD_IS_DIR (hint_text);
1828 0 : val = (char *)NULL;
1829 :
1830 0 : temp = rl_variable_value ("completion-ignore-case");
1831 0 : igncase = RL_BOOLEAN_VARIABLE_VALUE (temp);
1832 :
1833 0 : if (glob_matches)
1834 : {
1835 0 : free (glob_matches);
1836 0 : glob_matches = (char **)NULL;
1837 : }
1838 :
1839 0 : globpat = glob_pattern_p (hint_text);
1840 :
1841 : /* If this is an absolute program name, do not check it against
1842 : aliases, reserved words, functions or builtins. We must check
1843 : whether or not it is unique, and, if so, whether that filename
1844 : is executable. */
1845 0 : if (globpat || absolute_program (hint_text))
1846 : {
1847 : /* Perform tilde expansion on what's passed, so we don't end up
1848 : passing filenames with tildes directly to stat(). The rest of
1849 : the shell doesn't do variable expansion on the word following
1850 : the tilde, so we don't do it here even if direxpand is set. */
1851 0 : if (*hint_text == '~')
1852 : {
1853 0 : hint = bash_tilde_expand (hint_text, 0);
1854 0 : directory_part = savestring (hint_text);
1855 0 : temp = strchr (directory_part, '/');
1856 0 : if (temp)
1857 0 : *temp = 0;
1858 : else
1859 : {
1860 0 : free (directory_part);
1861 0 : directory_part = (char *)NULL;
1862 : }
1863 : }
1864 0 : else if (dircomplete_expand)
1865 : {
1866 0 : hint = savestring (hint_text);
1867 0 : bash_directory_completion_hook (&hint);
1868 : }
1869 : else
1870 0 : hint = savestring (hint_text);
1871 :
1872 0 : dequoted_hint = hint;
1873 : /* If readline's completer found a quote character somewhere, but
1874 : didn't set the quote character, there must have been a quote
1875 : character embedded in the filename. It can't be at the start of
1876 : the filename, so we need to dequote the filename before we look
1877 : in the file system for it. */
1878 0 : if (rl_completion_found_quote && rl_completion_quote_character == 0)
1879 : {
1880 0 : dequoted_hint = bash_dequote_filename (hint, 0);
1881 0 : free (hint);
1882 0 : hint = dequoted_hint;
1883 : }
1884 0 : hint_len = strlen (hint);
1885 :
1886 0 : if (filename_hint)
1887 0 : free (filename_hint);
1888 :
1889 0 : fnhint = filename_hint = savestring (hint);
1890 :
1891 0 : istate = 0;
1892 :
1893 0 : if (globpat)
1894 : {
1895 0 : mapping_over = 5;
1896 0 : goto globword;
1897 : }
1898 : else
1899 : {
1900 0 : if (dircomplete_expand && path_dot_or_dotdot (filename_hint))
1901 : {
1902 0 : dircomplete_expand = 0;
1903 0 : set_directory_hook ();
1904 0 : dircomplete_expand = 1;
1905 : }
1906 0 : mapping_over = 4;
1907 0 : goto inner;
1908 : }
1909 : }
1910 :
1911 0 : dequoted_hint = hint = savestring (hint_text);
1912 0 : hint_len = strlen (hint);
1913 :
1914 0 : if (rl_completion_found_quote && rl_completion_quote_character == 0)
1915 : {
1916 0 : dequoted_hint = bash_dequote_filename (hint, 0);
1917 : }
1918 :
1919 0 : path = get_string_value ("PATH");
1920 0 : path_index = dot_in_path = 0;
1921 :
1922 : /* Initialize the variables for each type of command word. */
1923 0 : local_index = 0;
1924 :
1925 0 : if (varlist)
1926 0 : free (varlist);
1927 :
1928 0 : varlist = all_visible_functions ();
1929 :
1930 : #if defined (ALIAS)
1931 0 : if (alias_list)
1932 0 : free (alias_list);
1933 :
1934 0 : alias_list = all_aliases ();
1935 : #endif /* ALIAS */
1936 : }
1937 :
1938 : /* mapping_over says what we are currently hacking. Note that every case
1939 : in this list must fall through when there are no more possibilities. */
1940 :
1941 0 : switch (mapping_over)
1942 : {
1943 : case 0: /* Aliases come first. */
1944 : #if defined (ALIAS)
1945 0 : while (alias_list && alias_list[local_index])
1946 : {
1947 0 : register char *alias;
1948 :
1949 0 : alias = alias_list[local_index++]->name;
1950 :
1951 0 : if (STREQN (alias, hint, hint_len))
1952 0 : return (savestring (alias));
1953 : }
1954 : #endif /* ALIAS */
1955 0 : local_index = 0;
1956 0 : mapping_over++;
1957 :
1958 : case 1: /* Then shell reserved words. */
1959 : {
1960 0 : while (word_token_alist[local_index].word)
1961 : {
1962 0 : register char *reserved_word;
1963 :
1964 0 : reserved_word = word_token_alist[local_index++].word;
1965 :
1966 0 : if (STREQN (reserved_word, hint, hint_len))
1967 0 : return (savestring (reserved_word));
1968 : }
1969 0 : local_index = 0;
1970 0 : mapping_over++;
1971 : }
1972 :
1973 : case 2: /* Then function names. */
1974 0 : while (varlist && varlist[local_index])
1975 : {
1976 0 : register char *varname;
1977 :
1978 0 : varname = varlist[local_index++]->name;
1979 :
1980 0 : if (STREQN (varname, hint, hint_len))
1981 0 : return (savestring (varname));
1982 : }
1983 0 : local_index = 0;
1984 0 : mapping_over++;
1985 :
1986 : case 3: /* Then shell builtins. */
1987 0 : for (; local_index < num_shell_builtins; local_index++)
1988 : {
1989 : /* Ignore it if it doesn't have a function pointer or if it
1990 : is not currently enabled. */
1991 0 : if (!shell_builtins[local_index].function ||
1992 0 : (shell_builtins[local_index].flags & BUILTIN_ENABLED) == 0)
1993 : continue;
1994 :
1995 0 : if (STREQN (shell_builtins[local_index].name, hint, hint_len))
1996 : {
1997 0 : int i = local_index++;
1998 :
1999 0 : return (savestring (shell_builtins[i].name));
2000 : }
2001 : }
2002 0 : local_index = 0;
2003 0 : mapping_over++;
2004 : }
2005 :
2006 0 : globword:
2007 : /* Limited support for completing command words with globbing chars. Only
2008 : a single match (multiple matches that end up reducing the number of
2009 : characters in the common prefix are bad) will ever be returned on
2010 : regular completion. */
2011 0 : if (globpat)
2012 : {
2013 0 : if (state == 0)
2014 : {
2015 0 : glob_ignore_case = igncase;
2016 0 : glob_matches = shell_glob_filename (hint);
2017 0 : glob_ignore_case = old_glob_ignore_case;
2018 :
2019 0 : if (GLOB_FAILED (glob_matches) || glob_matches == 0)
2020 : {
2021 0 : glob_matches = (char **)NULL;
2022 0 : return ((char *)NULL);
2023 : }
2024 :
2025 0 : local_index = 0;
2026 :
2027 0 : if (glob_matches[1] && rl_completion_type == TAB) /* multiple matches are bad */
2028 : return ((char *)NULL);
2029 : }
2030 :
2031 0 : while (val = glob_matches[local_index++])
2032 : {
2033 0 : if (executable_or_directory (val))
2034 : {
2035 0 : if (*hint_text == '~' && directory_part)
2036 : {
2037 0 : temp = maybe_restore_tilde (val, directory_part);
2038 0 : free (val);
2039 0 : val = temp;
2040 : }
2041 0 : return (val);
2042 : }
2043 0 : free (val);
2044 : }
2045 :
2046 0 : glob_ignore_case = old_glob_ignore_case;
2047 0 : return ((char *)NULL);
2048 : }
2049 :
2050 : /* If the text passed is a directory in the current directory, return it
2051 : as a possible match. Executables in directories in the current
2052 : directory can be specified using relative pathnames and successfully
2053 : executed even when `.' is not in $PATH. */
2054 0 : if (hint_is_dir)
2055 : {
2056 0 : hint_is_dir = 0; /* only return the hint text once */
2057 0 : return (savestring (hint_text));
2058 : }
2059 :
2060 : /* Repeatedly call filename_completion_function while we have
2061 : members of PATH left. Question: should we stat each file?
2062 : Answer: we call executable_file () on each file. */
2063 0 : outer:
2064 :
2065 0 : istate = (val != (char *)NULL);
2066 :
2067 0 : if (istate == 0)
2068 : {
2069 0 : char *current_path;
2070 :
2071 : /* Get the next directory from the path. If there is none, then we
2072 : are all done. */
2073 0 : if (path == 0 || path[path_index] == 0 ||
2074 0 : (current_path = extract_colon_unit (path, &path_index)) == 0)
2075 0 : return ((char *)NULL);
2076 :
2077 0 : searching_path = 1;
2078 0 : if (*current_path == 0)
2079 : {
2080 0 : free (current_path);
2081 0 : current_path = savestring (".");
2082 : }
2083 :
2084 0 : if (*current_path == '~')
2085 : {
2086 0 : char *t;
2087 :
2088 0 : t = bash_tilde_expand (current_path, 0);
2089 0 : free (current_path);
2090 0 : current_path = t;
2091 : }
2092 :
2093 0 : if (current_path[0] == '.' && current_path[1] == '\0')
2094 0 : dot_in_path = 1;
2095 :
2096 0 : if (fnhint && fnhint != filename_hint)
2097 0 : free (fnhint);
2098 0 : if (filename_hint)
2099 0 : free (filename_hint);
2100 :
2101 0 : filename_hint = sh_makepath (current_path, hint, 0);
2102 : /* Need a quoted version (though it doesn't matter much in most
2103 : cases) because rl_filename_completion_function dequotes the
2104 : filename it gets, assuming that it's been quoted as part of
2105 : the input line buffer. */
2106 0 : if (strpbrk (filename_hint, "\"'\\"))
2107 0 : fnhint = sh_backslash_quote (filename_hint, filename_bstab, 0);
2108 : else
2109 0 : fnhint = filename_hint;
2110 0 : free (current_path); /* XXX */
2111 : }
2112 :
2113 0 : inner:
2114 0 : val = rl_filename_completion_function (fnhint, istate);
2115 0 : if (mapping_over == 4 && dircomplete_expand)
2116 0 : set_directory_hook ();
2117 :
2118 0 : istate = 1;
2119 :
2120 0 : if (val == 0)
2121 : {
2122 : /* If the hint text is an absolute program, then don't bother
2123 : searching through PATH. */
2124 0 : if (absolute_program (hint))
2125 : return ((char *)NULL);
2126 :
2127 : goto outer;
2128 : }
2129 : else
2130 : {
2131 0 : int match, freetemp;
2132 :
2133 0 : if (absolute_program (hint))
2134 : {
2135 0 : if (igncase == 0)
2136 0 : match = strncmp (val, hint, hint_len) == 0;
2137 : else
2138 0 : match = strncasecmp (val, hint, hint_len) == 0;
2139 :
2140 : /* If we performed tilde expansion, restore the original
2141 : filename. */
2142 0 : if (*hint_text == '~')
2143 0 : temp = maybe_restore_tilde (val, directory_part);
2144 : else
2145 0 : temp = savestring (val);
2146 : freetemp = 1;
2147 : }
2148 : else
2149 : {
2150 0 : temp = strrchr (val, '/');
2151 :
2152 0 : if (temp)
2153 : {
2154 0 : temp++;
2155 0 : if (igncase == 0)
2156 0 : freetemp = match = strncmp (temp, hint, hint_len) == 0;
2157 : else
2158 0 : freetemp = match = strncasecmp (temp, hint, hint_len) == 0;
2159 0 : if (match)
2160 0 : temp = savestring (temp);
2161 : }
2162 : else
2163 : freetemp = match = 0;
2164 : }
2165 :
2166 : /* If we have found a match, and it is an executable file, return it.
2167 : We don't return directory names when searching $PATH, since the
2168 : bash execution code won't find executables in directories which
2169 : appear in directories in $PATH when they're specified using
2170 : relative pathnames. */
2171 : #if 0
2172 : /* If we're not searching $PATH and we have a relative pathname, we
2173 : need to re-canonicalize it before testing whether or not it's an
2174 : executable or a directory so the shell treats .. relative to $PWD
2175 : according to the physical/logical option. The shell already
2176 : canonicalizes the directory name in order to tell readline where
2177 : to look, so not doing it here will be inconsistent. */
2178 : /* XXX -- currently not used -- will introduce more inconsistency,
2179 : since shell does not canonicalize ../foo before passing it to
2180 : shell_execve(). */
2181 : if (match && searching_path == 0 && *val == '.')
2182 : {
2183 : char *t, *t1;
2184 :
2185 : t = get_working_directory ("command-word-completion");
2186 : t1 = make_absolute (val, t);
2187 : free (t);
2188 : cval = sh_canonpath (t1, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
2189 : }
2190 : else
2191 : #endif
2192 0 : cval = val;
2193 :
2194 0 : if (match && executable_completion ((searching_path ? val : cval), searching_path))
2195 : {
2196 0 : if (cval != val)
2197 0 : free (cval);
2198 0 : free (val);
2199 0 : val = ""; /* So it won't be NULL. */
2200 0 : return (temp);
2201 : }
2202 : else
2203 : {
2204 0 : if (freetemp)
2205 0 : free (temp);
2206 0 : if (cval != val)
2207 0 : free (cval);
2208 0 : free (val);
2209 0 : goto inner;
2210 : }
2211 : }
2212 : }
2213 :
2214 : /* Completion inside an unterminated command substitution. */
2215 : static char *
2216 0 : command_subst_completion_function (text, state)
2217 : const char *text;
2218 : int state;
2219 : {
2220 0 : static char **matches = (char **)NULL;
2221 0 : static const char *orig_start;
2222 0 : static char *filename_text = (char *)NULL;
2223 0 : static int cmd_index, start_len;
2224 0 : char *value;
2225 :
2226 0 : if (state == 0)
2227 : {
2228 0 : if (filename_text)
2229 0 : free (filename_text);
2230 0 : orig_start = text;
2231 0 : if (*text == '`')
2232 0 : text++;
2233 0 : else if (*text == '$' && text[1] == '(') /* ) */
2234 0 : text += 2;
2235 : /* If the text was quoted, suppress any quote character that the
2236 : readline completion code would insert. */
2237 0 : rl_completion_suppress_quote = 1;
2238 0 : start_len = text - orig_start;
2239 0 : filename_text = savestring (text);
2240 0 : if (matches)
2241 0 : free (matches);
2242 :
2243 : /*
2244 : * At this point we can entertain the idea of re-parsing
2245 : * `filename_text' into a (possibly incomplete) command name and
2246 : * arguments, and doing completion based on that. This is
2247 : * currently very rudimentary, but it is a small improvement.
2248 : */
2249 0 : for (value = filename_text + strlen (filename_text) - 1; value > filename_text; value--)
2250 0 : if (whitespace (*value) || member (*value, COMMAND_SEPARATORS))
2251 : break;
2252 0 : if (value <= filename_text)
2253 0 : matches = rl_completion_matches (filename_text, command_word_completion_function);
2254 : else
2255 : {
2256 0 : value++;
2257 0 : start_len += value - filename_text;
2258 0 : if (whitespace (value[-1]))
2259 0 : matches = rl_completion_matches (value, rl_filename_completion_function);
2260 : else
2261 0 : matches = rl_completion_matches (value, command_word_completion_function);
2262 : }
2263 :
2264 : /* If there is more than one match, rl_completion_matches has already
2265 : put the lcd in matches[0]. Skip over it. */
2266 0 : cmd_index = matches && matches[0] && matches[1];
2267 :
2268 : /* If there's a single match and it's a directory, set the append char
2269 : to the expected `/'. Otherwise, don't append anything. */
2270 0 : if (matches && matches[0] && matches[1] == 0 && test_for_directory (matches[0]))
2271 0 : rl_completion_append_character = '/';
2272 : else
2273 0 : rl_completion_suppress_append = 1;
2274 : }
2275 :
2276 0 : if (matches == 0 || matches[cmd_index] == 0)
2277 : {
2278 0 : rl_filename_quoting_desired = 0; /* disable quoting */
2279 0 : return ((char *)NULL);
2280 : }
2281 : else
2282 : {
2283 0 : value = (char *)xmalloc (1 + start_len + strlen (matches[cmd_index]));
2284 :
2285 0 : if (start_len == 1)
2286 0 : value[0] = *orig_start;
2287 : else
2288 0 : strncpy (value, orig_start, start_len);
2289 :
2290 0 : strcpy (value + start_len, matches[cmd_index]);
2291 :
2292 0 : cmd_index++;
2293 0 : return (value);
2294 : }
2295 : }
2296 :
2297 : /* Okay, now we write the entry_function for variable completion. */
2298 : static char *
2299 0 : variable_completion_function (text, state)
2300 : const char *text;
2301 : int state;
2302 : {
2303 0 : static char **varlist = (char **)NULL;
2304 0 : static int varlist_index;
2305 0 : static char *varname = (char *)NULL;
2306 0 : static int first_char, first_char_loc;
2307 :
2308 0 : if (!state)
2309 : {
2310 0 : if (varname)
2311 0 : free (varname);
2312 :
2313 0 : first_char_loc = 0;
2314 0 : first_char = text[0];
2315 :
2316 0 : if (first_char == '$')
2317 0 : first_char_loc++;
2318 :
2319 0 : if (text[first_char_loc] == '{')
2320 0 : first_char_loc++;
2321 :
2322 0 : varname = savestring (text + first_char_loc);
2323 :
2324 0 : if (varlist)
2325 0 : strvec_dispose (varlist);
2326 :
2327 0 : varlist = all_variables_matching_prefix (varname);
2328 0 : varlist_index = 0;
2329 : }
2330 :
2331 0 : if (!varlist || !varlist[varlist_index])
2332 : {
2333 : return ((char *)NULL);
2334 : }
2335 : else
2336 : {
2337 0 : char *value;
2338 :
2339 0 : value = (char *)xmalloc (4 + strlen (varlist[varlist_index]));
2340 :
2341 0 : if (first_char_loc)
2342 : {
2343 0 : value[0] = first_char;
2344 0 : if (first_char_loc == 2)
2345 0 : value[1] = '{';
2346 : }
2347 :
2348 0 : strcpy (value + first_char_loc, varlist[varlist_index]);
2349 0 : if (first_char_loc == 2)
2350 0 : strcat (value, "}");
2351 :
2352 0 : varlist_index++;
2353 0 : return (value);
2354 : }
2355 : }
2356 :
2357 : /* How about a completion function for hostnames? */
2358 : static char *
2359 0 : hostname_completion_function (text, state)
2360 : const char *text;
2361 : int state;
2362 : {
2363 0 : static char **list = (char **)NULL;
2364 0 : static int list_index = 0;
2365 0 : static int first_char, first_char_loc;
2366 :
2367 : /* If we don't have any state, make some. */
2368 0 : if (state == 0)
2369 : {
2370 0 : FREE (list);
2371 :
2372 0 : list = (char **)NULL;
2373 :
2374 0 : first_char_loc = 0;
2375 0 : first_char = *text;
2376 :
2377 0 : if (first_char == '@')
2378 0 : first_char_loc++;
2379 :
2380 0 : list = hostnames_matching ((char *)text+first_char_loc);
2381 0 : list_index = 0;
2382 : }
2383 :
2384 0 : if (list && list[list_index])
2385 : {
2386 0 : char *t;
2387 :
2388 0 : t = (char *)xmalloc (2 + strlen (list[list_index]));
2389 0 : *t = first_char;
2390 0 : strcpy (t + first_char_loc, list[list_index]);
2391 0 : list_index++;
2392 0 : return (t);
2393 : }
2394 :
2395 : return ((char *)NULL);
2396 : }
2397 :
2398 : /*
2399 : * A completion function for service names from /etc/services (or wherever).
2400 : */
2401 : char *
2402 0 : bash_servicename_completion_function (text, state)
2403 : const char *text;
2404 : int state;
2405 : {
2406 : #if defined (__WIN32__) || defined (__OPENNT) || !defined (HAVE_GETSERVENT)
2407 : return ((char *)NULL);
2408 : #else
2409 0 : static char *sname = (char *)NULL;
2410 0 : static struct servent *srvent;
2411 0 : static int snamelen;
2412 0 : char *value;
2413 0 : char **alist, *aentry;
2414 0 : int afound;
2415 :
2416 0 : if (state == 0)
2417 : {
2418 0 : FREE (sname);
2419 :
2420 0 : sname = savestring (text);
2421 0 : snamelen = strlen (sname);
2422 0 : setservent (0);
2423 : }
2424 :
2425 0 : while (srvent = getservent ())
2426 : {
2427 0 : afound = 0;
2428 0 : if (snamelen == 0 || (STREQN (sname, srvent->s_name, snamelen)))
2429 : break;
2430 : /* Not primary, check aliases */
2431 0 : for (alist = srvent->s_aliases; *alist; alist++)
2432 : {
2433 0 : aentry = *alist;
2434 0 : if (STREQN (sname, aentry, snamelen))
2435 : {
2436 : afound = 1;
2437 : break;
2438 : }
2439 : }
2440 :
2441 0 : if (afound)
2442 : break;
2443 : }
2444 :
2445 0 : if (srvent == 0)
2446 : {
2447 0 : endservent ();
2448 0 : return ((char *)NULL);
2449 : }
2450 :
2451 0 : value = afound ? savestring (aentry) : savestring (srvent->s_name);
2452 : return value;
2453 : #endif
2454 : }
2455 :
2456 : /*
2457 : * A completion function for group names from /etc/group (or wherever).
2458 : */
2459 : char *
2460 0 : bash_groupname_completion_function (text, state)
2461 : const char *text;
2462 : int state;
2463 : {
2464 : #if defined (__WIN32__) || defined (__OPENNT) || !defined (HAVE_GRP_H)
2465 : return ((char *)NULL);
2466 : #else
2467 0 : static char *gname = (char *)NULL;
2468 0 : static struct group *grent;
2469 0 : static int gnamelen;
2470 0 : char *value;
2471 :
2472 0 : if (state == 0)
2473 : {
2474 0 : FREE (gname);
2475 0 : gname = savestring (text);
2476 0 : gnamelen = strlen (gname);
2477 :
2478 0 : setgrent ();
2479 : }
2480 :
2481 0 : while (grent = getgrent ())
2482 : {
2483 0 : if (gnamelen == 0 || (STREQN (gname, grent->gr_name, gnamelen)))
2484 : break;
2485 : }
2486 :
2487 0 : if (grent == 0)
2488 : {
2489 0 : endgrent ();
2490 0 : return ((char *)NULL);
2491 : }
2492 :
2493 0 : value = savestring (grent->gr_name);
2494 0 : return (value);
2495 : #endif
2496 : }
2497 :
2498 : /* Functions to perform history and alias expansions on the current line. */
2499 :
2500 : #if defined (BANG_HISTORY)
2501 : /* Perform history expansion on the current line. If no history expansion
2502 : is done, pre_process_line() returns what it was passed, so we need to
2503 : allocate a new line here. */
2504 : static char *
2505 0 : history_expand_line_internal (line)
2506 : char *line;
2507 : {
2508 0 : char *new_line;
2509 0 : int old_verify;
2510 :
2511 0 : old_verify = hist_verify;
2512 0 : hist_verify = 0;
2513 0 : new_line = pre_process_line (line, 0, 0);
2514 0 : hist_verify = old_verify;
2515 :
2516 0 : return (new_line == line) ? savestring (line) : new_line;
2517 : }
2518 : #endif
2519 :
2520 : /* There was an error in expansion. Let the preprocessor print
2521 : the error here. */
2522 : static void
2523 0 : cleanup_expansion_error ()
2524 : {
2525 0 : char *to_free;
2526 : #if defined (BANG_HISTORY)
2527 0 : int old_verify;
2528 :
2529 0 : old_verify = hist_verify;
2530 0 : hist_verify = 0;
2531 : #endif
2532 :
2533 0 : fprintf (rl_outstream, "\r\n");
2534 0 : to_free = pre_process_line (rl_line_buffer, 1, 0);
2535 : #if defined (BANG_HISTORY)
2536 0 : hist_verify = old_verify;
2537 : #endif
2538 0 : if (to_free != rl_line_buffer)
2539 0 : FREE (to_free);
2540 0 : putc ('\r', rl_outstream);
2541 0 : rl_forced_update_display ();
2542 0 : }
2543 :
2544 : /* If NEW_LINE differs from what is in the readline line buffer, add an
2545 : undo record to get from the readline line buffer contents to the new
2546 : line and make NEW_LINE the current readline line. */
2547 : static void
2548 0 : maybe_make_readline_line (new_line)
2549 : char *new_line;
2550 : {
2551 0 : if (strcmp (new_line, rl_line_buffer) != 0)
2552 : {
2553 0 : rl_point = rl_end;
2554 :
2555 0 : rl_add_undo (UNDO_BEGIN, 0, 0, 0);
2556 0 : rl_delete_text (0, rl_point);
2557 0 : rl_point = rl_end = rl_mark = 0;
2558 0 : rl_insert_text (new_line);
2559 0 : rl_add_undo (UNDO_END, 0, 0, 0);
2560 : }
2561 0 : }
2562 :
2563 : /* Make NEW_LINE be the current readline line. This frees NEW_LINE. */
2564 : static void
2565 0 : set_up_new_line (new_line)
2566 : char *new_line;
2567 : {
2568 0 : int old_point, at_end;
2569 :
2570 0 : old_point = rl_point;
2571 0 : at_end = rl_point == rl_end;
2572 :
2573 : /* If the line was history and alias expanded, then make that
2574 : be one thing to undo. */
2575 0 : maybe_make_readline_line (new_line);
2576 0 : free (new_line);
2577 :
2578 : /* Place rl_point where we think it should go. */
2579 0 : if (at_end)
2580 0 : rl_point = rl_end;
2581 0 : else if (old_point < rl_end)
2582 : {
2583 0 : rl_point = old_point;
2584 0 : if (!whitespace (rl_line_buffer[rl_point]))
2585 0 : rl_forward_word (1, 0);
2586 : }
2587 0 : }
2588 :
2589 : #if defined (ALIAS)
2590 : /* Expand aliases in the current readline line. */
2591 : static int
2592 0 : alias_expand_line (count, ignore)
2593 : int count, ignore;
2594 : {
2595 0 : char *new_line;
2596 :
2597 0 : new_line = alias_expand (rl_line_buffer);
2598 :
2599 0 : if (new_line)
2600 : {
2601 0 : set_up_new_line (new_line);
2602 0 : return (0);
2603 : }
2604 : else
2605 : {
2606 0 : cleanup_expansion_error ();
2607 0 : return (1);
2608 : }
2609 : }
2610 : #endif
2611 :
2612 : #if defined (BANG_HISTORY)
2613 : /* History expand the line. */
2614 : static int
2615 0 : history_expand_line (count, ignore)
2616 : int count, ignore;
2617 : {
2618 0 : char *new_line;
2619 :
2620 0 : new_line = history_expand_line_internal (rl_line_buffer);
2621 :
2622 0 : if (new_line)
2623 : {
2624 0 : set_up_new_line (new_line);
2625 0 : return (0);
2626 : }
2627 : else
2628 : {
2629 0 : cleanup_expansion_error ();
2630 0 : return (1);
2631 : }
2632 : }
2633 :
2634 : /* Expand history substitutions in the current line and then insert a
2635 : space (hopefully close to where we were before). */
2636 : static int
2637 0 : tcsh_magic_space (count, ignore)
2638 : int count, ignore;
2639 : {
2640 0 : int dist_from_end, old_point;
2641 :
2642 0 : old_point = rl_point;
2643 0 : dist_from_end = rl_end - rl_point;
2644 0 : if (history_expand_line (count, ignore) == 0)
2645 : {
2646 : /* Try a simple heuristic from Stephen Gildea <gildea@intouchsys.com>.
2647 : This works if all expansions were before rl_point or if no expansions
2648 : were performed. */
2649 0 : rl_point = (old_point == 0) ? old_point : rl_end - dist_from_end;
2650 0 : rl_insert (1, ' ');
2651 0 : return (0);
2652 : }
2653 : else
2654 : return (1);
2655 : }
2656 : #endif /* BANG_HISTORY */
2657 :
2658 : /* History and alias expand the line. */
2659 : static int
2660 0 : history_and_alias_expand_line (count, ignore)
2661 : int count, ignore;
2662 : {
2663 0 : char *new_line;
2664 :
2665 0 : new_line = 0;
2666 : #if defined (BANG_HISTORY)
2667 0 : new_line = history_expand_line_internal (rl_line_buffer);
2668 : #endif
2669 :
2670 : #if defined (ALIAS)
2671 0 : if (new_line)
2672 : {
2673 0 : char *alias_line;
2674 :
2675 0 : alias_line = alias_expand (new_line);
2676 0 : free (new_line);
2677 0 : new_line = alias_line;
2678 : }
2679 : #endif /* ALIAS */
2680 :
2681 0 : if (new_line)
2682 : {
2683 0 : set_up_new_line (new_line);
2684 0 : return (0);
2685 : }
2686 : else
2687 : {
2688 0 : cleanup_expansion_error ();
2689 0 : return (1);
2690 : }
2691 : }
2692 :
2693 : /* History and alias expand the line, then perform the shell word
2694 : expansions by calling expand_string. This can't use set_up_new_line()
2695 : because we want the variable expansions as a separate undo'able
2696 : set of operations. */
2697 : static int
2698 0 : shell_expand_line (count, ignore)
2699 : int count, ignore;
2700 : {
2701 0 : char *new_line;
2702 0 : WORD_LIST *expanded_string;
2703 :
2704 0 : new_line = 0;
2705 : #if defined (BANG_HISTORY)
2706 0 : new_line = history_expand_line_internal (rl_line_buffer);
2707 : #endif
2708 :
2709 : #if defined (ALIAS)
2710 0 : if (new_line)
2711 : {
2712 0 : char *alias_line;
2713 :
2714 0 : alias_line = alias_expand (new_line);
2715 0 : free (new_line);
2716 0 : new_line = alias_line;
2717 : }
2718 : #endif /* ALIAS */
2719 :
2720 0 : if (new_line)
2721 : {
2722 0 : int old_point = rl_point;
2723 0 : int at_end = rl_point == rl_end;
2724 :
2725 : /* If the line was history and alias expanded, then make that
2726 : be one thing to undo. */
2727 0 : maybe_make_readline_line (new_line);
2728 0 : free (new_line);
2729 :
2730 : /* If there is variable expansion to perform, do that as a separate
2731 : operation to be undone. */
2732 0 : new_line = savestring (rl_line_buffer);
2733 0 : expanded_string = expand_string (new_line, 0);
2734 0 : FREE (new_line);
2735 0 : if (expanded_string == 0)
2736 : {
2737 0 : new_line = (char *)xmalloc (1);
2738 0 : new_line[0] = '\0';
2739 : }
2740 : else
2741 : {
2742 0 : new_line = string_list (expanded_string);
2743 0 : dispose_words (expanded_string);
2744 : }
2745 :
2746 0 : maybe_make_readline_line (new_line);
2747 0 : free (new_line);
2748 :
2749 : /* Place rl_point where we think it should go. */
2750 0 : if (at_end)
2751 0 : rl_point = rl_end;
2752 0 : else if (old_point < rl_end)
2753 : {
2754 0 : rl_point = old_point;
2755 0 : if (!whitespace (rl_line_buffer[rl_point]))
2756 0 : rl_forward_word (1, 0);
2757 : }
2758 0 : return 0;
2759 : }
2760 : else
2761 : {
2762 0 : cleanup_expansion_error ();
2763 0 : return 1;
2764 : }
2765 : }
2766 :
2767 : /* If FIGNORE is set, then don't match files with the given suffixes when
2768 : completing filenames. If only one of the possibilities has an acceptable
2769 : suffix, delete the others, else just return and let the completer
2770 : signal an error. It is called by the completer when real
2771 : completions are done on filenames by the completer's internal
2772 : function, not for completion lists (M-?) and not on "other"
2773 : completion types, such as hostnames or commands. */
2774 :
2775 : static struct ignorevar fignore =
2776 : {
2777 : "FIGNORE",
2778 : (struct ign *)0,
2779 : 0,
2780 : (char *)0,
2781 : (sh_iv_item_func_t *) 0,
2782 : };
2783 :
2784 : static void
2785 0 : _ignore_completion_names (names, name_func)
2786 : char **names;
2787 : sh_ignore_func_t *name_func;
2788 : {
2789 0 : char **newnames;
2790 0 : int idx, nidx;
2791 0 : char **oldnames = 0;
2792 0 : int oidx;
2793 :
2794 : /* If there is only one completion, see if it is acceptable. If it is
2795 : not, free it up. In any case, short-circuit and return. This is a
2796 : special case because names[0] is not the prefix of the list of names
2797 : if there is only one completion; it is the completion itself. */
2798 0 : if (names[1] == (char *)0)
2799 : {
2800 0 : if (force_fignore)
2801 0 : if ((*name_func) (names[0]) == 0)
2802 : {
2803 0 : free (names[0]);
2804 0 : names[0] = (char *)NULL;
2805 : }
2806 :
2807 0 : return;
2808 : }
2809 :
2810 : /* Allocate space for array to hold list of pointers to matching
2811 : filenames. The pointers are copied back to NAMES when done. */
2812 0 : for (nidx = 1; names[nidx]; nidx++)
2813 0 : ;
2814 0 : newnames = strvec_create (nidx + 1);
2815 :
2816 0 : if (force_fignore == 0)
2817 : {
2818 0 : oldnames = strvec_create (nidx - 1);
2819 0 : oidx = 0;
2820 : }
2821 :
2822 0 : newnames[0] = names[0];
2823 0 : for (idx = nidx = 1; names[idx]; idx++)
2824 : {
2825 0 : if ((*name_func) (names[idx]))
2826 0 : newnames[nidx++] = names[idx];
2827 0 : else if (force_fignore == 0)
2828 0 : oldnames[oidx++] = names[idx];
2829 : else
2830 0 : free (names[idx]);
2831 : }
2832 :
2833 0 : newnames[nidx] = (char *)NULL;
2834 :
2835 : /* If none are acceptable then let the completer handle it. */
2836 0 : if (nidx == 1)
2837 : {
2838 0 : if (force_fignore)
2839 : {
2840 0 : free (names[0]);
2841 0 : names[0] = (char *)NULL;
2842 : }
2843 : else
2844 0 : free (oldnames);
2845 :
2846 0 : free (newnames);
2847 0 : return;
2848 : }
2849 :
2850 0 : if (force_fignore == 0)
2851 : {
2852 0 : while (oidx)
2853 0 : free (oldnames[--oidx]);
2854 0 : free (oldnames);
2855 : }
2856 :
2857 : /* If only one is acceptable, copy it to names[0] and return. */
2858 0 : if (nidx == 2)
2859 : {
2860 0 : free (names[0]);
2861 0 : names[0] = newnames[1];
2862 0 : names[1] = (char *)NULL;
2863 0 : free (newnames);
2864 0 : return;
2865 : }
2866 :
2867 : /* Copy the acceptable names back to NAMES, set the new array end,
2868 : and return. */
2869 0 : for (nidx = 1; newnames[nidx]; nidx++)
2870 0 : names[nidx] = newnames[nidx];
2871 0 : names[nidx] = (char *)NULL;
2872 0 : free (newnames);
2873 : }
2874 :
2875 : static int
2876 0 : name_is_acceptable (name)
2877 : const char *name;
2878 : {
2879 0 : struct ign *p;
2880 0 : int nlen;
2881 :
2882 0 : for (nlen = strlen (name), p = fignore.ignores; p->val; p++)
2883 : {
2884 0 : if (nlen > p->len && p->len > 0 && STREQ (p->val, &name[nlen - p->len]))
2885 : return (0);
2886 : }
2887 :
2888 : return (1);
2889 : }
2890 :
2891 : #if 0
2892 : static int
2893 : ignore_dot_names (name)
2894 : char *name;
2895 : {
2896 : return (name[0] != '.');
2897 : }
2898 : #endif
2899 :
2900 : static int
2901 0 : filename_completion_ignore (names)
2902 : char **names;
2903 : {
2904 : #if 0
2905 : if (glob_dot_filenames == 0)
2906 : _ignore_completion_names (names, ignore_dot_names);
2907 : #endif
2908 :
2909 0 : setup_ignore_patterns (&fignore);
2910 :
2911 0 : if (fignore.num_ignores == 0)
2912 : return 0;
2913 :
2914 0 : _ignore_completion_names (names, name_is_acceptable);
2915 :
2916 0 : return 0;
2917 : }
2918 :
2919 : /* Return 1 if NAME is a directory. NAME undergoes tilde expansion. */
2920 : static int
2921 0 : test_for_directory (name)
2922 : const char *name;
2923 : {
2924 0 : char *fn;
2925 0 : int r;
2926 :
2927 0 : fn = bash_tilde_expand (name, 0);
2928 0 : r = file_isdir (fn);
2929 0 : free (fn);
2930 :
2931 0 : return (r);
2932 : }
2933 :
2934 : /* Remove files from NAMES, leaving directories. */
2935 : static int
2936 0 : bash_ignore_filenames (names)
2937 : char **names;
2938 : {
2939 0 : _ignore_completion_names (names, test_for_directory);
2940 0 : return 0;
2941 : }
2942 :
2943 : static int
2944 0 : return_zero (name)
2945 : const char *name;
2946 : {
2947 0 : return 0;
2948 : }
2949 :
2950 : static int
2951 0 : bash_ignore_everything (names)
2952 : char **names;
2953 : {
2954 0 : _ignore_completion_names (names, return_zero);
2955 0 : return 0;
2956 : }
2957 :
2958 : /* Replace a tilde-prefix in VAL with a `~', assuming the user typed it. VAL
2959 : is an expanded filename. DIRECTORY_PART is the tilde-prefix portion
2960 : of the un-tilde-expanded version of VAL (what the user typed). */
2961 : static char *
2962 0 : restore_tilde (val, directory_part)
2963 : char *val, *directory_part;
2964 : {
2965 0 : int l, vl, dl2, xl;
2966 0 : char *dh2, *expdir, *ret;
2967 :
2968 0 : vl = strlen (val);
2969 :
2970 : /* We need to duplicate the expansions readline performs on the directory
2971 : portion before passing it to our completion function. */
2972 0 : dh2 = directory_part ? bash_dequote_filename (directory_part, 0) : 0;
2973 0 : bash_directory_expansion (&dh2);
2974 0 : dl2 = strlen (dh2);
2975 :
2976 0 : expdir = bash_tilde_expand (directory_part, 0);
2977 0 : xl = strlen (expdir);
2978 0 : free (expdir);
2979 :
2980 : /*
2981 : dh2 = unexpanded but dequoted tilde-prefix
2982 : dl2 = length of tilde-prefix
2983 : expdir = tilde-expanded tilde-prefix
2984 : xl = length of expanded tilde-prefix
2985 : l = length of remainder after tilde-prefix
2986 : */
2987 0 : l = (vl - xl) + 1;
2988 :
2989 0 : ret = (char *)xmalloc (dl2 + 2 + l);
2990 0 : strcpy (ret, dh2);
2991 0 : strcpy (ret + dl2, val + xl);
2992 :
2993 0 : free (dh2);
2994 0 : return (ret);
2995 : }
2996 :
2997 : static char *
2998 0 : maybe_restore_tilde (val, directory_part)
2999 : char *val, *directory_part;
3000 : {
3001 0 : rl_icppfunc_t *save;
3002 0 : char *ret;
3003 :
3004 0 : save = (dircomplete_expand == 0) ? save_directory_hook () : (rl_icppfunc_t *)0;
3005 0 : ret = restore_tilde (val, directory_part);
3006 0 : if (save)
3007 0 : restore_directory_hook (save);
3008 0 : return ret;
3009 : }
3010 :
3011 : /* Simulate the expansions that will be performed by
3012 : rl_filename_completion_function. This must be called with the address of
3013 : a pointer to malloc'd memory. */
3014 : static void
3015 0 : bash_directory_expansion (dirname)
3016 : char **dirname;
3017 : {
3018 0 : char *d, *nd;
3019 :
3020 0 : d = savestring (*dirname);
3021 :
3022 0 : if ((rl_directory_rewrite_hook) && (*rl_directory_rewrite_hook) (&d))
3023 : {
3024 0 : free (*dirname);
3025 0 : *dirname = d;
3026 : }
3027 0 : else if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&d))
3028 : {
3029 0 : free (*dirname);
3030 0 : *dirname = d;
3031 : }
3032 0 : else if (rl_completion_found_quote)
3033 : {
3034 0 : nd = bash_dequote_filename (d, rl_completion_quote_character);
3035 0 : free (*dirname);
3036 0 : free (d);
3037 0 : *dirname = nd;
3038 : }
3039 0 : }
3040 :
3041 : /* If necessary, rewrite directory entry */
3042 : static char *
3043 0 : bash_filename_rewrite_hook (fname, fnlen)
3044 : char *fname;
3045 : int fnlen;
3046 : {
3047 0 : char *conv;
3048 :
3049 0 : conv = fnx_fromfs (fname, fnlen);
3050 0 : if (conv != fname)
3051 0 : conv = savestring (conv);
3052 0 : return conv;
3053 : }
3054 :
3055 : /* Functions to save and restore the appropriate directory hook */
3056 : /* This is not static so the shopt code can call it */
3057 : void
3058 0 : set_directory_hook ()
3059 : {
3060 75 : if (dircomplete_expand)
3061 : {
3062 0 : rl_directory_completion_hook = bash_directory_completion_hook;
3063 0 : rl_directory_rewrite_hook = (rl_icppfunc_t *)0;
3064 : }
3065 : else
3066 : {
3067 75 : rl_directory_rewrite_hook = bash_directory_completion_hook;
3068 75 : rl_directory_completion_hook = (rl_icppfunc_t *)0;
3069 : }
3070 0 : }
3071 :
3072 : static rl_icppfunc_t *
3073 : save_directory_hook ()
3074 : {
3075 0 : rl_icppfunc_t *ret;
3076 :
3077 0 : if (dircomplete_expand)
3078 : {
3079 0 : ret = rl_directory_completion_hook;
3080 0 : rl_directory_completion_hook = (rl_icppfunc_t *)NULL;
3081 : }
3082 : else
3083 : {
3084 0 : ret = rl_directory_rewrite_hook;
3085 0 : rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL;
3086 : }
3087 :
3088 0 : return ret;
3089 : }
3090 :
3091 : static void
3092 : restore_directory_hook (hookf)
3093 : rl_icppfunc_t *hookf;
3094 : {
3095 0 : if (dircomplete_expand)
3096 0 : rl_directory_completion_hook = hookf;
3097 : else
3098 0 : rl_directory_rewrite_hook = hookf;
3099 : }
3100 :
3101 : /* Check whether not DIRNAME, with any trailing slash removed, exists. If
3102 : SHOULD_DEQUOTE is non-zero, we dequote the directory name first. */
3103 : static int
3104 0 : directory_exists (dirname, should_dequote)
3105 : const char *dirname;
3106 : int should_dequote;
3107 : {
3108 0 : char *new_dirname;
3109 0 : int dirlen, r;
3110 0 : struct stat sb;
3111 :
3112 : /* We save the string and chop the trailing slash because stat/lstat behave
3113 : inconsistently if one is present. */
3114 0 : new_dirname = should_dequote ? bash_dequote_filename ((char *)dirname, rl_completion_quote_character) : savestring (dirname);
3115 0 : dirlen = STRLEN (new_dirname);
3116 0 : if (new_dirname[dirlen - 1] == '/')
3117 0 : new_dirname[dirlen - 1] = '\0';
3118 : #if defined (HAVE_LSTAT)
3119 0 : r = lstat (new_dirname, &sb) == 0;
3120 : #else
3121 : r = stat (new_dirname, &sb) == 0;
3122 : #endif
3123 0 : free (new_dirname);
3124 0 : return (r);
3125 : }
3126 :
3127 : /* Expand a filename before the readline completion code passes it to stat(2).
3128 : The filename will already have had tilde expansion performed. */
3129 : static int
3130 0 : bash_filename_stat_hook (dirname)
3131 : char **dirname;
3132 : {
3133 0 : char *local_dirname, *new_dirname, *t;
3134 0 : int should_expand_dirname, return_value;
3135 0 : int global_nounset;
3136 0 : WORD_LIST *wl;
3137 :
3138 0 : local_dirname = *dirname;
3139 0 : should_expand_dirname = return_value = 0;
3140 0 : if (t = mbschr (local_dirname, '$'))
3141 : should_expand_dirname = '$';
3142 0 : else if (t = mbschr (local_dirname, '`')) /* XXX */
3143 : should_expand_dirname = '`';
3144 :
3145 0 : if (should_expand_dirname && directory_exists (local_dirname, 0))
3146 : should_expand_dirname = 0;
3147 :
3148 0 : if (should_expand_dirname)
3149 : {
3150 0 : new_dirname = savestring (local_dirname);
3151 : /* no error messages, and expand_prompt_string doesn't longjmp so we don't
3152 : have to worry about restoring this setting. */
3153 0 : global_nounset = unbound_vars_is_error;
3154 0 : unbound_vars_is_error = 0;
3155 0 : wl = expand_prompt_string (new_dirname, 0, W_NOCOMSUB|W_NOPROCSUB|W_COMPLETE); /* does the right thing */
3156 0 : unbound_vars_is_error = global_nounset;
3157 0 : if (wl)
3158 : {
3159 0 : free (new_dirname);
3160 0 : new_dirname = string_list (wl);
3161 : /* Tell the completer we actually expanded something and change
3162 : *dirname only if we expanded to something non-null -- stat
3163 : behaves unpredictably when passed null or empty strings */
3164 0 : if (new_dirname && *new_dirname)
3165 : {
3166 0 : free (local_dirname); /* XXX */
3167 0 : local_dirname = *dirname = new_dirname;
3168 0 : return_value = STREQ (local_dirname, *dirname) == 0;
3169 : }
3170 : else
3171 0 : free (new_dirname);
3172 0 : dispose_words (wl);
3173 : }
3174 : else
3175 0 : free (new_dirname);
3176 : }
3177 :
3178 : /* This is very similar to the code in bash_directory_completion_hook below,
3179 : but without spelling correction and not worrying about whether or not
3180 : we change relative pathnames. */
3181 0 : if (no_symbolic_links == 0 && (local_dirname[0] != '.' || local_dirname[1]))
3182 : {
3183 0 : char *temp1, *temp2;
3184 :
3185 0 : t = get_working_directory ("symlink-hook");
3186 0 : temp1 = make_absolute (local_dirname, t);
3187 0 : free (t);
3188 0 : temp2 = sh_canonpath (temp1, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
3189 :
3190 : /* If we can't canonicalize, bail. */
3191 0 : if (temp2 == 0)
3192 : {
3193 0 : free (temp1);
3194 0 : return return_value;
3195 : }
3196 :
3197 0 : free (local_dirname);
3198 0 : *dirname = temp2;
3199 0 : free (temp1);
3200 : }
3201 :
3202 : return (return_value);
3203 : }
3204 :
3205 : /* Handle symbolic link references and other directory name
3206 : expansions while hacking completion. This should return 1 if it modifies
3207 : the DIRNAME argument, 0 otherwise. It should make sure not to modify
3208 : DIRNAME if it returns 0. */
3209 : static int
3210 0 : bash_directory_completion_hook (dirname)
3211 : char **dirname;
3212 : {
3213 0 : char *local_dirname, *new_dirname, *t;
3214 0 : int return_value, should_expand_dirname, nextch, closer;
3215 0 : WORD_LIST *wl;
3216 :
3217 0 : return_value = should_expand_dirname = nextch = closer = 0;
3218 0 : local_dirname = *dirname;
3219 :
3220 0 : if (t = mbschr (local_dirname, '$'))
3221 : {
3222 0 : should_expand_dirname = '$';
3223 0 : nextch = t[1];
3224 : /* Deliberately does not handle the deprecated $[...] arithmetic
3225 : expansion syntax */
3226 0 : if (nextch == '(')
3227 : closer = ')';
3228 0 : else if (nextch == '{')
3229 : closer = '}';
3230 : else
3231 0 : nextch = 0;
3232 : }
3233 0 : else if (local_dirname[0] == '~')
3234 : should_expand_dirname = '~';
3235 : else
3236 : {
3237 0 : t = mbschr (local_dirname, '`');
3238 0 : if (t && unclosed_pair (local_dirname, strlen (local_dirname), "`") == 0)
3239 0 : should_expand_dirname = '`';
3240 : }
3241 :
3242 0 : if (should_expand_dirname && directory_exists (local_dirname, 1))
3243 : should_expand_dirname = 0;
3244 :
3245 0 : if (should_expand_dirname)
3246 : {
3247 0 : new_dirname = savestring (local_dirname);
3248 0 : wl = expand_prompt_string (new_dirname, 0, W_NOCOMSUB|W_NOPROCSUB|W_COMPLETE); /* does the right thing */
3249 0 : if (wl)
3250 : {
3251 0 : *dirname = string_list (wl);
3252 : /* Tell the completer to replace the directory name only if we
3253 : actually expanded something. */
3254 0 : return_value = STREQ (local_dirname, *dirname) == 0;
3255 0 : free (local_dirname);
3256 0 : free (new_dirname);
3257 0 : dispose_words (wl);
3258 0 : local_dirname = *dirname;
3259 : /* XXX - change rl_filename_quote_characters here based on
3260 : should_expand_dirname/nextch/closer. This is the only place
3261 : custom_filename_quote_characters is modified. */
3262 0 : if (rl_filename_quote_characters && *rl_filename_quote_characters)
3263 : {
3264 0 : int i, j, c;
3265 0 : i = strlen (default_filename_quote_characters);
3266 0 : custom_filename_quote_characters = xrealloc (custom_filename_quote_characters, i+1);
3267 0 : for (i = j = 0; c = default_filename_quote_characters[i]; i++)
3268 : {
3269 0 : if (c == should_expand_dirname || c == nextch || c == closer)
3270 : continue;
3271 0 : custom_filename_quote_characters[j++] = c;
3272 : }
3273 0 : custom_filename_quote_characters[j] = '\0';
3274 0 : rl_filename_quote_characters = custom_filename_quote_characters;
3275 0 : set_filename_bstab (rl_filename_quote_characters);
3276 : }
3277 : }
3278 : else
3279 : {
3280 0 : free (new_dirname);
3281 0 : free (local_dirname);
3282 0 : *dirname = (char *)xmalloc (1);
3283 0 : **dirname = '\0';
3284 0 : return 1;
3285 : }
3286 : }
3287 : else
3288 : {
3289 : /* Dequote the filename even if we don't expand it. */
3290 0 : new_dirname = bash_dequote_filename (local_dirname, rl_completion_quote_character);
3291 0 : return_value = STREQ (local_dirname, new_dirname) == 0;
3292 0 : free (local_dirname);
3293 0 : local_dirname = *dirname = new_dirname;
3294 : }
3295 :
3296 : /* no_symbolic_links == 0 -> use (default) logical view of the file system.
3297 : local_dirname[0] == '.' && local_dirname[1] == '/' means files in the
3298 : current directory (./).
3299 : local_dirname[0] == '.' && local_dirname[1] == 0 means relative pathnames
3300 : in the current directory (e.g., lib/sh).
3301 : XXX - should we do spelling correction on these? */
3302 :
3303 : /* This is test as it was in bash-4.2: skip relative pathnames in current
3304 : directory. Change test to
3305 : (local_dirname[0] != '.' || (local_dirname[1] && local_dirname[1] != '/'))
3306 : if we want to skip paths beginning with ./ also. */
3307 0 : if (no_symbolic_links == 0 && (local_dirname[0] != '.' || local_dirname[1]))
3308 : {
3309 0 : char *temp1, *temp2;
3310 0 : int len1, len2;
3311 :
3312 : /* If we have a relative path
3313 : (local_dirname[0] != '/' && local_dirname[0] != '.')
3314 : that is canonical after appending it to the current directory, then
3315 : temp1 = temp2+'/'
3316 : That is,
3317 : strcmp (temp1, temp2) == 0
3318 : after adding a slash to temp2 below. It should be safe to not
3319 : change those.
3320 : */
3321 0 : t = get_working_directory ("symlink-hook");
3322 0 : temp1 = make_absolute (local_dirname, t);
3323 0 : free (t);
3324 0 : temp2 = sh_canonpath (temp1, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
3325 :
3326 : /* Try spelling correction if initial canonicalization fails. Make
3327 : sure we are set to replace the directory name with the results so
3328 : subsequent directory checks don't fail. */
3329 0 : if (temp2 == 0 && dircomplete_spelling && dircomplete_expand)
3330 : {
3331 0 : temp2 = dirspell (temp1);
3332 0 : if (temp2)
3333 : {
3334 0 : free (temp1);
3335 0 : temp1 = temp2;
3336 0 : temp2 = sh_canonpath (temp1, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
3337 0 : return_value |= temp2 != 0;
3338 : }
3339 : }
3340 : /* If we can't canonicalize, bail. */
3341 0 : if (temp2 == 0)
3342 : {
3343 0 : free (temp1);
3344 0 : return return_value;
3345 : }
3346 0 : len1 = strlen (temp1);
3347 0 : if (temp1[len1 - 1] == '/')
3348 : {
3349 0 : len2 = strlen (temp2);
3350 0 : if (len2 > 2) /* don't append `/' to `/' or `//' */
3351 : {
3352 0 : temp2 = (char *)xrealloc (temp2, len2 + 2);
3353 0 : temp2[len2] = '/';
3354 0 : temp2[len2 + 1] = '\0';
3355 : }
3356 : }
3357 :
3358 : /* dircomplete_expand_relpath == 0 means we want to leave relative
3359 : pathnames that are unchanged by canonicalization alone.
3360 : *local_dirname != '/' && *local_dirname != '.' == relative pathname
3361 : (consistent with general.c:absolute_pathname())
3362 : temp1 == temp2 (after appending a slash to temp2) means the pathname
3363 : is not changed by canonicalization as described above. */
3364 0 : if (dircomplete_expand_relpath || ((local_dirname[0] != '/' && local_dirname[0] != '.') && STREQ (temp1, temp2) == 0))
3365 0 : return_value |= STREQ (local_dirname, temp2) == 0;
3366 0 : free (local_dirname);
3367 0 : *dirname = temp2;
3368 0 : free (temp1);
3369 : }
3370 :
3371 : return (return_value);
3372 : }
3373 :
3374 : static char **history_completion_array = (char **)NULL;
3375 : static int harry_size;
3376 : static int harry_len;
3377 :
3378 : static void
3379 0 : build_history_completion_array ()
3380 : {
3381 0 : register int i, j;
3382 0 : HIST_ENTRY **hlist;
3383 0 : char **tokens;
3384 :
3385 : /* First, clear out the current dynamic history completion list. */
3386 0 : if (harry_size)
3387 : {
3388 0 : strvec_dispose (history_completion_array);
3389 0 : history_completion_array = (char **)NULL;
3390 0 : harry_size = 0;
3391 0 : harry_len = 0;
3392 : }
3393 :
3394 : /* Next, grovel each line of history, making each shell-sized token
3395 : a separate entry in the history_completion_array. */
3396 0 : hlist = history_list ();
3397 :
3398 0 : if (hlist)
3399 : {
3400 0 : for (i = 0; hlist[i]; i++)
3401 0 : ;
3402 0 : for ( --i; i >= 0; i--)
3403 : {
3404 : /* Separate each token, and place into an array. */
3405 0 : tokens = history_tokenize (hlist[i]->line);
3406 :
3407 0 : for (j = 0; tokens && tokens[j]; j++)
3408 : {
3409 0 : if (harry_len + 2 > harry_size)
3410 0 : history_completion_array = strvec_resize (history_completion_array, harry_size += 10);
3411 :
3412 0 : history_completion_array[harry_len++] = tokens[j];
3413 0 : history_completion_array[harry_len] = (char *)NULL;
3414 : }
3415 0 : free (tokens);
3416 : }
3417 :
3418 : /* Sort the complete list of tokens. */
3419 0 : if (dabbrev_expand_active == 0)
3420 0 : qsort (history_completion_array, harry_len, sizeof (char *), (QSFUNC *)strvec_strcmp);
3421 : }
3422 0 : }
3423 :
3424 : static char *
3425 0 : history_completion_generator (hint_text, state)
3426 : const char *hint_text;
3427 : int state;
3428 : {
3429 0 : static int local_index, len;
3430 0 : static const char *text;
3431 :
3432 : /* If this is the first call to the generator, then initialize the
3433 : list of strings to complete over. */
3434 0 : if (state == 0)
3435 : {
3436 0 : if (dabbrev_expand_active) /* This is kind of messy */
3437 0 : rl_completion_suppress_append = 1;
3438 0 : local_index = 0;
3439 0 : build_history_completion_array ();
3440 0 : text = hint_text;
3441 0 : len = strlen (text);
3442 : }
3443 :
3444 0 : while (history_completion_array && history_completion_array[local_index])
3445 : {
3446 0 : if (strncmp (text, history_completion_array[local_index++], len) == 0)
3447 0 : return (savestring (history_completion_array[local_index - 1]));
3448 : }
3449 : return ((char *)NULL);
3450 : }
3451 :
3452 : static int
3453 0 : dynamic_complete_history (count, key)
3454 : int count, key;
3455 : {
3456 0 : int r;
3457 0 : rl_compentry_func_t *orig_func;
3458 0 : rl_completion_func_t *orig_attempt_func;
3459 0 : rl_compignore_func_t *orig_ignore_func;
3460 :
3461 0 : orig_func = rl_completion_entry_function;
3462 0 : orig_attempt_func = rl_attempted_completion_function;
3463 0 : orig_ignore_func = rl_ignore_some_completions_function;
3464 :
3465 0 : rl_completion_entry_function = history_completion_generator;
3466 0 : rl_attempted_completion_function = (rl_completion_func_t *)NULL;
3467 0 : rl_ignore_some_completions_function = filename_completion_ignore;
3468 :
3469 : /* XXX - use rl_completion_mode here? */
3470 0 : if (rl_last_func == dynamic_complete_history)
3471 0 : r = rl_complete_internal ('?');
3472 : else
3473 0 : r = rl_complete_internal (TAB);
3474 :
3475 0 : rl_completion_entry_function = orig_func;
3476 0 : rl_attempted_completion_function = orig_attempt_func;
3477 0 : rl_ignore_some_completions_function = orig_ignore_func;
3478 :
3479 0 : return r;
3480 : }
3481 :
3482 : static int
3483 0 : bash_dabbrev_expand (count, key)
3484 : int count, key;
3485 : {
3486 0 : int r, orig_suppress, orig_sort;
3487 0 : rl_compentry_func_t *orig_func;
3488 0 : rl_completion_func_t *orig_attempt_func;
3489 0 : rl_compignore_func_t *orig_ignore_func;
3490 :
3491 0 : orig_func = rl_menu_completion_entry_function;
3492 0 : orig_attempt_func = rl_attempted_completion_function;
3493 0 : orig_ignore_func = rl_ignore_some_completions_function;
3494 0 : orig_suppress = rl_completion_suppress_append;
3495 0 : orig_sort = rl_sort_completion_matches;
3496 :
3497 0 : rl_menu_completion_entry_function = history_completion_generator;
3498 0 : rl_attempted_completion_function = (rl_completion_func_t *)NULL;
3499 0 : rl_ignore_some_completions_function = filename_completion_ignore;
3500 0 : rl_filename_completion_desired = 0;
3501 0 : rl_completion_suppress_append = 1;
3502 0 : rl_sort_completion_matches = 0;
3503 :
3504 : /* XXX - use rl_completion_mode here? */
3505 0 : dabbrev_expand_active = 1;
3506 0 : if (rl_last_func == bash_dabbrev_expand)
3507 0 : rl_last_func = rl_menu_complete;
3508 0 : r = rl_menu_complete (count, key);
3509 0 : dabbrev_expand_active = 0;
3510 :
3511 0 : rl_last_func = bash_dabbrev_expand;
3512 0 : rl_menu_completion_entry_function = orig_func;
3513 0 : rl_attempted_completion_function = orig_attempt_func;
3514 0 : rl_ignore_some_completions_function = orig_ignore_func;
3515 0 : rl_completion_suppress_append = orig_suppress;
3516 0 : rl_sort_completion_matches = orig_sort;
3517 :
3518 0 : return r;
3519 : }
3520 :
3521 : #if defined (SPECIFIC_COMPLETION_FUNCTIONS)
3522 : static int
3523 0 : bash_complete_username (ignore, ignore2)
3524 : int ignore, ignore2;
3525 : {
3526 0 : return bash_complete_username_internal (rl_completion_mode (bash_complete_username));
3527 : }
3528 :
3529 : static int
3530 0 : bash_possible_username_completions (ignore, ignore2)
3531 : int ignore, ignore2;
3532 : {
3533 0 : return bash_complete_username_internal ('?');
3534 : }
3535 :
3536 : static int
3537 0 : bash_complete_username_internal (what_to_do)
3538 : int what_to_do;
3539 : {
3540 0 : return bash_specific_completion (what_to_do, rl_username_completion_function);
3541 : }
3542 :
3543 : static int
3544 0 : bash_complete_filename (ignore, ignore2)
3545 : int ignore, ignore2;
3546 : {
3547 0 : return bash_complete_filename_internal (rl_completion_mode (bash_complete_filename));
3548 : }
3549 :
3550 : static int
3551 0 : bash_possible_filename_completions (ignore, ignore2)
3552 : int ignore, ignore2;
3553 : {
3554 0 : return bash_complete_filename_internal ('?');
3555 : }
3556 :
3557 : static int
3558 0 : bash_complete_filename_internal (what_to_do)
3559 : int what_to_do;
3560 : {
3561 0 : rl_compentry_func_t *orig_func;
3562 0 : rl_completion_func_t *orig_attempt_func;
3563 0 : rl_icppfunc_t *orig_dir_func;
3564 0 : rl_compignore_func_t *orig_ignore_func;
3565 0 : /*const*/ char *orig_rl_completer_word_break_characters;
3566 0 : int r;
3567 :
3568 0 : orig_func = rl_completion_entry_function;
3569 0 : orig_attempt_func = rl_attempted_completion_function;
3570 0 : orig_ignore_func = rl_ignore_some_completions_function;
3571 0 : orig_rl_completer_word_break_characters = rl_completer_word_break_characters;
3572 :
3573 0 : orig_dir_func = save_directory_hook ();
3574 :
3575 0 : rl_completion_entry_function = rl_filename_completion_function;
3576 0 : rl_attempted_completion_function = (rl_completion_func_t *)NULL;
3577 0 : rl_ignore_some_completions_function = filename_completion_ignore;
3578 0 : rl_completer_word_break_characters = " \t\n\"\'";
3579 :
3580 0 : r = rl_complete_internal (what_to_do);
3581 :
3582 0 : rl_completion_entry_function = orig_func;
3583 0 : rl_attempted_completion_function = orig_attempt_func;
3584 0 : rl_ignore_some_completions_function = orig_ignore_func;
3585 0 : rl_completer_word_break_characters = orig_rl_completer_word_break_characters;
3586 :
3587 0 : restore_directory_hook (orig_dir_func);
3588 :
3589 0 : return r;
3590 : }
3591 :
3592 : static int
3593 0 : bash_complete_hostname (ignore, ignore2)
3594 : int ignore, ignore2;
3595 : {
3596 0 : return bash_complete_hostname_internal (rl_completion_mode (bash_complete_hostname));
3597 : }
3598 :
3599 : static int
3600 0 : bash_possible_hostname_completions (ignore, ignore2)
3601 : int ignore, ignore2;
3602 : {
3603 0 : return bash_complete_hostname_internal ('?');
3604 : }
3605 :
3606 : static int
3607 0 : bash_complete_variable (ignore, ignore2)
3608 : int ignore, ignore2;
3609 : {
3610 0 : return bash_complete_variable_internal (rl_completion_mode (bash_complete_variable));
3611 : }
3612 :
3613 : static int
3614 0 : bash_possible_variable_completions (ignore, ignore2)
3615 : int ignore, ignore2;
3616 : {
3617 0 : return bash_complete_variable_internal ('?');
3618 : }
3619 :
3620 : static int
3621 0 : bash_complete_command (ignore, ignore2)
3622 : int ignore, ignore2;
3623 : {
3624 0 : return bash_complete_command_internal (rl_completion_mode (bash_complete_command));
3625 : }
3626 :
3627 : static int
3628 0 : bash_possible_command_completions (ignore, ignore2)
3629 : int ignore, ignore2;
3630 : {
3631 0 : return bash_complete_command_internal ('?');
3632 : }
3633 :
3634 : static int
3635 0 : bash_complete_hostname_internal (what_to_do)
3636 : int what_to_do;
3637 : {
3638 0 : return bash_specific_completion (what_to_do, hostname_completion_function);
3639 : }
3640 :
3641 : static int
3642 0 : bash_complete_variable_internal (what_to_do)
3643 : int what_to_do;
3644 : {
3645 0 : return bash_specific_completion (what_to_do, variable_completion_function);
3646 : }
3647 :
3648 : static int
3649 0 : bash_complete_command_internal (what_to_do)
3650 : int what_to_do;
3651 : {
3652 0 : return bash_specific_completion (what_to_do, command_word_completion_function);
3653 : }
3654 :
3655 : static char *globtext;
3656 : static char *globorig;
3657 :
3658 : static char *
3659 0 : glob_complete_word (text, state)
3660 : const char *text;
3661 : int state;
3662 : {
3663 0 : static char **matches = (char **)NULL;
3664 0 : static int ind;
3665 0 : int glen;
3666 0 : char *ret, *ttext;
3667 :
3668 0 : if (state == 0)
3669 : {
3670 0 : rl_filename_completion_desired = 1;
3671 0 : FREE (matches);
3672 0 : if (globorig != globtext)
3673 0 : FREE (globorig);
3674 0 : FREE (globtext);
3675 :
3676 0 : ttext = bash_tilde_expand (text, 0);
3677 :
3678 0 : if (rl_explicit_arg)
3679 : {
3680 0 : globorig = savestring (ttext);
3681 0 : glen = strlen (ttext);
3682 0 : globtext = (char *)xmalloc (glen + 2);
3683 0 : strcpy (globtext, ttext);
3684 0 : globtext[glen] = '*';
3685 0 : globtext[glen+1] = '\0';
3686 : }
3687 : else
3688 0 : globtext = globorig = savestring (ttext);
3689 :
3690 0 : if (ttext != text)
3691 0 : free (ttext);
3692 :
3693 0 : matches = shell_glob_filename (globtext);
3694 0 : if (GLOB_FAILED (matches))
3695 0 : matches = (char **)NULL;
3696 0 : ind = 0;
3697 : }
3698 :
3699 0 : ret = matches ? matches[ind] : (char *)NULL;
3700 0 : ind++;
3701 0 : return ret;
3702 : }
3703 :
3704 : static int
3705 0 : bash_glob_completion_internal (what_to_do)
3706 : int what_to_do;
3707 : {
3708 0 : return bash_specific_completion (what_to_do, glob_complete_word);
3709 : }
3710 :
3711 : /* A special quoting function so we don't end up quoting globbing characters
3712 : in the word if there are no matches or multiple matches. */
3713 : static char *
3714 0 : bash_glob_quote_filename (s, rtype, qcp)
3715 : char *s;
3716 : int rtype;
3717 : char *qcp;
3718 : {
3719 0 : if (globorig && qcp && *qcp == '\0' && STREQ (s, globorig))
3720 0 : return (savestring (s));
3721 : else
3722 0 : return (bash_quote_filename (s, rtype, qcp));
3723 : }
3724 :
3725 : static int
3726 0 : bash_glob_complete_word (count, key)
3727 : int count, key;
3728 : {
3729 0 : int r;
3730 0 : rl_quote_func_t *orig_quoting_function;
3731 :
3732 0 : if (rl_editing_mode == EMACS_EDITING_MODE)
3733 0 : rl_explicit_arg = 1; /* force `*' append */
3734 0 : orig_quoting_function = rl_filename_quoting_function;
3735 0 : rl_filename_quoting_function = bash_glob_quote_filename;
3736 :
3737 0 : r = bash_glob_completion_internal (rl_completion_mode (bash_glob_complete_word));
3738 :
3739 0 : rl_filename_quoting_function = orig_quoting_function;
3740 0 : return r;
3741 : }
3742 :
3743 : static int
3744 0 : bash_glob_expand_word (count, key)
3745 : int count, key;
3746 : {
3747 0 : return bash_glob_completion_internal ('*');
3748 : }
3749 :
3750 : static int
3751 0 : bash_glob_list_expansions (count, key)
3752 : int count, key;
3753 : {
3754 0 : return bash_glob_completion_internal ('?');
3755 : }
3756 :
3757 : static int
3758 : bash_specific_completion (what_to_do, generator)
3759 : int what_to_do;
3760 : rl_compentry_func_t *generator;
3761 : {
3762 0 : rl_compentry_func_t *orig_func;
3763 0 : rl_completion_func_t *orig_attempt_func;
3764 0 : rl_compignore_func_t *orig_ignore_func;
3765 0 : int r;
3766 :
3767 0 : orig_func = rl_completion_entry_function;
3768 0 : orig_attempt_func = rl_attempted_completion_function;
3769 0 : orig_ignore_func = rl_ignore_some_completions_function;
3770 0 : rl_completion_entry_function = generator;
3771 0 : rl_attempted_completion_function = NULL;
3772 0 : rl_ignore_some_completions_function = orig_ignore_func;
3773 :
3774 0 : r = rl_complete_internal (what_to_do);
3775 :
3776 0 : rl_completion_entry_function = orig_func;
3777 0 : rl_attempted_completion_function = orig_attempt_func;
3778 0 : rl_ignore_some_completions_function = orig_ignore_func;
3779 :
3780 0 : return r;
3781 : }
3782 :
3783 : #endif /* SPECIFIC_COMPLETION_FUNCTIONS */
3784 :
3785 : #if defined (VI_MODE)
3786 : /* Completion, from vi mode's point of view. This is a modified version of
3787 : rl_vi_complete which uses the bash globbing code to implement what POSIX
3788 : specifies, which is to append a `*' and attempt filename generation (which
3789 : has the side effect of expanding any globbing characters in the word). */
3790 : static int
3791 0 : bash_vi_complete (count, key)
3792 : int count, key;
3793 : {
3794 : #if defined (SPECIFIC_COMPLETION_FUNCTIONS)
3795 0 : int p, r;
3796 0 : char *t;
3797 :
3798 0 : if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point])))
3799 : {
3800 0 : if (!whitespace (rl_line_buffer[rl_point + 1]))
3801 0 : rl_vi_end_word (1, 'E');
3802 0 : rl_point++;
3803 : }
3804 :
3805 : /* Find boundaries of current word, according to vi definition of a
3806 : `bigword'. */
3807 0 : t = 0;
3808 0 : if (rl_point > 0)
3809 : {
3810 0 : p = rl_point;
3811 0 : rl_vi_bWord (1, 'B');
3812 0 : r = rl_point;
3813 0 : rl_point = p;
3814 0 : p = r;
3815 :
3816 0 : t = substring (rl_line_buffer, p, rl_point);
3817 : }
3818 :
3819 0 : if (t && glob_pattern_p (t) == 0)
3820 0 : rl_explicit_arg = 1; /* XXX - force glob_complete_word to append `*' */
3821 0 : FREE (t);
3822 :
3823 0 : if (key == '*') /* Expansion and replacement. */
3824 0 : r = bash_glob_expand_word (count, key);
3825 0 : else if (key == '=') /* List possible completions. */
3826 0 : r = bash_glob_list_expansions (count, key);
3827 0 : else if (key == '\\') /* Standard completion */
3828 0 : r = bash_glob_complete_word (count, key);
3829 : else
3830 0 : r = rl_complete (0, key);
3831 :
3832 0 : if (key == '*' || key == '\\')
3833 0 : rl_vi_start_inserting (key, 1, 1);
3834 :
3835 0 : return (r);
3836 : #else
3837 : return rl_vi_complete (count, key);
3838 : #endif /* !SPECIFIC_COMPLETION_FUNCTIONS */
3839 : }
3840 : #endif /* VI_MODE */
3841 :
3842 : /* Filename quoting for completion. */
3843 : /* A function to strip unquoted quote characters (single quotes, double
3844 : quotes, and backslashes). It allows single quotes to appear
3845 : within double quotes, and vice versa. It should be smarter. */
3846 : static char *
3847 0 : bash_dequote_filename (text, quote_char)
3848 : char *text;
3849 : int quote_char;
3850 : {
3851 0 : char *ret, *p, *r;
3852 0 : int l, quoted;
3853 :
3854 0 : l = strlen (text);
3855 0 : ret = (char *)xmalloc (l + 1);
3856 0 : for (quoted = quote_char, p = text, r = ret; p && *p; p++)
3857 : {
3858 : /* Allow backslash-escaped characters to pass through unscathed. */
3859 0 : if (*p == '\\')
3860 : {
3861 : /* Backslashes are preserved within single quotes. */
3862 0 : if (quoted == '\'')
3863 0 : *r++ = *p;
3864 : /* Backslashes are preserved within double quotes unless the
3865 : character is one that is defined to be escaped */
3866 0 : else if (quoted == '"' && ((sh_syntaxtab[(unsigned char) p[1]] & CBSDQUOTE) == 0))
3867 0 : *r++ = *p;
3868 :
3869 0 : *r++ = *++p;
3870 0 : if (*p == '\0')
3871 : return ret; /* XXX - was break; */
3872 : continue;
3873 : }
3874 : /* Close quote. */
3875 0 : if (quoted && *p == quoted)
3876 : {
3877 : quoted = 0;
3878 : continue;
3879 : }
3880 : /* Open quote. */
3881 0 : if (quoted == 0 && (*p == '\'' || *p == '"'))
3882 : {
3883 0 : quoted = *p;
3884 0 : continue;
3885 : }
3886 0 : *r++ = *p;
3887 : }
3888 0 : *r = '\0';
3889 0 : return ret;
3890 : }
3891 :
3892 : /* Quote characters that the readline completion code would treat as
3893 : word break characters with backslashes. Pass backslash-quoted
3894 : characters through without examination. */
3895 : static char *
3896 0 : quote_word_break_chars (text)
3897 : char *text;
3898 : {
3899 0 : char *ret, *r, *s;
3900 0 : int l;
3901 :
3902 0 : l = strlen (text);
3903 0 : ret = (char *)xmalloc ((2 * l) + 1);
3904 0 : for (s = text, r = ret; *s; s++)
3905 : {
3906 : /* Pass backslash-quoted characters through, including the backslash. */
3907 0 : if (*s == '\\')
3908 : {
3909 0 : *r++ = '\\';
3910 0 : *r++ = *++s;
3911 0 : if (*s == '\0')
3912 : break;
3913 : continue;
3914 : }
3915 : /* OK, we have an unquoted character. Check its presence in
3916 : rl_completer_word_break_characters. */
3917 0 : if (mbschr (rl_completer_word_break_characters, *s))
3918 0 : *r++ = '\\';
3919 : /* XXX -- check for standalone tildes here and backslash-quote them */
3920 0 : if (s == text && *s == '~' && file_exists (text))
3921 0 : *r++ = '\\';
3922 0 : *r++ = *s;
3923 : }
3924 0 : *r = '\0';
3925 0 : return ret;
3926 : }
3927 :
3928 : /* Use characters in STRING to populate the table of characters that should
3929 : be backslash-quoted. The table will be used for sh_backslash_quote from
3930 : this file. */
3931 : static void
3932 75 : set_filename_bstab (string)
3933 : const char *string;
3934 : {
3935 75 : const char *s;
3936 :
3937 75 : memset (filename_bstab, 0, sizeof (filename_bstab));
3938 1950 : for (s = string; s && *s; s++)
3939 1875 : filename_bstab[(unsigned char) *s] = 1;
3940 75 : }
3941 :
3942 : /* Quote a filename using double quotes, single quotes, or backslashes
3943 : depending on the value of completion_quoting_style. If we're
3944 : completing using backslashes, we need to quote some additional
3945 : characters (those that readline treats as word breaks), so we call
3946 : quote_word_break_chars on the result. This returns newly-allocated
3947 : memory. */
3948 : static char *
3949 0 : bash_quote_filename (s, rtype, qcp)
3950 : char *s;
3951 : int rtype;
3952 : char *qcp;
3953 : {
3954 0 : char *rtext, *mtext, *ret;
3955 0 : int rlen, cs;
3956 :
3957 0 : rtext = (char *)NULL;
3958 :
3959 : /* If RTYPE == MULT_MATCH, it means that there is
3960 : more than one match. In this case, we do not add
3961 : the closing quote or attempt to perform tilde
3962 : expansion. If RTYPE == SINGLE_MATCH, we try
3963 : to perform tilde expansion, because single and double
3964 : quotes inhibit tilde expansion by the shell. */
3965 :
3966 0 : cs = completion_quoting_style;
3967 : /* Might need to modify the default completion style based on *qcp,
3968 : since it's set to any user-provided opening quote. We also change
3969 : to single-quoting if there is no user-provided opening quote and
3970 : the word being completed contains newlines, since those are not
3971 : quoted correctly using backslashes (a backslash-newline pair is
3972 : special to the shell parser). */
3973 0 : if (*qcp == '\0' && cs == COMPLETE_BSQUOTE && mbschr (s, '\n'))
3974 : cs = COMPLETE_SQUOTE;
3975 0 : else if (*qcp == '"')
3976 : cs = COMPLETE_DQUOTE;
3977 0 : else if (*qcp == '\'')
3978 : cs = COMPLETE_SQUOTE;
3979 : #if defined (BANG_HISTORY)
3980 0 : else if (*qcp == '\0' && history_expansion && cs == COMPLETE_DQUOTE &&
3981 0 : history_expansion_inhibited == 0 && mbschr (s, '!'))
3982 0 : cs = COMPLETE_BSQUOTE;
3983 :
3984 0 : if (*qcp == '"' && history_expansion && cs == COMPLETE_DQUOTE &&
3985 0 : history_expansion_inhibited == 0 && mbschr (s, '!'))
3986 : {
3987 0 : cs = COMPLETE_BSQUOTE;
3988 0 : *qcp = '\0';
3989 : }
3990 : #endif
3991 :
3992 : /* Don't tilde-expand backslash-quoted filenames, since only single and
3993 : double quotes inhibit tilde expansion. */
3994 0 : mtext = s;
3995 0 : if (mtext[0] == '~' && rtype == SINGLE_MATCH && cs != COMPLETE_BSQUOTE)
3996 0 : mtext = bash_tilde_expand (s, 0);
3997 :
3998 0 : switch (cs)
3999 : {
4000 0 : case COMPLETE_DQUOTE:
4001 0 : rtext = sh_double_quote (mtext);
4002 0 : break;
4003 0 : case COMPLETE_SQUOTE:
4004 0 : rtext = sh_single_quote (mtext);
4005 0 : break;
4006 0 : case COMPLETE_BSQUOTE:
4007 0 : rtext = sh_backslash_quote (mtext, complete_fullquote ? 0 : filename_bstab, 0);
4008 0 : break;
4009 : }
4010 :
4011 0 : if (mtext != s)
4012 0 : free (mtext);
4013 :
4014 : /* We may need to quote additional characters: those that readline treats
4015 : as word breaks that are not quoted by backslash_quote. */
4016 0 : if (rtext && cs == COMPLETE_BSQUOTE)
4017 : {
4018 0 : mtext = quote_word_break_chars (rtext);
4019 0 : free (rtext);
4020 0 : rtext = mtext;
4021 : }
4022 :
4023 : /* Leave the opening quote intact. The readline completion code takes
4024 : care of avoiding doubled opening quotes. */
4025 0 : if (rtext)
4026 : {
4027 0 : rlen = strlen (rtext);
4028 0 : ret = (char *)xmalloc (rlen + 1);
4029 0 : strcpy (ret, rtext);
4030 : }
4031 : else
4032 : {
4033 0 : ret = (char *)xmalloc (rlen = 1);
4034 0 : ret[0] = '\0';
4035 : }
4036 :
4037 : /* If there are multiple matches, cut off the closing quote. */
4038 0 : if (rtype == MULT_MATCH && cs != COMPLETE_BSQUOTE)
4039 0 : ret[rlen - 1] = '\0';
4040 0 : free (rtext);
4041 0 : return ret;
4042 : }
4043 :
4044 : /* Support for binding readline key sequences to Unix commands. */
4045 : static Keymap cmd_xmap;
4046 :
4047 : #if 0
4048 : #ifdef _MINIX
4049 : static void
4050 : #else
4051 : static int
4052 : #endif
4053 : putx(c)
4054 : int c;
4055 : {
4056 : int x;
4057 : x = putc (c, rl_outstream);
4058 : #ifndef _MINIX
4059 : return x;
4060 : #endif
4061 : }
4062 : #endif
4063 :
4064 : static int
4065 0 : bash_execute_unix_command (count, key)
4066 : int count; /* ignored */
4067 : int key;
4068 : {
4069 0 : int type;
4070 0 : register int i, r;
4071 0 : intmax_t mi;
4072 0 : sh_parser_state_t ps;
4073 0 : char *cmd, *value, *l, *l1, *ce;
4074 0 : SHELL_VAR *v;
4075 0 : char ibuf[INT_STRLEN_BOUND(int) + 1];
4076 :
4077 : /* First, we need to find the right command to execute. This is tricky,
4078 : because we might have already indirected into another keymap, so we
4079 : have to walk cmd_xmap using the entire key sequence. */
4080 0 : cmd = (char *)rl_function_of_keyseq (rl_executing_keyseq, cmd_xmap, &type);
4081 :
4082 0 : if (cmd == 0 || type != ISMACR)
4083 : {
4084 0 : rl_crlf ();
4085 0 : internal_error (_("bash_execute_unix_command: cannot find keymap for command"));
4086 0 : rl_forced_update_display ();
4087 0 : return 1;
4088 : }
4089 :
4090 0 : ce = rl_get_termcap ("ce");
4091 0 : if (ce) /* clear current line */
4092 : {
4093 : #if 0
4094 : fprintf (rl_outstream, "\r");
4095 : tputs (ce, 1, putx);
4096 : #else
4097 0 : rl_clear_visible_line ();
4098 : #endif
4099 0 : fflush (rl_outstream);
4100 : }
4101 : else
4102 0 : rl_crlf (); /* move to a new line */
4103 :
4104 0 : v = bind_variable ("READLINE_LINE", rl_line_buffer, 0);
4105 0 : if (v)
4106 0 : VSETATTR (v, att_exported);
4107 0 : l = v ? value_cell (v) : 0;
4108 0 : value = inttostr (rl_point, ibuf, sizeof (ibuf));
4109 0 : v = bind_int_variable ("READLINE_POINT", value);
4110 0 : if (v)
4111 0 : VSETATTR (v, att_exported);
4112 0 : array_needs_making = 1;
4113 :
4114 0 : save_parser_state (&ps);
4115 0 : r = parse_and_execute (cmd, "bash_execute_unix_command", SEVAL_NOHIST|SEVAL_NOFREE);
4116 0 : restore_parser_state (&ps);
4117 :
4118 0 : v = find_variable ("READLINE_LINE");
4119 0 : l1 = v ? value_cell (v) : 0;
4120 0 : if (l1 != l)
4121 0 : maybe_make_readline_line (value_cell (v));
4122 0 : v = find_variable ("READLINE_POINT");
4123 0 : if (v && legal_number (value_cell (v), &mi))
4124 : {
4125 0 : i = mi;
4126 0 : if (i != rl_point)
4127 : {
4128 0 : rl_point = i;
4129 0 : if (rl_point > rl_end)
4130 0 : rl_point = rl_end;
4131 0 : else if (rl_point < 0)
4132 0 : rl_point = 0;
4133 : }
4134 : }
4135 :
4136 0 : check_unbind_variable ("READLINE_LINE");
4137 0 : check_unbind_variable ("READLINE_POINT");
4138 0 : array_needs_making = 1;
4139 :
4140 : /* and restore the readline buffer and display after command execution. */
4141 : /* If we clear the last line of the prompt above, redraw only that last
4142 : line. If the command returns 124, we redraw unconditionally as in
4143 : previous versions. */
4144 0 : if (ce && r != 124)
4145 0 : rl_redraw_prompt_last_line ();
4146 : else
4147 0 : rl_forced_update_display ();
4148 :
4149 : return 0;
4150 : }
4151 :
4152 : int
4153 0 : print_unix_command_map ()
4154 : {
4155 0 : Keymap save;
4156 :
4157 0 : save = rl_get_keymap ();
4158 0 : rl_set_keymap (cmd_xmap);
4159 0 : rl_macro_dumper (1);
4160 0 : rl_set_keymap (save);
4161 0 : return 0;
4162 : }
4163 :
4164 : static void
4165 : init_unix_command_map ()
4166 : {
4167 0 : cmd_xmap = rl_make_bare_keymap ();
4168 : }
4169 :
4170 : static int
4171 0 : isolate_sequence (string, ind, need_dquote, startp)
4172 : char *string;
4173 : int ind, need_dquote, *startp;
4174 : {
4175 0 : register int i;
4176 0 : int c, passc, delim;
4177 :
4178 0 : for (i = ind; string[i] && whitespace (string[i]); i++)
4179 0 : ;
4180 : /* NEED_DQUOTE means that the first non-white character *must* be `"'. */
4181 0 : if (need_dquote && string[i] != '"')
4182 : {
4183 0 : builtin_error (_("%s: first non-whitespace character is not `\"'"), string);
4184 0 : return -1;
4185 : }
4186 :
4187 : /* We can have delimited strings even if NEED_DQUOTE == 0, like the command
4188 : string to bind the key sequence to. */
4189 0 : delim = (string[i] == '"' || string[i] == '\'') ? string[i] : 0;
4190 :
4191 0 : if (startp)
4192 0 : *startp = delim ? ++i : i;
4193 :
4194 0 : for (passc = 0; c = string[i]; i++)
4195 : {
4196 0 : if (passc)
4197 : {
4198 : passc = 0;
4199 : continue;
4200 : }
4201 0 : if (c == '\\')
4202 : {
4203 : passc++;
4204 : continue;
4205 : }
4206 0 : if (c == delim)
4207 : break;
4208 : }
4209 :
4210 0 : if (delim && string[i] != delim)
4211 : {
4212 0 : builtin_error (_("no closing `%c' in %s"), delim, string);
4213 0 : return -1;
4214 : }
4215 :
4216 : return i;
4217 : }
4218 :
4219 : int
4220 0 : bind_keyseq_to_unix_command (line)
4221 : char *line;
4222 : {
4223 0 : Keymap kmap;
4224 0 : char *kseq, *value;
4225 0 : int i, kstart;
4226 :
4227 0 : if (cmd_xmap == 0)
4228 0 : init_unix_command_map ();
4229 :
4230 0 : kmap = rl_get_keymap ();
4231 :
4232 : /* We duplicate some of the work done by rl_parse_and_bind here, but
4233 : this code only has to handle `"keyseq": ["]command["]' and can
4234 : generate an error for anything else. */
4235 0 : i = isolate_sequence (line, 0, 1, &kstart);
4236 0 : if (i < 0)
4237 : return -1;
4238 :
4239 : /* Create the key sequence string to pass to rl_generic_bind */
4240 0 : kseq = substring (line, kstart, i);
4241 :
4242 0 : for ( ; line[i] && line[i] != ':'; i++)
4243 0 : ;
4244 0 : if (line[i] != ':')
4245 : {
4246 0 : builtin_error (_("%s: missing colon separator"), line);
4247 0 : FREE (kseq);
4248 0 : return -1;
4249 : }
4250 :
4251 0 : i = isolate_sequence (line, i + 1, 0, &kstart);
4252 0 : if (i < 0)
4253 : {
4254 0 : FREE (kseq);
4255 0 : return -1;
4256 : }
4257 :
4258 : /* Create the value string containing the command to execute. */
4259 0 : value = substring (line, kstart, i);
4260 :
4261 : /* Save the command to execute and the key sequence in the CMD_XMAP */
4262 0 : rl_generic_bind (ISMACR, kseq, value, cmd_xmap);
4263 :
4264 : /* and bind the key sequence in the current keymap to a function that
4265 : understands how to execute from CMD_XMAP */
4266 0 : rl_bind_keyseq_in_map (kseq, bash_execute_unix_command, kmap);
4267 :
4268 0 : free (kseq);
4269 0 : return 0;
4270 : }
4271 :
4272 : /* Used by the programmable completion code. Complete TEXT as a filename,
4273 : but return only directories as matches. Dequotes the filename before
4274 : attempting to find matches. */
4275 : char **
4276 0 : bash_directory_completion_matches (text)
4277 : const char *text;
4278 : {
4279 0 : char **m1;
4280 0 : char *dfn;
4281 0 : int qc;
4282 :
4283 0 : qc = rl_dispatching ? rl_completion_quote_character : 0;
4284 : /* If rl_completion_found_quote != 0, rl_completion_matches will call the
4285 : filename dequoting function, causing the directory name to be dequoted
4286 : twice. */
4287 0 : if (rl_dispatching && rl_completion_found_quote == 0)
4288 0 : dfn = bash_dequote_filename ((char *)text, qc);
4289 : else
4290 : dfn = (char *)text;
4291 0 : m1 = rl_completion_matches (dfn, rl_filename_completion_function);
4292 0 : if (dfn != text)
4293 0 : free (dfn);
4294 :
4295 0 : if (m1 == 0 || m1[0] == 0)
4296 : return m1;
4297 : /* We don't bother recomputing the lcd of the matches, because it will just
4298 : get thrown away by the programmable completion code and recomputed
4299 : later. */
4300 0 : (void)bash_ignore_filenames (m1);
4301 0 : return m1;
4302 : }
4303 :
4304 : char *
4305 0 : bash_dequote_text (text)
4306 : const char *text;
4307 : {
4308 0 : char *dtxt;
4309 0 : int qc;
4310 :
4311 0 : qc = (text[0] == '"' || text[0] == '\'') ? text[0] : 0;
4312 0 : dtxt = bash_dequote_filename ((char *)text, qc);
4313 0 : return (dtxt);
4314 : }
4315 :
4316 : /* This event hook is designed to be called after readline receives a signal
4317 : that interrupts read(2). It gives reasonable responsiveness to interrupts
4318 : and fatal signals without executing too much code in a signal handler
4319 : context. */
4320 : static int
4321 0 : bash_event_hook ()
4322 : {
4323 : /* If we're going to longjmp to top_level, make sure we clean up readline.
4324 : check_signals will call QUIT, which will eventually longjmp to top_level,
4325 : calling run_interrupt_trap along the way. The check for sigalrm_seen is
4326 : to clean up the read builtin's state. */
4327 0 : if (terminating_signal || interrupt_state || sigalrm_seen)
4328 0 : rl_cleanup_after_signal ();
4329 0 : bashline_reset_event_hook ();
4330 0 : check_signals_and_traps (); /* XXX */
4331 0 : return 0;
4332 : }
4333 :
4334 : #endif /* READLINE */
|