blob: 03af185a394b18ef72a4a61db81b9381432ee32d [file] [log] [blame]
Jari Aalto726f6381996-08-26 18:22:31 +00001/* bashline.c -- Bash's interface to the readline library. */
2
3/* Copyright (C) 1987,1991 Free Software Foundation, Inc.
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
7 Bash is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 1, or (at your option)
10 any later version.
11
12 Bash is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Bash; see the file COPYING. If not, write to the Free
19 Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
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 Aalto726f6381996-08-26 18:22:31 +000032#include <stdio.h>
33#include "bashansi.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000034#include "shell.h"
35#include "builtins.h"
36#include "bashhist.h"
37#include "bashline.h"
38#include "execute_cmd.h"
Jari Aaltocce855b1998-04-17 19:52:44 +000039#include "findcmd.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000040#include "pathexp.h"
41#include "builtins/common.h"
Jari Aalto726f6381996-08-26 18:22:31 +000042#include <readline/rlconf.h>
43#include <readline/readline.h>
44#include <readline/history.h>
Jari Aaltoccc6cda1996-12-23 17:02:34 +000045
46#include <glob/glob.h>
Jari Aalto726f6381996-08-26 18:22:31 +000047
48#if defined (ALIAS)
49# include "alias.h"
50#endif
51
Jari Aalto726f6381996-08-26 18:22:31 +000052#if defined (BRACE_COMPLETION)
53extern void bash_brace_completion ();
54#endif /* BRACE_COMPLETION */
55
56/* Functions bound to keys in Readline for Bash users. */
57static void shell_expand_line ();
58static void display_shell_version (), operate_and_get_next ();
Jari Aaltocce855b1998-04-17 19:52:44 +000059static void bash_ignore_filenames ();
Jari Aaltod166f041997-06-05 14:59:13 +000060static void cleanup_expansion_error (), set_up_new_line ();
Jari Aalto726f6381996-08-26 18:22:31 +000061
Jari Aaltocce855b1998-04-17 19:52:44 +000062#if defined (BANG_HISTORY)
63static int history_expand_line ();
64static int tcsh_magic_space ();
65#endif /* BANG_HISTORY */
66#ifdef ALIAS
67static int alias_expand_line ();
68#endif
69#if defined (BANG_HISTORY) && defined (ALIAS)
70static int history_and_alias_expand_line ();
71#endif
72
Jari Aalto726f6381996-08-26 18:22:31 +000073/* Helper functions for Readline. */
74static int bash_directory_completion_hook ();
75static void filename_completion_ignore ();
76static void bash_push_line ();
77
78static char **attempt_shell_completion ();
79static char *variable_completion_function ();
80static char *hostname_completion_function ();
81static char *command_word_completion_function ();
82static char *command_subst_completion_function ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +000083static void dynamic_complete_history ();
84
85static char *glob_complete_word ();
86static void bash_glob_expand_word ();
87static void bash_glob_list_expansions ();
Jari Aalto726f6381996-08-26 18:22:31 +000088
89static void snarf_hosts_from_file (), add_host_name ();
Jari Aalto726f6381996-08-26 18:22:31 +000090
Jari Aaltoccc6cda1996-12-23 17:02:34 +000091static char *bash_dequote_filename ();
92static char *bash_quote_filename ();
93
94#if defined (ALIAS)
95static int posix_edit_macros ();
96#endif
Jari Aalto726f6381996-08-26 18:22:31 +000097
98/* Variables used here but defined in other files. */
99extern int posixly_correct, no_symbolic_links;
100extern int rl_explicit_arg;
101extern char *current_prompt_string, *ps1_prompt;
102extern STRING_INT_ALIST word_token_alist[];
103extern Function *rl_last_func;
104extern int rl_filename_completion_desired;
105
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000106/* Helper functions from subst.c */
107extern int char_is_quoted ();
108extern int unclosed_pair ();
109
Jari Aalto726f6381996-08-26 18:22:31 +0000110/* SPECIFIC_COMPLETION_FUNCTIONS specifies that we have individual
111 completion functions which indicate what type of completion should be
112 done (at or before point) that can be bound to key sequences with
113 the readline library. */
114#define SPECIFIC_COMPLETION_FUNCTIONS
115
116#if defined (SPECIFIC_COMPLETION_FUNCTIONS)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000117static void bash_specific_completion ();
118static void bash_complete_filename (), bash_possible_filename_completions ();
119static void bash_complete_filename_internal ();
120static void bash_complete_username (), bash_possible_username_completions ();
121static void bash_complete_username_internal ();
122static void bash_complete_hostname (), bash_possible_hostname_completions ();
123static void bash_complete_hostname_internal ();
124static void bash_complete_variable (), bash_possible_variable_completions ();
125static void bash_complete_variable_internal ();
126static void bash_complete_command (), bash_possible_command_completions ();
127static void bash_complete_command_internal ();
Jari Aalto726f6381996-08-26 18:22:31 +0000128#endif /* SPECIFIC_COMPLETION_FUNCTIONS */
129
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000130#if defined (VI_MODE)
131static void vi_edit_and_execute_command ();
132#endif
133
Jari Aalto726f6381996-08-26 18:22:31 +0000134/* Non-zero once initalize_readline () has been called. */
135int bash_readline_initialized = 0;
136
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000137/* If non-zero, we do hostname completion, breaking words at `@' and
138 trying to complete the stuff after the `@' from our own internal
139 host list. */
140int perform_hostname_completion = 1;
141
142static char *bash_completer_word_break_characters = " \t\n\"'@><=;|&(:";
143static char *bash_nohostname_word_break_characters = " \t\n\"'><=;|&(:";
Jari Aalto726f6381996-08-26 18:22:31 +0000144
145static Function *old_rl_startup_hook = (Function *) NULL;
146
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000147/* What kind of quoting is performed by bash_quote_filename:
148 COMPLETE_DQUOTE = double-quoting the filename
149 COMPLETE_SQUOTE = single_quoting the filename
150 COMPLETE_BSQUOTE = backslash-quoting special chars in the filename
151*/
152#define COMPLETE_DQUOTE 1
153#define COMPLETE_SQUOTE 2
154#define COMPLETE_BSQUOTE 3
155static int completion_quoting_style = COMPLETE_BSQUOTE;
156
Jari Aalto726f6381996-08-26 18:22:31 +0000157/* Change the readline VI-mode keymaps into or out of Posix.2 compliance.
158 Called when the shell is put into or out of `posix' mode. */
159void
160posix_readline_initialize (on_or_off)
161 int on_or_off;
162{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000163 if (on_or_off)
164 rl_variable_bind ("comment-begin", "#");
Jari Aalto726f6381996-08-26 18:22:31 +0000165#if defined (VI_MODE)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000166 rl_bind_key_in_map (CTRL('I'), on_or_off ? rl_insert : rl_complete, vi_insertion_keymap);
167#endif
168}
169
170void
171enable_hostname_completion (on_or_off)
172 int on_or_off;
173{
Jari Aalto726f6381996-08-26 18:22:31 +0000174 if (on_or_off)
175 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000176 perform_hostname_completion = 1;
177 rl_special_prefixes = "$@";
178 rl_completer_word_break_characters = bash_completer_word_break_characters;
Jari Aalto726f6381996-08-26 18:22:31 +0000179 }
180 else
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000181 {
182 perform_hostname_completion = 0;
183 rl_special_prefixes = "$";
184 rl_completer_word_break_characters = bash_nohostname_word_break_characters;
185 }
186}
Jari Aalto726f6381996-08-26 18:22:31 +0000187
188/* Called once from parse.y if we are going to use readline. */
189void
190initialize_readline ()
191{
192 if (bash_readline_initialized)
193 return;
194
195 rl_terminal_name = get_string_value ("TERM");
196 rl_instream = stdin;
197 rl_outstream = stderr;
Jari Aalto726f6381996-08-26 18:22:31 +0000198
199 /* Allow conditional parsing of the ~/.inputrc file. */
200 rl_readline_name = "Bash";
201
202 /* Bind up our special shell functions. */
203 rl_add_defun ("shell-expand-line", (Function *)shell_expand_line, -1);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000204 rl_bind_key_in_map (CTRL('E'), (Function *)shell_expand_line, emacs_meta_keymap);
Jari Aalto726f6381996-08-26 18:22:31 +0000205
206 /* Bind up our special shell functions. */
Jari Aaltocce855b1998-04-17 19:52:44 +0000207#ifdef BANG_HISTORY
Jari Aalto726f6381996-08-26 18:22:31 +0000208 rl_add_defun ("history-expand-line", (Function *)history_expand_line, -1);
209 rl_bind_key_in_map ('^', (Function *)history_expand_line, emacs_meta_keymap);
210
Jari Aaltocce855b1998-04-17 19:52:44 +0000211 rl_add_defun ("magic-space", (Function *)tcsh_magic_space, -1);
212#endif
213
Jari Aaltod166f041997-06-05 14:59:13 +0000214#ifdef ALIAS
215 rl_add_defun ("alias-expand-line", (Function *)alias_expand_line, -1);
Jari Aaltobc4cd231998-07-23 14:37:54 +0000216# ifdef BANG_HISTORY
Jari Aaltod166f041997-06-05 14:59:13 +0000217 rl_add_defun ("history-and-alias-expand-line", (Function *)history_and_alias_expand_line, -1);
Jari Aaltobc4cd231998-07-23 14:37:54 +0000218# endif
Jari Aaltod166f041997-06-05 14:59:13 +0000219#endif
220
Jari Aalto726f6381996-08-26 18:22:31 +0000221 /* Backwards compatibility. */
222 rl_add_defun ("insert-last-argument", rl_yank_last_arg, -1);
223
224 rl_add_defun
225 ("operate-and-get-next", (Function *)operate_and_get_next, CTRL('O'));
226
227 rl_add_defun
228 ("display-shell-version", (Function *)display_shell_version, -1);
Jari Aalto726f6381996-08-26 18:22:31 +0000229 rl_bind_key_in_map
230 (CTRL ('V'), (Function *)display_shell_version, emacs_ctlx_keymap);
231
232 /* In Bash, the user can switch editing modes with "set -o [vi emacs]",
233 so it is not necessary to allow C-M-j for context switching. Turn
234 off this occasionally confusing behaviour. */
235 rl_unbind_key_in_map (CTRL('J'), emacs_meta_keymap);
236 rl_unbind_key_in_map (CTRL('M'), emacs_meta_keymap);
237#if defined (VI_MODE)
238 rl_unbind_key_in_map (CTRL('E'), vi_movement_keymap);
239#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000240
Jari Aalto726f6381996-08-26 18:22:31 +0000241#if defined (BRACE_COMPLETION)
Jari Aaltob72432f1999-02-19 17:11:39 +0000242 rl_add_defun ("complete-into-braces", (Function *)bash_brace_completion, -1);
243 rl_bind_key_in_map ('{', (Function *)bash_brace_completion, emacs_meta_keymap);
Jari Aalto726f6381996-08-26 18:22:31 +0000244#endif /* BRACE_COMPLETION */
245
246#if defined (SPECIFIC_COMPLETION_FUNCTIONS)
Jari Aaltob72432f1999-02-19 17:11:39 +0000247 rl_add_defun ("complete-filename", (Function *)bash_complete_filename, -1);
248 rl_bind_key_in_map ('/', (Function *)bash_complete_filename, emacs_meta_keymap);
Jari Aalto726f6381996-08-26 18:22:31 +0000249 rl_add_defun ("possible-filename-completions",
Jari Aaltob72432f1999-02-19 17:11:39 +0000250 (Function *)bash_possible_filename_completions, -1);
251 rl_bind_key_in_map ('/', (Function *)bash_possible_filename_completions, emacs_ctlx_keymap);
Jari Aalto726f6381996-08-26 18:22:31 +0000252
Jari Aaltob72432f1999-02-19 17:11:39 +0000253 rl_add_defun ("complete-username", (Function *)bash_complete_username, -1);
254 rl_bind_key_in_map ('~', (Function *)bash_complete_username, emacs_meta_keymap);
Jari Aalto726f6381996-08-26 18:22:31 +0000255 rl_add_defun ("possible-username-completions",
Jari Aaltob72432f1999-02-19 17:11:39 +0000256 (Function *)bash_possible_username_completions, -1);
257 rl_bind_key_in_map ('~', (Function *)bash_possible_username_completions, emacs_ctlx_keymap);
Jari Aalto726f6381996-08-26 18:22:31 +0000258
Jari Aaltob72432f1999-02-19 17:11:39 +0000259 rl_add_defun ("complete-hostname", (Function *)bash_complete_hostname, -1);
260 rl_bind_key_in_map ('@', (Function *)bash_complete_hostname, emacs_meta_keymap);
Jari Aalto726f6381996-08-26 18:22:31 +0000261 rl_add_defun ("possible-hostname-completions",
Jari Aaltob72432f1999-02-19 17:11:39 +0000262 (Function *)bash_possible_hostname_completions, -1);
263 rl_bind_key_in_map ('@', (Function *)bash_possible_hostname_completions, emacs_ctlx_keymap);
Jari Aalto726f6381996-08-26 18:22:31 +0000264
Jari Aaltob72432f1999-02-19 17:11:39 +0000265 rl_add_defun ("complete-variable", (Function *)bash_complete_variable, -1);
266 rl_bind_key_in_map ('$', (Function *)bash_complete_variable, emacs_meta_keymap);
Jari Aalto726f6381996-08-26 18:22:31 +0000267 rl_add_defun ("possible-variable-completions",
Jari Aaltob72432f1999-02-19 17:11:39 +0000268 (Function *)bash_possible_variable_completions, -1);
269 rl_bind_key_in_map ('$', (Function *)bash_possible_variable_completions, emacs_ctlx_keymap);
Jari Aalto726f6381996-08-26 18:22:31 +0000270
Jari Aaltob72432f1999-02-19 17:11:39 +0000271 rl_add_defun ("complete-command", (Function *)bash_complete_command, -1);
272 rl_bind_key_in_map ('!', (Function *)bash_complete_command, emacs_meta_keymap);
Jari Aalto726f6381996-08-26 18:22:31 +0000273 rl_add_defun ("possible-command-completions",
Jari Aaltob72432f1999-02-19 17:11:39 +0000274 (Function *)bash_possible_command_completions, -1);
275 rl_bind_key_in_map ('!', (Function *)bash_possible_command_completions, emacs_ctlx_keymap);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000276
Jari Aaltob72432f1999-02-19 17:11:39 +0000277 rl_add_defun ("glob-expand-word", (Function *)bash_glob_expand_word, -1);
278 rl_add_defun ("glob-list-expansions", (Function *)bash_glob_list_expansions, -1);
279 rl_bind_key_in_map ('*', (Function *)bash_glob_expand_word, emacs_ctlx_keymap);
280 rl_bind_key_in_map ('g', (Function *)bash_glob_list_expansions, emacs_ctlx_keymap);
Jari Aalto726f6381996-08-26 18:22:31 +0000281
282#endif /* SPECIFIC_COMPLETION_FUNCTIONS */
283
Jari Aaltob72432f1999-02-19 17:11:39 +0000284 rl_add_defun ("dynamic-complete-history", (Function *)dynamic_complete_history, -1);
285 rl_bind_key_in_map (TAB, (Function *)dynamic_complete_history, emacs_meta_keymap);
Jari Aalto726f6381996-08-26 18:22:31 +0000286
287 /* Tell the completer that we want a crack first. */
288 rl_attempted_completion_function = (CPPFunction *)attempt_shell_completion;
289
290 /* Tell the completer that we might want to follow symbolic links or
291 do other expansion on directory names. */
292 rl_directory_completion_hook = bash_directory_completion_hook;
293
294 /* Tell the filename completer we want a chance to ignore some names. */
295 rl_ignore_some_completions_function = (Function *)filename_completion_ignore;
296
297#if defined (VI_MODE)
Jari Aaltob72432f1999-02-19 17:11:39 +0000298 rl_bind_key_in_map ('v', (Function *)vi_edit_and_execute_command, vi_movement_keymap);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000299# if defined (ALIAS)
Jari Aaltob72432f1999-02-19 17:11:39 +0000300 rl_bind_key_in_map ('@', (Function *)posix_edit_macros, vi_movement_keymap);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000301# endif
Jari Aalto726f6381996-08-26 18:22:31 +0000302#endif
303
304 rl_completer_quote_characters = "'\"";
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000305
306 /* This sets rl_completer_word_break_characters and rl_special_prefixes
307 to the appropriate values, depending on whether or not hostname
308 completion is enabled. */
309 enable_hostname_completion (perform_hostname_completion);
310
311 /* characters that need to be quoted when appearing in filenames. */
Jari Aaltod166f041997-06-05 14:59:13 +0000312 rl_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:";
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000313 rl_filename_quoting_function = bash_quote_filename;
314 rl_filename_dequoting_function = bash_dequote_filename;
315 rl_char_is_quoted_p = char_is_quoted;
Jari Aalto726f6381996-08-26 18:22:31 +0000316
317 if (posixly_correct)
318 posix_readline_initialize (1);
319
320 bash_readline_initialized = 1;
321}
322
323/* On Sun systems at least, rl_attempted_completion_function can end up
324 getting set to NULL, and rl_completion_entry_function set to do command
325 word completion if Bash is interrupted while trying to complete a command
326 word. This just resets all the completion functions to the right thing.
327 It's called from throw_to_top_level(). */
328void
329bashline_reinitialize ()
330{
331 tilde_initialize ();
332 rl_attempted_completion_function = attempt_shell_completion;
333 rl_completion_entry_function = (Function *)NULL;
334 rl_directory_completion_hook = bash_directory_completion_hook;
335 rl_ignore_some_completions_function = (Function *)filename_completion_ignore;
336}
337
338/* Contains the line to push into readline. */
339static char *push_to_readline = (char *)NULL;
340
341/* Push the contents of push_to_readline into the
342 readline buffer. */
343static void
344bash_push_line ()
345{
346 if (push_to_readline)
347 {
348 rl_insert_text (push_to_readline);
349 free (push_to_readline);
350 push_to_readline = (char *)NULL;
351 rl_startup_hook = old_rl_startup_hook;
352 }
353}
354
355/* Call this to set the initial text for the next line to read
356 from readline. */
357int
358bash_re_edit (line)
359 char *line;
360{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000361 FREE (push_to_readline);
Jari Aalto726f6381996-08-26 18:22:31 +0000362
363 push_to_readline = savestring (line);
364 old_rl_startup_hook = rl_startup_hook;
365 rl_startup_hook = (Function *)bash_push_line;
366
367 return (0);
368}
369
370static void
371display_shell_version (count, c)
372 int count, c;
373{
374 crlf ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000375 show_shell_version (0);
Jari Aalto726f6381996-08-26 18:22:31 +0000376 putc ('\r', rl_outstream);
377 fflush (rl_outstream);
378 rl_on_new_line ();
379 rl_redisplay ();
380}
381
382/* **************************************************************** */
383/* */
384/* Readline Stuff */
385/* */
386/* **************************************************************** */
387
388/* If the user requests hostname completion, then simply build a list
389 of hosts, and complete from that forever more. */
Jari Aalto726f6381996-08-26 18:22:31 +0000390
391/* The kept list of hostnames. */
392static char **hostname_list = (char **)NULL;
393
394/* The physical size of the above list. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000395static int hostname_list_size;
Jari Aalto726f6381996-08-26 18:22:31 +0000396
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000397/* The number of hostnames in the above list. */
398static int hostname_list_length;
Jari Aalto726f6381996-08-26 18:22:31 +0000399
400/* Whether or not HOSTNAME_LIST has been initialized. */
401int hostname_list_initialized = 0;
402
Jari Aalto726f6381996-08-26 18:22:31 +0000403/* Initialize the hostname completion table. */
404static void
405initialize_hostname_list ()
406{
407 char *temp;
408
409 temp = get_string_value ("HOSTFILE");
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000410 if (temp == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000411 temp = get_string_value ("hostname_completion_file");
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000412 if (temp == 0)
413 temp = DEFAULT_HOSTS_FILE;
Jari Aalto726f6381996-08-26 18:22:31 +0000414
415 snarf_hosts_from_file (temp);
Jari Aalto726f6381996-08-26 18:22:31 +0000416
417 if (hostname_list)
418 hostname_list_initialized++;
419}
420
421/* Add NAME to the list of hosts. */
422static void
423add_host_name (name)
424 char *name;
425{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000426 long size;
427
Jari Aalto726f6381996-08-26 18:22:31 +0000428 if (hostname_list_length + 2 > hostname_list_size)
429 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000430 hostname_list_size = (hostname_list_size + 32) - (hostname_list_size % 32);
431 size = hostname_list_size * sizeof (char *);
432 hostname_list = (char **)xrealloc (hostname_list, size);
Jari Aalto726f6381996-08-26 18:22:31 +0000433 }
434
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000435 hostname_list[hostname_list_length++] = savestring (name);
436 hostname_list[hostname_list_length] = (char *)NULL;
Jari Aalto726f6381996-08-26 18:22:31 +0000437}
438
439#define cr_whitespace(c) ((c) == '\r' || (c) == '\n' || whitespace(c))
440
441static void
442snarf_hosts_from_file (filename)
443 char *filename;
444{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000445 FILE *file;
Jari Aalto726f6381996-08-26 18:22:31 +0000446 char *temp, buffer[256], name[256];
447 register int i, start;
448
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000449 file = fopen (filename, "r");
450 if (file == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000451 return;
452
453 while (temp = fgets (buffer, 255, file))
454 {
455 /* Skip to first character. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000456 for (i = 0; buffer[i] && cr_whitespace (buffer[i]); i++)
457 ;
Jari Aalto726f6381996-08-26 18:22:31 +0000458
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000459 /* If comment or blank line, ignore. */
460 if (buffer[i] == '\0' || buffer[i] == '#')
Jari Aalto726f6381996-08-26 18:22:31 +0000461 continue;
462
463 /* If `preprocessor' directive, do the include. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000464 if (strncmp (buffer + i, "$include ", 9) == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000465 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000466 char *incfile, *t;
Jari Aalto726f6381996-08-26 18:22:31 +0000467
468 /* Find start of filename. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000469 for (incfile = buffer + i + 9; *incfile && whitespace (*incfile); incfile++)
470 ;
Jari Aalto726f6381996-08-26 18:22:31 +0000471
472 /* Find end of filename. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000473 for (t = incfile; *t && cr_whitespace (*t) == 0; t++)
474 ;
Jari Aalto726f6381996-08-26 18:22:31 +0000475
476 *t = '\0';
477
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000478 snarf_hosts_from_file (incfile);
Jari Aalto726f6381996-08-26 18:22:31 +0000479 continue;
480 }
481
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000482 /* Skip internet address if present. */
483 if (digit (buffer[i]))
484 for (; buffer[i] && cr_whitespace (buffer[i]) == 0; i++);
Jari Aalto726f6381996-08-26 18:22:31 +0000485
486 /* Gobble up names. Each name is separated with whitespace. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000487 while (buffer[i])
Jari Aalto726f6381996-08-26 18:22:31 +0000488 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000489 for (; cr_whitespace (buffer[i]); i++)
490 ;
491 if (buffer[i] == '\0' || buffer[i] == '#')
492 break;
493
494 /* Isolate the current word. */
495 for (start = i; buffer[i] && cr_whitespace (buffer[i]) == 0; i++)
496 ;
497 if (i == start)
Jari Aalto726f6381996-08-26 18:22:31 +0000498 continue;
499 strncpy (name, buffer + start, i - start);
500 name[i - start] = '\0';
501 add_host_name (name);
502 }
503 }
504 fclose (file);
505}
506
507/* Return a NULL terminated list of hostnames which begin with TEXT.
508 Initialize the hostname list the first time if neccessary.
509 The array is malloc ()'ed, but not the individual strings. */
510static char **
511hostnames_matching (text)
512 char *text;
513{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000514 register int i, len, nmatch, rsize;
515 char **result;
Jari Aalto726f6381996-08-26 18:22:31 +0000516
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000517 if (hostname_list_initialized == 0)
518 initialize_hostname_list ();
Jari Aalto726f6381996-08-26 18:22:31 +0000519
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000520 if (hostname_list_initialized == 0)
521 return ((char **)NULL);
Jari Aalto726f6381996-08-26 18:22:31 +0000522
523 /* Special case. If TEXT consists of nothing, then the whole list is
524 what is desired. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000525 if (*text == '\0')
Jari Aalto726f6381996-08-26 18:22:31 +0000526 {
527 result = (char **)xmalloc ((1 + hostname_list_length) * sizeof (char *));
528 for (i = 0; i < hostname_list_length; i++)
529 result[i] = hostname_list[i];
530 result[i] = (char *)NULL;
531 return (result);
532 }
533
534 /* Scan until found, or failure. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000535 len = strlen (text);
536 result = (char **)NULL;
537 for (i = nmatch = rsize = 0; i < hostname_list_length; i++)
Jari Aalto726f6381996-08-26 18:22:31 +0000538 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000539 if (STREQN (text, hostname_list[i], len) == 0)
540 continue;
Jari Aalto726f6381996-08-26 18:22:31 +0000541
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000542 /* OK, it matches. Add it to the list. */
Jari Aaltobc4cd231998-07-23 14:37:54 +0000543 if (nmatch >= (rsize - 1))
Jari Aalto726f6381996-08-26 18:22:31 +0000544 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000545 rsize = (rsize + 16) - (rsize % 16);
546 result = (char **)xrealloc (result, rsize * sizeof (char *));
Jari Aalto726f6381996-08-26 18:22:31 +0000547 }
548
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000549 result[nmatch++] = hostname_list[i];
Jari Aalto726f6381996-08-26 18:22:31 +0000550 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000551 if (nmatch)
552 result[nmatch] = (char *)NULL;
553 return (result);
Jari Aalto726f6381996-08-26 18:22:31 +0000554}
555
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000556/* The equivalent of the Korn shell C-o operate-and-get-next-history-line
Jari Aalto726f6381996-08-26 18:22:31 +0000557 editing command. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000558static int saved_history_line_to_use = -1;
Jari Aalto726f6381996-08-26 18:22:31 +0000559
560static void
561set_saved_history ()
562{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000563 if (saved_history_line_to_use >= 0)
Jari Aaltob72432f1999-02-19 17:11:39 +0000564 rl_get_previous_history (history_length - saved_history_line_to_use, 0);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000565 saved_history_line_to_use = -1;
Jari Aalto726f6381996-08-26 18:22:31 +0000566 rl_startup_hook = old_rl_startup_hook;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000567}
Jari Aalto726f6381996-08-26 18:22:31 +0000568
569static void
570operate_and_get_next (count, c)
571 int count, c;
572{
573 int where;
574
575 /* Accept the current line. */
Jari Aaltob72432f1999-02-19 17:11:39 +0000576 rl_newline (1, c);
Jari Aalto726f6381996-08-26 18:22:31 +0000577
578 /* Find the current line, and find the next line to use. */
579 where = where_history ();
580
581 if ((history_is_stifled () && (history_length >= max_input_history)) ||
582 (where >= history_length - 1))
583 saved_history_line_to_use = where;
584 else
585 saved_history_line_to_use = where + 1;
586
587 old_rl_startup_hook = rl_startup_hook;
588 rl_startup_hook = (Function *)set_saved_history;
589}
590
591#if defined (VI_MODE)
592/* This vi mode command causes VI_EDIT_COMMAND to be run on the current
593 command being entered (if no explicit argument is given), otherwise on
594 a command from the history file. */
595
596#define VI_EDIT_COMMAND "fc -e ${VISUAL:-${EDITOR:-vi}}"
597
598static void
599vi_edit_and_execute_command (count, c)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000600 int count, c;
Jari Aalto726f6381996-08-26 18:22:31 +0000601{
602 char *command;
603
604 /* Accept the current line. */
Jari Aaltob72432f1999-02-19 17:11:39 +0000605 rl_newline (1, c);
Jari Aalto726f6381996-08-26 18:22:31 +0000606
607 if (rl_explicit_arg)
608 {
609 command = xmalloc (strlen (VI_EDIT_COMMAND) + 8);
610 sprintf (command, "%s %d", VI_EDIT_COMMAND, count);
611 }
612 else
613 {
614 /* Take the command we were just editing, add it to the history file,
615 then call fc to operate on it. We have to add a dummy command to
616 the end of the history because fc ignores the last command (assumes
617 it's supposed to deal with the command before the `fc'). */
618 using_history ();
Jari Aaltod166f041997-06-05 14:59:13 +0000619 bash_add_history (rl_line_buffer);
620 bash_add_history ("");
Jari Aalto726f6381996-08-26 18:22:31 +0000621 history_lines_this_session++;
622 using_history ();
623 command = savestring (VI_EDIT_COMMAND);
624 }
Jari Aaltod166f041997-06-05 14:59:13 +0000625 parse_and_execute (command, "v", SEVAL_NOHIST);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000626 rl_line_buffer[0] = '\0'; /* XXX */
Jari Aalto726f6381996-08-26 18:22:31 +0000627}
628#endif /* VI_MODE */
629
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000630#if defined (ALIAS)
631static int
632posix_edit_macros (count, key)
633 int count, key;
634{
635 int c;
636 char alias_name[3], *alias_value, *macro;
637
638 c = rl_read_key ();
639 alias_name[0] = '_';
640 alias_name[1] = c;
641 alias_name[2] = '\0';
642
643 alias_value = get_alias_value (alias_name);
644 if (alias_value && *alias_value)
645 {
646 macro = savestring (alias_value);
647 rl_push_macro_input (macro);
648 }
649 return 0;
650}
651#endif
652
Jari Aalto726f6381996-08-26 18:22:31 +0000653/* **************************************************************** */
654/* */
655/* How To Do Shell Completion */
656/* */
657/* **************************************************************** */
658
659/* Do some completion on TEXT. The indices of TEXT in RL_LINE_BUFFER are
660 at START and END. Return an array of matches, or NULL if none. */
661static char **
662attempt_shell_completion (text, start, end)
663 char *text;
664 int start, end;
665{
666 int in_command_position, ti;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000667 char **matches, *command_separator_chars;
Jari Aalto726f6381996-08-26 18:22:31 +0000668
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000669 command_separator_chars = ";|&{(`";
670 matches = (char **)NULL;
671 rl_ignore_some_completions_function = (Function *)filename_completion_ignore;
Jari Aalto726f6381996-08-26 18:22:31 +0000672
673 /* Determine if this could be a command word. It is if it appears at
674 the start of the line (ignoring preceding whitespace), or if it
675 appears after a character that separates commands. It cannot be a
676 command word if we aren't at the top-level prompt. */
677 ti = start - 1;
678
679 while ((ti > -1) && (whitespace (rl_line_buffer[ti])))
680 ti--;
681
682 in_command_position = 0;
683 if (ti < 0)
684 {
685 /* Only do command completion at the start of a line when we
686 are prompting at the top level. */
687 if (current_prompt_string == ps1_prompt)
688 in_command_position++;
689 }
690 else if (member (rl_line_buffer[ti], command_separator_chars))
691 {
692 register int this_char, prev_char;
693
694 in_command_position++;
695
696 /* Handle the two character tokens `>&', `<&', and `>|'.
697 We are not in a command position after one of these. */
698 this_char = rl_line_buffer[ti];
699 prev_char = rl_line_buffer[ti - 1];
700
701 if ((this_char == '&' && (prev_char == '<' || prev_char == '>')) ||
702 (this_char == '|' && prev_char == '>'))
703 in_command_position = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000704 else if ((this_char == '{' && prev_char == '$') ||
705 (char_is_quoted (rl_line_buffer, ti)))
Jari Aalto726f6381996-08-26 18:22:31 +0000706 in_command_position = 0;
707 }
708 else
709 {
710 /* This still could be in command position. It is possible
711 that all of the previous words on the line are variable
712 assignments. */
713 }
714
Jari Aaltod166f041997-06-05 14:59:13 +0000715 /* Check that we haven't incorrectly flagged a closed command substitution
716 as indicating we're in a command position. */
Jari Aaltoe8ce7751997-09-22 20:22:27 +0000717 if (in_command_position && ti >= 0 && rl_line_buffer[ti] == '`' &&
718 *text != '`' && unclosed_pair (rl_line_buffer, 0, "`") == 0)
Jari Aaltod166f041997-06-05 14:59:13 +0000719 in_command_position = 0;
720
721 /* Special handling for command substitution. If *TEXT is a backquote,
722 it can be the start or end of an old-style command substitution, or
723 unmatched. If it's unmatched, both calls to unclosed_pair will
724 succeed. */
725 if (*text == '`' && unclosed_pair (rl_line_buffer, start, "`") &&
726 unclosed_pair (rl_line_buffer, end, "`"))
Jari Aalto726f6381996-08-26 18:22:31 +0000727 matches = completion_matches (text, command_subst_completion_function);
728
729 /* Variable name? */
730 if (!matches && *text == '$')
731 matches = completion_matches (text, variable_completion_function);
732
733 /* If the word starts in `~', and there is no slash in the word, then
734 try completing this word as a username. */
735 if (!matches && *text == '~' && !strchr (text, '/'))
736 matches = completion_matches (text, username_completion_function);
737
738 /* Another one. Why not? If the word starts in '@', then look through
739 the world of known hostnames for completion first. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000740 if (!matches && perform_hostname_completion && *text == '@')
Jari Aalto726f6381996-08-26 18:22:31 +0000741 matches = completion_matches (text, hostname_completion_function);
742
743 /* And last, (but not least) if this word is in a command position, then
744 complete over possible command names, including aliases, functions,
745 and command names. */
746 if (!matches && in_command_position)
747 {
748 matches = completion_matches (text, command_word_completion_function);
749 /* If we are attempting command completion and nothing matches, we
750 do not want readline to perform filename completion for us. We
751 still want to be able to complete partial pathnames, so set the
752 completion ignore function to something which will remove filenames
753 and leave directories in the match list. */
754 if (!matches)
755 rl_ignore_some_completions_function = (Function *)bash_ignore_filenames;
756 }
757
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000758 /* This could be a globbing pattern, so try to expand it using pathname
759 expansion. */
760 if (!matches && glob_pattern_p (text))
Jari Aaltoe8ce7751997-09-22 20:22:27 +0000761 {
762 matches = completion_matches (text, glob_complete_word);
763 /* A glob expression that matches more than one filename is problematic.
764 If we match more than one filename, punt. */
765 if (matches && matches[1])
766 {
767 free_array (matches);
768 matches = (char **)0;
769 }
770 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000771
Jari Aalto726f6381996-08-26 18:22:31 +0000772 return (matches);
773}
774
775/* This is the function to call when the word to complete is in a position
776 where a command word can be found. It grovels $PATH, looking for commands
777 that match. It also scans aliases, function names, and the shell_builtin
778 table. */
779static char *
780command_word_completion_function (hint_text, state)
781 char *hint_text;
782 int state;
783{
784 static char *hint = (char *)NULL;
785 static char *path = (char *)NULL;
786 static char *val = (char *)NULL;
787 static char *filename_hint = (char *)NULL;
788 static int path_index, hint_len, istate;
789 static int mapping_over, local_index;
790 static SHELL_VAR **varlist = (SHELL_VAR **)NULL;
791#if defined (ALIAS)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000792 static alias_t **alias_list = (alias_t **)NULL;
Jari Aalto726f6381996-08-26 18:22:31 +0000793#endif /* ALIAS */
794
795 /* We have to map over the possibilities for command words. If we have
796 no state, then make one just for that purpose. */
Jari Aalto726f6381996-08-26 18:22:31 +0000797 if (!state)
798 {
799 if (hint)
800 free (hint);
801
802 mapping_over = 0;
803 val = (char *)NULL;
804
805 /* If this is an absolute program name, do not check it against
806 aliases, reserved words, functions or builtins. We must check
807 whether or not it is unique, and, if so, whether that filename
808 is executable. */
809 if (absolute_program (hint_text))
810 {
811 /* Perform tilde expansion on what's passed, so we don't end up
812 passing filenames with tildes directly to stat(). */
813 if (*hint_text == '~')
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000814 hint = bash_tilde_expand (hint_text);
Jari Aalto726f6381996-08-26 18:22:31 +0000815 else
816 hint = savestring (hint_text);
817 hint_len = strlen (hint);
818
819 if (filename_hint)
820 free (filename_hint);
821 filename_hint = savestring (hint);
822
823 mapping_over = 4;
824 istate = 0;
825 goto inner;
826 }
827
828 hint = savestring (hint_text);
829 hint_len = strlen (hint);
830
831 path = get_string_value ("PATH");
832 path_index = 0;
833
834 /* Initialize the variables for each type of command word. */
835 local_index = 0;
836
837 if (varlist)
838 free (varlist);
839
840 varlist = all_visible_functions ();
841
842#if defined (ALIAS)
843 if (alias_list)
844 free (alias_list);
845
846 alias_list = all_aliases ();
847#endif /* ALIAS */
848 }
849
850 /* mapping_over says what we are currently hacking. Note that every case
851 in this list must fall through when there are no more possibilities. */
852
853 switch (mapping_over)
854 {
855 case 0: /* Aliases come first. */
856#if defined (ALIAS)
857 while (alias_list && alias_list[local_index])
858 {
859 register char *alias;
860
861 alias = alias_list[local_index++]->name;
862
863 if (STREQN (alias, hint, hint_len))
864 return (savestring (alias));
865 }
866#endif /* ALIAS */
867 local_index = 0;
868 mapping_over++;
869
870 case 1: /* Then shell reserved words. */
871 {
872 while (word_token_alist[local_index].word)
873 {
874 register char *reserved_word;
875
876 reserved_word = word_token_alist[local_index++].word;
877
878 if (STREQN (reserved_word, hint, hint_len))
879 return (savestring (reserved_word));
880 }
881 local_index = 0;
882 mapping_over++;
883 }
884
885 case 2: /* Then function names. */
886 while (varlist && varlist[local_index])
887 {
888 register char *varname;
889
890 varname = varlist[local_index++]->name;
891
892 if (STREQN (varname, hint, hint_len))
893 return (savestring (varname));
894 }
895 local_index = 0;
896 mapping_over++;
897
898 case 3: /* Then shell builtins. */
899 for (; local_index < num_shell_builtins; local_index++)
900 {
901 /* Ignore it if it doesn't have a function pointer or if it
902 is not currently enabled. */
903 if (!shell_builtins[local_index].function ||
904 (shell_builtins[local_index].flags & BUILTIN_ENABLED) == 0)
905 continue;
906
907 if (STREQN (shell_builtins[local_index].name, hint, hint_len))
908 {
909 int i = local_index++;
910
911 return (savestring (shell_builtins[i].name));
912 }
913 }
914 local_index = 0;
915 mapping_over++;
916 }
917
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000918 /* Repeatedly call filename_completion_function while we have
Jari Aalto726f6381996-08-26 18:22:31 +0000919 members of PATH left. Question: should we stat each file?
920 Answer: we call executable_file () on each file. */
921 outer:
922
923 istate = (val != (char *)NULL);
924
925 if (!istate)
926 {
927 char *current_path;
928
929 /* Get the next directory from the path. If there is none, then we
930 are all done. */
931 if (!path || !path[path_index] ||
932 (current_path = extract_colon_unit (path, &path_index)) == 0)
933 return ((char *)NULL);
934
935 if (*current_path == 0)
936 {
937 free (current_path);
938 current_path = savestring (".");
939 }
940
941 if (*current_path == '~')
942 {
943 char *t;
944
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000945 t = bash_tilde_expand (current_path);
Jari Aalto726f6381996-08-26 18:22:31 +0000946 free (current_path);
947 current_path = t;
948 }
949
950 if (filename_hint)
951 free (filename_hint);
952
953 filename_hint = xmalloc (2 + strlen (current_path) + hint_len);
954 sprintf (filename_hint, "%s/%s", current_path, hint);
955
956 free (current_path);
957 }
958
959 inner:
960 val = filename_completion_function (filename_hint, istate);
961 istate = 1;
962
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000963 if (val == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000964 {
965 /* If the hint text is an absolute program, then don't bother
966 searching through PATH. */
967 if (absolute_program (hint))
968 return ((char *)NULL);
969
970 goto outer;
971 }
972 else
973 {
Jari Aaltod166f041997-06-05 14:59:13 +0000974 int match, freetemp;
Jari Aalto726f6381996-08-26 18:22:31 +0000975 char *temp;
976
977 if (absolute_program (hint))
978 {
979 match = strncmp (val, hint, hint_len) == 0;
980 /* If we performed tilde expansion, restore the original
981 filename. */
982 if (*hint_text == '~')
983 {
984 int l, tl, vl;
985 vl = strlen (val);
986 tl = strlen (hint_text);
987 l = vl - hint_len; /* # of chars added */
988 temp = xmalloc (l + 2 + tl);
989 strcpy (temp, hint_text);
990 strcpy (temp + tl, val + vl - l);
991 }
992 else
993 temp = savestring (val);
Jari Aaltod166f041997-06-05 14:59:13 +0000994 freetemp = 1;
Jari Aalto726f6381996-08-26 18:22:31 +0000995 }
996 else
997 {
998 temp = strrchr (val, '/');
999
1000 if (temp)
1001 {
1002 temp++;
Jari Aaltod166f041997-06-05 14:59:13 +00001003 freetemp = match = strncmp (temp, hint, hint_len) == 0;
Jari Aalto726f6381996-08-26 18:22:31 +00001004 if (match)
1005 temp = savestring (temp);
1006 }
1007 else
Jari Aaltod166f041997-06-05 14:59:13 +00001008 freetemp = match = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00001009 }
1010
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001011 /* If we have found a match, and it is an executable file or a
1012 directory name, return it. */
1013 if (match && (executable_file (val) || is_directory (val)))
Jari Aalto726f6381996-08-26 18:22:31 +00001014 {
1015 free (val);
1016 val = ""; /* So it won't be NULL. */
1017 return (temp);
1018 }
1019 else
1020 {
Jari Aaltod166f041997-06-05 14:59:13 +00001021 if (freetemp)
1022 free (temp);
Jari Aalto726f6381996-08-26 18:22:31 +00001023 free (val);
1024 goto inner;
1025 }
1026 }
1027}
1028
Jari Aaltod166f041997-06-05 14:59:13 +00001029/* Completion inside an unterminated command substitution. */
Jari Aalto726f6381996-08-26 18:22:31 +00001030static char *
1031command_subst_completion_function (text, state)
Jari Aalto726f6381996-08-26 18:22:31 +00001032 char *text;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001033 int state;
Jari Aalto726f6381996-08-26 18:22:31 +00001034{
1035 static char **matches = (char **)NULL;
1036 static char *orig_start, *filename_text = (char *)NULL;
1037 static int cmd_index, start_len;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001038 char *value;
Jari Aalto726f6381996-08-26 18:22:31 +00001039
1040 if (state == 0)
1041 {
1042 if (filename_text)
1043 free (filename_text);
1044 orig_start = text;
1045 if (*text == '`')
1046 text++;
Jari Aaltocce855b1998-04-17 19:52:44 +00001047 else if (*text == '$' && text[1] == '(') /* ) */
Jari Aalto726f6381996-08-26 18:22:31 +00001048 text += 2;
1049 start_len = text - orig_start;
1050 filename_text = savestring (text);
1051 if (matches)
1052 free (matches);
1053 matches = completion_matches (filename_text, command_word_completion_function);
1054 cmd_index = 0;
1055 }
1056
1057 if (!matches || !matches[cmd_index])
1058 {
1059 rl_filename_quoting_desired = 0; /* disable quoting */
1060 return ((char *)NULL);
1061 }
1062 else
1063 {
Jari Aalto726f6381996-08-26 18:22:31 +00001064 value = xmalloc (1 + start_len + strlen (matches[cmd_index]));
1065
1066 if (start_len == 1)
1067 value[0] = *orig_start;
1068 else
1069 strncpy (value, orig_start, start_len);
1070
1071 strcpy (value + start_len, matches[cmd_index]);
1072
1073 cmd_index++;
1074 return (value);
1075 }
1076}
1077
1078/* Okay, now we write the entry_function for variable completion. */
1079static char *
1080variable_completion_function (text, state)
1081 int state;
1082 char *text;
1083{
1084 register SHELL_VAR *var = (SHELL_VAR *)NULL;
1085 static SHELL_VAR **varlist = (SHELL_VAR **)NULL;
1086 static int varlist_index;
1087 static char *varname = (char *)NULL;
1088 static int namelen;
1089 static int first_char, first_char_loc;
1090
1091 if (!state)
1092 {
1093 if (varname)
1094 free (varname);
1095
1096 first_char_loc = 0;
1097 first_char = text[0];
1098
1099 if (first_char == '$')
1100 first_char_loc++;
1101
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001102 if (text[first_char_loc] == '{')
1103 first_char_loc++;
1104
Jari Aalto726f6381996-08-26 18:22:31 +00001105 varname = savestring (text + first_char_loc);
1106
1107 namelen = strlen (varname);
1108 if (varlist)
1109 free (varlist);
1110 varlist = all_visible_variables ();
1111 varlist_index = 0;
1112 }
1113
1114 while (varlist && varlist[varlist_index])
1115 {
1116 var = varlist[varlist_index];
1117
1118 /* Compare. You can't do better than Zayre. No text is also
1119 a match. */
1120 if (!*varname || (strncmp (varname, var->name, namelen) == 0))
1121 break;
1122 varlist_index++;
1123 }
1124
1125 if (!varlist || !varlist[varlist_index])
1126 {
1127 return ((char *)NULL);
1128 }
1129 else
1130 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001131 char *value = xmalloc (4 + strlen (var->name));
Jari Aalto726f6381996-08-26 18:22:31 +00001132
1133 if (first_char_loc)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001134 {
1135 value[0] = first_char;
1136 if (first_char_loc == 2)
1137 value[1] = '{';
1138 }
Jari Aalto726f6381996-08-26 18:22:31 +00001139
1140 strcpy (&value[first_char_loc], var->name);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001141 if (first_char_loc == 2)
1142 strcat (value, "}");
Jari Aalto726f6381996-08-26 18:22:31 +00001143
1144 varlist_index++;
1145 return (value);
1146 }
1147}
1148
1149/* How about a completion function for hostnames? */
1150static char *
1151hostname_completion_function (text, state)
1152 int state;
1153 char *text;
1154{
1155 static char **list = (char **)NULL;
1156 static int list_index = 0;
1157 static int first_char, first_char_loc;
1158
1159 /* If we don't have any state, make some. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001160 if (state == 0)
Jari Aalto726f6381996-08-26 18:22:31 +00001161 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001162 FREE (list);
Jari Aalto726f6381996-08-26 18:22:31 +00001163
1164 list = (char **)NULL;
1165
1166 first_char_loc = 0;
1167 first_char = *text;
1168
1169 if (first_char == '@')
1170 first_char_loc++;
1171
1172 list = hostnames_matching (&text[first_char_loc]);
1173 list_index = 0;
1174 }
1175
1176 if (list && list[list_index])
1177 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001178 char *t;
Jari Aalto726f6381996-08-26 18:22:31 +00001179
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001180 t = xmalloc (2 + strlen (list[list_index]));
Jari Aalto726f6381996-08-26 18:22:31 +00001181 *t = first_char;
1182 strcpy (t + first_char_loc, list[list_index]);
1183 list_index++;
1184 return (t);
1185 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001186
1187 return ((char *)NULL);
Jari Aalto726f6381996-08-26 18:22:31 +00001188}
1189
Jari Aaltocce855b1998-04-17 19:52:44 +00001190/* Functions to perform history and alias expansions on the current line. */
1191
1192#if defined (BANG_HISTORY)
1193/* Perform history expansion on the current line. If no history expansion
1194 is done, pre_process_line() returns what it was passed, so we need to
1195 allocate a new line here. */
Jari Aalto726f6381996-08-26 18:22:31 +00001196static char *
1197history_expand_line_internal (line)
1198 char *line;
1199{
1200 char *new_line;
1201
1202 new_line = pre_process_line (line, 0, 0);
Jari Aaltod166f041997-06-05 14:59:13 +00001203 return (new_line == line) ? savestring (line) : new_line;
Jari Aalto726f6381996-08-26 18:22:31 +00001204}
Jari Aalto726f6381996-08-26 18:22:31 +00001205#endif
1206
1207/* There was an error in expansion. Let the preprocessor print
1208 the error here. */
1209static void
1210cleanup_expansion_error ()
1211{
1212 char *to_free;
1213
1214 fprintf (rl_outstream, "\r\n");
1215 to_free = pre_process_line (rl_line_buffer, 1, 0);
Jari Aaltod166f041997-06-05 14:59:13 +00001216 if (to_free != rl_line_buffer)
1217 free (to_free);
Jari Aalto726f6381996-08-26 18:22:31 +00001218 putc ('\r', rl_outstream);
1219 rl_forced_update_display ();
1220}
1221
1222/* If NEW_LINE differs from what is in the readline line buffer, add an
1223 undo record to get from the readline line buffer contents to the new
1224 line and make NEW_LINE the current readline line. */
1225static void
1226maybe_make_readline_line (new_line)
1227 char *new_line;
1228{
1229 if (strcmp (new_line, rl_line_buffer) != 0)
1230 {
1231 rl_point = rl_end;
1232
1233 rl_add_undo (UNDO_BEGIN, 0, 0, 0);
1234 rl_delete_text (0, rl_point);
1235 rl_point = rl_end = 0;
1236 rl_insert_text (new_line);
1237 rl_add_undo (UNDO_END, 0, 0, 0);
1238 }
1239}
1240
1241/* Make NEW_LINE be the current readline line. This frees NEW_LINE. */
1242static void
1243set_up_new_line (new_line)
1244 char *new_line;
1245{
1246 int old_point = rl_point;
1247 int at_end = rl_point == rl_end;
1248
1249 /* If the line was history and alias expanded, then make that
1250 be one thing to undo. */
1251 maybe_make_readline_line (new_line);
1252 free (new_line);
1253
1254 /* Place rl_point where we think it should go. */
1255 if (at_end)
1256 rl_point = rl_end;
1257 else if (old_point < rl_end)
1258 {
1259 rl_point = old_point;
1260 if (!whitespace (rl_line_buffer[rl_point]))
Jari Aaltob72432f1999-02-19 17:11:39 +00001261 rl_forward_word (1, 0);
Jari Aalto726f6381996-08-26 18:22:31 +00001262 }
1263}
1264
Jari Aaltocce855b1998-04-17 19:52:44 +00001265#if defined (ALIAS)
1266/* Expand aliases in the current readline line. */
1267static int
1268alias_expand_line (ignore)
1269 int ignore;
1270{
1271 char *new_line;
1272
1273 new_line = alias_expand (rl_line_buffer);
1274
1275 if (new_line)
1276 {
1277 set_up_new_line (new_line);
1278 return (0);
1279 }
1280 else
1281 {
1282 cleanup_expansion_error ();
1283 return (1);
1284 }
1285}
1286#endif
1287
1288#if defined (BANG_HISTORY)
Jari Aalto726f6381996-08-26 18:22:31 +00001289/* History expand the line. */
Jari Aaltocce855b1998-04-17 19:52:44 +00001290static int
Jari Aalto726f6381996-08-26 18:22:31 +00001291history_expand_line (ignore)
1292 int ignore;
1293{
1294 char *new_line;
1295
1296 new_line = history_expand_line_internal (rl_line_buffer);
1297
1298 if (new_line)
Jari Aaltocce855b1998-04-17 19:52:44 +00001299 {
1300 set_up_new_line (new_line);
1301 return (0);
1302 }
Jari Aalto726f6381996-08-26 18:22:31 +00001303 else
Jari Aaltocce855b1998-04-17 19:52:44 +00001304 {
1305 cleanup_expansion_error ();
1306 return (1);
1307 }
Jari Aalto726f6381996-08-26 18:22:31 +00001308}
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001309
Jari Aaltocce855b1998-04-17 19:52:44 +00001310/* Expand history substitutions in the current line and then insert a
1311 space wherever set_up_new_line decided to put rl_point. */
1312static int
1313tcsh_magic_space (ignore)
1314 int ignore;
1315{
1316 if (history_expand_line (ignore) == 0)
1317 {
1318 rl_insert (1, ' ');
1319 return (0);
1320 }
1321 else
1322 return (1);
1323}
1324#endif
1325
Jari Aalto726f6381996-08-26 18:22:31 +00001326/* History and alias expand the line. */
Jari Aaltocce855b1998-04-17 19:52:44 +00001327static int
Jari Aalto726f6381996-08-26 18:22:31 +00001328history_and_alias_expand_line (ignore)
1329 int ignore;
1330{
1331 char *new_line;
1332
1333 new_line = pre_process_line (rl_line_buffer, 0, 0);
Jari Aaltod166f041997-06-05 14:59:13 +00001334 if (new_line == rl_line_buffer)
1335 new_line = savestring (new_line);
Jari Aalto726f6381996-08-26 18:22:31 +00001336
1337#if defined (ALIAS)
1338 if (new_line)
1339 {
1340 char *alias_line;
1341
1342 alias_line = alias_expand (new_line);
1343 free (new_line);
1344 new_line = alias_line;
1345 }
1346#endif /* ALIAS */
1347
1348 if (new_line)
Jari Aaltocce855b1998-04-17 19:52:44 +00001349 {
1350 set_up_new_line (new_line);
1351 return (0);
1352 }
Jari Aalto726f6381996-08-26 18:22:31 +00001353 else
Jari Aaltocce855b1998-04-17 19:52:44 +00001354 {
1355 cleanup_expansion_error ();
1356 return (1);
1357 }
Jari Aalto726f6381996-08-26 18:22:31 +00001358}
1359
1360/* History and alias expand the line, then perform the shell word
Jari Aaltocce855b1998-04-17 19:52:44 +00001361 expansions by calling expand_string. This can't use set_up_new_line()
1362 because we want the variable expansions as a separate undo'able
1363 set of operations. */
Jari Aalto726f6381996-08-26 18:22:31 +00001364static void
1365shell_expand_line (ignore)
1366 int ignore;
1367{
1368 char *new_line;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001369 WORD_LIST *expanded_string;
Jari Aalto726f6381996-08-26 18:22:31 +00001370
1371 new_line = pre_process_line (rl_line_buffer, 0, 0);
Jari Aaltod166f041997-06-05 14:59:13 +00001372 if (new_line == rl_line_buffer)
1373 new_line = savestring (new_line);
Jari Aalto726f6381996-08-26 18:22:31 +00001374
1375#if defined (ALIAS)
1376 if (new_line)
1377 {
1378 char *alias_line;
1379
1380 alias_line = alias_expand (new_line);
1381 free (new_line);
1382 new_line = alias_line;
1383 }
1384#endif /* ALIAS */
1385
1386 if (new_line)
1387 {
1388 int old_point = rl_point;
1389 int at_end = rl_point == rl_end;
1390
1391 /* If the line was history and alias expanded, then make that
1392 be one thing to undo. */
1393 maybe_make_readline_line (new_line);
1394 free (new_line);
1395
1396 /* If there is variable expansion to perform, do that as a separate
1397 operation to be undone. */
Jari Aaltod166f041997-06-05 14:59:13 +00001398 new_line = savestring (rl_line_buffer);
1399 expanded_string = expand_string (new_line, 0);
1400 FREE (new_line);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001401 if (expanded_string == 0)
1402 {
1403 new_line = xmalloc (1);
1404 new_line[0] = '\0';
1405 }
1406 else
1407 {
1408 new_line = string_list (expanded_string);
1409 dispose_words (expanded_string);
1410 }
Jari Aalto726f6381996-08-26 18:22:31 +00001411
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001412 maybe_make_readline_line (new_line);
1413 free (new_line);
Jari Aalto726f6381996-08-26 18:22:31 +00001414
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001415 /* Place rl_point where we think it should go. */
1416 if (at_end)
1417 rl_point = rl_end;
1418 else if (old_point < rl_end)
1419 {
1420 rl_point = old_point;
1421 if (!whitespace (rl_line_buffer[rl_point]))
Jari Aaltob72432f1999-02-19 17:11:39 +00001422 rl_forward_word (1, 0);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001423 }
Jari Aalto726f6381996-08-26 18:22:31 +00001424 }
1425 else
1426 cleanup_expansion_error ();
1427}
1428
Jari Aaltocce855b1998-04-17 19:52:44 +00001429/* Define NO_FORCE_FIGNORE if you want to match filenames that would
1430 otherwise be ignored if they are the only possible matches. */
1431/* #define NO_FORCE_FIGNORE */
1432
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001433/* If FIGNORE is set, then don't match files with the given suffixes when
1434 completing filenames. If only one of the possibilities has an acceptable
Jari Aalto726f6381996-08-26 18:22:31 +00001435 suffix, delete the others, else just return and let the completer
1436 signal an error. It is called by the completer when real
1437 completions are done on filenames by the completer's internal
1438 function, not for completion lists (M-?) and not on "other"
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001439 completion types, such as hostnames or commands. */
Jari Aalto726f6381996-08-26 18:22:31 +00001440
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001441static struct ignorevar fignore =
1442{
1443 "FIGNORE",
1444 (struct ign *)0,
1445 0,
1446 (char *)0,
1447 (Function *) 0,
Jari Aalto726f6381996-08-26 18:22:31 +00001448};
1449
Jari Aalto726f6381996-08-26 18:22:31 +00001450static void
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001451_ignore_completion_names (names, name_func)
Jari Aalto726f6381996-08-26 18:22:31 +00001452 char **names;
1453 Function *name_func;
1454{
1455 char **newnames;
1456 int idx, nidx;
Jari Aaltocce855b1998-04-17 19:52:44 +00001457#ifdef NO_FORCE_FIGNORE
1458 char **oldnames;
1459 int oidx;
1460#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001461
1462 /* If there is only one completion, see if it is acceptable. If it is
1463 not, free it up. In any case, short-circuit and return. This is a
1464 special case because names[0] is not the prefix of the list of names
1465 if there is only one completion; it is the completion itself. */
1466 if (names[1] == (char *)0)
1467 {
Jari Aaltocce855b1998-04-17 19:52:44 +00001468#ifndef NO_FORCE_FIGNORE
Jari Aalto726f6381996-08-26 18:22:31 +00001469 if ((*name_func) (names[0]) == 0)
1470 {
1471 free (names[0]);
1472 names[0] = (char *)NULL;
1473 }
Jari Aaltocce855b1998-04-17 19:52:44 +00001474#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001475 return;
1476 }
1477
1478 /* Allocate space for array to hold list of pointers to matching
1479 filenames. The pointers are copied back to NAMES when done. */
1480 for (nidx = 1; names[nidx]; nidx++)
1481 ;
1482 newnames = (char **)xmalloc ((nidx + 1) * (sizeof (char *)));
Jari Aaltocce855b1998-04-17 19:52:44 +00001483#ifdef NO_FORCE_FIGNORE
1484 oldnames = (char **)xmalloc ((nidx - 1) * (sizeof (char *)));
1485 oidx = 0;
1486#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001487
1488 newnames[0] = names[0];
1489 for (idx = nidx = 1; names[idx]; idx++)
1490 {
1491 if ((*name_func) (names[idx]))
1492 newnames[nidx++] = names[idx];
1493 else
Jari Aaltocce855b1998-04-17 19:52:44 +00001494#ifndef NO_FORCE_FIGNORE
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001495 free (names[idx]);
Jari Aaltocce855b1998-04-17 19:52:44 +00001496#else
1497 oldnames[oidx++] = names[idx];
1498#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001499 }
1500
1501 newnames[nidx] = (char *)NULL;
1502
1503 /* If none are acceptable then let the completer handle it. */
1504 if (nidx == 1)
1505 {
Jari Aaltocce855b1998-04-17 19:52:44 +00001506#ifndef NO_FORCE_FIGNORE
Jari Aalto726f6381996-08-26 18:22:31 +00001507 free (names[0]);
1508 names[0] = (char *)NULL;
Jari Aaltocce855b1998-04-17 19:52:44 +00001509#else
1510 free (oldnames);
1511#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001512 free (newnames);
1513 return;
1514 }
1515
Jari Aaltocce855b1998-04-17 19:52:44 +00001516#ifdef NO_FORCE_FIGNORE
1517 while (oidx)
1518 free (oldnames[--oidx]);
1519 free (oldnames);
1520#endif
1521
Jari Aalto726f6381996-08-26 18:22:31 +00001522 /* If only one is acceptable, copy it to names[0] and return. */
1523 if (nidx == 2)
1524 {
1525 free (names[0]);
1526 names[0] = newnames[1];
1527 names[1] = (char *)NULL;
1528 free (newnames);
1529 return;
1530 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001531
Jari Aalto726f6381996-08-26 18:22:31 +00001532 /* Copy the acceptable names back to NAMES, set the new array end,
1533 and return. */
1534 for (nidx = 1; newnames[nidx]; nidx++)
1535 names[nidx] = newnames[nidx];
1536 names[nidx] = (char *)NULL;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001537 free (newnames);
1538}
1539
1540static int
1541name_is_acceptable (name)
1542 char *name;
1543{
1544 struct ign *p;
1545 int nlen;
1546
1547 for (nlen = strlen (name), p = fignore.ignores; p->val; p++)
1548 {
1549 if (nlen > p->len && p->len > 0 && STREQ (p->val, &name[nlen - p->len]))
1550 return (0);
1551 }
1552
1553 return (1);
Jari Aalto726f6381996-08-26 18:22:31 +00001554}
1555
Jari Aaltob72432f1999-02-19 17:11:39 +00001556#if 0
1557static int
1558ignore_dot_names (name)
1559 char *name;
1560{
1561 return (name[0] != '.');
1562}
1563#endif
1564
Jari Aalto726f6381996-08-26 18:22:31 +00001565static void
1566filename_completion_ignore (names)
1567 char **names;
1568{
Jari Aaltob72432f1999-02-19 17:11:39 +00001569#if 0
1570 if (glob_dot_filenames == 0)
1571 _ignore_completion_names (names, ignore_dot_names);
1572#endif
1573
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001574 setup_ignore_patterns (&fignore);
Jari Aalto726f6381996-08-26 18:22:31 +00001575
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001576 if (fignore.num_ignores == 0)
Jari Aalto726f6381996-08-26 18:22:31 +00001577 return;
1578
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001579 _ignore_completion_names (names, name_is_acceptable);
Jari Aalto726f6381996-08-26 18:22:31 +00001580}
1581
1582/* Return 1 if NAME is a directory. */
1583static int
1584test_for_directory (name)
1585 char *name;
1586{
1587 struct stat finfo;
1588 char *fn;
1589
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001590 fn = bash_tilde_expand (name);
Jari Aalto726f6381996-08-26 18:22:31 +00001591 if (stat (fn, &finfo) != 0)
1592 {
1593 free (fn);
1594 return 0;
1595 }
1596 free (fn);
1597 return (S_ISDIR (finfo.st_mode));
1598}
1599
1600/* Remove files from NAMES, leaving directories. */
1601static void
1602bash_ignore_filenames (names)
1603 char **names;
1604{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001605 _ignore_completion_names (names, test_for_directory);
Jari Aalto726f6381996-08-26 18:22:31 +00001606}
1607
1608/* Handle symbolic link references and other directory name
1609 expansions while hacking completion. */
1610static int
1611bash_directory_completion_hook (dirname)
1612 char **dirname;
1613{
Jari Aaltob72432f1999-02-19 17:11:39 +00001614 char *local_dirname, *new_dirname, *t;
Jari Aalto726f6381996-08-26 18:22:31 +00001615 int return_value = 0;
1616 WORD_LIST *wl;
1617
1618 local_dirname = *dirname;
Jari Aaltob72432f1999-02-19 17:11:39 +00001619 new_dirname = savestring (local_dirname);
Jari Aalto726f6381996-08-26 18:22:31 +00001620 if (strchr (local_dirname, '$') || strchr (local_dirname, '`'))
1621 {
Jari Aaltob72432f1999-02-19 17:11:39 +00001622 wl = expand_string (new_dirname, 0);
Jari Aalto726f6381996-08-26 18:22:31 +00001623 if (wl)
1624 {
1625 *dirname = string_list (wl);
1626 /* Tell the completer to replace the directory name only if we
1627 actually expanded something. */
1628 return_value = STREQ (local_dirname, *dirname) == 0;
1629 free (local_dirname);
Jari Aaltob72432f1999-02-19 17:11:39 +00001630 free (new_dirname);
Jari Aalto726f6381996-08-26 18:22:31 +00001631 dispose_words (wl);
1632 local_dirname = *dirname;
1633 }
1634 else
1635 {
Jari Aaltob72432f1999-02-19 17:11:39 +00001636 free (new_dirname);
Jari Aalto726f6381996-08-26 18:22:31 +00001637 free (local_dirname);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001638 *dirname = xmalloc (1);
1639 **dirname = '\0';
Jari Aalto726f6381996-08-26 18:22:31 +00001640 return 1;
1641 }
1642 }
1643
1644 if (!no_symbolic_links && (local_dirname[0] != '.' || local_dirname[1]))
1645 {
1646 char *temp1, *temp2;
1647 int len1, len2;
1648
1649 t = get_working_directory ("symlink-hook");
1650 temp1 = make_absolute (local_dirname, t);
1651 free (t);
1652 temp2 = canonicalize_pathname (temp1);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001653 /* If we can't canonicalize, bail. */
1654 if (temp2 == 0)
1655 {
1656 free (temp1);
1657 return 1;
1658 }
Jari Aalto726f6381996-08-26 18:22:31 +00001659 len1 = strlen (temp1);
1660 if (temp1[len1 - 1] == '/')
1661 {
1662 len2 = strlen (temp2);
1663 temp2 = xrealloc (temp2, len2 + 2);
1664 temp2[len2] = '/';
1665 temp2[len2 + 1] = '\0';
1666 }
1667 free (local_dirname);
1668 *dirname = temp2;
1669 free (temp1);
1670 }
1671 return (return_value);
1672}
1673
Jari Aalto726f6381996-08-26 18:22:31 +00001674static char **history_completion_array = (char **)NULL;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001675static int harry_size;
1676static int harry_len;
Jari Aalto726f6381996-08-26 18:22:31 +00001677
1678static void
1679build_history_completion_array ()
1680{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001681 register int i, j;
1682 HIST_ENTRY **hlist;
1683 char **tokens;
Jari Aalto726f6381996-08-26 18:22:31 +00001684
1685 /* First, clear out the current dynamic history completion list. */
1686 if (harry_size)
1687 {
1688 for (i = 0; history_completion_array[i]; i++)
1689 free (history_completion_array[i]);
1690
1691 free (history_completion_array);
1692
1693 history_completion_array = (char **)NULL;
1694 harry_size = 0;
1695 harry_len = 0;
1696 }
1697
1698 /* Next, grovel each line of history, making each shell-sized token
1699 a separate entry in the history_completion_array. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001700 hlist = history_list ();
Jari Aalto726f6381996-08-26 18:22:31 +00001701
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001702 if (hlist)
1703 {
1704 for (i = 0; hlist[i]; i++)
1705 {
1706 /* Separate each token, and place into an array. */
1707 tokens = history_tokenize (hlist[i]->line);
Jari Aalto726f6381996-08-26 18:22:31 +00001708
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001709 for (j = 0; tokens && tokens[j]; j++)
1710 {
1711 if (harry_len + 2 > harry_size)
1712 {
1713 harry_size += 10;
Jari Aalto726f6381996-08-26 18:22:31 +00001714 history_completion_array = (char **) xrealloc
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001715 (history_completion_array, harry_size * sizeof (char *));
1716 }
Jari Aalto726f6381996-08-26 18:22:31 +00001717
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001718 history_completion_array[harry_len++] = tokens[j];
1719 history_completion_array[harry_len] = (char *)NULL;
1720 }
1721 free (tokens);
1722 }
Jari Aalto726f6381996-08-26 18:22:31 +00001723
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001724 /* Sort the complete list of tokens. */
1725 qsort (history_completion_array, harry_len, sizeof (char *), (Function *)qsort_string_compare);
1726 }
Jari Aalto726f6381996-08-26 18:22:31 +00001727}
1728
1729static char *
1730history_completion_generator (hint_text, state)
1731 char *hint_text;
1732 int state;
1733{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001734 static int local_index, len;
1735 static char *text;
Jari Aalto726f6381996-08-26 18:22:31 +00001736
1737 /* If this is the first call to the generator, then initialize the
1738 list of strings to complete over. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001739 if (state == 0)
Jari Aalto726f6381996-08-26 18:22:31 +00001740 {
1741 local_index = 0;
1742 build_history_completion_array ();
1743 text = hint_text;
1744 len = strlen (text);
1745 }
1746
1747 while (history_completion_array && history_completion_array[local_index])
1748 {
1749 if (strncmp (text, history_completion_array[local_index++], len) == 0)
1750 return (savestring (history_completion_array[local_index - 1]));
1751 }
1752 return ((char *)NULL);
1753}
1754
1755static void
1756dynamic_complete_history (count, key)
1757 int count, key;
1758{
1759 Function *orig_func;
1760 CPPFunction *orig_attempt_func;
1761
1762 orig_func = rl_completion_entry_function;
1763 orig_attempt_func = rl_attempted_completion_function;
1764 rl_completion_entry_function = (Function *)history_completion_generator;
1765 rl_attempted_completion_function = (CPPFunction *)NULL;
1766
1767 if (rl_last_func == (Function *)dynamic_complete_history)
1768 rl_complete_internal ('?');
1769 else
1770 rl_complete_internal (TAB);
1771
1772 rl_completion_entry_function = orig_func;
1773 rl_attempted_completion_function = orig_attempt_func;
1774}
1775
Jari Aalto726f6381996-08-26 18:22:31 +00001776#if defined (SPECIFIC_COMPLETION_FUNCTIONS)
1777static void
1778bash_complete_username (ignore, ignore2)
1779 int ignore, ignore2;
1780{
1781 bash_complete_username_internal (TAB);
1782}
1783
1784static void
1785bash_possible_username_completions (ignore, ignore2)
1786 int ignore, ignore2;
1787{
1788 bash_complete_username_internal ('?');
1789}
1790
1791static void
1792bash_complete_username_internal (what_to_do)
1793 int what_to_do;
1794{
1795 bash_specific_completion
1796 (what_to_do, (Function *)username_completion_function);
1797}
1798
1799static void
1800bash_complete_filename (ignore, ignore2)
1801 int ignore, ignore2;
1802{
1803 bash_complete_filename_internal (TAB);
1804}
1805
1806static void
1807bash_possible_filename_completions (ignore, ignore2)
1808 int ignore, ignore2;
1809{
1810 bash_complete_filename_internal ('?');
1811}
1812
1813static void
1814bash_complete_filename_internal (what_to_do)
1815 int what_to_do;
1816{
1817 Function *orig_func, *orig_dir_func;
1818 CPPFunction *orig_attempt_func;
1819 char *orig_rl_completer_word_break_characters;
1820
1821 orig_func = rl_completion_entry_function;
1822 orig_attempt_func = rl_attempted_completion_function;
1823 orig_dir_func = rl_directory_completion_hook;
1824 orig_rl_completer_word_break_characters = rl_completer_word_break_characters;
1825 rl_completion_entry_function = (Function *)filename_completion_function;
1826 rl_attempted_completion_function = (CPPFunction *)NULL;
1827 rl_directory_completion_hook = (Function *)NULL;
1828 rl_completer_word_break_characters = " \t\n\"\'";
1829
1830 rl_complete_internal (what_to_do);
1831
1832 rl_completion_entry_function = orig_func;
1833 rl_attempted_completion_function = orig_attempt_func;
1834 rl_directory_completion_hook = orig_dir_func;
1835 rl_completer_word_break_characters = orig_rl_completer_word_break_characters;
1836}
1837
1838static void
1839bash_complete_hostname (ignore, ignore2)
1840 int ignore, ignore2;
1841{
1842 bash_complete_hostname_internal (TAB);
1843}
1844
1845static void
1846bash_possible_hostname_completions (ignore, ignore2)
1847 int ignore, ignore2;
1848{
1849 bash_complete_hostname_internal ('?');
1850}
1851
1852static void
1853bash_complete_variable (ignore, ignore2)
1854 int ignore, ignore2;
1855{
1856 bash_complete_variable_internal (TAB);
1857}
1858
1859static void
1860bash_possible_variable_completions (ignore, ignore2)
1861 int ignore, ignore2;
1862{
1863 bash_complete_variable_internal ('?');
1864}
1865
1866static void
1867bash_complete_command (ignore, ignore2)
1868 int ignore, ignore2;
1869{
1870 bash_complete_command_internal (TAB);
1871}
1872
1873static void
1874bash_possible_command_completions (ignore, ignore2)
1875 int ignore, ignore2;
1876{
1877 bash_complete_command_internal ('?');
1878}
1879
1880static void
1881bash_complete_hostname_internal (what_to_do)
1882 int what_to_do;
1883{
1884 bash_specific_completion
1885 (what_to_do, (Function *)hostname_completion_function);
1886}
1887
1888static void
1889bash_complete_variable_internal (what_to_do)
1890 int what_to_do;
1891{
1892 bash_specific_completion
1893 (what_to_do, (Function *)variable_completion_function);
1894}
1895
1896static void
1897bash_complete_command_internal (what_to_do)
1898 int what_to_do;
1899{
1900 bash_specific_completion
1901 (what_to_do, (Function *)command_word_completion_function);
1902}
1903
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001904static char *
1905glob_complete_word (text, state)
1906 char *text;
1907 int state;
1908{
1909 static char **matches = (char **)NULL;
1910 static int ind;
1911 char *ret;
1912
1913 if (state == 0)
1914 {
Jari Aaltoe8ce7751997-09-22 20:22:27 +00001915 rl_filename_completion_desired = 1;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001916 if (matches)
1917 free (matches);
1918 matches = shell_glob_filename (text);
1919 if (GLOB_FAILED (matches))
1920 matches = (char **)NULL;
1921 ind = 0;
1922 }
1923
1924 ret = matches ? matches[ind] : (char *)NULL;
1925 ind++;
1926 return ret;
1927}
1928
1929static void
1930bash_glob_completion_internal (what_to_do)
1931 int what_to_do;
1932{
1933 bash_specific_completion (what_to_do, (Function *)glob_complete_word);
1934}
1935
1936static void
1937bash_glob_expand_word (count, key)
1938 int count, key;
1939{
1940 bash_glob_completion_internal ('*');
1941}
1942
1943static void
1944bash_glob_list_expansions (count, key)
1945 int count, key;
1946{
1947 bash_glob_completion_internal ('?');
1948}
1949
Jari Aalto726f6381996-08-26 18:22:31 +00001950static void
1951bash_specific_completion (what_to_do, generator)
1952 int what_to_do;
1953 Function *generator;
1954{
1955 Function *orig_func;
1956 CPPFunction *orig_attempt_func;
1957
1958 orig_func = rl_completion_entry_function;
1959 orig_attempt_func = rl_attempted_completion_function;
1960 rl_completion_entry_function = generator;
1961 rl_attempted_completion_function = (CPPFunction *)NULL;
1962
1963 rl_complete_internal (what_to_do);
1964
1965 rl_completion_entry_function = orig_func;
1966 rl_attempted_completion_function = orig_attempt_func;
1967}
1968
1969#endif /* SPECIFIC_COMPLETION_FUNCTIONS */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001970
1971/* Filename quoting for completion. */
1972/* A function to strip quotes that are not protected by backquotes. It
1973 allows single quotes to appear within double quotes, and vice versa.
1974 It should be smarter. */
1975static char *
1976bash_dequote_filename (text, quote_char)
1977 char *text;
1978{
1979 char *ret, *p, *r;
1980 int l, quoted;
1981
1982 l = strlen (text);
1983 ret = xmalloc (l + 1);
1984 for (quoted = quote_char, p = text, r = ret; p && *p; p++)
1985 {
1986 /* Allow backslash-quoted characters to pass through unscathed. */
1987 if (*p == '\\')
1988 {
1989 *r++ = *++p;
1990 if (*p == '\0')
1991 break;
1992 continue;
1993 }
1994 /* Close quote. */
1995 if (quoted && *p == quoted)
1996 {
1997 quoted = 0;
1998 continue;
1999 }
2000 /* Open quote. */
2001 if (quoted == 0 && (*p == '\'' || *p == '"'))
2002 {
2003 quoted = *p;
2004 continue;
2005 }
2006 *r++ = *p;
2007 }
2008 *r = '\0';
2009 return ret;
2010}
2011
Jari Aaltod166f041997-06-05 14:59:13 +00002012/* Quote characters that the readline completion code would treat as
2013 word break characters with backslashes. Pass backslash-quoted
2014 characters through without examination. */
2015static char *
2016quote_word_break_chars (text)
2017 char *text;
2018{
2019 char *ret, *r, *s;
2020 int l;
2021
2022 l = strlen (text);
2023 ret = xmalloc ((2 * l) + 1);
2024 for (s = text, r = ret; *s; s++)
2025 {
2026 /* Pass backslash-quoted characters through, including the backslash. */
2027 if (*s == '\\')
2028 {
2029 *r++ = '\\';
2030 *r++ = *++s;
2031 if (*s == '\0')
2032 break;
2033 continue;
2034 }
2035 /* OK, we have an unquoted character. Check its presence in
2036 rl_completer_word_break_characters. */
2037 if (strchr (rl_completer_word_break_characters, *s))
2038 *r++ = '\\';
2039 *r++ = *s;
2040 }
2041 *r = '\0';
2042 return ret;
2043}
2044
2045/* Quote a filename using double quotes, single quotes, or backslashes
2046 depending on the value of completion_quoting_style. If we're
2047 completing using backslashes, we need to quote some additional
2048 characters (those that readline treats as word breaks), so we call
2049 quote_word_break_chars on the result. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002050static char *
2051bash_quote_filename (s, rtype, qcp)
2052 char *s;
2053 int rtype;
2054 char *qcp;
2055{
2056 char *rtext, *mtext, *ret;
2057 int rlen, cs;
2058
2059 rtext = (char *)NULL;
2060
2061 /* If RTYPE == MULT_MATCH, it means that there is
2062 more than one match. In this case, we do not add
2063 the closing quote or attempt to perform tilde
2064 expansion. If RTYPE == SINGLE_MATCH, we try
2065 to perform tilde expansion, because single and double
2066 quotes inhibit tilde expansion by the shell. */
2067
2068 mtext = s;
2069 if (mtext[0] == '~' && rtype == SINGLE_MATCH)
2070 mtext = bash_tilde_expand (s);
2071
2072 cs = completion_quoting_style;
2073 /* Might need to modify the default completion style based on *qcp,
2074 since it's set to any user-provided opening quote. */
2075 if (*qcp == '"')
2076 cs = COMPLETE_DQUOTE;
2077 else if (*qcp == '\'')
2078 cs = COMPLETE_SQUOTE;
2079#if defined (BANG_HISTORY)
2080 else if (*qcp == '\0' && history_expansion && cs == COMPLETE_DQUOTE &&
2081 history_expansion_inhibited == 0 && strchr (mtext, '!'))
2082 cs = COMPLETE_BSQUOTE;
Jari Aaltod166f041997-06-05 14:59:13 +00002083
2084 if (*qcp == '"' && history_expansion && cs == COMPLETE_DQUOTE &&
2085 history_expansion_inhibited == 0 && strchr (mtext, '!'))
2086 {
2087 cs = COMPLETE_BSQUOTE;
2088 *qcp = '\0';
2089 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002090#endif
2091
2092 switch (cs)
2093 {
2094 case COMPLETE_DQUOTE:
2095 rtext = double_quote (mtext);
2096 break;
2097 case COMPLETE_SQUOTE:
2098 rtext = single_quote (mtext);
2099 break;
2100 case COMPLETE_BSQUOTE:
2101 rtext = backslash_quote (mtext);
2102 break;
2103 }
2104
2105 if (mtext != s)
2106 free (mtext);
2107
Jari Aaltod166f041997-06-05 14:59:13 +00002108 /* We may need to quote additional characters: those that readline treats
2109 as word breaks that are not quoted by backslash_quote. */
2110 if (rtext && cs == COMPLETE_BSQUOTE)
2111 {
2112 mtext = quote_word_break_chars (rtext);
2113 free (rtext);
2114 rtext = mtext;
2115 }
2116
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002117 /* Leave the opening quote intact. The readline completion code takes
2118 care of avoiding doubled opening quotes. */
2119 rlen = strlen (rtext);
2120 ret = xmalloc (rlen + 1);
2121 strcpy (ret, rtext);
2122
2123 /* If there are multiple matches, cut off the closing quote. */
2124 if (rtype == MULT_MATCH && cs != COMPLETE_BSQUOTE)
2125 ret[rlen - 1] = '\0';
2126 free (rtext);
2127 return ret;
2128}
2129
2130#endif /* READLINE */