blob: c85b05b69e36b9484043a5a66d98a9a39135db8a [file] [log] [blame]
Jari Aalto726f6381996-08-26 18:22:31 +00001/* bashline.c -- Bash's interface to the readline library. */
2
Chet Ramey74091dd2022-09-26 11:49:46 -04003/* Copyright (C) 1987-2022 Free Software Foundation, Inc.
Jari Aalto726f6381996-08-26 18:22:31 +00004
5 This file is part of GNU Bash, the Bourne Again SHell.
6
Jari Aalto31859422009-01-12 13:36:28 +00007 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.
Jari Aalto726f6381996-08-26 18:22:31 +000011
Jari Aalto31859422009-01-12 13:36:28 +000012 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.
Jari Aalto726f6381996-08-26 18:22:31 +000016
17 You should have received a copy of the GNU General Public License
Jari Aalto31859422009-01-12 13:36:28 +000018 along with Bash. If not, see <http://www.gnu.org/licenses/>.
19*/
Jari Aalto726f6381996-08-26 18:22:31 +000020
Jari Aaltoccc6cda1996-12-23 17:02:34 +000021#include "config.h"
22
23#if defined (READLINE)
24
Jari Aalto726f6381996-08-26 18:22:31 +000025#include "bashtypes.h"
26#include "posixstat.h"
27
Jari Aaltoccc6cda1996-12-23 17:02:34 +000028#if defined (HAVE_UNISTD_H)
29# include <unistd.h>
30#endif
31
Jari Aaltof73dda02001-11-13 17:56:06 +000032#if defined (HAVE_GRP_H)
33# include <grp.h>
34#endif
35
Jari Aalto7117c2d2002-07-17 14:10:11 +000036#if defined (HAVE_NETDB_H)
37# include <netdb.h>
38#endif
39
Chet Rameyac50fba2014-02-26 09:36:43 -050040#include <signal.h>
41
Jari Aalto726f6381996-08-26 18:22:31 +000042#include <stdio.h>
Jari Aaltof73dda02001-11-13 17:56:06 +000043#include "chartypes.h"
Jari Aalto726f6381996-08-26 18:22:31 +000044#include "bashansi.h"
Jari Aaltob80f6442004-07-27 13:29:18 +000045#include "bashintl.h"
46
Jari Aaltoccc6cda1996-12-23 17:02:34 +000047#include "shell.h"
Jari Aalto7117c2d2002-07-17 14:10:11 +000048#include "input.h"
Chet Rameyd233b482019-01-07 09:27:52 -050049#include "parser.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000050#include "builtins.h"
51#include "bashhist.h"
52#include "bashline.h"
53#include "execute_cmd.h"
Jari Aaltocce855b1998-04-17 19:52:44 +000054#include "findcmd.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000055#include "pathexp.h"
Jari Aalto31859422009-01-12 13:36:28 +000056#include "shmbutil.h"
Chet Rameyac50fba2014-02-26 09:36:43 -050057#include "trap.h"
Chet Rameya0c0a002016-09-15 16:59:08 -040058#include "flags.h"
Chet Ramey74091dd2022-09-26 11:49:46 -040059#include "timer.h"
Chet Rameya0c0a002016-09-15 16:59:08 -040060
61#if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR)
62# include <mbstr.h> /* mbschr */
63#endif
Jari Aalto31859422009-01-12 13:36:28 +000064
Jari Aaltoccc6cda1996-12-23 17:02:34 +000065#include "builtins/common.h"
Chet Ramey8868eda2020-12-06 15:51:17 -050066#include "builtins/builtext.h" /* for read_builtin */
Jari Aalto31859422009-01-12 13:36:28 +000067
Jari Aalto726f6381996-08-26 18:22:31 +000068#include <readline/rlconf.h>
69#include <readline/readline.h>
70#include <readline/history.h>
Chet Rameyd233b482019-01-07 09:27:52 -050071#include <readline/rlmbutil.h>
Jari Aaltoccc6cda1996-12-23 17:02:34 +000072
73#include <glob/glob.h>
Jari Aalto726f6381996-08-26 18:22:31 +000074
75#if defined (ALIAS)
76# include "alias.h"
77#endif
78
Jari Aaltobb706242000-03-17 21:46:59 +000079#if defined (PROGRAMMABLE_COMPLETION)
80# include "pcomplete.h"
81#endif
82
Jari Aalto7117c2d2002-07-17 14:10:11 +000083/* 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
Chet Ramey8868eda2020-12-06 15:51:17 -050091/* 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
Jari Aalto31859422009-01-12 13:36:28 +0000104#define RL_BOOLEAN_VARIABLE_VALUE(s) ((s)[0] == 'o' && (s)[1] == 'n' && (s)[2] == '\0')
105
Jari Aalto726f6381996-08-26 18:22:31 +0000106#if defined (BRACE_COMPLETION)
Chet Ramey8868eda2020-12-06 15:51:17 -0500107extern int bash_brace_completion PARAMS((int, int));
Jari Aalto726f6381996-08-26 18:22:31 +0000108#endif /* BRACE_COMPLETION */
109
Chet Ramey00018032011-11-21 20:51:19 -0500110/* To avoid including curses.h/term.h/termcap.h and that whole mess. */
Chet Rameyac50fba2014-02-26 09:36:43 -0500111#ifdef _MINIX
Chet Ramey8868eda2020-12-06 15:51:17 -0500112extern int tputs PARAMS((const char *string, int nlines, void (*outx)(int)));
Chet Rameyac50fba2014-02-26 09:36:43 -0500113#else
Chet Ramey8868eda2020-12-06 15:51:17 -0500114extern int tputs PARAMS((const char *string, int nlines, int (*outx)(int)));
Chet Rameyac50fba2014-02-26 09:36:43 -0500115#endif
Chet Ramey00018032011-11-21 20:51:19 -0500116
Jari Aalto28ef6c32001-04-06 19:14:31 +0000117/* Forward declarations */
118
Jari Aalto726f6381996-08-26 18:22:31 +0000119/* Functions bound to keys in Readline for Bash users. */
Chet Ramey8868eda2020-12-06 15:51:17 -0500120static int shell_expand_line PARAMS((int, int));
121static int display_shell_version PARAMS((int, int));
Jari Aalto28ef6c32001-04-06 19:14:31 +0000122
Chet Ramey8868eda2020-12-06 15:51:17 -0500123static int bash_ignore_filenames PARAMS((char **));
124static int bash_ignore_everything PARAMS((char **));
125static int bash_progcomp_ignore_filenames PARAMS((char **));
Jari Aalto28ef6c32001-04-06 19:14:31 +0000126
Jari Aaltocce855b1998-04-17 19:52:44 +0000127#if defined (BANG_HISTORY)
Chet Ramey8868eda2020-12-06 15:51:17 -0500128static char *history_expand_line_internal PARAMS((char *));
129static int history_expand_line PARAMS((int, int));
130static int tcsh_magic_space PARAMS((int, int));
Jari Aaltocce855b1998-04-17 19:52:44 +0000131#endif /* BANG_HISTORY */
132#ifdef ALIAS
Chet Ramey8868eda2020-12-06 15:51:17 -0500133static int alias_expand_line PARAMS((int, int));
Jari Aaltocce855b1998-04-17 19:52:44 +0000134#endif
135#if defined (BANG_HISTORY) && defined (ALIAS)
Chet Ramey8868eda2020-12-06 15:51:17 -0500136static int history_and_alias_expand_line PARAMS((int, int));
Jari Aaltocce855b1998-04-17 19:52:44 +0000137#endif
138
Chet Ramey8868eda2020-12-06 15:51:17 -0500139static 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));
Jari Aalto31859422009-01-12 13:36:28 +0000144
Chet Ramey74091dd2022-09-26 11:49:46 -0400145static int bash_spell_correct_shellword PARAMS((int, int));
146
Jari Aalto726f6381996-08-26 18:22:31 +0000147/* Helper functions for Readline. */
Chet Ramey8868eda2020-12-06 15:51:17 -0500148static char *restore_tilde PARAMS((char *, char *));
149static char *maybe_restore_tilde PARAMS((char *, char *));
Jari Aalto31859422009-01-12 13:36:28 +0000150
Chet Ramey8868eda2020-12-06 15:51:17 -0500151static char *bash_filename_rewrite_hook PARAMS((char *, int));
Chet Rameyac50fba2014-02-26 09:36:43 -0500152
Chet Ramey8868eda2020-12-06 15:51:17 -0500153static 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));
Jari Aalto726f6381996-08-26 18:22:31 +0000159
Chet Ramey8868eda2020-12-06 15:51:17 -0500160static int executable_completion PARAMS((const char *, int));
Chet Rameyac50fba2014-02-26 09:36:43 -0500161
Chet Ramey8868eda2020-12-06 15:51:17 -0500162static rl_icppfunc_t *save_directory_hook PARAMS((void));
163static void restore_directory_hook PARAMS((rl_icppfunc_t));
Chet Ramey16b2d7f2012-05-31 15:11:45 -0400164
Chet Ramey8868eda2020-12-06 15:51:17 -0500165static int directory_exists PARAMS((const char *, int));
Chet Rameya0c0a002016-09-15 16:59:08 -0400166
Chet Ramey8868eda2020-12-06 15:51:17 -0500167static void cleanup_expansion_error PARAMS((void));
168static void maybe_make_readline_line PARAMS((char *));
169static void set_up_new_line PARAMS((char *));
Jari Aaltof73dda02001-11-13 17:56:06 +0000170
Chet Ramey8868eda2020-12-06 15:51:17 -0500171static 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));
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000176
Chet Ramey8868eda2020-12-06 15:51:17 -0500177static 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));
Jari Aalto726f6381996-08-26 18:22:31 +0000181
Chet Ramey8868eda2020-12-06 15:51:17 -0500182static 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 *));
Jari Aaltof73dda02001-11-13 17:56:06 +0000186
Chet Ramey8868eda2020-12-06 15:51:17 -0500187static 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 *));
Jari Aalto28ef6c32001-04-06 19:14:31 +0000192
Chet Ramey8868eda2020-12-06 15:51:17 -0500193static char *bash_dequote_filename PARAMS((char *, int));
194static char *quote_word_break_chars PARAMS((char *));
Chet Ramey74091dd2022-09-26 11:49:46 -0400195static int bash_check_expchar PARAMS((char *, int, int *, int *));
196static void set_filename_quote_chars PARAMS((int, int, int));
Chet Ramey8868eda2020-12-06 15:51:17 -0500197static void set_filename_bstab PARAMS((const char *));
198static char *bash_quote_filename PARAMS((char *, int, char *));
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000199
Chet Rameyac50fba2014-02-26 09:36:43 -0500200#ifdef _MINIX
Chet Ramey8868eda2020-12-06 15:51:17 -0500201static void putx PARAMS((int));
Chet Rameyac50fba2014-02-26 09:36:43 -0500202#else
Chet Ramey8868eda2020-12-06 15:51:17 -0500203static int putx PARAMS((int));
Chet Rameyac50fba2014-02-26 09:36:43 -0500204#endif
Chet Ramey8868eda2020-12-06 15:51:17 -0500205static int readline_get_char_offset PARAMS((int));
206static void readline_set_char_offset PARAMS((int, int *));
Jari Aaltof73dda02001-11-13 17:56:06 +0000207
Chet Ramey8868eda2020-12-06 15:51:17 -0500208static Keymap get_cmd_xmap_from_edit_mode PARAMS((void));
209static Keymap get_cmd_xmap_from_keymap PARAMS((Keymap));
210
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));
Jari Aaltof73dda02001-11-13 17:56:06 +0000215
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000216#if defined (ALIAS)
Chet Ramey8868eda2020-12-06 15:51:17 -0500217static int posix_edit_macros PARAMS((int, int));
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000218#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000219
Chet Ramey8868eda2020-12-06 15:51:17 -0500220static int bash_event_hook PARAMS((void));
Chet Rameyac50fba2014-02-26 09:36:43 -0500221
Jari Aaltobb706242000-03-17 21:46:59 +0000222#if defined (PROGRAMMABLE_COMPLETION)
Chet Ramey8868eda2020-12-06 15:51:17 -0500223static 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));
Jari Aaltof73dda02001-11-13 17:56:06 +0000227
Jari Aaltobb706242000-03-17 21:46:59 +0000228static char **prog_complete_matches;
Jari Aaltobb706242000-03-17 21:46:59 +0000229#endif
230
Chet Rameyd233b482019-01-07 09:27:52 -0500231extern int no_symbolic_links;
Jari Aalto726f6381996-08-26 18:22:31 +0000232extern STRING_INT_ALIST word_token_alist[];
Chet Ramey74091dd2022-09-26 11:49:46 -0400233extern sh_timer *read_timeout;
Jari Aalto726f6381996-08-26 18:22:31 +0000234
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)
Chet Ramey8868eda2020-12-06 15:51:17 -0500242static int bash_specific_completion PARAMS((int, rl_compentry_func_t *));
Jari Aalto28ef6c32001-04-06 19:14:31 +0000243
Chet Ramey8868eda2020-12-06 15:51:17 -0500244static 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));
Jari Aalto28ef6c32001-04-06 19:14:31 +0000249
Chet Ramey8868eda2020-12-06 15:51:17 -0500250static 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));
Jari Aaltof73dda02001-11-13 17:56:06 +0000260
Chet Ramey8868eda2020-12-06 15:51:17 -0500261static 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));
Jari Aaltob80f6442004-07-27 13:29:18 +0000267
Jari Aalto726f6381996-08-26 18:22:31 +0000268#endif /* SPECIFIC_COMPLETION_FUNCTIONS */
269
Chet Ramey8868eda2020-12-06 15:51:17 -0500270static int edit_and_execute_command PARAMS((int, int, int, char *));
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000271#if defined (VI_MODE)
Chet Ramey8868eda2020-12-06 15:51:17 -0500272static int vi_edit_and_execute_command PARAMS((int, int));
273static int bash_vi_complete PARAMS((int, int));
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000274#endif
Chet Ramey8868eda2020-12-06 15:51:17 -0500275static int emacs_edit_and_execute_command PARAMS((int, int));
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000276
Chet Ramey8868eda2020-12-06 15:51:17 -0500277/* Non-zero once initialize_readline () has been called. */
Jari Aalto726f6381996-08-26 18:22:31 +0000278int bash_readline_initialized = 0;
279
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000280/* 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
Jari Aaltobb706242000-03-17 21:46:59 +0000285/* If non-zero, we don't do command completion on an empty line. */
286int no_empty_command_completion;
287
Jari Aaltob80f6442004-07-27 13:29:18 +0000288/* 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
Jari Aalto31859422009-01-12 13:36:28 +0000293/* Perform spelling correction on directory names during word completion */
294int dircomplete_spelling = 0;
295
Chet Ramey16b2d7f2012-05-31 15:11:45 -0400296/* Expand directory names during word/filename completion. */
Chet Rameyac50fba2014-02-26 09:36:43 -0500297#if DIRCOMPLETE_EXPAND_DEFAULT
298int dircomplete_expand = 1;
299int dircomplete_expand_relpath = 1;
300#else
Chet Ramey16b2d7f2012-05-31 15:11:45 -0400301int dircomplete_expand = 0;
302int dircomplete_expand_relpath = 0;
Chet Rameyac50fba2014-02-26 09:36:43 -0500303#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
Chet Ramey8868eda2020-12-06 15:51:17 -0500307 variable reference, so dollar signs in a filename get quoted appropriately.
Chet Rameyac50fba2014-02-26 09:36:43 -0500308 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;
Chet Ramey16b2d7f2012-05-31 15:11:45 -0400311
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000312static char *bash_completer_word_break_characters = " \t\n\"'@><=;|&(:";
313static char *bash_nohostname_word_break_characters = " \t\n\"'><=;|&(:";
Jari Aaltob80f6442004-07-27 13:29:18 +0000314/* )) */
Jari Aalto726f6381996-08-26 18:22:31 +0000315
Chet Ramey16b2d7f2012-05-31 15:11:45 -0400316static const char *default_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{~"; /*}*/
317static char *custom_filename_quote_characters = 0;
Chet Rameyac50fba2014-02-26 09:36:43 -0500318static char filename_bstab[256];
Chet Ramey16b2d7f2012-05-31 15:11:45 -0400319
Jari Aalto28ef6c32001-04-06 19:14:31 +0000320static rl_hook_func_t *old_rl_startup_hook = (rl_hook_func_t *)NULL;
Jari Aalto726f6381996-08-26 18:22:31 +0000321
Jari Aalto95732b42005-12-07 14:08:12 +0000322static int dot_in_path = 0;
323
Chet Ramey00018032011-11-21 20:51:19 -0500324/* Set to non-zero when dabbrev-expand is running */
325static int dabbrev_expand_active = 0;
326
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000327/* 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
Jari Aalto06285672006-10-10 14:15:34 +0000337/* Flag values for the final argument to bash_default_completion */
338#define DEFCOMP_CMDPOS 1
339
Chet Ramey8868eda2020-12-06 15:51:17 -0500340static rl_command_func_t *vi_tab_binding = rl_complete;
341
Jari Aalto726f6381996-08-26 18:22:31 +0000342/* 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{
Chet Ramey8868eda2020-12-06 15:51:17 -0500348 static char kseq[2] = { CTRL ('I'), 0 }; /* TAB */
349
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000350 if (on_or_off)
351 rl_variable_bind ("comment-begin", "#");
Jari Aalto726f6381996-08-26 18:22:31 +0000352#if defined (VI_MODE)
Chet Ramey8868eda2020-12-06 15:51:17 -0500353 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 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000363#endif
364}
365
Jari Aalto31859422009-01-12 13:36:28 +0000366void
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
Jari Aaltob80f6442004-07-27 13:29:18 +0000372/* When this function returns, rl_completer_word_break_characters points to
373 dynamically allocated memory. */
Jari Aaltof73dda02001-11-13 17:56:06 +0000374int
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000375enable_hostname_completion (on_or_off)
376 int on_or_off;
377{
Jari Aaltof73dda02001-11-13 17:56:06 +0000378 int old_value;
Chet Ramey74091dd2022-09-26 11:49:46 -0400379 char *nv, *nval;
380 const char *at;
Jari Aaltof73dda02001-11-13 17:56:06 +0000381
382 old_value = perform_hostname_completion;
383
Jari Aalto726f6381996-08-26 18:22:31 +0000384 if (on_or_off)
385 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000386 perform_hostname_completion = 1;
387 rl_special_prefixes = "$@";
Jari Aalto726f6381996-08-26 18:22:31 +0000388 }
389 else
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000390 {
391 perform_hostname_completion = 0;
392 rl_special_prefixes = "$";
Jari Aaltob80f6442004-07-27 13:29:18 +0000393 }
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))
Jari Aaltoeb873672004-11-09 21:37:25 +0000417 return old_value;
Jari Aaltob80f6442004-07-27 13:29:18 +0000418
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
Chet Ramey74091dd2022-09-26 11:49:46 -0400440 free ((void *)rl_completer_word_break_characters);
Jari Aaltob80f6442004-07-27 13:29:18 +0000441 rl_completer_word_break_characters = nval;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000442 }
Jari Aaltof73dda02001-11-13 17:56:06 +0000443
444 return (old_value);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000445}
Jari Aalto726f6381996-08-26 18:22:31 +0000446
447/* Called once from parse.y if we are going to use readline. */
448void
449initialize_readline ()
450{
Jari Aaltob80f6442004-07-27 13:29:18 +0000451 rl_command_func_t *func;
452 char kseq[2];
453
Jari Aalto726f6381996-08-26 18:22:31 +0000454 if (bash_readline_initialized)
455 return;
456
457 rl_terminal_name = get_string_value ("TERM");
458 rl_instream = stdin;
459 rl_outstream = stderr;
Jari Aalto726f6381996-08-26 18:22:31 +0000460
461 /* Allow conditional parsing of the ~/.inputrc file. */
462 rl_readline_name = "Bash";
463
Jari Aalto28ef6c32001-04-06 19:14:31 +0000464 /* 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);
Jari Aaltocce855b1998-04-17 19:52:44 +0000467#ifdef BANG_HISTORY
Jari Aalto28ef6c32001-04-06 19:14:31 +0000468 rl_add_defun ("history-expand-line", history_expand_line, -1);
469 rl_add_defun ("magic-space", tcsh_magic_space, -1);
Jari Aaltocce855b1998-04-17 19:52:44 +0000470#endif
471
Jari Aalto31859422009-01-12 13:36:28 +0000472 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);
Chet Ramey8868eda2020-12-06 15:51:17 -0500476 rl_add_defun ("shell-transpose-words", bash_transpose_shellwords, -1);
Jari Aalto31859422009-01-12 13:36:28 +0000477
Chet Ramey74091dd2022-09-26 11:49:46 -0400478 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
Jari Aaltod166f041997-06-05 14:59:13 +0000481#ifdef ALIAS
Jari Aalto28ef6c32001-04-06 19:14:31 +0000482 rl_add_defun ("alias-expand-line", alias_expand_line, -1);
Jari Aaltobc4cd231998-07-23 14:37:54 +0000483# ifdef BANG_HISTORY
Jari Aalto28ef6c32001-04-06 19:14:31 +0000484 rl_add_defun ("history-and-alias-expand-line", history_and_alias_expand_line, -1);
Jari Aaltobc4cd231998-07-23 14:37:54 +0000485# endif
Jari Aaltod166f041997-06-05 14:59:13 +0000486#endif
487
Jari Aalto726f6381996-08-26 18:22:31 +0000488 /* Backwards compatibility. */
489 rl_add_defun ("insert-last-argument", rl_yank_last_arg, -1);
490
Jari Aalto28ef6c32001-04-06 19:14:31 +0000491 rl_add_defun ("display-shell-version", display_shell_version, -1);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000492 rl_add_defun ("edit-and-execute-command", emacs_edit_and_execute_command, -1);
Chet Ramey74091dd2022-09-26 11:49:46 -0400493#if defined (VI_MODE)
494 rl_add_defun ("vi-edit-and-execute-command", vi_edit_and_execute_command, -1);
495#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000496
Jari Aalto28ef6c32001-04-06 19:14:31 +0000497#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);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000512 rl_add_defun ("glob-complete-word", bash_glob_complete_word, -1);
Jari Aalto28ef6c32001-04-06 19:14:31 +0000513 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);
Jari Aalto31859422009-01-12 13:36:28 +0000518 rl_add_defun ("dabbrev-expand", bash_dabbrev_expand, -1);
Jari Aalto28ef6c32001-04-06 19:14:31 +0000519
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. */
Jari Aaltob80f6442004-07-27 13:29:18 +0000525 rl_bind_key_if_unbound_in_map (CTRL('E'), shell_expand_line, emacs_meta_keymap);
Jari Aalto28ef6c32001-04-06 19:14:31 +0000526
Jari Aalto28ef6c32001-04-06 19:14:31 +0000527#ifdef BANG_HISTORY
Jari Aaltob80f6442004-07-27 13:29:18 +0000528 rl_bind_key_if_unbound_in_map ('^', history_expand_line, emacs_meta_keymap);
Jari Aalto28ef6c32001-04-06 19:14:31 +0000529#endif
530
Jari Aaltob80f6442004-07-27 13:29:18 +0000531 rl_bind_key_if_unbound_in_map (CTRL ('V'), display_shell_version, emacs_ctlx_keymap);
Jari Aalto726f6381996-08-26 18:22:31 +0000532
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. */
Jari Aaltob80f6442004-07-27 13:29:18 +0000536 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);
Jari Aalto726f6381996-08-26 18:22:31 +0000545#if defined (VI_MODE)
Chet Ramey8868eda2020-12-06 15:51:17 -0500546 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);
Jari Aalto726f6381996-08-26 18:22:31 +0000550#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000551
Jari Aalto726f6381996-08-26 18:22:31 +0000552#if defined (BRACE_COMPLETION)
Jari Aaltob80f6442004-07-27 13:29:18 +0000553 rl_bind_key_if_unbound_in_map ('{', bash_brace_completion, emacs_meta_keymap); /*}*/
Jari Aalto726f6381996-08-26 18:22:31 +0000554#endif /* BRACE_COMPLETION */
555
556#if defined (SPECIFIC_COMPLETION_FUNCTIONS)
Jari Aaltob80f6442004-07-27 13:29:18 +0000557 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);
Jari Aalto726f6381996-08-26 18:22:31 +0000559
Jari Aaltob80f6442004-07-27 13:29:18 +0000560 /* 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);
Jari Aalto726f6381996-08-26 18:22:31 +0000567
Jari Aaltob80f6442004-07-27 13:29:18 +0000568 rl_bind_key_if_unbound_in_map ('~', bash_possible_username_completions, emacs_ctlx_keymap);
Jari Aalto726f6381996-08-26 18:22:31 +0000569
Jari Aaltob80f6442004-07-27 13:29:18 +0000570 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);
Jari Aalto726f6381996-08-26 18:22:31 +0000572
Jari Aaltob80f6442004-07-27 13:29:18 +0000573 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);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000575
Jari Aaltob80f6442004-07-27 13:29:18 +0000576 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);
Jari Aalto726f6381996-08-26 18:22:31 +0000582
583#endif /* SPECIFIC_COMPLETION_FUNCTIONS */
584
Jari Aalto95732b42005-12-07 14:08:12 +0000585 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);
Jari Aalto726f6381996-08-26 18:22:31 +0000590
591 /* Tell the completer that we want a crack first. */
Jari Aalto28ef6c32001-04-06 19:14:31 +0000592 rl_attempted_completion_function = attempt_shell_completion;
Jari Aalto726f6381996-08-26 18:22:31 +0000593
594 /* Tell the completer that we might want to follow symbolic links or
595 do other expansion on directory names. */
Chet Ramey16b2d7f2012-05-31 15:11:45 -0400596 set_directory_hook ();
Jari Aalto726f6381996-08-26 18:22:31 +0000597
Chet Ramey00018032011-11-21 20:51:19 -0500598 rl_filename_rewrite_hook = bash_filename_rewrite_hook;
599
Chet Rameyac50fba2014-02-26 09:36:43 -0500600 rl_filename_stat_hook = bash_filename_stat_hook;
601
Jari Aalto726f6381996-08-26 18:22:31 +0000602 /* Tell the filename completer we want a chance to ignore some names. */
Jari Aalto28ef6c32001-04-06 19:14:31 +0000603 rl_ignore_some_completions_function = filename_completion_ignore;
Jari Aalto726f6381996-08-26 18:22:31 +0000604
Jari Aalto7117c2d2002-07-17 14:10:11 +0000605 /* Bind C-xC-e to invoke emacs and run result as commands. */
Jari Aaltob80f6442004-07-27 13:29:18 +0000606 rl_bind_key_if_unbound_in_map (CTRL ('E'), emacs_edit_and_execute_command, emacs_ctlx_keymap);
Jari Aalto726f6381996-08-26 18:22:31 +0000607#if defined (VI_MODE)
Jari Aaltob80f6442004-07-27 13:29:18 +0000608 rl_bind_key_if_unbound_in_map ('v', vi_edit_and_execute_command, vi_movement_keymap);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000609# if defined (ALIAS)
Jari Aaltob80f6442004-07-27 13:29:18 +0000610 rl_bind_key_if_unbound_in_map ('@', posix_edit_macros, vi_movement_keymap);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000611# endif
Jari Aaltob80f6442004-07-27 13:29:18 +0000612
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);
Jari Aalto726f6381996-08-26 18:22:31 +0000616#endif
617
618 rl_completer_quote_characters = "'\"";
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000619
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. */
Chet Ramey16b2d7f2012-05-31 15:11:45 -0400626 rl_filename_quote_characters = default_filename_quote_characters;
Chet Rameyac50fba2014-02-26 09:36:43 -0500627 set_filename_bstab (rl_filename_quote_characters);
Chet Ramey495aee42011-11-22 19:11:26 -0500628
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000629 rl_filename_quoting_function = bash_quote_filename;
630 rl_filename_dequoting_function = bash_dequote_filename;
631 rl_char_is_quoted_p = char_is_quoted;
Jari Aalto726f6381996-08-26 18:22:31 +0000632
Chet Ramey8868eda2020-12-06 15:51:17 -0500633 /* 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
Jari Aalto7117c2d2002-07-17 14:10:11 +0000640#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. */
Jari Aalto726f6381996-08-26 18:22:31 +0000645 if (posixly_correct)
646 posix_readline_initialize (1);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000647#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000648
649 bash_readline_initialized = 1;
650}
651
Jari Aalto31859422009-01-12 13:36:28 +0000652void
653bashline_reinitialize ()
654{
655 bash_readline_initialized = 0;
656}
657
Chet Rameyac50fba2014-02-26 09:36:43 -0500658void
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
Jari Aalto726f6381996-08-26 18:22:31 +0000670/* 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
Jari Aalto31859422009-01-12 13:36:28 +0000676bashline_reset ()
Jari Aalto726f6381996-08-26 18:22:31 +0000677{
678 tilde_initialize ();
679 rl_attempted_completion_function = attempt_shell_completion;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000680 rl_completion_entry_function = NULL;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000681 rl_ignore_some_completions_function = filename_completion_ignore;
Chet Ramey74091dd2022-09-26 11:49:46 -0400682
683 complete_fullquote = 1;
Chet Ramey16b2d7f2012-05-31 15:11:45 -0400684 rl_filename_quote_characters = default_filename_quote_characters;
Chet Rameyac50fba2014-02-26 09:36:43 -0500685 set_filename_bstab (rl_filename_quote_characters);
Chet Ramey16b2d7f2012-05-31 15:11:45 -0400686
687 set_directory_hook ();
Chet Rameyac50fba2014-02-26 09:36:43 -0500688 rl_filename_stat_hook = bash_filename_stat_hook;
689
690 bashline_reset_event_hook ();
Chet Rameya0c0a002016-09-15 16:59:08 -0400691
692 rl_sort_completion_matches = 1;
Jari Aalto726f6381996-08-26 18:22:31 +0000693}
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. */
Jari Aalto28ef6c32001-04-06 19:14:31 +0000700static int
Jari Aalto726f6381996-08-26 18:22:31 +0000701bash_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 }
Jari Aalto28ef6c32001-04-06 19:14:31 +0000710 return 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000711}
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{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000719 FREE (push_to_readline);
Jari Aalto726f6381996-08-26 18:22:31 +0000720
721 push_to_readline = savestring (line);
722 old_rl_startup_hook = rl_startup_hook;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000723 rl_startup_hook = bash_push_line;
Jari Aalto726f6381996-08-26 18:22:31 +0000724
725 return (0);
726}
727
Jari Aalto28ef6c32001-04-06 19:14:31 +0000728static int
Jari Aalto726f6381996-08-26 18:22:31 +0000729display_shell_version (count, c)
730 int count, c;
731{
Jari Aalto28ef6c32001-04-06 19:14:31 +0000732 rl_crlf ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000733 show_shell_version (0);
Jari Aalto726f6381996-08-26 18:22:31 +0000734 putc ('\r', rl_outstream);
735 fflush (rl_outstream);
736 rl_on_new_line ();
737 rl_redisplay ();
Jari Aalto28ef6c32001-04-06 19:14:31 +0000738 return 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000739}
740
741/* **************************************************************** */
742/* */
743/* Readline Stuff */
744/* */
745/* **************************************************************** */
746
747/* If the user requests hostname completion, then simply build a list
Jari Aaltobb706242000-03-17 21:46:59 +0000748 of hosts, and complete from that forever more, or at least until
749 HOSTFILE is unset. */
Jari Aalto726f6381996-08-26 18:22:31 +0000750
Jari Aaltobb706242000-03-17 21:46:59 +0000751/* THIS SHOULD BE A STRINGLIST. */
Jari Aalto726f6381996-08-26 18:22:31 +0000752/* The kept list of hostnames. */
753static char **hostname_list = (char **)NULL;
754
755/* The physical size of the above list. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000756static int hostname_list_size;
Jari Aalto726f6381996-08-26 18:22:31 +0000757
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000758/* The number of hostnames in the above list. */
759static int hostname_list_length;
Jari Aalto726f6381996-08-26 18:22:31 +0000760
761/* Whether or not HOSTNAME_LIST has been initialized. */
762int hostname_list_initialized = 0;
763
Jari Aalto726f6381996-08-26 18:22:31 +0000764/* Initialize the hostname completion table. */
765static void
766initialize_hostname_list ()
767{
768 char *temp;
769
770 temp = get_string_value ("HOSTFILE");
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000771 if (temp == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000772 temp = get_string_value ("hostname_completion_file");
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000773 if (temp == 0)
774 temp = DEFAULT_HOSTS_FILE;
Jari Aalto726f6381996-08-26 18:22:31 +0000775
776 snarf_hosts_from_file (temp);
Jari Aalto726f6381996-08-26 18:22:31 +0000777
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 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000789 hostname_list_size = (hostname_list_size + 32) - (hostname_list_size % 32);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000790 hostname_list = strvec_resize (hostname_list, hostname_list_size);
Jari Aalto726f6381996-08-26 18:22:31 +0000791 }
792
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000793 hostname_list[hostname_list_length++] = savestring (name);
794 hostname_list[hostname_list_length] = (char *)NULL;
Jari Aalto726f6381996-08-26 18:22:31 +0000795}
796
797#define cr_whitespace(c) ((c) == '\r' || (c) == '\n' || whitespace(c))
798
799static void
800snarf_hosts_from_file (filename)
801 char *filename;
802{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000803 FILE *file;
Jari Aalto726f6381996-08-26 18:22:31 +0000804 char *temp, buffer[256], name[256];
805 register int i, start;
806
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000807 file = fopen (filename, "r");
808 if (file == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000809 return;
810
811 while (temp = fgets (buffer, 255, file))
812 {
813 /* Skip to first character. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000814 for (i = 0; buffer[i] && cr_whitespace (buffer[i]); i++)
815 ;
Jari Aalto726f6381996-08-26 18:22:31 +0000816
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000817 /* If comment or blank line, ignore. */
818 if (buffer[i] == '\0' || buffer[i] == '#')
Jari Aalto726f6381996-08-26 18:22:31 +0000819 continue;
820
821 /* If `preprocessor' directive, do the include. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000822 if (strncmp (buffer + i, "$include ", 9) == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000823 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000824 char *incfile, *t;
Jari Aalto726f6381996-08-26 18:22:31 +0000825
826 /* Find start of filename. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000827 for (incfile = buffer + i + 9; *incfile && whitespace (*incfile); incfile++)
828 ;
Jari Aalto726f6381996-08-26 18:22:31 +0000829
830 /* Find end of filename. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000831 for (t = incfile; *t && cr_whitespace (*t) == 0; t++)
832 ;
Jari Aalto726f6381996-08-26 18:22:31 +0000833
834 *t = '\0';
835
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000836 snarf_hosts_from_file (incfile);
Jari Aalto726f6381996-08-26 18:22:31 +0000837 continue;
838 }
839
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000840 /* Skip internet address if present. */
Jari Aaltof73dda02001-11-13 17:56:06 +0000841 if (DIGIT (buffer[i]))
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000842 for (; buffer[i] && cr_whitespace (buffer[i]) == 0; i++);
Jari Aalto726f6381996-08-26 18:22:31 +0000843
844 /* Gobble up names. Each name is separated with whitespace. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000845 while (buffer[i])
Jari Aalto726f6381996-08-26 18:22:31 +0000846 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000847 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)
Jari Aalto726f6381996-08-26 18:22:31 +0000856 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
Jari Aaltobb706242000-03-17 21:46:59 +0000865/* 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]);
Chet Ramey00018032011-11-21 20:51:19 -0500883 hostname_list_length = hostname_list_initialized = 0;
Jari Aaltobb706242000-03-17 21:46:59 +0000884}
885
Jari Aalto726f6381996-08-26 18:22:31 +0000886/* Return a NULL terminated list of hostnames which begin with TEXT.
Chet Rameyac50fba2014-02-26 09:36:43 -0500887 Initialize the hostname list the first time if necessary.
Jari Aalto726f6381996-08-26 18:22:31 +0000888 The array is malloc ()'ed, but not the individual strings. */
889static char **
890hostnames_matching (text)
891 char *text;
892{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000893 register int i, len, nmatch, rsize;
894 char **result;
Jari Aalto726f6381996-08-26 18:22:31 +0000895
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000896 if (hostname_list_initialized == 0)
897 initialize_hostname_list ();
Jari Aalto726f6381996-08-26 18:22:31 +0000898
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000899 if (hostname_list_initialized == 0)
900 return ((char **)NULL);
Jari Aalto726f6381996-08-26 18:22:31 +0000901
902 /* Special case. If TEXT consists of nothing, then the whole list is
903 what is desired. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000904 if (*text == '\0')
Jari Aalto726f6381996-08-26 18:22:31 +0000905 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000906 result = strvec_create (1 + hostname_list_length);
Jari Aalto726f6381996-08-26 18:22:31 +0000907 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. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000914 len = strlen (text);
915 result = (char **)NULL;
916 for (i = nmatch = rsize = 0; i < hostname_list_length; i++)
Jari Aalto726f6381996-08-26 18:22:31 +0000917 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000918 if (STREQN (text, hostname_list[i], len) == 0)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000919 continue;
Jari Aalto726f6381996-08-26 18:22:31 +0000920
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000921 /* OK, it matches. Add it to the list. */
Jari Aaltobc4cd231998-07-23 14:37:54 +0000922 if (nmatch >= (rsize - 1))
Jari Aalto726f6381996-08-26 18:22:31 +0000923 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000924 rsize = (rsize + 16) - (rsize % 16);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000925 result = strvec_resize (result, rsize);
Jari Aalto726f6381996-08-26 18:22:31 +0000926 }
927
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000928 result[nmatch++] = hostname_list[i];
Jari Aalto726f6381996-08-26 18:22:31 +0000929 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000930 if (nmatch)
931 result[nmatch] = (char *)NULL;
932 return (result);
Jari Aalto726f6381996-08-26 18:22:31 +0000933}
934
Jari Aalto726f6381996-08-26 18:22:31 +0000935/* 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
Jari Aaltob80f6442004-07-27 13:29:18 +0000939#define VI_EDIT_COMMAND "fc -e \"${VISUAL:-${EDITOR:-vi}}\""
940#define EMACS_EDIT_COMMAND "fc -e \"${VISUAL:-${EDITOR:-emacs}}\""
Jari Aalto95732b42005-12-07 14:08:12 +0000941#define POSIX_VI_EDIT_COMMAND "fc -e vi"
Jari Aalto726f6381996-08-26 18:22:31 +0000942
Jari Aalto28ef6c32001-04-06 19:14:31 +0000943static int
Jari Aalto7117c2d2002-07-17 14:10:11 +0000944edit_and_execute_command (count, c, editing_mode, edit_command)
945 int count, c, editing_mode;
946 char *edit_command;
Jari Aalto726f6381996-08-26 18:22:31 +0000947{
Jari Aalto31859422009-01-12 13:36:28 +0000948 char *command, *metaval;
Chet Ramey495aee42011-11-22 19:11:26 -0500949 int r, rrs, metaflag;
950 sh_parser_state_t ps;
Jari Aaltof73dda02001-11-13 17:56:06 +0000951
952 rrs = rl_readline_state;
Chet Ramey495aee42011-11-22 19:11:26 -0500953 saved_command_line_count = current_command_line_count;
Jari Aalto726f6381996-08-26 18:22:31 +0000954
955 /* Accept the current line. */
Jari Aaltob72432f1999-02-19 17:11:39 +0000956 rl_newline (1, c);
Jari Aalto726f6381996-08-26 18:22:31 +0000957
958 if (rl_explicit_arg)
959 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000960 command = (char *)xmalloc (strlen (edit_command) + 8);
961 sprintf (command, "%s %d", edit_command, count);
Jari Aalto726f6381996-08-26 18:22:31 +0000962 }
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'). */
Chet Ramey495aee42011-11-22 19:11:26 -0500969 /* This breaks down when using command-oriented history and are not
970 finished with the command, so we should not ignore the last command */
Jari Aalto726f6381996-08-26 18:22:31 +0000971 using_history ();
Chet Ramey8b6524c2020-02-07 15:18:41 -0500972 current_command_line_count++; /* for rl_newline above */
973 bash_add_history (rl_line_buffer);
Chet Rameyac50fba2014-02-26 09:36:43 -0500974 current_command_line_count = 0; /* for dummy history entry */
Jari Aaltod166f041997-06-05 14:59:13 +0000975 bash_add_history ("");
Jari Aalto726f6381996-08-26 18:22:31 +0000976 history_lines_this_session++;
977 using_history ();
Jari Aalto7117c2d2002-07-17 14:10:11 +0000978 command = savestring (edit_command);
Jari Aalto726f6381996-08-26 18:22:31 +0000979 }
Jari Aalto7117c2d2002-07-17 14:10:11 +0000980
Jari Aalto31859422009-01-12 13:36:28 +0000981 metaval = rl_variable_value ("input-meta");
982 metaflag = RL_BOOLEAN_VARIABLE_VALUE (metaval);
983
Jari Aalto31859422009-01-12 13:36:28 +0000984 if (rl_deprep_term_function)
985 (*rl_deprep_term_function) ();
Chet Ramey8868eda2020-12-06 15:51:17 -0500986 rl_clear_signals ();
Chet Ramey495aee42011-11-22 19:11:26 -0500987 save_parser_state (&ps);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000988 r = parse_and_execute (command, (editing_mode == VI_EDITING_MODE) ? "v" : "C-xC-e", SEVAL_NOHIST);
Chet Ramey495aee42011-11-22 19:11:26 -0500989 restore_parser_state (&ps);
Chet Ramey8868eda2020-12-06 15:51:17 -0500990
991 /* if some kind of reset_parser was called, undo it. */
992 reset_readahead_token ();
993
Jari Aalto31859422009-01-12 13:36:28 +0000994 if (rl_prep_term_function)
995 (*rl_prep_term_function) (metaflag);
Chet Ramey8868eda2020-12-06 15:51:17 -0500996 rl_set_signals ();
Jari Aaltof73dda02001-11-13 17:56:06 +0000997
Chet Ramey495aee42011-11-22 19:11:26 -0500998 current_command_line_count = saved_command_line_count;
Jari Aaltof73dda02001-11-13 17:56:06 +0000999
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. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001003 rl_line_buffer[0] = '\0'; /* XXX */
Jari Aaltof73dda02001-11-13 17:56:06 +00001004 rl_point = rl_end = 0;
1005 rl_done = 0;
1006 rl_readline_state = rrs;
1007
Chet Rameyd233b482019-01-07 09:27:52 -05001008#if defined (VI_MODE)
1009 if (editing_mode == VI_EDITING_MODE)
1010 rl_vi_insertion_mode (1, c);
1011#endif
1012
Jari Aaltof73dda02001-11-13 17:56:06 +00001013 rl_forced_update_display ();
Jari Aalto28ef6c32001-04-06 19:14:31 +00001014
1015 return r;
Jari Aalto726f6381996-08-26 18:22:31 +00001016}
Jari Aalto7117c2d2002-07-17 14:10:11 +00001017
1018#if defined (VI_MODE)
1019static int
1020vi_edit_and_execute_command (count, c)
1021 int count, c;
1022{
Jari Aalto95732b42005-12-07 14:08:12 +00001023 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));
Jari Aalto7117c2d2002-07-17 14:10:11 +00001027}
Jari Aalto726f6381996-08-26 18:22:31 +00001028#endif /* VI_MODE */
1029
Jari Aalto7117c2d2002-07-17 14:10:11 +00001030static 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
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001037#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 ();
Chet Ramey74091dd2022-09-26 11:49:46 -04001046 if (c <= 0)
1047 return 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001048 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
Jari Aalto31859422009-01-12 13:36:28 +00001062/* 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;
Chet Rameyd233b482019-01-07 09:27:52 -05001072 int c, p;
Jari Aalto31859422009-01-12 13:36:28 +00001073 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
Chet Ramey495aee42011-11-22 19:11:26 -05001094 /* 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. */
Jari Aalto31859422009-01-12 13:36:28 +00001108 /* 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;
Chet Ramey8868eda2020-12-06 15:51:17 -05001181 int c, p, prev_p;
Jari Aalto31859422009-01-12 13:36:28 +00001182 DECLARE_MBSTATE;
Chet Rameyd233b482019-01-07 09:27:52 -05001183
Jari Aalto31859422009-01-12 13:36:28 +00001184 if (count < 0)
1185 return (bash_forward_shellword (-count, key));
1186
1187 p = rl_point;
1188 slen = rl_end;
Chet Rameyd233b482019-01-07 09:27:52 -05001189
Jari Aalto31859422009-01-12 13:36:28 +00001190 while (count)
1191 {
1192 if (p == 0)
1193 {
1194 rl_point = 0;
1195 return 0;
1196 }
1197
Chet Ramey8868eda2020-12-06 15:51:17 -05001198 /* 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);
Jari Aalto31859422009-01-12 13:36:28 +00001202 while (p > 0)
1203 {
1204 c = rl_line_buffer[p];
Chet Rameyd233b482019-01-07 09:27:52 -05001205 if (WORDDELIM (c) == 0 || char_is_quoted (rl_line_buffer, p))
1206 break;
1207 BACKUP_CHAR (rl_line_buffer, slen, p);
Jari Aalto31859422009-01-12 13:36:28 +00001208 }
1209
1210 if (p == 0)
1211 {
1212 rl_point = 0;
1213 return 0;
1214 }
1215
Chet Ramey8868eda2020-12-06 15:51:17 -05001216 /* 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;
Jari Aalto31859422009-01-12 13:36:28 +00001219 while (p > 0)
1220 {
1221 c = rl_line_buffer[p];
1222 if (WORDDELIM (c) && char_is_quoted (rl_line_buffer, p) == 0)
Chet Ramey8868eda2020-12-06 15:51:17 -05001223 {
1224 p = prev_p;
1225 break;
1226 }
1227 prev_p = p;
Jari Aalto31859422009-01-12 13:36:28 +00001228 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;
Chet Ramey8868eda2020-12-06 15:51:17 -05001254 if (rl_editing_mode == EMACS_EDITING_MODE) /* 1 == emacs_mode */
Jari Aalto31859422009-01-12 13:36:28 +00001255 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
Chet Ramey8868eda2020-12-06 15:51:17 -05001275 if (rl_editing_mode == EMACS_EDITING_MODE) /* 1 == emacs_mode */
Jari Aalto31859422009-01-12 13:36:28 +00001276 rl_mark = rl_point;
1277
1278 return 0;
1279}
1280
Chet Ramey8868eda2020-12-06 15:51:17 -05001281static 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}
Jari Aalto31859422009-01-12 13:36:28 +00001339
Chet Ramey74091dd2022-09-26 11:49:46 -04001340/* 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
Jari Aalto726f6381996-08-26 18:22:31 +00001389/* **************************************************************** */
1390/* */
1391/* How To Do Shell Completion */
1392/* */
1393/* **************************************************************** */
1394
Jari Aaltobb706242000-03-17 21:46:59 +00001395#define COMMAND_SEPARATORS ";|&{(`"
Jari Aaltob80f6442004-07-27 13:29:18 +00001396/* )} */
Chet Rameyac50fba2014-02-26 09:36:43 -05001397#define COMMAND_SEPARATORS_PLUS_WS ";|&{(` \t"
1398/* )} */
Jari Aaltobb706242000-03-17 21:46:59 +00001399
Chet Rameyac50fba2014-02-26 09:36:43 -05001400/* check for redirections and other character combinations that are not
1401 command separators */
Jari Aaltobb706242000-03-17 21:46:59 +00001402static 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];
Chet Rameya0c0a002016-09-15 16:59:08 -04001411 prev_char = (ti > 0) ? rl_line_buffer[ti - 1] : 0;
Jari Aaltobb706242000-03-17 21:46:59 +00001412
1413 if ((this_char == '&' && (prev_char == '<' || prev_char == '>')) ||
1414 (this_char == '|' && prev_char == '>'))
1415 return (1);
Chet Rameyac50fba2014-02-26 09:36:43 -05001416 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))
Jari Aaltobb706242000-03-17 21:46:59 +00001429 return (1);
1430 return (0);
1431}
1432
1433#if defined (PROGRAMMABLE_COMPLETION)
Jari Aaltof73dda02001-11-13 17:56:06 +00001434/*
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 */
Jari Aaltobb706242000-03-17 21:46:59 +00001439static int
1440find_cmd_start (start)
1441 int start;
1442{
Chet Rameya0c0a002016-09-15 16:59:08 -04001443 register int s, os, ns;
Jari Aaltobb706242000-03-17 21:46:59 +00001444
1445 os = 0;
Chet Rameyac50fba2014-02-26 09:36:43 -05001446 /* 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. */
Chet Rameya0c0a002016-09-15 16:59:08 -04001449 while (((s = skip_to_delim (rl_line_buffer, os, COMMAND_SEPARATORS, SD_NOJMP|SD_COMPLETE/*|SD_NOSKIPCMD*/)) <= start) &&
Jari Aaltobb706242000-03-17 21:46:59 +00001450 rl_line_buffer[s])
Chet Rameya0c0a002016-09-15 16:59:08 -04001451 {
1452 /* Handle >| token crudely; treat as > not | */
Chet Ramey8868eda2020-12-06 15:51:17 -05001453 if (s > 0 && rl_line_buffer[s] == '|' && rl_line_buffer[s-1] == '>')
Chet Rameya0c0a002016-09-15 16:59:08 -04001454 {
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 }
Chet Ramey8868eda2020-12-06 15:51:17 -05001461 /* 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 }
Chet Rameya0c0a002016-09-15 16:59:08 -04001483 os = s+1;
1484 }
Jari Aaltobb706242000-03-17 21:46:59 +00001485 return os;
1486}
1487
1488static int
1489find_cmd_end (end)
1490 int end;
1491{
1492 register int e;
1493
Chet Rameya0c0a002016-09-15 16:59:08 -04001494 e = skip_to_delim (rl_line_buffer, end, COMMAND_SEPARATORS, SD_NOJMP|SD_COMPLETE);
Jari Aaltobb706242000-03-17 21:46:59 +00001495 return e;
1496}
1497
1498static char *
Chet Rameyac50fba2014-02-26 09:36:43 -05001499find_cmd_name (start, sp, ep)
Jari Aaltobb706242000-03-17 21:46:59 +00001500 int start;
Chet Rameyac50fba2014-02-26 09:36:43 -05001501 int *sp, *ep;
Jari Aaltobb706242000-03-17 21:46:59 +00001502{
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 */
Chet Rameya0c0a002016-09-15 16:59:08 -04001510 e = skip_to_delim (rl_line_buffer, s, "()<>;&| \t\n", SD_NOJMP|SD_COMPLETE);
Jari Aaltobb706242000-03-17 21:46:59 +00001511
1512 name = substring (rl_line_buffer, s, e);
1513
Chet Rameyac50fba2014-02-26 09:36:43 -05001514 if (sp)
1515 *sp = s;
1516 if (ep)
1517 *ep = e;
1518
Jari Aaltobb706242000-03-17 21:46:59 +00001519 return (name);
1520}
1521
1522static char *
1523prog_complete_return (text, matchnum)
Jari Aaltof73dda02001-11-13 17:56:06 +00001524 const char *text;
Jari Aaltobb706242000-03-17 21:46:59 +00001525 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
Chet Rameya0c0a002016-09-15 16:59:08 -04001539/* 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
Jari Aalto726f6381996-08-26 18:22:31 +00001567/* 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)
Jari Aalto28ef6c32001-04-06 19:14:31 +00001571 const char *text;
Jari Aalto726f6381996-08-26 18:22:31 +00001572 int start, end;
1573{
Chet Rameyd233b482019-01-07 09:27:52 -05001574 int in_command_position, ti, qc, dflags;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001575 char **matches, *command_separator_chars;
Chet Rameyac50fba2014-02-26 09:36:43 -05001576#if defined (PROGRAMMABLE_COMPLETION)
1577 int have_progcomps, was_assignment;
Chet Rameyd233b482019-01-07 09:27:52 -05001578 COMPSPEC *iw_compspec;
Chet Rameyac50fba2014-02-26 09:36:43 -05001579#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001580
Jari Aaltobb706242000-03-17 21:46:59 +00001581 command_separator_chars = COMMAND_SEPARATORS;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001582 matches = (char **)NULL;
Jari Aalto28ef6c32001-04-06 19:14:31 +00001583 rl_ignore_some_completions_function = filename_completion_ignore;
Jari Aalto726f6381996-08-26 18:22:31 +00001584
Chet Ramey74091dd2022-09-26 11:49:46 -04001585 complete_fullquote = 1; /* full filename quoting by default */
Chet Ramey16b2d7f2012-05-31 15:11:45 -04001586 rl_filename_quote_characters = default_filename_quote_characters;
Chet Rameyac50fba2014-02-26 09:36:43 -05001587 set_filename_bstab (rl_filename_quote_characters);
Chet Ramey16b2d7f2012-05-31 15:11:45 -04001588 set_directory_hook ();
Chet Rameyac50fba2014-02-26 09:36:43 -05001589 rl_filename_stat_hook = bash_filename_stat_hook;
Chet Ramey16b2d7f2012-05-31 15:11:45 -04001590
Chet Rameya0c0a002016-09-15 16:59:08 -04001591 rl_sort_completion_matches = 1; /* sort by default */
1592
Jari Aalto726f6381996-08-26 18:22:31 +00001593 /* 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;
Chet Rameyd233b482019-01-07 09:27:52 -05001598 qc = -1;
Jari Aalto726f6381996-08-26 18:22:31 +00001599
1600 while ((ti > -1) && (whitespace (rl_line_buffer[ti])))
1601 ti--;
1602
Jari Aaltobb706242000-03-17 21:46:59 +00001603#if 1
1604 /* If this is an open quote, maybe we're trying to complete a quoted
1605 command name. */
Jari Aaltob80f6442004-07-27 13:29:18 +00001606 if (ti >= 0 && (rl_line_buffer[ti] == '"' || rl_line_buffer[ti] == '\''))
Jari Aaltobb706242000-03-17 21:46:59 +00001607 {
1608 qc = rl_line_buffer[ti];
Chet Rameyd233b482019-01-07 09:27:52 -05001609 ti--;
Jari Aaltobb706242000-03-17 21:46:59 +00001610 while (ti > -1 && (whitespace (rl_line_buffer[ti])))
Jari Aalto28ef6c32001-04-06 19:14:31 +00001611 ti--;
Jari Aaltobb706242000-03-17 21:46:59 +00001612 }
1613#endif
1614
Jari Aalto726f6381996-08-26 18:22:31 +00001615 in_command_position = 0;
1616 if (ti < 0)
1617 {
1618 /* Only do command completion at the start of a line when we
Jari Aalto28ef6c32001-04-06 19:14:31 +00001619 are prompting at the top level. */
Jari Aalto726f6381996-08-26 18:22:31 +00001620 if (current_prompt_string == ps1_prompt)
1621 in_command_position++;
Chet Rameyac50fba2014-02-26 09:36:43 -05001622 else if (parser_in_command_position ())
1623 in_command_position++;
Jari Aalto726f6381996-08-26 18:22:31 +00001624 }
1625 else if (member (rl_line_buffer[ti], command_separator_chars))
1626 {
Jari Aalto726f6381996-08-26 18:22:31 +00001627 in_command_position++;
1628
Jari Aaltobb706242000-03-17 21:46:59 +00001629 if (check_redir (ti) == 1)
Chet Ramey74091dd2022-09-26 11:49:46 -04001630 in_command_position = -1; /* sentinel that we're not the first word on the line */
Jari Aalto726f6381996-08-26 18:22:31 +00001631 }
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
Chet Ramey74091dd2022-09-26 11:49:46 -04001639 if (in_command_position > 0 && invalid_completion (text, ti))
Chet Rameya0c0a002016-09-15 16:59:08 -04001640 {
1641 rl_attempted_completion_over = 1;
1642 return ((char **)NULL);
1643 }
1644
Jari Aaltod166f041997-06-05 14:59:13 +00001645 /* Check that we haven't incorrectly flagged a closed command substitution
1646 as indicating we're in a command position. */
Chet Ramey74091dd2022-09-26 11:49:46 -04001647 if (in_command_position > 0 && ti >= 0 && rl_line_buffer[ti] == '`' &&
Jari Aaltobb706242000-03-17 21:46:59 +00001648 *text != '`' && unclosed_pair (rl_line_buffer, end, "`") == 0)
Chet Ramey74091dd2022-09-26 11:49:46 -04001649 in_command_position = -1; /* not following a command separator */
Jari Aaltod166f041997-06-05 14:59:13 +00001650
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
Chet Ramey00018032011-11-21 20:51:19 -05001654 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 != '\'' &&
Chet Ramey74091dd2022-09-26 11:49:46 -04001657 (in_command_position > 0 || (unclosed_pair (rl_line_buffer, start, "`") &&
1658 unclosed_pair (rl_line_buffer, end, "`"))))
Jari Aalto28ef6c32001-04-06 19:14:31 +00001659 matches = rl_completion_matches (text, command_subst_completion_function);
Jari Aalto726f6381996-08-26 18:22:31 +00001660
Jari Aaltobb706242000-03-17 21:46:59 +00001661#if defined (PROGRAMMABLE_COMPLETION)
1662 /* Attempt programmable completion. */
Chet Rameyac50fba2014-02-26 09:36:43 -05001663 have_progcomps = prog_completion_enabled && (progcomp_size () > 0);
Chet Rameyd233b482019-01-07 09:27:52 -05001664 iw_compspec = progcomp_search (INITIALWORD);
1665 if (matches == 0 &&
Chet Ramey74091dd2022-09-26 11:49:46 -04001666 (in_command_position == 0 || text[0] == '\0' || (in_command_position > 0 && iw_compspec)) &&
Jari Aalto31859422009-01-12 13:36:28 +00001667 current_prompt_string == ps1_prompt)
Jari Aaltobb706242000-03-17 21:46:59 +00001668 {
Chet Rameyac50fba2014-02-26 09:36:43 -05001669 int s, e, s1, e1, os, foundcs;
Jari Aaltobb706242000-03-17 21:46:59 +00001670 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
Chet Rameyac50fba2014-02-26 09:36:43 -05001677 os = start;
1678 n = 0;
Chet Ramey2b3ca7e2015-08-13 15:38:31 -04001679 was_assignment = 0;
Chet Rameyac50fba2014-02-26 09:36:43 -05001680 s = find_cmd_start (os);
Jari Aaltobb706242000-03-17 21:46:59 +00001681 e = find_cmd_end (end);
Chet Rameyac50fba2014-02-26 09:36:43 -05001682 do
1683 {
Chet Ramey2b3ca7e2015-08-13 15:38:31 -04001684 /* 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 }
Chet Rameyac50fba2014-02-26 09:36:43 -05001696 /* 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 */
Chet Rameyd233b482019-01-07 09:27:52 -05001720 prog_complete_matches = programmable_completions (EMPTYCMD, text, s, e, &foundcs);
Chet Rameyac50fba2014-02-26 09:36:43 -05001721 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 */
Chet Rameyd233b482019-01-07 09:27:52 -05001734 /* 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;
Chet Rameyac50fba2014-02-26 09:36:43 -05001738 }
Chet Rameya0c0a002016-09-15 16:59:08 -04001739 /* 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 }
Chet Rameyac50fba2014-02-26 09:36:43 -05001746 else if (s >= e && n[0] == '\0' && text[0] == '\0' && start > 0)
1747 {
Chet Rameyd233b482019-01-07 09:27:52 -05001748 foundcs = 0; /* empty command name following optional assignments */
1749 in_command_position += was_assignment;
Chet Rameyac50fba2014-02-26 09:36:43 -05001750 }
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 }
Jari Aaltof73dda02001-11-13 17:56:06 +00001756 else
1757 foundcs = 0;
Chet Rameyd233b482019-01-07 09:27:52 -05001758
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
Jari Aaltobb706242000-03-17 21:46:59 +00001764 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
Jari Aalto28ef6c32001-04-06 19:14:31 +00001767 filename completion that readline will do unless the COPT_DEFAULT
Jari Aalto31859422009-01-12 13:36:28 +00001768 option has been set with the `-o default' option to complete or
1769 compopt. */
Jari Aaltobb706242000-03-17 21:46:59 +00001770 if (foundcs)
1771 {
Jari Aalto31859422009-01-12 13:36:28 +00001772 pcomp_set_readline_variables (foundcs, 1);
Jari Aaltobb706242000-03-17 21:46:59 +00001773 /* Turn what the programmable completion code returns into what
1774 readline wants. I should have made compute_lcd_of_matches
1775 external... */
Jari Aalto28ef6c32001-04-06 19:14:31 +00001776 matches = rl_completion_matches (text, prog_complete_return);
1777 if ((foundcs & COPT_DEFAULT) == 0)
1778 rl_attempted_completion_over = 1; /* no default */
Jari Aaltob80f6442004-07-27 13:29:18 +00001779 if (matches || ((foundcs & COPT_BASHDEFAULT) == 0))
1780 return (matches);
Jari Aaltobb706242000-03-17 21:46:59 +00001781 }
1782 }
1783#endif
1784
Jari Aaltob80f6442004-07-27 13:29:18 +00001785 if (matches == 0)
Jari Aalto06285672006-10-10 14:15:34 +00001786 {
1787 dflags = 0;
Chet Ramey74091dd2022-09-26 11:49:46 -04001788 if (in_command_position > 0)
Jari Aalto06285672006-10-10 14:15:34 +00001789 dflags |= DEFCOMP_CMDPOS;
1790 matches = bash_default_completion (text, start, end, qc, dflags);
1791 }
Jari Aaltob80f6442004-07-27 13:29:18 +00001792
1793 return matches;
1794}
1795
1796char **
Jari Aalto06285672006-10-10 14:15:34 +00001797bash_default_completion (text, start, end, qc, compflags)
Jari Aaltob80f6442004-07-27 13:29:18 +00001798 const char *text;
Jari Aalto06285672006-10-10 14:15:34 +00001799 int start, end, qc, compflags;
Jari Aaltob80f6442004-07-27 13:29:18 +00001800{
Chet Rameyac50fba2014-02-26 09:36:43 -05001801 char **matches, *t;
Jari Aaltob80f6442004-07-27 13:29:18 +00001802
1803 matches = (char **)NULL;
1804
Jari Aaltobb706242000-03-17 21:46:59 +00001805 /* New posix-style command substitution or variable name? */
Chet Rameyd233b482019-01-07 09:27:52 -05001806 if (*text == '$')
Jari Aaltobb706242000-03-17 21:46:59 +00001807 {
1808 if (qc != '\'' && text[1] == '(') /* ) */
Jari Aalto28ef6c32001-04-06 19:14:31 +00001809 matches = rl_completion_matches (text, command_subst_completion_function);
Jari Aaltobb706242000-03-17 21:46:59 +00001810 else
Chet Rameyac50fba2014-02-26 09:36:43 -05001811 {
1812 matches = rl_completion_matches (text, variable_completion_function);
Chet Rameya0c0a002016-09-15 16:59:08 -04001813 /* 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. */
Chet Rameyac50fba2014-02-26 09:36:43 -05001818 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 }
Jari Aaltobb706242000-03-17 21:46:59 +00001829 }
Jari Aalto726f6381996-08-26 18:22:31 +00001830
1831 /* If the word starts in `~', and there is no slash in the word, then
1832 try completing this word as a username. */
Chet Ramey495aee42011-11-22 19:11:26 -05001833 if (matches == 0 && *text == '~' && mbschr (text, '/') == 0)
Jari Aalto28ef6c32001-04-06 19:14:31 +00001834 matches = rl_completion_matches (text, rl_username_completion_function);
Jari Aalto726f6381996-08-26 18:22:31 +00001835
1836 /* Another one. Why not? If the word starts in '@', then look through
1837 the world of known hostnames for completion first. */
Chet Ramey495aee42011-11-22 19:11:26 -05001838 if (matches == 0 && perform_hostname_completion && *text == '@')
Jari Aalto28ef6c32001-04-06 19:14:31 +00001839 matches = rl_completion_matches (text, hostname_completion_function);
Jari Aalto726f6381996-08-26 18:22:31 +00001840
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. */
Jari Aalto06285672006-10-10 14:15:34 +00001844 if (matches == 0 && (compflags & DEFCOMP_CMDPOS))
Jari Aalto726f6381996-08-26 18:22:31 +00001845 {
Jari Aalto06285672006-10-10 14:15:34 +00001846 /* 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')
Jari Aaltobb706242000-03-17 21:46:59 +00001849 {
1850 matches = (char **)NULL;
Jari Aalto28ef6c32001-04-06 19:14:31 +00001851 rl_ignore_some_completions_function = bash_ignore_everything;
Jari Aaltobb706242000-03-17 21:46:59 +00001852 }
1853 else
1854 {
Jari Aaltob80f6442004-07-27 13:29:18 +00001855#define CMD_IS_DIR(x) (absolute_pathname(x) == 0 && absolute_program(x) == 0 && *(x) != '~' && test_for_directory (x))
1856
Jari Aalto95732b42005-12-07 14:08:12 +00001857 dot_in_path = 0;
Jari Aalto28ef6c32001-04-06 19:14:31 +00001858 matches = rl_completion_matches (text, command_word_completion_function);
Jari Aaltob80f6442004-07-27 13:29:18 +00001859
Jari Aaltobb706242000-03-17 21:46:59 +00001860 /* 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)
Jari Aalto28ef6c32001-04-06 19:14:31 +00001866 rl_ignore_some_completions_function = bash_ignore_filenames;
Jari Aalto95732b42005-12-07 14:08:12 +00001867 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 }
Jari Aaltob80f6442004-07-27 13:29:18 +00001876 else if (matches[0] && matches[1] && STREQ (matches[0], matches[1]) && CMD_IS_DIR (matches[0]))
Jari Aalto7117c2d2002-07-17 14:10:11 +00001877 /* 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
Jari Aalto95732b42005-12-07 14:08:12 +00001880 will distill them all down to one. We turn on
1881 rl_completion_suppress_append for the same reason as above.
Jari Aalto7117c2d2002-07-17 14:10:11 +00001882 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. */
Jari Aalto95732b42005-12-07 14:08:12 +00001885 {
1886 rl_completion_suppress_append = 1;
1887 rl_filename_completion_desired = 0;
1888 }
Jari Aaltobb706242000-03-17 21:46:59 +00001889 }
Jari Aalto726f6381996-08-26 18:22:31 +00001890 }
1891
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001892 /* This could be a globbing pattern, so try to expand it using pathname
1893 expansion. */
Chet Ramey4d2e3152019-01-18 15:12:37 -05001894 if (!matches && completion_glob_pattern ((char *)text))
Jari Aaltoe8ce7751997-09-22 20:22:27 +00001895 {
Jari Aalto28ef6c32001-04-06 19:14:31 +00001896 matches = rl_completion_matches (text, glob_complete_word);
Jari Aaltoe8ce7751997-09-22 20:22:27 +00001897 /* A glob expression that matches more than one filename is problematic.
1898 If we match more than one filename, punt. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00001899 if (matches && matches[1] && rl_completion_type == TAB)
Jari Aaltoe8ce7751997-09-22 20:22:27 +00001900 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00001901 strvec_dispose (matches);
Jari Aaltoe8ce7751997-09-22 20:22:27 +00001902 matches = (char **)0;
1903 }
Chet Rameyac50fba2014-02-26 09:36:43 -05001904 else if (matches && matches[1] && rl_completion_type == '!')
1905 {
1906 rl_completion_suppress_append = 1;
1907 rl_filename_completion_desired = 0;
1908 }
Jari Aaltoe8ce7751997-09-22 20:22:27 +00001909 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001910
Jari Aalto726f6381996-08-26 18:22:31 +00001911 return (matches);
1912}
1913
Chet Rameyac50fba2014-02-26 09:36:43 -05001914static 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{
Chet Ramey74091dd2022-09-26 11:49:46 -04001942 char *f, c;
Chet Rameyac50fba2014-02-26 09:36:43 -05001943 int r;
1944
Chet Ramey74091dd2022-09-26 11:49:46 -04001945 /* 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
Chet Rameyac50fba2014-02-26 09:36:43 -05001948 f = savestring (filename);
Chet Ramey74091dd2022-09-26 11:49:46 -04001949#else
1950 c = 0;
1951 f = bash_quote_filename ((char *)filename, SINGLE_MATCH, &c);
1952#endif
Chet Rameyac50fba2014-02-26 09:36:43 -05001953 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
Jari Aalto726f6381996-08-26 18:22:31 +00001960/* 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. */
Jari Aaltobb706242000-03-17 21:46:59 +00001964char *
Jari Aalto726f6381996-08-26 18:22:31 +00001965command_word_completion_function (hint_text, state)
Jari Aalto28ef6c32001-04-06 19:14:31 +00001966 const char *hint_text;
Jari Aalto726f6381996-08-26 18:22:31 +00001967 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;
Chet Rameyac50fba2014-02-26 09:36:43 -05001973 static char *fnhint = (char *)NULL;
Jari Aalto95732b42005-12-07 14:08:12 +00001974 static char *dequoted_hint = (char *)NULL;
Jari Aalto31859422009-01-12 13:36:28 +00001975 static char *directory_part = (char *)NULL;
1976 static char **glob_matches = (char **)NULL;
Chet Rameyd233b482019-01-07 09:27:52 -05001977 static int path_index, hint_len, istate, igncase;
Jari Aalto06285672006-10-10 14:15:34 +00001978 static int mapping_over, local_index, searching_path, hint_is_dir;
Jari Aalto31859422009-01-12 13:36:28 +00001979 static int old_glob_ignore_case, globpat;
Jari Aalto726f6381996-08-26 18:22:31 +00001980 static SHELL_VAR **varlist = (SHELL_VAR **)NULL;
1981#if defined (ALIAS)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001982 static alias_t **alias_list = (alias_t **)NULL;
Jari Aalto726f6381996-08-26 18:22:31 +00001983#endif /* ALIAS */
Chet Rameyac50fba2014-02-26 09:36:43 -05001984 char *temp, *cval;
Jari Aalto726f6381996-08-26 18:22:31 +00001985
1986 /* We have to map over the possibilities for command words. If we have
1987 no state, then make one just for that purpose. */
Jari Aalto31859422009-01-12 13:36:28 +00001988 if (state == 0)
Jari Aalto726f6381996-08-26 18:22:31 +00001989 {
Chet Rameyac50fba2014-02-26 09:36:43 -05001990 rl_filename_stat_hook = bash_command_name_stat_hook;
1991
Jari Aalto95732b42005-12-07 14:08:12 +00001992 if (dequoted_hint && dequoted_hint != hint)
1993 free (dequoted_hint);
Jari Aalto726f6381996-08-26 18:22:31 +00001994 if (hint)
1995 free (hint);
1996
Jari Aalto06285672006-10-10 14:15:34 +00001997 mapping_over = searching_path = 0;
1998 hint_is_dir = CMD_IS_DIR (hint_text);
Jari Aalto726f6381996-08-26 18:22:31 +00001999 val = (char *)NULL;
2000
Jari Aalto95732b42005-12-07 14:08:12 +00002001 temp = rl_variable_value ("completion-ignore-case");
Jari Aalto31859422009-01-12 13:36:28 +00002002 igncase = RL_BOOLEAN_VARIABLE_VALUE (temp);
2003
Chet Ramey74091dd2022-09-26 11:49:46 -04002004 old_glob_ignore_case = glob_ignore_case;
2005
Jari Aalto31859422009-01-12 13:36:28 +00002006 if (glob_matches)
2007 {
2008 free (glob_matches);
2009 glob_matches = (char **)NULL;
2010 }
2011
Chet Ramey4d2e3152019-01-18 15:12:37 -05002012 globpat = completion_glob_pattern ((char *)hint_text);
Jari Aalto95732b42005-12-07 14:08:12 +00002013
Jari Aalto726f6381996-08-26 18:22:31 +00002014 /* 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. */
Jari Aalto31859422009-01-12 13:36:28 +00002018 if (globpat || absolute_program (hint_text))
Jari Aalto726f6381996-08-26 18:22:31 +00002019 {
2020 /* Perform tilde expansion on what's passed, so we don't end up
Chet Rameya0c0a002016-09-15 16:59:08 -04002021 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. */
Jari Aalto726f6381996-08-26 18:22:31 +00002024 if (*hint_text == '~')
Jari Aalto31859422009-01-12 13:36:28 +00002025 {
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 }
Chet Rameya0c0a002016-09-15 16:59:08 -04002037 else if (dircomplete_expand)
2038 {
2039 hint = savestring (hint_text);
2040 bash_directory_completion_hook (&hint);
2041 }
Jari Aalto726f6381996-08-26 18:22:31 +00002042 else
2043 hint = savestring (hint_text);
Jari Aalto95732b42005-12-07 14:08:12 +00002044
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 }
Chet Rameyd233b482019-01-07 09:27:52 -05002057 hint_len = strlen (hint);
Jari Aalto726f6381996-08-26 18:22:31 +00002058
2059 if (filename_hint)
2060 free (filename_hint);
Jari Aalto95732b42005-12-07 14:08:12 +00002061
Chet Rameyac50fba2014-02-26 09:36:43 -05002062 fnhint = filename_hint = savestring (hint);
Jari Aalto726f6381996-08-26 18:22:31 +00002063
Jari Aalto726f6381996-08-26 18:22:31 +00002064 istate = 0;
Jari Aalto31859422009-01-12 13:36:28 +00002065
2066 if (globpat)
2067 {
2068 mapping_over = 5;
2069 goto globword;
2070 }
2071 else
2072 {
Chet Rameyac50fba2014-02-26 09:36:43 -05002073 if (dircomplete_expand && path_dot_or_dotdot (filename_hint))
Chet Ramey16b2d7f2012-05-31 15:11:45 -04002074 {
2075 dircomplete_expand = 0;
2076 set_directory_hook ();
2077 dircomplete_expand = 1;
2078 }
Jari Aalto31859422009-01-12 13:36:28 +00002079 mapping_over = 4;
2080 goto inner;
2081 }
Jari Aalto726f6381996-08-26 18:22:31 +00002082 }
2083
Jari Aalto95732b42005-12-07 14:08:12 +00002084 dequoted_hint = hint = savestring (hint_text);
Chet Rameyd233b482019-01-07 09:27:52 -05002085 hint_len = strlen (hint);
Jari Aalto726f6381996-08-26 18:22:31 +00002086
Jari Aalto95732b42005-12-07 14:08:12 +00002087 if (rl_completion_found_quote && rl_completion_quote_character == 0)
Chet Rameyd233b482019-01-07 09:27:52 -05002088 dequoted_hint = bash_dequote_filename (hint, 0);
Jari Aalto95732b42005-12-07 14:08:12 +00002089
Jari Aalto726f6381996-08-26 18:22:31 +00002090 path = get_string_value ("PATH");
Jari Aalto95732b42005-12-07 14:08:12 +00002091 path_index = dot_in_path = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00002092
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
Chet Rameyd233b482019-01-07 09:27:52 -05002122 if (igncase == 0 && (STREQN (alias, hint, hint_len)))
2123 return (savestring (alias));
2124 else if (igncase && strncasecmp (alias, hint, hint_len) == 0)
Jari Aalto726f6381996-08-26 18:22:31 +00002125 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
Chet Rameyd233b482019-01-07 09:27:52 -05002153 /* 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)
Jari Aalto726f6381996-08-26 18:22:31 +00002157 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
Jari Aalto31859422009-01-12 13:36:28 +00002182globword:
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. */
Chet Ramey30d188c2011-11-21 20:57:16 -05002187 if (globpat)
Jari Aalto31859422009-01-12 13:36:28 +00002188 {
2189 if (state == 0)
2190 {
Chet Ramey74091dd2022-09-26 11:49:46 -04002191 rl_filename_completion_desired = 1;
2192
Jari Aalto31859422009-01-12 13:36:28 +00002193 glob_ignore_case = igncase;
Chet Ramey8868eda2020-12-06 15:51:17 -05002194 glob_matches = shell_glob_filename (hint, 0);
Jari Aalto31859422009-01-12 13:36:28 +00002195 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 {
Chet Rameyac50fba2014-02-26 09:36:43 -05002213 if (*hint_text == '~' && directory_part)
Jari Aalto31859422009-01-12 13:36:28 +00002214 {
Chet Rameyac50fba2014-02-26 09:36:43 -05002215 temp = maybe_restore_tilde (val, directory_part);
Jari Aalto31859422009-01-12 13:36:28 +00002216 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
Jari Aalto06285672006-10-10 14:15:34 +00002228 /* 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
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002238 /* Repeatedly call filename_completion_function while we have
Jari Aalto726f6381996-08-26 18:22:31 +00002239 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
Jari Aalto31859422009-01-12 13:36:28 +00002245 if (istate == 0)
Jari Aalto726f6381996-08-26 18:22:31 +00002246 {
2247 char *current_path;
2248
2249 /* Get the next directory from the path. If there is none, then we
2250 are all done. */
Jari Aalto31859422009-01-12 13:36:28 +00002251 if (path == 0 || path[path_index] == 0 ||
Jari Aalto726f6381996-08-26 18:22:31 +00002252 (current_path = extract_colon_unit (path, &path_index)) == 0)
2253 return ((char *)NULL);
2254
Jari Aalto06285672006-10-10 14:15:34 +00002255 searching_path = 1;
Jari Aalto726f6381996-08-26 18:22:31 +00002256 if (*current_path == 0)
2257 {
2258 free (current_path);
2259 current_path = savestring (".");
2260 }
2261
2262 if (*current_path == '~')
2263 {
2264 char *t;
2265
Jari Aalto7117c2d2002-07-17 14:10:11 +00002266 t = bash_tilde_expand (current_path, 0);
Jari Aalto726f6381996-08-26 18:22:31 +00002267 free (current_path);
2268 current_path = t;
2269 }
2270
Jari Aalto95732b42005-12-07 14:08:12 +00002271 if (current_path[0] == '.' && current_path[1] == '\0')
2272 dot_in_path = 1;
2273
Chet Rameyac50fba2014-02-26 09:36:43 -05002274 if (fnhint && fnhint != filename_hint)
2275 free (fnhint);
Jari Aalto726f6381996-08-26 18:22:31 +00002276 if (filename_hint)
2277 free (filename_hint);
2278
Jari Aalto7117c2d2002-07-17 14:10:11 +00002279 filename_hint = sh_makepath (current_path, hint, 0);
Chet Rameyac50fba2014-02-26 09:36:43 -05002280 /* 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;
Jari Aalto31859422009-01-12 13:36:28 +00002288 free (current_path); /* XXX */
Jari Aalto726f6381996-08-26 18:22:31 +00002289 }
2290
2291 inner:
Chet Rameyac50fba2014-02-26 09:36:43 -05002292 val = rl_filename_completion_function (fnhint, istate);
Chet Ramey16b2d7f2012-05-31 15:11:45 -04002293 if (mapping_over == 4 && dircomplete_expand)
2294 set_directory_hook ();
2295
Jari Aalto726f6381996-08-26 18:22:31 +00002296 istate = 1;
2297
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002298 if (val == 0)
Jari Aalto726f6381996-08-26 18:22:31 +00002299 {
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 {
Jari Aaltod166f041997-06-05 14:59:13 +00002309 int match, freetemp;
Jari Aalto726f6381996-08-26 18:22:31 +00002310
2311 if (absolute_program (hint))
2312 {
Chet Ramey74091dd2022-09-26 11:49:46 -04002313#if 0
Jari Aalto95732b42005-12-07 14:08:12 +00002314 if (igncase == 0)
2315 match = strncmp (val, hint, hint_len) == 0;
2316 else
2317 match = strncasecmp (val, hint, hint_len) == 0;
Chet Ramey74091dd2022-09-26 11:49:46 -04002318#else
2319 /* Why duplicate the comparison rl_filename_completion_function
2320 already performs? */
2321 match = 1;
2322#endif
Jari Aalto95732b42005-12-07 14:08:12 +00002323
Jari Aalto726f6381996-08-26 18:22:31 +00002324 /* If we performed tilde expansion, restore the original
2325 filename. */
2326 if (*hint_text == '~')
Chet Rameyac50fba2014-02-26 09:36:43 -05002327 temp = maybe_restore_tilde (val, directory_part);
Jari Aalto726f6381996-08-26 18:22:31 +00002328 else
2329 temp = savestring (val);
Jari Aaltod166f041997-06-05 14:59:13 +00002330 freetemp = 1;
Jari Aalto726f6381996-08-26 18:22:31 +00002331 }
2332 else
2333 {
2334 temp = strrchr (val, '/');
2335
2336 if (temp)
2337 {
2338 temp++;
Jari Aalto95732b42005-12-07 14:08:12 +00002339 if (igncase == 0)
2340 freetemp = match = strncmp (temp, hint, hint_len) == 0;
2341 else
2342 freetemp = match = strncasecmp (temp, hint, hint_len) == 0;
Jari Aalto726f6381996-08-26 18:22:31 +00002343 if (match)
2344 temp = savestring (temp);
2345 }
2346 else
Jari Aaltod166f041997-06-05 14:59:13 +00002347 freetemp = match = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00002348 }
2349
Jari Aalto06285672006-10-10 14:15:34 +00002350 /* 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
Chet Rameyac50fba2014-02-26 09:36:43 -05002354 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 == '.')
Jari Aalto726f6381996-08-26 18:22:31 +00002366 {
Chet Rameyac50fba2014-02-26 09:36:43 -05002367 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
2375#endif
2376 cval = val;
2377
2378 if (match && executable_completion ((searching_path ? val : cval), searching_path))
2379 {
2380 if (cval != val)
2381 free (cval);
Jari Aalto726f6381996-08-26 18:22:31 +00002382 free (val);
2383 val = ""; /* So it won't be NULL. */
2384 return (temp);
2385 }
2386 else
2387 {
Jari Aaltod166f041997-06-05 14:59:13 +00002388 if (freetemp)
2389 free (temp);
Chet Rameyac50fba2014-02-26 09:36:43 -05002390 if (cval != val)
2391 free (cval);
Jari Aalto726f6381996-08-26 18:22:31 +00002392 free (val);
2393 goto inner;
2394 }
2395 }
2396}
2397
Jari Aaltod166f041997-06-05 14:59:13 +00002398/* Completion inside an unterminated command substitution. */
Jari Aalto726f6381996-08-26 18:22:31 +00002399static char *
2400command_subst_completion_function (text, state)
Jari Aalto28ef6c32001-04-06 19:14:31 +00002401 const char *text;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002402 int state;
Jari Aalto726f6381996-08-26 18:22:31 +00002403{
2404 static char **matches = (char **)NULL;
Jari Aalto28ef6c32001-04-06 19:14:31 +00002405 static const char *orig_start;
2406 static char *filename_text = (char *)NULL;
Jari Aalto726f6381996-08-26 18:22:31 +00002407 static int cmd_index, start_len;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002408 char *value;
Jari Aalto726f6381996-08-26 18:22:31 +00002409
2410 if (state == 0)
2411 {
2412 if (filename_text)
2413 free (filename_text);
2414 orig_start = text;
2415 if (*text == '`')
Jari Aalto28ef6c32001-04-06 19:14:31 +00002416 text++;
Jari Aaltocce855b1998-04-17 19:52:44 +00002417 else if (*text == '$' && text[1] == '(') /* ) */
Jari Aalto28ef6c32001-04-06 19:14:31 +00002418 text += 2;
Jari Aaltob80f6442004-07-27 13:29:18 +00002419 /* If the text was quoted, suppress any quote character that the
2420 readline completion code would insert. */
2421 rl_completion_suppress_quote = 1;
Jari Aalto726f6381996-08-26 18:22:31 +00002422 start_len = text - orig_start;
2423 filename_text = savestring (text);
2424 if (matches)
2425 free (matches);
Jari Aalto7117c2d2002-07-17 14:10:11 +00002426
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];
Jari Aalto95732b42005-12-07 14:08:12 +00002451
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;
Jari Aalto726f6381996-08-26 18:22:31 +00002458 }
2459
Chet Rameyac50fba2014-02-26 09:36:43 -05002460 if (matches == 0 || matches[cmd_index] == 0)
Jari Aalto726f6381996-08-26 18:22:31 +00002461 {
2462 rl_filename_quoting_desired = 0; /* disable quoting */
2463 return ((char *)NULL);
2464 }
2465 else
2466 {
Jari Aaltof73dda02001-11-13 17:56:06 +00002467 value = (char *)xmalloc (1 + start_len + strlen (matches[cmd_index]));
Jari Aalto726f6381996-08-26 18:22:31 +00002468
2469 if (start_len == 1)
Jari Aalto28ef6c32001-04-06 19:14:31 +00002470 value[0] = *orig_start;
Jari Aalto726f6381996-08-26 18:22:31 +00002471 else
Jari Aalto28ef6c32001-04-06 19:14:31 +00002472 strncpy (value, orig_start, start_len);
Jari Aalto726f6381996-08-26 18:22:31 +00002473
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)
Jari Aalto28ef6c32001-04-06 19:14:31 +00002484 const char *text;
Jari Aalto726f6381996-08-26 18:22:31 +00002485 int state;
Jari Aalto726f6381996-08-26 18:22:31 +00002486{
Jari Aaltobb706242000-03-17 21:46:59 +00002487 static char **varlist = (char **)NULL;
Jari Aalto726f6381996-08-26 18:22:31 +00002488 static int varlist_index;
2489 static char *varname = (char *)NULL;
Jari Aalto726f6381996-08-26 18:22:31 +00002490 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
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002503 if (text[first_char_loc] == '{')
Jari Aalto28ef6c32001-04-06 19:14:31 +00002504 first_char_loc++;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002505
Jari Aalto726f6381996-08-26 18:22:31 +00002506 varname = savestring (text + first_char_loc);
2507
Jari Aalto726f6381996-08-26 18:22:31 +00002508 if (varlist)
Jari Aalto7117c2d2002-07-17 14:10:11 +00002509 strvec_dispose (varlist);
Jari Aaltobb706242000-03-17 21:46:59 +00002510
2511 varlist = all_variables_matching_prefix (varname);
Jari Aalto726f6381996-08-26 18:22:31 +00002512 varlist_index = 0;
2513 }
2514
Jari Aalto726f6381996-08-26 18:22:31 +00002515 if (!varlist || !varlist[varlist_index])
2516 {
2517 return ((char *)NULL);
2518 }
2519 else
2520 {
Jari Aaltof73dda02001-11-13 17:56:06 +00002521 char *value;
2522
2523 value = (char *)xmalloc (4 + strlen (varlist[varlist_index]));
Jari Aalto726f6381996-08-26 18:22:31 +00002524
2525 if (first_char_loc)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002526 {
2527 value[0] = first_char;
2528 if (first_char_loc == 2)
2529 value[1] = '{';
2530 }
Jari Aalto726f6381996-08-26 18:22:31 +00002531
Jari Aaltobb706242000-03-17 21:46:59 +00002532 strcpy (value + first_char_loc, varlist[varlist_index]);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002533 if (first_char_loc == 2)
Jari Aalto28ef6c32001-04-06 19:14:31 +00002534 strcat (value, "}");
Jari Aalto726f6381996-08-26 18:22:31 +00002535
2536 varlist_index++;
2537 return (value);
2538 }
2539}
2540
2541/* How about a completion function for hostnames? */
2542static char *
2543hostname_completion_function (text, state)
Jari Aalto28ef6c32001-04-06 19:14:31 +00002544 const char *text;
Jari Aalto726f6381996-08-26 18:22:31 +00002545 int state;
Jari Aalto726f6381996-08-26 18:22:31 +00002546{
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. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002552 if (state == 0)
Jari Aalto726f6381996-08-26 18:22:31 +00002553 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002554 FREE (list);
Jari Aalto726f6381996-08-26 18:22:31 +00002555
2556 list = (char **)NULL;
2557
2558 first_char_loc = 0;
2559 first_char = *text;
2560
2561 if (first_char == '@')
2562 first_char_loc++;
2563
Jari Aaltof73dda02001-11-13 17:56:06 +00002564 list = hostnames_matching ((char *)text+first_char_loc);
Jari Aalto726f6381996-08-26 18:22:31 +00002565 list_index = 0;
2566 }
2567
2568 if (list && list[list_index])
2569 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002570 char *t;
Jari Aalto726f6381996-08-26 18:22:31 +00002571
Jari Aaltof73dda02001-11-13 17:56:06 +00002572 t = (char *)xmalloc (2 + strlen (list[list_index]));
Jari Aalto726f6381996-08-26 18:22:31 +00002573 *t = first_char;
2574 strcpy (t + first_char_loc, list[list_index]);
2575 list_index++;
2576 return (t);
2577 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002578
2579 return ((char *)NULL);
Jari Aalto726f6381996-08-26 18:22:31 +00002580}
2581
Jari Aalto7117c2d2002-07-17 14:10:11 +00002582/*
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;
Chet Rameyd233b482019-01-07 09:27:52 -05002595 static int snamelen;
Jari Aalto7117c2d2002-07-17 14:10:11 +00002596 char *value;
2597 char **alist, *aentry;
2598 int afound;
2599
2600 if (state == 0)
2601 {
2602 FREE (sname);
Jari Aalto7117c2d2002-07-17 14:10:11 +00002603
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 */
Jari Aalto06285672006-10-10 14:15:34 +00002615 for (alist = srvent->s_aliases; *alist; alist++)
Jari Aalto7117c2d2002-07-17 14:10:11 +00002616 {
Jari Aalto06285672006-10-10 14:15:34 +00002617 aentry = *alist;
Jari Aalto7117c2d2002-07-17 14:10:11 +00002618 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 */
Jari Aaltof73dda02001-11-13 17:56:06 +00002643char *
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
Jari Aaltocce855b1998-04-17 19:52:44 +00002682/* 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. */
Jari Aalto726f6381996-08-26 18:22:31 +00002688static char *
2689history_expand_line_internal (line)
2690 char *line;
2691{
2692 char *new_line;
Jari Aaltob80f6442004-07-27 13:29:18 +00002693 int old_verify;
Jari Aalto726f6381996-08-26 18:22:31 +00002694
Jari Aaltob80f6442004-07-27 13:29:18 +00002695 old_verify = hist_verify;
2696 hist_verify = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00002697 new_line = pre_process_line (line, 0, 0);
Jari Aaltob80f6442004-07-27 13:29:18 +00002698 hist_verify = old_verify;
2699
Jari Aaltod166f041997-06-05 14:59:13 +00002700 return (new_line == line) ? savestring (line) : new_line;
Jari Aalto726f6381996-08-26 18:22:31 +00002701}
Jari Aalto726f6381996-08-26 18:22:31 +00002702#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;
Jari Aaltob80f6442004-07-27 13:29:18 +00002710#if defined (BANG_HISTORY)
2711 int old_verify;
2712
2713 old_verify = hist_verify;
2714 hist_verify = 0;
2715#endif
Jari Aalto726f6381996-08-26 18:22:31 +00002716
2717 fprintf (rl_outstream, "\r\n");
2718 to_free = pre_process_line (rl_line_buffer, 1, 0);
Jari Aaltob80f6442004-07-27 13:29:18 +00002719#if defined (BANG_HISTORY)
2720 hist_verify = old_verify;
2721#endif
Jari Aaltod166f041997-06-05 14:59:13 +00002722 if (to_free != rl_line_buffer)
Jari Aaltob80f6442004-07-27 13:29:18 +00002723 FREE (to_free);
Jari Aalto726f6381996-08-26 18:22:31 +00002724 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{
Chet Rameyd233b482019-01-07 09:27:52 -05002735 if (new_line && strcmp (new_line, rl_line_buffer) != 0)
Jari Aalto726f6381996-08-26 18:22:31 +00002736 {
2737 rl_point = rl_end;
2738
2739 rl_add_undo (UNDO_BEGIN, 0, 0, 0);
2740 rl_delete_text (0, rl_point);
Jari Aalto7117c2d2002-07-17 14:10:11 +00002741 rl_point = rl_end = rl_mark = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00002742 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{
Jari Aaltof73dda02001-11-13 17:56:06 +00002752 int old_point, at_end;
2753
2754 old_point = rl_point;
2755 at_end = rl_point == rl_end;
Jari Aalto726f6381996-08-26 18:22:31 +00002756
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]))
Jari Aaltob72432f1999-02-19 17:11:39 +00002769 rl_forward_word (1, 0);
Jari Aalto726f6381996-08-26 18:22:31 +00002770 }
2771}
2772
Jari Aaltocce855b1998-04-17 19:52:44 +00002773#if defined (ALIAS)
2774/* Expand aliases in the current readline line. */
2775static int
Jari Aalto28ef6c32001-04-06 19:14:31 +00002776alias_expand_line (count, ignore)
2777 int count, ignore;
Jari Aaltocce855b1998-04-17 19:52:44 +00002778{
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)
Jari Aalto726f6381996-08-26 18:22:31 +00002797/* History expand the line. */
Jari Aaltocce855b1998-04-17 19:52:44 +00002798static int
Jari Aalto28ef6c32001-04-06 19:14:31 +00002799history_expand_line (count, ignore)
2800 int count, ignore;
Jari Aalto726f6381996-08-26 18:22:31 +00002801{
2802 char *new_line;
2803
2804 new_line = history_expand_line_internal (rl_line_buffer);
2805
2806 if (new_line)
Jari Aaltocce855b1998-04-17 19:52:44 +00002807 {
2808 set_up_new_line (new_line);
2809 return (0);
2810 }
Jari Aalto726f6381996-08-26 18:22:31 +00002811 else
Jari Aaltocce855b1998-04-17 19:52:44 +00002812 {
2813 cleanup_expansion_error ();
2814 return (1);
2815 }
Jari Aalto726f6381996-08-26 18:22:31 +00002816}
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002817
Jari Aaltocce855b1998-04-17 19:52:44 +00002818/* Expand history substitutions in the current line and then insert a
Jari Aalto28ef6c32001-04-06 19:14:31 +00002819 space (hopefully close to where we were before). */
Jari Aaltocce855b1998-04-17 19:52:44 +00002820static int
Jari Aalto28ef6c32001-04-06 19:14:31 +00002821tcsh_magic_space (count, ignore)
2822 int count, ignore;
Jari Aaltocce855b1998-04-17 19:52:44 +00002823{
Jari Aalto28ef6c32001-04-06 19:14:31 +00002824 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)
Jari Aaltocce855b1998-04-17 19:52:44 +00002829 {
Jari Aalto28ef6c32001-04-06 19:14:31 +00002830 /* 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;
Jari Aaltocce855b1998-04-17 19:52:44 +00002834 rl_insert (1, ' ');
2835 return (0);
2836 }
2837 else
2838 return (1);
2839}
Jari Aalto95732b42005-12-07 14:08:12 +00002840#endif /* BANG_HISTORY */
Jari Aaltocce855b1998-04-17 19:52:44 +00002841
Jari Aalto726f6381996-08-26 18:22:31 +00002842/* History and alias expand the line. */
Jari Aaltocce855b1998-04-17 19:52:44 +00002843static int
Jari Aalto28ef6c32001-04-06 19:14:31 +00002844history_and_alias_expand_line (count, ignore)
2845 int count, ignore;
Jari Aalto726f6381996-08-26 18:22:31 +00002846{
Chet Ramey74091dd2022-09-26 11:49:46 -04002847 char *new_line, *t;
Jari Aalto726f6381996-08-26 18:22:31 +00002848
Jari Aalto95732b42005-12-07 14:08:12 +00002849 new_line = 0;
2850#if defined (BANG_HISTORY)
Jari Aaltob80f6442004-07-27 13:29:18 +00002851 new_line = history_expand_line_internal (rl_line_buffer);
Jari Aalto95732b42005-12-07 14:08:12 +00002852#endif
Jari Aalto726f6381996-08-26 18:22:31 +00002853
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)
Jari Aaltocce855b1998-04-17 19:52:44 +00002866 {
2867 set_up_new_line (new_line);
2868 return (0);
2869 }
Jari Aalto726f6381996-08-26 18:22:31 +00002870 else
Jari Aaltocce855b1998-04-17 19:52:44 +00002871 {
2872 cleanup_expansion_error ();
2873 return (1);
2874 }
Jari Aalto726f6381996-08-26 18:22:31 +00002875}
2876
2877/* History and alias expand the line, then perform the shell word
Jari Aaltocce855b1998-04-17 19:52:44 +00002878 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. */
Jari Aalto28ef6c32001-04-06 19:14:31 +00002881static int
2882shell_expand_line (count, ignore)
2883 int count, ignore;
Jari Aalto726f6381996-08-26 18:22:31 +00002884{
Chet Ramey74091dd2022-09-26 11:49:46 -04002885 char *new_line, *t;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002886 WORD_LIST *expanded_string;
Chet Rameyd233b482019-01-07 09:27:52 -05002887 WORD_DESC *w;
Jari Aalto726f6381996-08-26 18:22:31 +00002888
Jari Aalto95732b42005-12-07 14:08:12 +00002889 new_line = 0;
2890#if defined (BANG_HISTORY)
Jari Aaltob80f6442004-07-27 13:29:18 +00002891 new_line = history_expand_line_internal (rl_line_buffer);
Jari Aalto95732b42005-12-07 14:08:12 +00002892#endif
Jari Aalto726f6381996-08-26 18:22:31 +00002893
Chet Ramey74091dd2022-09-26 11:49:46 -04002894 t = expand_string_dollar_quote (new_line ? new_line : rl_line_buffer, 0);
2895 FREE (new_line);
2896 new_line = t;
2897
Jari Aalto726f6381996-08-26 18:22:31 +00002898#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. */
Chet Rameyd233b482019-01-07 09:27:52 -05002921
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
Jari Aaltod166f041997-06-05 14:59:13 +00002929 new_line = savestring (rl_line_buffer);
2930 expanded_string = expand_string (new_line, 0);
2931 FREE (new_line);
Chet Rameyd233b482019-01-07 09:27:52 -05002932#endif
2933
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002934 if (expanded_string == 0)
2935 {
Jari Aaltof73dda02001-11-13 17:56:06 +00002936 new_line = (char *)xmalloc (1);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002937 new_line[0] = '\0';
2938 }
2939 else
2940 {
2941 new_line = string_list (expanded_string);
2942 dispose_words (expanded_string);
2943 }
Jari Aalto726f6381996-08-26 18:22:31 +00002944
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002945 maybe_make_readline_line (new_line);
2946 free (new_line);
Jari Aalto726f6381996-08-26 18:22:31 +00002947
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002948 /* 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]))
Jari Aaltob72432f1999-02-19 17:11:39 +00002955 rl_forward_word (1, 0);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002956 }
Jari Aalto28ef6c32001-04-06 19:14:31 +00002957 return 0;
Jari Aalto726f6381996-08-26 18:22:31 +00002958 }
2959 else
Jari Aalto28ef6c32001-04-06 19:14:31 +00002960 {
2961 cleanup_expansion_error ();
2962 return 1;
2963 }
Jari Aalto726f6381996-08-26 18:22:31 +00002964}
2965
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002966/* 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
Jari Aalto726f6381996-08-26 18:22:31 +00002968 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"
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002972 completion types, such as hostnames or commands. */
Jari Aalto726f6381996-08-26 18:22:31 +00002973
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002974static struct ignorevar fignore =
2975{
2976 "FIGNORE",
2977 (struct ign *)0,
2978 0,
2979 (char *)0,
Jari Aaltof73dda02001-11-13 17:56:06 +00002980 (sh_iv_item_func_t *) 0,
Jari Aalto726f6381996-08-26 18:22:31 +00002981};
2982
Jari Aalto726f6381996-08-26 18:22:31 +00002983static void
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002984_ignore_completion_names (names, name_func)
Jari Aalto726f6381996-08-26 18:22:31 +00002985 char **names;
Jari Aaltof73dda02001-11-13 17:56:06 +00002986 sh_ignore_func_t *name_func;
Jari Aalto726f6381996-08-26 18:22:31 +00002987{
2988 char **newnames;
2989 int idx, nidx;
Jari Aaltocce855b1998-04-17 19:52:44 +00002990 char **oldnames;
2991 int oidx;
Jari Aalto726f6381996-08-26 18:22:31 +00002992
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 {
Jari Aaltob80f6442004-07-27 13:29:18 +00002999 if (force_fignore)
3000 if ((*name_func) (names[0]) == 0)
3001 {
3002 free (names[0]);
3003 names[0] = (char *)NULL;
3004 }
3005
Jari Aalto726f6381996-08-26 18:22:31 +00003006 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 ;
Jari Aalto7117c2d2002-07-17 14:10:11 +00003013 newnames = strvec_create (nidx + 1);
Jari Aaltob80f6442004-07-27 13:29:18 +00003014
3015 if (force_fignore == 0)
3016 {
3017 oldnames = strvec_create (nidx - 1);
3018 oidx = 0;
3019 }
Jari Aalto726f6381996-08-26 18:22:31 +00003020
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];
Jari Aaltob80f6442004-07-27 13:29:18 +00003026 else if (force_fignore == 0)
Jari Aaltocce855b1998-04-17 19:52:44 +00003027 oldnames[oidx++] = names[idx];
Jari Aaltob80f6442004-07-27 13:29:18 +00003028 else
3029 free (names[idx]);
Jari Aalto726f6381996-08-26 18:22:31 +00003030 }
3031
3032 newnames[nidx] = (char *)NULL;
3033
3034 /* If none are acceptable then let the completer handle it. */
3035 if (nidx == 1)
3036 {
Jari Aaltob80f6442004-07-27 13:29:18 +00003037 if (force_fignore)
3038 {
3039 free (names[0]);
3040 names[0] = (char *)NULL;
3041 }
3042 else
3043 free (oldnames);
3044
Jari Aalto726f6381996-08-26 18:22:31 +00003045 free (newnames);
3046 return;
3047 }
3048
Jari Aaltob80f6442004-07-27 13:29:18 +00003049 if (force_fignore == 0)
3050 {
3051 while (oidx)
3052 free (oldnames[--oidx]);
3053 free (oldnames);
3054 }
Jari Aaltocce855b1998-04-17 19:52:44 +00003055
Jari Aalto726f6381996-08-26 18:22:31 +00003056 /* 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 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003065
Jari Aalto726f6381996-08-26 18:22:31 +00003066 /* 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;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003071 free (newnames);
3072}
3073
3074static int
3075name_is_acceptable (name)
Jari Aaltof73dda02001-11-13 17:56:06 +00003076 const char *name;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003077{
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);
Jari Aalto726f6381996-08-26 18:22:31 +00003088}
3089
Jari Aaltob72432f1999-02-19 17:11:39 +00003090#if 0
3091static int
3092ignore_dot_names (name)
3093 char *name;
3094{
3095 return (name[0] != '.');
3096}
3097#endif
3098
Jari Aalto28ef6c32001-04-06 19:14:31 +00003099static int
Jari Aalto726f6381996-08-26 18:22:31 +00003100filename_completion_ignore (names)
3101 char **names;
3102{
Jari Aaltob72432f1999-02-19 17:11:39 +00003103#if 0
3104 if (glob_dot_filenames == 0)
3105 _ignore_completion_names (names, ignore_dot_names);
3106#endif
3107
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003108 setup_ignore_patterns (&fignore);
Jari Aalto726f6381996-08-26 18:22:31 +00003109
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003110 if (fignore.num_ignores == 0)
Jari Aalto28ef6c32001-04-06 19:14:31 +00003111 return 0;
Jari Aalto726f6381996-08-26 18:22:31 +00003112
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003113 _ignore_completion_names (names, name_is_acceptable);
Jari Aalto28ef6c32001-04-06 19:14:31 +00003114
3115 return 0;
Jari Aalto726f6381996-08-26 18:22:31 +00003116}
3117
Jari Aalto31859422009-01-12 13:36:28 +00003118/* Return 1 if NAME is a directory. NAME undergoes tilde expansion. */
Jari Aalto726f6381996-08-26 18:22:31 +00003119static int
3120test_for_directory (name)
Jari Aaltof73dda02001-11-13 17:56:06 +00003121 const char *name;
Jari Aalto726f6381996-08-26 18:22:31 +00003122{
Jari Aalto726f6381996-08-26 18:22:31 +00003123 char *fn;
Jari Aalto31859422009-01-12 13:36:28 +00003124 int r;
Jari Aalto726f6381996-08-26 18:22:31 +00003125
Jari Aalto7117c2d2002-07-17 14:10:11 +00003126 fn = bash_tilde_expand (name, 0);
Jari Aalto31859422009-01-12 13:36:28 +00003127 r = file_isdir (fn);
Jari Aalto726f6381996-08-26 18:22:31 +00003128 free (fn);
Jari Aalto31859422009-01-12 13:36:28 +00003129
3130 return (r);
Jari Aalto726f6381996-08-26 18:22:31 +00003131}
3132
Chet Ramey8868eda2020-12-06 15:51:17 -05003133static 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
Jari Aalto726f6381996-08-26 18:22:31 +00003148/* Remove files from NAMES, leaving directories. */
Jari Aalto28ef6c32001-04-06 19:14:31 +00003149static int
Jari Aalto726f6381996-08-26 18:22:31 +00003150bash_ignore_filenames (names)
3151 char **names;
3152{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003153 _ignore_completion_names (names, test_for_directory);
Jari Aalto28ef6c32001-04-06 19:14:31 +00003154 return 0;
Jari Aalto726f6381996-08-26 18:22:31 +00003155}
3156
Jari Aaltobb706242000-03-17 21:46:59 +00003157static int
Chet Ramey8868eda2020-12-06 15:51:17 -05003158bash_progcomp_ignore_filenames (names)
3159 char **names;
3160{
3161 _ignore_completion_names (names, test_for_canon_directory);
3162 return 0;
3163}
3164
3165static int
Jari Aaltobb706242000-03-17 21:46:59 +00003166return_zero (name)
Jari Aaltof73dda02001-11-13 17:56:06 +00003167 const char *name;
Jari Aaltobb706242000-03-17 21:46:59 +00003168{
3169 return 0;
3170}
3171
Jari Aalto28ef6c32001-04-06 19:14:31 +00003172static int
Jari Aaltobb706242000-03-17 21:46:59 +00003173bash_ignore_everything (names)
3174 char **names;
3175{
3176 _ignore_completion_names (names, return_zero);
Jari Aalto28ef6c32001-04-06 19:14:31 +00003177 return 0;
Jari Aaltobb706242000-03-17 21:46:59 +00003178}
3179
Jari Aalto31859422009-01-12 13:36:28 +00003180/* 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;
Chet Rameyd233b482019-01-07 09:27:52 -05003188 char *dh2, *expdir, *ret, *v;
Jari Aalto31859422009-01-12 13:36:28 +00003189
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);
Chet Rameyd233b482019-01-07 09:27:52 -05003200 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 }
Jari Aalto31859422009-01-12 13:36:28 +00003216 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;
Chet Rameyd233b482019-01-07 09:27:52 -05003226 if (l <= 0)
3227 {
3228 free (dh2);
3229 return (savestring (val)); /* XXX - just punt */
3230 }
Jari Aalto31859422009-01-12 13:36:28 +00003231
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
Chet Rameyac50fba2014-02-26 09:36:43 -05003240static 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
Jari Aaltoeb873672004-11-09 21:37:25 +00003254/* 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. */
Jari Aalto95732b42005-12-07 14:08:12 +00003257static void
Jari Aaltoeb873672004-11-09 21:37:25 +00003258bash_directory_expansion (dirname)
3259 char **dirname;
3260{
Jari Aalto06285672006-10-10 14:15:34 +00003261 char *d, *nd;
Jari Aaltoeb873672004-11-09 21:37:25 +00003262
3263 d = savestring (*dirname);
3264
Chet Rameyac50fba2014-02-26 09:36:43 -05003265 if ((rl_directory_rewrite_hook) && (*rl_directory_rewrite_hook) (&d))
3266 {
3267 free (*dirname);
3268 *dirname = d;
3269 }
Chet Ramey495aee42011-11-22 19:11:26 -05003270 else if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&d))
Jari Aaltoeb873672004-11-09 21:37:25 +00003271 {
3272 free (*dirname);
3273 *dirname = d;
3274 }
Jari Aalto06285672006-10-10 14:15:34 +00003275 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 }
Chet Ramey74091dd2022-09-26 11:49:46 -04003282 else
3283 free (d);
Jari Aaltoeb873672004-11-09 21:37:25 +00003284}
Jari Aalto31859422009-01-12 13:36:28 +00003285
Chet Ramey00018032011-11-21 20:51:19 -05003286/* 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
Chet Ramey16b2d7f2012-05-31 15:11:45 -04003300/* 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
Chet Ramey4f747ed2017-01-20 11:47:55 -05003346/* Check whether not DIRNAME, with any trailing slash removed, exists. If
3347 SHOULD_DEQUOTE is non-zero, we dequote the directory name first. */
Chet Rameya0c0a002016-09-15 16:59:08 -04003348static int
Chet Ramey4f747ed2017-01-20 11:47:55 -05003349directory_exists (dirname, should_dequote)
Chet Rameya0c0a002016-09-15 16:59:08 -04003350 const char *dirname;
Chet Ramey4f747ed2017-01-20 11:47:55 -05003351 int should_dequote;
Chet Rameya0c0a002016-09-15 16:59:08 -04003352{
3353 char *new_dirname;
3354 int dirlen, r;
3355 struct stat sb;
3356
Chet Ramey4f747ed2017-01-20 11:47:55 -05003357 /* 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);
Chet Rameya0c0a002016-09-15 16:59:08 -04003360 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
Chet Rameyac50fba2014-02-26 09:36:43 -05003372/* 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;
Chet Rameya0c0a002016-09-15 16:59:08 -04003380 int global_nounset;
Chet Rameyac50fba2014-02-26 09:36:43 -05003381 WORD_LIST *wl;
Chet Rameyac50fba2014-02-26 09:36:43 -05003382
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
Chet Ramey4f747ed2017-01-20 11:47:55 -05003390 if (should_expand_dirname && directory_exists (local_dirname, 0))
Chet Rameyac50fba2014-02-26 09:36:43 -05003391 should_expand_dirname = 0;
3392
3393 if (should_expand_dirname)
3394 {
3395 new_dirname = savestring (local_dirname);
Chet Rameya0c0a002016-09-15 16:59:08 -04003396 /* 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;
Chet Ramey4f747ed2017-01-20 11:47:55 -05003400 wl = expand_prompt_string (new_dirname, 0, W_NOCOMSUB|W_NOPROCSUB|W_COMPLETE); /* does the right thing */
Chet Rameya0c0a002016-09-15 16:59:08 -04003401 unbound_vars_is_error = global_nounset;
Chet Rameyac50fba2014-02-26 09:36:43 -05003402 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
Jari Aalto726f6381996-08-26 18:22:31 +00003450/* Handle symbolic link references and other directory name
Chet Ramey495aee42011-11-22 19:11:26 -05003451 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. */
Jari Aalto726f6381996-08-26 18:22:31 +00003454static int
3455bash_directory_completion_hook (dirname)
3456 char **dirname;
3457{
Jari Aaltob72432f1999-02-19 17:11:39 +00003458 char *local_dirname, *new_dirname, *t;
Chet Rameyd233b482019-01-07 09:27:52 -05003459 int return_value, should_expand_dirname, nextch, closer;
Jari Aalto726f6381996-08-26 18:22:31 +00003460 WORD_LIST *wl;
3461
Chet Ramey16b2d7f2012-05-31 15:11:45 -04003462 return_value = should_expand_dirname = nextch = closer = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00003463 local_dirname = *dirname;
Jari Aaltobb706242000-03-17 21:46:59 +00003464
Chet Ramey74091dd2022-09-26 11:49:46 -04003465 should_expand_dirname = bash_check_expchar (local_dirname, 1, &nextch, &closer);
Jari Aaltobb706242000-03-17 21:46:59 +00003466
Chet Ramey4f747ed2017-01-20 11:47:55 -05003467 if (should_expand_dirname && directory_exists (local_dirname, 1))
Jari Aaltob80f6442004-07-27 13:29:18 +00003468 should_expand_dirname = 0;
3469
Jari Aaltobb706242000-03-17 21:46:59 +00003470 if (should_expand_dirname)
3471 {
3472 new_dirname = savestring (local_dirname);
Chet Ramey4f747ed2017-01-20 11:47:55 -05003473 wl = expand_prompt_string (new_dirname, 0, W_NOCOMSUB|W_NOPROCSUB|W_COMPLETE); /* does the right thing */
Jari Aalto726f6381996-08-26 18:22:31 +00003474 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);
Jari Aaltob72432f1999-02-19 17:11:39 +00003481 free (new_dirname);
Jari Aalto726f6381996-08-26 18:22:31 +00003482 dispose_words (wl);
3483 local_dirname = *dirname;
Chet Ramey74091dd2022-09-26 11:49:46 -04003484
3485 set_filename_quote_chars (should_expand_dirname, nextch, closer);
Jari Aalto726f6381996-08-26 18:22:31 +00003486 }
3487 else
3488 {
Jari Aaltob72432f1999-02-19 17:11:39 +00003489 free (new_dirname);
Jari Aalto726f6381996-08-26 18:22:31 +00003490 free (local_dirname);
Jari Aaltof73dda02001-11-13 17:56:06 +00003491 *dirname = (char *)xmalloc (1);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003492 **dirname = '\0';
Jari Aalto726f6381996-08-26 18:22:31 +00003493 return 1;
3494 }
3495 }
Jari Aalto06285672006-10-10 14:15:34 +00003496 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);
Chet Ramey495aee42011-11-22 19:11:26 -05003500 return_value = STREQ (local_dirname, new_dirname) == 0;
Jari Aalto06285672006-10-10 14:15:34 +00003501 free (local_dirname);
3502 local_dirname = *dirname = new_dirname;
3503 }
Jari Aalto726f6381996-08-26 18:22:31 +00003504
Chet Ramey16b2d7f2012-05-31 15:11:45 -04003505 /* 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. */
Jari Aalto31859422009-01-12 13:36:28 +00003516 if (no_symbolic_links == 0 && (local_dirname[0] != '.' || local_dirname[1]))
Jari Aalto726f6381996-08-26 18:22:31 +00003517 {
3518 char *temp1, *temp2;
3519 int len1, len2;
3520
Chet Ramey16b2d7f2012-05-31 15:11:45 -04003521 /* 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 */
Jari Aalto726f6381996-08-26 18:22:31 +00003530 t = get_working_directory ("symlink-hook");
3531 temp1 = make_absolute (local_dirname, t);
3532 free (t);
Jari Aalto28ef6c32001-04-06 19:14:31 +00003533 temp2 = sh_canonpath (temp1, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
Jari Aalto31859422009-01-12 13:36:28 +00003534
Chet Rameyac50fba2014-02-26 09:36:43 -05003535 /* 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)
Jari Aalto31859422009-01-12 13:36:28 +00003539 {
Chet Ramey74091dd2022-09-26 11:49:46 -04003540 size_t l1, l2;
3541
Jari Aalto31859422009-01-12 13:36:28 +00003542 temp2 = dirspell (temp1);
Chet Ramey74091dd2022-09-26 11:49:46 -04003543 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 }
Jari Aalto31859422009-01-12 13:36:28 +00003550 if (temp2)
3551 {
3552 free (temp1);
3553 temp1 = temp2;
3554 temp2 = sh_canonpath (temp1, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
Chet Ramey495aee42011-11-22 19:11:26 -05003555 return_value |= temp2 != 0;
Jari Aalto31859422009-01-12 13:36:28 +00003556 }
3557 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003558 /* If we can't canonicalize, bail. */
3559 if (temp2 == 0)
3560 {
3561 free (temp1);
Chet Ramey495aee42011-11-22 19:11:26 -05003562 return return_value;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003563 }
Jari Aalto726f6381996-08-26 18:22:31 +00003564 len1 = strlen (temp1);
3565 if (temp1[len1 - 1] == '/')
Jari Aalto28ef6c32001-04-06 19:14:31 +00003566 {
Jari Aalto726f6381996-08-26 18:22:31 +00003567 len2 = strlen (temp2);
Jari Aalto95732b42005-12-07 14:08:12 +00003568 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 }
Jari Aalto28ef6c32001-04-06 19:14:31 +00003574 }
Chet Ramey16b2d7f2012-05-31 15:11:45 -04003575
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;
Jari Aalto726f6381996-08-26 18:22:31 +00003584 free (local_dirname);
3585 *dirname = temp2;
3586 free (temp1);
3587 }
Chet Ramey495aee42011-11-22 19:11:26 -05003588
Jari Aalto726f6381996-08-26 18:22:31 +00003589 return (return_value);
3590}
3591
Jari Aalto726f6381996-08-26 18:22:31 +00003592static char **history_completion_array = (char **)NULL;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003593static int harry_size;
3594static int harry_len;
Jari Aalto726f6381996-08-26 18:22:31 +00003595
3596static void
3597build_history_completion_array ()
3598{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003599 register int i, j;
3600 HIST_ENTRY **hlist;
3601 char **tokens;
Jari Aalto726f6381996-08-26 18:22:31 +00003602
3603 /* First, clear out the current dynamic history completion list. */
3604 if (harry_size)
3605 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00003606 strvec_dispose (history_completion_array);
Jari Aalto726f6381996-08-26 18:22:31 +00003607 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. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003614 hlist = history_list ();
Jari Aalto726f6381996-08-26 18:22:31 +00003615
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003616 if (hlist)
3617 {
3618 for (i = 0; hlist[i]; i++)
Chet Ramey00018032011-11-21 20:51:19 -05003619 ;
3620 for ( --i; i >= 0; i--)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003621 {
3622 /* Separate each token, and place into an array. */
3623 tokens = history_tokenize (hlist[i]->line);
Jari Aalto726f6381996-08-26 18:22:31 +00003624
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003625 for (j = 0; tokens && tokens[j]; j++)
3626 {
3627 if (harry_len + 2 > harry_size)
Jari Aalto7117c2d2002-07-17 14:10:11 +00003628 history_completion_array = strvec_resize (history_completion_array, harry_size += 10);
Jari Aalto726f6381996-08-26 18:22:31 +00003629
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003630 history_completion_array[harry_len++] = tokens[j];
3631 history_completion_array[harry_len] = (char *)NULL;
3632 }
3633 free (tokens);
3634 }
Jari Aalto726f6381996-08-26 18:22:31 +00003635
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003636 /* Sort the complete list of tokens. */
Chet Ramey00018032011-11-21 20:51:19 -05003637 if (dabbrev_expand_active == 0)
3638 qsort (history_completion_array, harry_len, sizeof (char *), (QSFUNC *)strvec_strcmp);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003639 }
Jari Aalto726f6381996-08-26 18:22:31 +00003640}
3641
3642static char *
3643history_completion_generator (hint_text, state)
Jari Aaltof73dda02001-11-13 17:56:06 +00003644 const char *hint_text;
Jari Aalto726f6381996-08-26 18:22:31 +00003645 int state;
3646{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003647 static int local_index, len;
Jari Aaltof73dda02001-11-13 17:56:06 +00003648 static const char *text;
Jari Aalto726f6381996-08-26 18:22:31 +00003649
3650 /* If this is the first call to the generator, then initialize the
3651 list of strings to complete over. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003652 if (state == 0)
Jari Aalto726f6381996-08-26 18:22:31 +00003653 {
Chet Ramey00018032011-11-21 20:51:19 -05003654 if (dabbrev_expand_active) /* This is kind of messy */
3655 rl_completion_suppress_append = 1;
Jari Aalto726f6381996-08-26 18:22:31 +00003656 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 {
Chet Rameyd233b482019-01-07 09:27:52 -05003664 /* XXX - should this use completion-ignore-case? */
Jari Aalto726f6381996-08-26 18:22:31 +00003665 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
Jari Aalto28ef6c32001-04-06 19:14:31 +00003671static int
Jari Aalto726f6381996-08-26 18:22:31 +00003672dynamic_complete_history (count, key)
3673 int count, key;
3674{
Jari Aaltof73dda02001-11-13 17:56:06 +00003675 int r;
Jari Aalto28ef6c32001-04-06 19:14:31 +00003676 rl_compentry_func_t *orig_func;
3677 rl_completion_func_t *orig_attempt_func;
Chet Ramey495aee42011-11-22 19:11:26 -05003678 rl_compignore_func_t *orig_ignore_func;
Jari Aalto726f6381996-08-26 18:22:31 +00003679
3680 orig_func = rl_completion_entry_function;
3681 orig_attempt_func = rl_attempted_completion_function;
Chet Ramey495aee42011-11-22 19:11:26 -05003682 orig_ignore_func = rl_ignore_some_completions_function;
Jari Aalto31859422009-01-12 13:36:28 +00003683
Jari Aalto28ef6c32001-04-06 19:14:31 +00003684 rl_completion_entry_function = history_completion_generator;
3685 rl_attempted_completion_function = (rl_completion_func_t *)NULL;
Chet Ramey495aee42011-11-22 19:11:26 -05003686 rl_ignore_some_completions_function = filename_completion_ignore;
Jari Aalto726f6381996-08-26 18:22:31 +00003687
Jari Aalto7117c2d2002-07-17 14:10:11 +00003688 /* XXX - use rl_completion_mode here? */
Jari Aalto28ef6c32001-04-06 19:14:31 +00003689 if (rl_last_func == dynamic_complete_history)
Jari Aaltof73dda02001-11-13 17:56:06 +00003690 r = rl_complete_internal ('?');
Jari Aalto726f6381996-08-26 18:22:31 +00003691 else
Jari Aaltof73dda02001-11-13 17:56:06 +00003692 r = rl_complete_internal (TAB);
Jari Aalto726f6381996-08-26 18:22:31 +00003693
3694 rl_completion_entry_function = orig_func;
3695 rl_attempted_completion_function = orig_attempt_func;
Chet Ramey495aee42011-11-22 19:11:26 -05003696 rl_ignore_some_completions_function = orig_ignore_func;
3697
Jari Aaltof73dda02001-11-13 17:56:06 +00003698 return r;
Jari Aalto726f6381996-08-26 18:22:31 +00003699}
3700
Jari Aalto31859422009-01-12 13:36:28 +00003701static int
3702bash_dabbrev_expand (count, key)
3703 int count, key;
3704{
Chet Ramey00018032011-11-21 20:51:19 -05003705 int r, orig_suppress, orig_sort;
Jari Aalto31859422009-01-12 13:36:28 +00003706 rl_compentry_func_t *orig_func;
3707 rl_completion_func_t *orig_attempt_func;
Chet Ramey495aee42011-11-22 19:11:26 -05003708 rl_compignore_func_t *orig_ignore_func;
Jari Aalto31859422009-01-12 13:36:28 +00003709
3710 orig_func = rl_menu_completion_entry_function;
3711 orig_attempt_func = rl_attempted_completion_function;
Chet Ramey495aee42011-11-22 19:11:26 -05003712 orig_ignore_func = rl_ignore_some_completions_function;
Chet Ramey00018032011-11-21 20:51:19 -05003713 orig_suppress = rl_completion_suppress_append;
3714 orig_sort = rl_sort_completion_matches;
Jari Aalto31859422009-01-12 13:36:28 +00003715
3716 rl_menu_completion_entry_function = history_completion_generator;
3717 rl_attempted_completion_function = (rl_completion_func_t *)NULL;
Chet Ramey495aee42011-11-22 19:11:26 -05003718 rl_ignore_some_completions_function = filename_completion_ignore;
Jari Aalto31859422009-01-12 13:36:28 +00003719 rl_filename_completion_desired = 0;
Chet Ramey00018032011-11-21 20:51:19 -05003720 rl_completion_suppress_append = 1;
3721 rl_sort_completion_matches = 0;
Jari Aalto31859422009-01-12 13:36:28 +00003722
3723 /* XXX - use rl_completion_mode here? */
Chet Ramey00018032011-11-21 20:51:19 -05003724 dabbrev_expand_active = 1;
Jari Aalto31859422009-01-12 13:36:28 +00003725 if (rl_last_func == bash_dabbrev_expand)
3726 rl_last_func = rl_menu_complete;
3727 r = rl_menu_complete (count, key);
Chet Ramey00018032011-11-21 20:51:19 -05003728 dabbrev_expand_active = 0;
Jari Aalto31859422009-01-12 13:36:28 +00003729
3730 rl_last_func = bash_dabbrev_expand;
3731 rl_menu_completion_entry_function = orig_func;
3732 rl_attempted_completion_function = orig_attempt_func;
Chet Ramey495aee42011-11-22 19:11:26 -05003733 rl_ignore_some_completions_function = orig_ignore_func;
Chet Ramey00018032011-11-21 20:51:19 -05003734 rl_completion_suppress_append = orig_suppress;
3735 rl_sort_completion_matches = orig_sort;
Jari Aalto31859422009-01-12 13:36:28 +00003736
3737 return r;
3738}
3739
Jari Aalto726f6381996-08-26 18:22:31 +00003740#if defined (SPECIFIC_COMPLETION_FUNCTIONS)
Jari Aalto28ef6c32001-04-06 19:14:31 +00003741static int
Jari Aalto726f6381996-08-26 18:22:31 +00003742bash_complete_username (ignore, ignore2)
3743 int ignore, ignore2;
3744{
Jari Aalto7117c2d2002-07-17 14:10:11 +00003745 return bash_complete_username_internal (rl_completion_mode (bash_complete_username));
Jari Aalto726f6381996-08-26 18:22:31 +00003746}
3747
Jari Aalto28ef6c32001-04-06 19:14:31 +00003748static int
Jari Aalto726f6381996-08-26 18:22:31 +00003749bash_possible_username_completions (ignore, ignore2)
3750 int ignore, ignore2;
3751{
Jari Aalto28ef6c32001-04-06 19:14:31 +00003752 return bash_complete_username_internal ('?');
Jari Aalto726f6381996-08-26 18:22:31 +00003753}
3754
Jari Aalto28ef6c32001-04-06 19:14:31 +00003755static int
Jari Aalto726f6381996-08-26 18:22:31 +00003756bash_complete_username_internal (what_to_do)
3757 int what_to_do;
3758{
Jari Aalto28ef6c32001-04-06 19:14:31 +00003759 return bash_specific_completion (what_to_do, rl_username_completion_function);
Jari Aalto726f6381996-08-26 18:22:31 +00003760}
3761
Jari Aalto28ef6c32001-04-06 19:14:31 +00003762static int
Jari Aalto726f6381996-08-26 18:22:31 +00003763bash_complete_filename (ignore, ignore2)
3764 int ignore, ignore2;
3765{
Jari Aalto7117c2d2002-07-17 14:10:11 +00003766 return bash_complete_filename_internal (rl_completion_mode (bash_complete_filename));
Jari Aalto726f6381996-08-26 18:22:31 +00003767}
3768
Jari Aalto28ef6c32001-04-06 19:14:31 +00003769static int
Jari Aalto726f6381996-08-26 18:22:31 +00003770bash_possible_filename_completions (ignore, ignore2)
3771 int ignore, ignore2;
3772{
Jari Aalto28ef6c32001-04-06 19:14:31 +00003773 return bash_complete_filename_internal ('?');
Jari Aalto726f6381996-08-26 18:22:31 +00003774}
3775
Jari Aalto28ef6c32001-04-06 19:14:31 +00003776static int
Jari Aalto726f6381996-08-26 18:22:31 +00003777bash_complete_filename_internal (what_to_do)
3778 int what_to_do;
3779{
Jari Aalto28ef6c32001-04-06 19:14:31 +00003780 rl_compentry_func_t *orig_func;
3781 rl_completion_func_t *orig_attempt_func;
3782 rl_icppfunc_t *orig_dir_func;
Chet Ramey495aee42011-11-22 19:11:26 -05003783 rl_compignore_func_t *orig_ignore_func;
Chet Ramey74091dd2022-09-26 11:49:46 -04003784 const char *orig_rl_completer_word_break_characters;
Jari Aalto28ef6c32001-04-06 19:14:31 +00003785 int r;
Jari Aalto726f6381996-08-26 18:22:31 +00003786
3787 orig_func = rl_completion_entry_function;
3788 orig_attempt_func = rl_attempted_completion_function;
Chet Ramey495aee42011-11-22 19:11:26 -05003789 orig_ignore_func = rl_ignore_some_completions_function;
Jari Aalto726f6381996-08-26 18:22:31 +00003790 orig_rl_completer_word_break_characters = rl_completer_word_break_characters;
Chet Ramey16b2d7f2012-05-31 15:11:45 -04003791
3792 orig_dir_func = save_directory_hook ();
3793
Jari Aalto28ef6c32001-04-06 19:14:31 +00003794 rl_completion_entry_function = rl_filename_completion_function;
3795 rl_attempted_completion_function = (rl_completion_func_t *)NULL;
Chet Ramey495aee42011-11-22 19:11:26 -05003796 rl_ignore_some_completions_function = filename_completion_ignore;
Jari Aalto726f6381996-08-26 18:22:31 +00003797 rl_completer_word_break_characters = " \t\n\"\'";
3798
Jari Aalto28ef6c32001-04-06 19:14:31 +00003799 r = rl_complete_internal (what_to_do);
Jari Aalto726f6381996-08-26 18:22:31 +00003800
3801 rl_completion_entry_function = orig_func;
3802 rl_attempted_completion_function = orig_attempt_func;
Chet Ramey495aee42011-11-22 19:11:26 -05003803 rl_ignore_some_completions_function = orig_ignore_func;
Jari Aalto726f6381996-08-26 18:22:31 +00003804 rl_completer_word_break_characters = orig_rl_completer_word_break_characters;
Jari Aalto28ef6c32001-04-06 19:14:31 +00003805
Chet Ramey16b2d7f2012-05-31 15:11:45 -04003806 restore_directory_hook (orig_dir_func);
3807
Jari Aalto28ef6c32001-04-06 19:14:31 +00003808 return r;
Jari Aalto726f6381996-08-26 18:22:31 +00003809}
3810
Jari Aalto28ef6c32001-04-06 19:14:31 +00003811static int
Jari Aalto726f6381996-08-26 18:22:31 +00003812bash_complete_hostname (ignore, ignore2)
3813 int ignore, ignore2;
3814{
Jari Aalto7117c2d2002-07-17 14:10:11 +00003815 return bash_complete_hostname_internal (rl_completion_mode (bash_complete_hostname));
Jari Aalto726f6381996-08-26 18:22:31 +00003816}
3817
Jari Aalto28ef6c32001-04-06 19:14:31 +00003818static int
Jari Aalto726f6381996-08-26 18:22:31 +00003819bash_possible_hostname_completions (ignore, ignore2)
3820 int ignore, ignore2;
3821{
Jari Aalto28ef6c32001-04-06 19:14:31 +00003822 return bash_complete_hostname_internal ('?');
Jari Aalto726f6381996-08-26 18:22:31 +00003823}
3824
Jari Aalto28ef6c32001-04-06 19:14:31 +00003825static int
Jari Aalto726f6381996-08-26 18:22:31 +00003826bash_complete_variable (ignore, ignore2)
3827 int ignore, ignore2;
3828{
Jari Aalto7117c2d2002-07-17 14:10:11 +00003829 return bash_complete_variable_internal (rl_completion_mode (bash_complete_variable));
Jari Aalto726f6381996-08-26 18:22:31 +00003830}
3831
Jari Aalto28ef6c32001-04-06 19:14:31 +00003832static int
Jari Aalto726f6381996-08-26 18:22:31 +00003833bash_possible_variable_completions (ignore, ignore2)
3834 int ignore, ignore2;
3835{
Jari Aalto28ef6c32001-04-06 19:14:31 +00003836 return bash_complete_variable_internal ('?');
Jari Aalto726f6381996-08-26 18:22:31 +00003837}
3838
Jari Aalto28ef6c32001-04-06 19:14:31 +00003839static int
Jari Aalto726f6381996-08-26 18:22:31 +00003840bash_complete_command (ignore, ignore2)
3841 int ignore, ignore2;
3842{
Jari Aalto7117c2d2002-07-17 14:10:11 +00003843 return bash_complete_command_internal (rl_completion_mode (bash_complete_command));
Jari Aalto726f6381996-08-26 18:22:31 +00003844}
3845
Jari Aalto28ef6c32001-04-06 19:14:31 +00003846static int
Jari Aalto726f6381996-08-26 18:22:31 +00003847bash_possible_command_completions (ignore, ignore2)
3848 int ignore, ignore2;
3849{
Jari Aalto28ef6c32001-04-06 19:14:31 +00003850 return bash_complete_command_internal ('?');
Jari Aalto726f6381996-08-26 18:22:31 +00003851}
3852
Jari Aalto28ef6c32001-04-06 19:14:31 +00003853static int
Jari Aalto726f6381996-08-26 18:22:31 +00003854bash_complete_hostname_internal (what_to_do)
3855 int what_to_do;
3856{
Jari Aalto28ef6c32001-04-06 19:14:31 +00003857 return bash_specific_completion (what_to_do, hostname_completion_function);
Jari Aalto726f6381996-08-26 18:22:31 +00003858}
3859
Jari Aalto28ef6c32001-04-06 19:14:31 +00003860static int
Jari Aalto726f6381996-08-26 18:22:31 +00003861bash_complete_variable_internal (what_to_do)
3862 int what_to_do;
3863{
Jari Aalto28ef6c32001-04-06 19:14:31 +00003864 return bash_specific_completion (what_to_do, variable_completion_function);
Jari Aalto726f6381996-08-26 18:22:31 +00003865}
3866
Jari Aalto28ef6c32001-04-06 19:14:31 +00003867static int
Jari Aalto726f6381996-08-26 18:22:31 +00003868bash_complete_command_internal (what_to_do)
3869 int what_to_do;
3870{
Jari Aalto28ef6c32001-04-06 19:14:31 +00003871 return bash_specific_completion (what_to_do, command_word_completion_function);
Jari Aalto726f6381996-08-26 18:22:31 +00003872}
3873
Chet Ramey4d2e3152019-01-18 15:12:37 -05003874static int
3875completion_glob_pattern (string)
3876 char *string;
3877{
Chet Ramey8868eda2020-12-06 15:51:17 -05003878 return (glob_pattern_p (string) == 1);
Chet Ramey4d2e3152019-01-18 15:12:37 -05003879}
3880
Jari Aalto7117c2d2002-07-17 14:10:11 +00003881static char *globtext;
3882static char *globorig;
3883
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003884static char *
3885glob_complete_word (text, state)
Jari Aalto28ef6c32001-04-06 19:14:31 +00003886 const char *text;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003887 int state;
3888{
3889 static char **matches = (char **)NULL;
3890 static int ind;
Jari Aalto7117c2d2002-07-17 14:10:11 +00003891 int glen;
Jari Aaltoeb873672004-11-09 21:37:25 +00003892 char *ret, *ttext;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003893
3894 if (state == 0)
3895 {
Jari Aaltoe8ce7751997-09-22 20:22:27 +00003896 rl_filename_completion_desired = 1;
Jari Aalto7117c2d2002-07-17 14:10:11 +00003897 FREE (matches);
3898 if (globorig != globtext)
3899 FREE (globorig);
3900 FREE (globtext);
3901
Jari Aaltoeb873672004-11-09 21:37:25 +00003902 ttext = bash_tilde_expand (text, 0);
3903
Jari Aalto7117c2d2002-07-17 14:10:11 +00003904 if (rl_explicit_arg)
3905 {
Jari Aaltoeb873672004-11-09 21:37:25 +00003906 globorig = savestring (ttext);
3907 glen = strlen (ttext);
Jari Aalto7117c2d2002-07-17 14:10:11 +00003908 globtext = (char *)xmalloc (glen + 2);
Jari Aaltoeb873672004-11-09 21:37:25 +00003909 strcpy (globtext, ttext);
Jari Aalto7117c2d2002-07-17 14:10:11 +00003910 globtext[glen] = '*';
3911 globtext[glen+1] = '\0';
3912 }
3913 else
Jari Aaltoeb873672004-11-09 21:37:25 +00003914 globtext = globorig = savestring (ttext);
3915
3916 if (ttext != text)
3917 free (ttext);
Jari Aalto7117c2d2002-07-17 14:10:11 +00003918
Chet Ramey8868eda2020-12-06 15:51:17 -05003919 matches = shell_glob_filename (globtext, 0);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003920 if (GLOB_FAILED (matches))
Jari Aalto28ef6c32001-04-06 19:14:31 +00003921 matches = (char **)NULL;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003922 ind = 0;
3923 }
3924
3925 ret = matches ? matches[ind] : (char *)NULL;
3926 ind++;
3927 return ret;
3928}
3929
Jari Aalto28ef6c32001-04-06 19:14:31 +00003930static int
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003931bash_glob_completion_internal (what_to_do)
3932 int what_to_do;
3933{
Jari Aalto28ef6c32001-04-06 19:14:31 +00003934 return bash_specific_completion (what_to_do, glob_complete_word);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003935}
3936
Jari Aalto7117c2d2002-07-17 14:10:11 +00003937/* 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
Jari Aaltob80f6442004-07-27 13:29:18 +00003958 if (rl_editing_mode == EMACS_EDITING_MODE)
3959 rl_explicit_arg = 1; /* force `*' append */
Jari Aalto7117c2d2002-07-17 14:10:11 +00003960 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
Jari Aalto28ef6c32001-04-06 19:14:31 +00003969static int
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003970bash_glob_expand_word (count, key)
3971 int count, key;
3972{
Jari Aalto28ef6c32001-04-06 19:14:31 +00003973 return bash_glob_completion_internal ('*');
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003974}
3975
Jari Aalto28ef6c32001-04-06 19:14:31 +00003976static int
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003977bash_glob_list_expansions (count, key)
3978 int count, key;
3979{
Jari Aalto28ef6c32001-04-06 19:14:31 +00003980 return bash_glob_completion_internal ('?');
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003981}
3982
Jari Aalto28ef6c32001-04-06 19:14:31 +00003983static int
Jari Aalto726f6381996-08-26 18:22:31 +00003984bash_specific_completion (what_to_do, generator)
3985 int what_to_do;
Jari Aalto28ef6c32001-04-06 19:14:31 +00003986 rl_compentry_func_t *generator;
Jari Aalto726f6381996-08-26 18:22:31 +00003987{
Jari Aalto28ef6c32001-04-06 19:14:31 +00003988 rl_compentry_func_t *orig_func;
3989 rl_completion_func_t *orig_attempt_func;
Chet Ramey495aee42011-11-22 19:11:26 -05003990 rl_compignore_func_t *orig_ignore_func;
Jari Aalto28ef6c32001-04-06 19:14:31 +00003991 int r;
Jari Aalto726f6381996-08-26 18:22:31 +00003992
3993 orig_func = rl_completion_entry_function;
3994 orig_attempt_func = rl_attempted_completion_function;
Chet Ramey495aee42011-11-22 19:11:26 -05003995 orig_ignore_func = rl_ignore_some_completions_function;
Jari Aalto726f6381996-08-26 18:22:31 +00003996 rl_completion_entry_function = generator;
Jari Aalto28ef6c32001-04-06 19:14:31 +00003997 rl_attempted_completion_function = NULL;
Chet Ramey495aee42011-11-22 19:11:26 -05003998 rl_ignore_some_completions_function = orig_ignore_func;
Jari Aalto726f6381996-08-26 18:22:31 +00003999
Jari Aalto28ef6c32001-04-06 19:14:31 +00004000 r = rl_complete_internal (what_to_do);
Jari Aalto726f6381996-08-26 18:22:31 +00004001
4002 rl_completion_entry_function = orig_func;
4003 rl_attempted_completion_function = orig_attempt_func;
Chet Ramey495aee42011-11-22 19:11:26 -05004004 rl_ignore_some_completions_function = orig_ignore_func;
Jari Aalto28ef6c32001-04-06 19:14:31 +00004005
4006 return r;
Jari Aalto726f6381996-08-26 18:22:31 +00004007}
4008
4009#endif /* SPECIFIC_COMPLETION_FUNCTIONS */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004010
Jari Aaltob80f6442004-07-27 13:29:18 +00004011#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
Chet Ramey4d2e3152019-01-18 15:12:37 -05004045 if (t && completion_glob_pattern (t) == 0)
Jari Aaltob80f6442004-07-27 13:29:18 +00004046 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
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004068/* Filename quoting for completion. */
Jari Aaltobb706242000-03-17 21:46:59 +00004069/* 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. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004072static char *
4073bash_dequote_filename (text, quote_char)
4074 char *text;
Jari Aalto28ef6c32001-04-06 19:14:31 +00004075 int quote_char;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004076{
4077 char *ret, *p, *r;
4078 int l, quoted;
4079
4080 l = strlen (text);
Jari Aaltof73dda02001-11-13 17:56:06 +00004081 ret = (char *)xmalloc (l + 1);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004082 for (quoted = quote_char, p = text, r = ret; p && *p; p++)
4083 {
Jari Aalto31859422009-01-12 13:36:28 +00004084 /* Allow backslash-escaped characters to pass through unscathed. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004085 if (*p == '\\')
4086 {
Jari Aalto31859422009-01-12 13:36:28 +00004087 /* 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 */
Chet Rameyd233b482019-01-07 09:27:52 -05004092 else if (quoted == '"' && ((sh_syntaxtab[(unsigned char)p[1]] & CBSDQUOTE) == 0))
Jari Aalto31859422009-01-12 13:36:28 +00004093 *r++ = *p;
4094
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004095 *r++ = *++p;
4096 if (*p == '\0')
Chet Ramey00018032011-11-21 20:51:19 -05004097 return ret; /* XXX - was break; */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004098 continue;
4099 }
4100 /* Close quote. */
4101 if (quoted && *p == quoted)
Jari Aalto28ef6c32001-04-06 19:14:31 +00004102 {
4103 quoted = 0;
4104 continue;
4105 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004106 /* Open quote. */
4107 if (quoted == 0 && (*p == '\'' || *p == '"'))
Jari Aalto28ef6c32001-04-06 19:14:31 +00004108 {
4109 quoted = *p;
4110 continue;
4111 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004112 *r++ = *p;
4113 }
4114 *r = '\0';
4115 return ret;
4116}
4117
Jari Aaltod166f041997-06-05 14:59:13 +00004118/* 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);
Jari Aaltof73dda02001-11-13 17:56:06 +00004129 ret = (char *)xmalloc ((2 * l) + 1);
Jari Aaltod166f041997-06-05 14:59:13 +00004130 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. */
Chet Ramey00018032011-11-21 20:51:19 -05004143 if (mbschr (rl_completer_word_break_characters, *s))
Jari Aalto28ef6c32001-04-06 19:14:31 +00004144 *r++ = '\\';
Jari Aalto31859422009-01-12 13:36:28 +00004145 /* XXX -- check for standalone tildes here and backslash-quote them */
4146 if (s == text && *s == '~' && file_exists (text))
4147 *r++ = '\\';
Jari Aaltod166f041997-06-05 14:59:13 +00004148 *r++ = *s;
4149 }
4150 *r = '\0';
4151 return ret;
4152}
4153
Chet Ramey74091dd2022-09-26 11:49:46 -04004154/* 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
Chet Rameyac50fba2014-02-26 09:36:43 -05004243/* 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++)
Chet Ramey8868eda2020-12-06 15:51:17 -05004254 filename_bstab[(unsigned char)*s] = 1;
Chet Rameyac50fba2014-02-26 09:36:43 -05004255}
4256
Jari Aaltod166f041997-06-05 14:59:13 +00004257/* 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
Jari Aalto7117c2d2002-07-17 14:10:11 +00004261 quote_word_break_chars on the result. This returns newly-allocated
4262 memory. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004263static 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;
Chet Ramey74091dd2022-09-26 11:49:46 -04004271 int expchar, nextch, closer;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004272
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
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004282 cs = completion_quoting_style;
4283 /* Might need to modify the default completion style based on *qcp,
Jari Aaltobb706242000-03-17 21:46:59 +00004284 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). */
Chet Ramey74091dd2022-09-26 11:49:46 -04004289 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'))
Jari Aaltobb706242000-03-17 21:46:59 +00004301 cs = COMPLETE_SQUOTE;
4302 else if (*qcp == '"')
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004303 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 &&
Chet Ramey00018032011-11-21 20:51:19 -05004308 history_expansion_inhibited == 0 && mbschr (s, '!'))
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004309 cs = COMPLETE_BSQUOTE;
Jari Aaltod166f041997-06-05 14:59:13 +00004310
4311 if (*qcp == '"' && history_expansion && cs == COMPLETE_DQUOTE &&
Chet Ramey00018032011-11-21 20:51:19 -05004312 history_expansion_inhibited == 0 && mbschr (s, '!'))
Jari Aaltod166f041997-06-05 14:59:13 +00004313 {
4314 cs = COMPLETE_BSQUOTE;
4315 *qcp = '\0';
4316 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004317#endif
4318
Jari Aalto95732b42005-12-07 14:08:12 +00004319 /* 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
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004325 switch (cs)
4326 {
4327 case COMPLETE_DQUOTE:
Jari Aalto28ef6c32001-04-06 19:14:31 +00004328 rtext = sh_double_quote (mtext);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004329 break;
4330 case COMPLETE_SQUOTE:
Jari Aalto28ef6c32001-04-06 19:14:31 +00004331 rtext = sh_single_quote (mtext);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004332 break;
4333 case COMPLETE_BSQUOTE:
Chet Rameyac50fba2014-02-26 09:36:43 -05004334 rtext = sh_backslash_quote (mtext, complete_fullquote ? 0 : filename_bstab, 0);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004335 break;
4336 }
4337
4338 if (mtext != s)
4339 free (mtext);
4340
Jari Aaltod166f041997-06-05 14:59:13 +00004341 /* We may need to quote additional characters: those that readline treats
4342 as word breaks that are not quoted by backslash_quote. */
Chet Ramey74091dd2022-09-26 11:49:46 -04004343 /* XXX - test complete_fullquote here? */
4344 if (rtext && cs == COMPLETE_BSQUOTE && rl_completer_word_break_characters)
Jari Aaltod166f041997-06-05 14:59:13 +00004345 {
4346 mtext = quote_word_break_chars (rtext);
4347 free (rtext);
4348 rtext = mtext;
4349 }
4350
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004351 /* Leave the opening quote intact. The readline completion code takes
4352 care of avoiding doubled opening quotes. */
Chet Rameyac50fba2014-02-26 09:36:43 -05004353 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 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004364
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
Chet Ramey8868eda2020-12-06 15:51:17 -05004372/* 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
Jari Aaltobb706242000-03-17 21:46:59 +00004380
Chet Rameyac50fba2014-02-26 09:36:43 -05004381#ifdef _MINIX
4382static void
4383#else
Jari Aaltobb706242000-03-17 21:46:59 +00004384static int
Chet Rameyac50fba2014-02-26 09:36:43 -05004385#endif
Chet Ramey00018032011-11-21 20:51:19 -05004386putx(c)
4387 int c;
4388{
Chet Ramey495aee42011-11-22 19:11:26 -05004389 int x;
Chet Ramey495aee42011-11-22 19:11:26 -05004390 x = putc (c, rl_outstream);
Chet Rameyac50fba2014-02-26 09:36:43 -05004391#ifndef _MINIX
4392 return x;
4393#endif
Chet Ramey00018032011-11-21 20:51:19 -05004394}
Chet Ramey8868eda2020-12-06 15:51:17 -05004395
Chet Ramey00018032011-11-21 20:51:19 -05004396static int
Chet Ramey8868eda2020-12-06 15:51:17 -05004397readline_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
Jari Aaltobb706242000-03-17 21:46:59 +00004439bash_execute_unix_command (count, key)
4440 int count; /* ignored */
4441 int key;
4442{
Chet Rameyac50fba2014-02-26 09:36:43 -05004443 int type;
Chet Ramey00018032011-11-21 20:51:19 -05004444 register int i, r;
Jari Aalto31859422009-01-12 13:36:28 +00004445 intmax_t mi;
Jari Aaltob80f6442004-07-27 13:29:18 +00004446 sh_parser_state_t ps;
Chet Rameyd233b482019-01-07 09:27:52 -05004447 char *cmd, *value, *ce, old_ch;
Jari Aalto31859422009-01-12 13:36:28 +00004448 SHELL_VAR *v;
4449 char ibuf[INT_STRLEN_BOUND(int) + 1];
Chet Ramey8868eda2020-12-06 15:51:17 -05004450 Keymap cmd_xmap;
Chet Ramey74091dd2022-09-26 11:49:46 -04004451 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 }
Jari Aaltobb706242000-03-17 21:46:59 +00004467
4468 /* First, we need to find the right command to execute. This is tricky,
Chet Rameyac50fba2014-02-26 09:36:43 -05004469 because we might have already indirected into another keymap, so we
4470 have to walk cmd_xmap using the entire key sequence. */
Chet Ramey8868eda2020-12-06 15:51:17 -05004471 cmd_xmap = get_cmd_xmap_from_keymap (rl_get_keymap ());
Chet Ramey74091dd2022-09-26 11:49:46 -04004472 cmd = (char *)rl_function_of_keyseq_len (kseq, kslen, cmd_xmap, &type);
Chet Ramey8868eda2020-12-06 15:51:17 -05004473
4474 if (type == ISKMAP && (type = ((Keymap) cmd)[ANYOTHERKEY].type) == ISMACR)
4475 cmd = (char*)((Keymap) cmd)[ANYOTHERKEY].function;
4476
Chet Rameyac50fba2014-02-26 09:36:43 -05004477 if (cmd == 0 || type != ISMACR)
Jari Aaltobb706242000-03-17 21:46:59 +00004478 {
Chet Rameyac50fba2014-02-26 09:36:43 -05004479 rl_crlf ();
4480 internal_error (_("bash_execute_unix_command: cannot find keymap for command"));
4481 rl_forced_update_display ();
Jari Aaltobb706242000-03-17 21:46:59 +00004482 return 1;
4483 }
4484
Chet Ramey00018032011-11-21 20:51:19 -05004485 ce = rl_get_termcap ("ce");
4486 if (ce) /* clear current line */
4487 {
Chet Rameya0c0a002016-09-15 16:59:08 -04004488 rl_clear_visible_line ();
Chet Ramey00018032011-11-21 20:51:19 -05004489 fflush (rl_outstream);
4490 }
4491 else
4492 rl_crlf (); /* move to a new line */
Jari Aaltobb706242000-03-17 21:46:59 +00004493
Jari Aalto31859422009-01-12 13:36:28 +00004494 v = bind_variable ("READLINE_LINE", rl_line_buffer, 0);
4495 if (v)
4496 VSETATTR (v, att_exported);
Chet Ramey8868eda2020-12-06 15:51:17 -05004497
4498 i = readline_get_char_offset (rl_point);
Chet Rameyd233b482019-01-07 09:27:52 -05004499 value = inttostr (i, ibuf, sizeof (ibuf));
4500 v = bind_int_variable ("READLINE_POINT", value, 0);
Jari Aalto31859422009-01-12 13:36:28 +00004501 if (v)
4502 VSETATTR (v, att_exported);
Chet Ramey8868eda2020-12-06 15:51:17 -05004503
4504 i = readline_get_char_offset (rl_mark);
4505 value = inttostr (i, ibuf, sizeof (ibuf));
4506 v = bind_int_variable ("READLINE_MARK", value, 0);
4507 if (v)
4508 VSETATTR (v, att_exported);
Chet Ramey74091dd2022-09-26 11:49:46 -04004509
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 }
Jari Aalto31859422009-01-12 13:36:28 +00004517 array_needs_making = 1;
4518
Jari Aaltob80f6442004-07-27 13:29:18 +00004519 save_parser_state (&ps);
Chet Ramey8868eda2020-12-06 15:51:17 -05004520 rl_clear_signals ();
4521 r = parse_and_execute (savestring (cmd), "bash_execute_unix_command", SEVAL_NOHIST);
4522 rl_set_signals ();
Jari Aaltob80f6442004-07-27 13:29:18 +00004523 restore_parser_state (&ps);
Jari Aaltobb706242000-03-17 21:46:59 +00004524
Jari Aalto31859422009-01-12 13:36:28 +00004525 v = find_variable ("READLINE_LINE");
Chet Rameyd233b482019-01-07 09:27:52 -05004526 maybe_make_readline_line (v ? value_cell (v) : 0);
4527
Jari Aalto31859422009-01-12 13:36:28 +00004528 v = find_variable ("READLINE_POINT");
4529 if (v && legal_number (value_cell (v), &mi))
Chet Ramey8868eda2020-12-06 15:51:17 -05004530 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);
Jari Aalto31859422009-01-12 13:36:28 +00004535
Chet Rameya0c0a002016-09-15 16:59:08 -04004536 check_unbind_variable ("READLINE_LINE");
4537 check_unbind_variable ("READLINE_POINT");
Chet Ramey8868eda2020-12-06 15:51:17 -05004538 check_unbind_variable ("READLINE_MARK");
Chet Ramey74091dd2022-09-26 11:49:46 -04004539 check_unbind_variable ("READLINE_ARGUMENT");
Jari Aalto31859422009-01-12 13:36:28 +00004540 array_needs_making = 1;
4541
Jari Aaltobb706242000-03-17 21:46:59 +00004542 /* and restore the readline buffer and display after command execution. */
Chet Rameya0c0a002016-09-15 16:59:08 -04004543 /* 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
Jari Aaltobb706242000-03-17 21:46:59 +00004551 return 0;
4552}
4553
Chet Rameyac50fba2014-02-26 09:36:43 -05004554int
4555print_unix_command_map ()
4556{
Chet Ramey8868eda2020-12-06 15:51:17 -05004557 Keymap save, cmd_xmap;
Chet Rameyac50fba2014-02-26 09:36:43 -05004558
4559 save = rl_get_keymap ();
Chet Ramey8868eda2020-12-06 15:51:17 -05004560 cmd_xmap = get_cmd_xmap_from_keymap (save);
Chet Rameyac50fba2014-02-26 09:36:43 -05004561 rl_set_keymap (cmd_xmap);
4562 rl_macro_dumper (1);
4563 rl_set_keymap (save);
4564 return 0;
4565}
4566
Jari Aaltobb706242000-03-17 21:46:59 +00004567static void
4568init_unix_command_map ()
4569{
Chet Ramey8868eda2020-12-06 15:51:17 -05004570 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;
Jari Aaltobb706242000-03-17 21:46:59 +00004623}
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 {
Jari Aaltob80f6442004-07-27 13:29:18 +00004638 builtin_error (_("%s: first non-whitespace character is not `\"'"), string);
Jari Aaltobb706242000-03-17 21:46:59 +00004639 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)
Jari Aalto28ef6c32001-04-06 19:14:31 +00004662 break;
Jari Aaltobb706242000-03-17 21:46:59 +00004663 }
4664
4665 if (delim && string[i] != delim)
4666 {
Jari Aaltob80f6442004-07-27 13:29:18 +00004667 builtin_error (_("no closing `%c' in %s"), delim, string);
Jari Aaltobb706242000-03-17 21:46:59 +00004668 return -1;
4669 }
4670
4671 return i;
4672}
4673
4674int
4675bind_keyseq_to_unix_command (line)
4676 char *line;
4677{
Chet Ramey8868eda2020-12-06 15:51:17 -05004678 Keymap kmap, cmd_xmap;
Jari Aaltobb706242000-03-17 21:46:59 +00004679 char *kseq, *value;
Jari Aaltof73dda02001-11-13 17:56:06 +00004680 int i, kstart;
Jari Aaltobb706242000-03-17 21:46:59 +00004681
Jari Aaltobb706242000-03-17 21:46:59 +00004682 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 {
Jari Aaltob80f6442004-07-27 13:29:18 +00004698 builtin_error (_("%s: missing colon separator"), line);
Chet Rameyac50fba2014-02-26 09:36:43 -05004699 FREE (kseq);
Jari Aaltobb706242000-03-17 21:46:59 +00004700 return -1;
4701 }
4702
4703 i = isolate_sequence (line, i + 1, 0, &kstart);
4704 if (i < 0)
Chet Rameyac50fba2014-02-26 09:36:43 -05004705 {
4706 FREE (kseq);
4707 return -1;
4708 }
Jari Aaltobb706242000-03-17 21:46:59 +00004709
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 */
Chet Ramey8868eda2020-12-06 15:51:17 -05004714 cmd_xmap = get_cmd_xmap_from_keymap (kmap);
Jari Aaltobb706242000-03-17 21:46:59 +00004715 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 */
Jari Aaltob80f6442004-07-27 13:29:18 +00004719 rl_bind_keyseq_in_map (kseq, bash_execute_unix_command, kmap);
Chet Rameyac50fba2014-02-26 09:36:43 -05004720
4721 free (kseq);
Jari Aaltobb706242000-03-17 21:46:59 +00004722 return 0;
4723}
4724
Chet Ramey8868eda2020-12-06 15:51:17 -05004725int
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
Jari Aaltobb706242000-03-17 21:46:59 +00004740/* 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)
Jari Aalto28ef6c32001-04-06 19:14:31 +00004745 const char *text;
Jari Aaltobb706242000-03-17 21:46:59 +00004746{
4747 char **m1;
4748 char *dfn;
4749 int qc;
4750
Jari Aaltob80f6442004-07-27 13:29:18 +00004751 qc = rl_dispatching ? rl_completion_quote_character : 0;
Chet Rameyc6dcdf42014-05-16 14:18:15 -04004752 /* 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;
Jari Aalto28ef6c32001-04-06 19:14:31 +00004759 m1 = rl_completion_matches (dfn, rl_filename_completion_function);
Chet Rameyc6dcdf42014-05-16 14:18:15 -04004760 if (dfn != text)
4761 free (dfn);
Jari Aaltobb706242000-03-17 21:46:59 +00004762
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. */
Chet Ramey8868eda2020-12-06 15:51:17 -05004768 (void)bash_progcomp_ignore_filenames (m1);
Jari Aaltobb706242000-03-17 21:46:59 +00004769 return m1;
4770}
Jari Aaltob80f6442004-07-27 13:29:18 +00004771
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}
Chet Rameyac50fba2014-02-26 09:36:43 -05004783
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{
Chet Ramey8868eda2020-12-06 15:51:17 -05004791 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;
Chet Ramey74091dd2022-09-26 11:49:46 -04004807 else if (read_timeout && read_timeout->alrmflag)
Chet Ramey8868eda2020-12-06 15:51:17 -05004808 sig = SIGALRM;
Chet Ramey74091dd2022-09-26 11:49:46 -04004809 else if (RL_ISSTATE (RL_STATE_TIMEOUT)) /* just in case */
4810 {
4811 sig = SIGALRM;
4812 if (read_timeout)
4813 read_timeout->alrmflag = 1;
4814 }
Chet Ramey8868eda2020-12-06 15:51:17 -05004815 else
4816 sig = first_pending_trap ();
4817
Chet Rameyac50fba2014-02-26 09:36:43 -05004818 /* 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,
Chet Ramey74091dd2022-09-26 11:49:46 -04004820 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))
Chet Rameyac50fba2014-02-26 09:36:43 -05004823 rl_cleanup_after_signal ();
4824 bashline_reset_event_hook ();
Chet Ramey8868eda2020-12-06 15:51:17 -05004825
Chet Ramey74091dd2022-09-26 11:49:46 -04004826 RL_UNSETSTATE (RL_STATE_TIMEOUT); /* XXX */
4827
Chet Ramey8868eda2020-12-06 15:51:17 -05004828 /* posix mode SIGINT during read -e. We only get here if SIGINT is trapped. */
Chet Ramey74091dd2022-09-26 11:49:46 -04004829 if (posixly_correct && this_shell_builtin == read_builtin && sig == SIGINT)
Chet Ramey8868eda2020-12-06 15:51:17 -05004830 {
4831 last_command_exit_value = 128|SIGINT;
4832 throw_to_top_level ();
4833 }
4834
Chet Rameyac50fba2014-02-26 09:36:43 -05004835 check_signals_and_traps (); /* XXX */
4836 return 0;
4837}
4838
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004839#endif /* READLINE */