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