]> git.ipfire.org Git - thirdparty/bash.git/blame - bashline.c
Imported from ../bash-2.02.1.tar.gz.
[thirdparty/bash.git] / bashline.c
CommitLineData
726f6388
JA
1/* 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
ccc6cda3
JA
21#include "config.h"
22
23#if defined (READLINE)
24
726f6388
JA
25#include "bashtypes.h"
26#include "posixstat.h"
27
ccc6cda3
JA
28#if defined (HAVE_UNISTD_H)
29# include <unistd.h>
30#endif
31
726f6388
JA
32#include <stdio.h>
33#include "bashansi.h"
726f6388
JA
34#include "shell.h"
35#include "builtins.h"
726f6388 36#include "bashhist.h"
ccc6cda3 37#include "bashline.h"
726f6388 38#include "execute_cmd.h"
cce855bc 39#include "findcmd.h"
ccc6cda3
JA
40#include "pathexp.h"
41#include "builtins/common.h"
42#include <readline/rlconf.h>
43#include <readline/readline.h>
44#include <readline/history.h>
45
46#include <glob/glob.h>
726f6388
JA
47
48#if defined (ALIAS)
49# include "alias.h"
50#endif
51
726f6388
JA
52#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 ();
cce855bc
JA
59static void bash_ignore_filenames ();
60static void cleanup_expansion_error (), set_up_new_line ();
61
62#if defined (BANG_HISTORY)
63static int history_expand_line ();
64static int tcsh_magic_space ();
65#endif /* BANG_HISTORY */
d166f048 66#ifdef ALIAS
cce855bc
JA
67static int alias_expand_line ();
68#endif
69#if defined (BANG_HISTORY) && defined (ALIAS)
70static int history_and_alias_expand_line ();
d166f048 71#endif
726f6388
JA
72
73/* 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 ();
ccc6cda3
JA
83static void dynamic_complete_history ();
84
85static char *glob_complete_word ();
86static void bash_glob_expand_word ();
87static void bash_glob_list_expansions ();
726f6388
JA
88
89static void snarf_hosts_from_file (), add_host_name ();
726f6388 90
ccc6cda3
JA
91static char *bash_dequote_filename ();
92static char *bash_quote_filename ();
93
94#if defined (ALIAS)
95static int posix_edit_macros ();
96#endif
726f6388
JA
97
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
ccc6cda3
JA
106/* Helper functions from subst.c */
107extern int char_is_quoted ();
108extern int unclosed_pair ();
109
726f6388
JA
110/* 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)
ccc6cda3
JA
117static 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 ();
726f6388
JA
128#endif /* SPECIFIC_COMPLETION_FUNCTIONS */
129
726f6388
JA
130#if defined (VI_MODE)
131static void vi_edit_and_execute_command ();
726f6388
JA
132#endif
133
ccc6cda3
JA
134/* Non-zero once initalize_readline () has been called. */
135int bash_readline_initialized = 0;
136
137/* 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\"'><=;|&(:";
144
726f6388
JA
145static Function *old_rl_startup_hook = (Function *) NULL;
146
ccc6cda3
JA
147/* 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
726f6388
JA
157/* 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{
ccc6cda3
JA
163 if (on_or_off)
164 rl_variable_bind ("comment-begin", "#");
726f6388 165#if defined (VI_MODE)
ccc6cda3
JA
166 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{
726f6388
JA
174 if (on_or_off)
175 {
ccc6cda3
JA
176 perform_hostname_completion = 1;
177 rl_special_prefixes = "$@";
178 rl_completer_word_break_characters = bash_completer_word_break_characters;
726f6388
JA
179 }
180 else
ccc6cda3
JA
181 {
182 perform_hostname_completion = 0;
183 rl_special_prefixes = "$";
184 rl_completer_word_break_characters = bash_nohostname_word_break_characters;
185 }
186}
726f6388
JA
187
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;
726f6388
JA
198
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);
ccc6cda3 204 rl_bind_key_in_map (CTRL('E'), (Function *)shell_expand_line, emacs_meta_keymap);
726f6388
JA
205
206 /* Bind up our special shell functions. */
cce855bc 207#ifdef BANG_HISTORY
726f6388
JA
208 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
cce855bc
JA
211 rl_add_defun ("magic-space", (Function *)tcsh_magic_space, -1);
212#endif
213
d166f048
JA
214#ifdef ALIAS
215 rl_add_defun ("alias-expand-line", (Function *)alias_expand_line, -1);
bc4cd23c 216# ifdef BANG_HISTORY
d166f048 217 rl_add_defun ("history-and-alias-expand-line", (Function *)history_and_alias_expand_line, -1);
bc4cd23c 218# endif
d166f048
JA
219#endif
220
726f6388
JA
221 /* 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);
726f6388
JA
229 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
ccc6cda3 240
726f6388
JA
241#if defined (BRACE_COMPLETION)
242 rl_add_defun ("complete-into-braces", bash_brace_completion, -1);
243 rl_bind_key_in_map ('{', bash_brace_completion, emacs_meta_keymap);
244#endif /* BRACE_COMPLETION */
245
246#if defined (SPECIFIC_COMPLETION_FUNCTIONS)
247 rl_add_defun ("complete-filename", bash_complete_filename, -1);
248 rl_bind_key_in_map ('/', bash_complete_filename, emacs_meta_keymap);
249 rl_add_defun ("possible-filename-completions",
250 bash_possible_filename_completions, -1);
ccc6cda3 251 rl_bind_key_in_map ('/', bash_possible_filename_completions, emacs_ctlx_keymap);
726f6388
JA
252
253 rl_add_defun ("complete-username", bash_complete_username, -1);
254 rl_bind_key_in_map ('~', bash_complete_username, emacs_meta_keymap);
255 rl_add_defun ("possible-username-completions",
256 bash_possible_username_completions, -1);
ccc6cda3 257 rl_bind_key_in_map ('~', bash_possible_username_completions, emacs_ctlx_keymap);
726f6388
JA
258
259 rl_add_defun ("complete-hostname", bash_complete_hostname, -1);
260 rl_bind_key_in_map ('@', bash_complete_hostname, emacs_meta_keymap);
261 rl_add_defun ("possible-hostname-completions",
262 bash_possible_hostname_completions, -1);
ccc6cda3 263 rl_bind_key_in_map ('@', bash_possible_hostname_completions, emacs_ctlx_keymap);
726f6388
JA
264
265 rl_add_defun ("complete-variable", bash_complete_variable, -1);
266 rl_bind_key_in_map ('$', bash_complete_variable, emacs_meta_keymap);
267 rl_add_defun ("possible-variable-completions",
268 bash_possible_variable_completions, -1);
ccc6cda3 269 rl_bind_key_in_map ('$', bash_possible_variable_completions, emacs_ctlx_keymap);
726f6388
JA
270
271 rl_add_defun ("complete-command", bash_complete_command, -1);
272 rl_bind_key_in_map ('!', bash_complete_command, emacs_meta_keymap);
273 rl_add_defun ("possible-command-completions",
274 bash_possible_command_completions, -1);
ccc6cda3
JA
275 rl_bind_key_in_map ('!', bash_possible_command_completions, emacs_ctlx_keymap);
276
277 rl_add_defun ("glob-expand-word", bash_glob_expand_word, -1);
278 rl_add_defun ("glob-list-expansions", bash_glob_list_expansions, -1);
279 rl_bind_key_in_map ('*', bash_glob_expand_word, emacs_ctlx_keymap);
280 rl_bind_key_in_map ('g', bash_glob_list_expansions, emacs_ctlx_keymap);
726f6388
JA
281
282#endif /* SPECIFIC_COMPLETION_FUNCTIONS */
283
726f6388
JA
284 rl_add_defun ("dynamic-complete-history", dynamic_complete_history, -1);
285 rl_bind_key_in_map (TAB, dynamic_complete_history, emacs_meta_keymap);
726f6388
JA
286
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)
298 rl_bind_key_in_map ('v', vi_edit_and_execute_command, vi_movement_keymap);
ccc6cda3
JA
299# if defined (ALIAS)
300 rl_bind_key_in_map ('@', posix_edit_macros, vi_movement_keymap);
301# endif
726f6388
JA
302#endif
303
304 rl_completer_quote_characters = "'\"";
ccc6cda3
JA
305
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. */
d166f048 312 rl_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:";
ccc6cda3
JA
313 rl_filename_quoting_function = bash_quote_filename;
314 rl_filename_dequoting_function = bash_dequote_filename;
315 rl_char_is_quoted_p = char_is_quoted;
726f6388
JA
316
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{
ccc6cda3 361 FREE (push_to_readline);
726f6388
JA
362
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 ();
ccc6cda3 375 show_shell_version (0);
726f6388
JA
376 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. */
726f6388
JA
390
391/* The kept list of hostnames. */
392static char **hostname_list = (char **)NULL;
393
394/* The physical size of the above list. */
ccc6cda3 395static int hostname_list_size;
726f6388 396
ccc6cda3
JA
397/* The number of hostnames in the above list. */
398static int hostname_list_length;
726f6388
JA
399
400/* Whether or not HOSTNAME_LIST has been initialized. */
401int hostname_list_initialized = 0;
402
726f6388
JA
403/* Initialize the hostname completion table. */
404static void
405initialize_hostname_list ()
406{
407 char *temp;
408
409 temp = get_string_value ("HOSTFILE");
ccc6cda3 410 if (temp == 0)
726f6388 411 temp = get_string_value ("hostname_completion_file");
ccc6cda3
JA
412 if (temp == 0)
413 temp = DEFAULT_HOSTS_FILE;
726f6388
JA
414
415 snarf_hosts_from_file (temp);
726f6388
JA
416
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{
ccc6cda3
JA
426 long size;
427
726f6388
JA
428 if (hostname_list_length + 2 > hostname_list_size)
429 {
ccc6cda3
JA
430 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);
726f6388
JA
433 }
434
ccc6cda3
JA
435 hostname_list[hostname_list_length++] = savestring (name);
436 hostname_list[hostname_list_length] = (char *)NULL;
726f6388
JA
437}
438
439#define cr_whitespace(c) ((c) == '\r' || (c) == '\n' || whitespace(c))
440
441static void
442snarf_hosts_from_file (filename)
443 char *filename;
444{
ccc6cda3 445 FILE *file;
726f6388
JA
446 char *temp, buffer[256], name[256];
447 register int i, start;
448
ccc6cda3
JA
449 file = fopen (filename, "r");
450 if (file == 0)
726f6388
JA
451 return;
452
453 while (temp = fgets (buffer, 255, file))
454 {
455 /* Skip to first character. */
ccc6cda3
JA
456 for (i = 0; buffer[i] && cr_whitespace (buffer[i]); i++)
457 ;
726f6388 458
ccc6cda3
JA
459 /* If comment or blank line, ignore. */
460 if (buffer[i] == '\0' || buffer[i] == '#')
726f6388
JA
461 continue;
462
463 /* If `preprocessor' directive, do the include. */
ccc6cda3 464 if (strncmp (buffer + i, "$include ", 9) == 0)
726f6388 465 {
ccc6cda3 466 char *incfile, *t;
726f6388
JA
467
468 /* Find start of filename. */
ccc6cda3
JA
469 for (incfile = buffer + i + 9; *incfile && whitespace (*incfile); incfile++)
470 ;
726f6388
JA
471
472 /* Find end of filename. */
ccc6cda3
JA
473 for (t = incfile; *t && cr_whitespace (*t) == 0; t++)
474 ;
726f6388
JA
475
476 *t = '\0';
477
ccc6cda3 478 snarf_hosts_from_file (incfile);
726f6388
JA
479 continue;
480 }
481
ccc6cda3
JA
482 /* Skip internet address if present. */
483 if (digit (buffer[i]))
484 for (; buffer[i] && cr_whitespace (buffer[i]) == 0; i++);
726f6388
JA
485
486 /* Gobble up names. Each name is separated with whitespace. */
ccc6cda3 487 while (buffer[i])
726f6388 488 {
ccc6cda3
JA
489 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)
726f6388
JA
498 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{
ccc6cda3
JA
514 register int i, len, nmatch, rsize;
515 char **result;
726f6388 516
ccc6cda3
JA
517 if (hostname_list_initialized == 0)
518 initialize_hostname_list ();
726f6388 519
ccc6cda3
JA
520 if (hostname_list_initialized == 0)
521 return ((char **)NULL);
726f6388
JA
522
523 /* Special case. If TEXT consists of nothing, then the whole list is
524 what is desired. */
ccc6cda3 525 if (*text == '\0')
726f6388
JA
526 {
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. */
ccc6cda3
JA
535 len = strlen (text);
536 result = (char **)NULL;
537 for (i = nmatch = rsize = 0; i < hostname_list_length; i++)
726f6388 538 {
ccc6cda3
JA
539 if (STREQN (text, hostname_list[i], len) == 0)
540 continue;
726f6388 541
ccc6cda3 542 /* OK, it matches. Add it to the list. */
bc4cd23c 543 if (nmatch >= (rsize - 1))
726f6388 544 {
ccc6cda3
JA
545 rsize = (rsize + 16) - (rsize % 16);
546 result = (char **)xrealloc (result, rsize * sizeof (char *));
726f6388
JA
547 }
548
ccc6cda3 549 result[nmatch++] = hostname_list[i];
726f6388 550 }
ccc6cda3
JA
551 if (nmatch)
552 result[nmatch] = (char *)NULL;
553 return (result);
726f6388
JA
554}
555
ccc6cda3 556/* The equivalent of the Korn shell C-o operate-and-get-next-history-line
726f6388 557 editing command. */
ccc6cda3 558static int saved_history_line_to_use = -1;
726f6388
JA
559
560static void
561set_saved_history ()
562{
ccc6cda3 563 if (saved_history_line_to_use >= 0)
726f6388 564 rl_get_previous_history (history_length - saved_history_line_to_use);
ccc6cda3 565 saved_history_line_to_use = -1;
726f6388 566 rl_startup_hook = old_rl_startup_hook;
ccc6cda3 567}
726f6388
JA
568
569static void
570operate_and_get_next (count, c)
571 int count, c;
572{
573 int where;
574
575 /* Accept the current line. */
ccc6cda3 576 rl_newline ();
726f6388
JA
577
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)
ccc6cda3 600 int count, c;
726f6388
JA
601{
602 char *command;
603
604 /* Accept the current line. */
ccc6cda3 605 rl_newline ();
726f6388
JA
606
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 ();
d166f048
JA
619 bash_add_history (rl_line_buffer);
620 bash_add_history ("");
726f6388
JA
621 history_lines_this_session++;
622 using_history ();
623 command = savestring (VI_EDIT_COMMAND);
624 }
d166f048 625 parse_and_execute (command, "v", SEVAL_NOHIST);
ccc6cda3 626 rl_line_buffer[0] = '\0'; /* XXX */
726f6388
JA
627}
628#endif /* VI_MODE */
629
ccc6cda3
JA
630#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
726f6388
JA
653/* **************************************************************** */
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;
ccc6cda3 667 char **matches, *command_separator_chars;
726f6388 668
ccc6cda3
JA
669 command_separator_chars = ";|&{(`";
670 matches = (char **)NULL;
671 rl_ignore_some_completions_function = (Function *)filename_completion_ignore;
726f6388
JA
672
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;
ccc6cda3
JA
704 else if ((this_char == '{' && prev_char == '$') ||
705 (char_is_quoted (rl_line_buffer, ti)))
726f6388
JA
706 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
d166f048
JA
715 /* Check that we haven't incorrectly flagged a closed command substitution
716 as indicating we're in a command position. */
e8ce775d
JA
717 if (in_command_position && ti >= 0 && rl_line_buffer[ti] == '`' &&
718 *text != '`' && unclosed_pair (rl_line_buffer, 0, "`") == 0)
d166f048
JA
719 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, "`"))
726f6388
JA
727 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. */
ccc6cda3 740 if (!matches && perform_hostname_completion && *text == '@')
726f6388
JA
741 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
ccc6cda3
JA
758 /* This could be a globbing pattern, so try to expand it using pathname
759 expansion. */
760 if (!matches && glob_pattern_p (text))
e8ce775d
JA
761 {
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 }
ccc6cda3 771
726f6388
JA
772 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)
ccc6cda3 792 static alias_t **alias_list = (alias_t **)NULL;
726f6388
JA
793#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. */
726f6388
JA
797 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 == '~')
ccc6cda3 814 hint = bash_tilde_expand (hint_text);
726f6388
JA
815 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
ccc6cda3 918 /* Repeatedly call filename_completion_function while we have
726f6388
JA
919 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
ccc6cda3 945 t = bash_tilde_expand (current_path);
726f6388
JA
946 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
ccc6cda3 963 if (val == 0)
726f6388
JA
964 {
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 {
d166f048 974 int match, freetemp;
726f6388
JA
975 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);
d166f048 994 freetemp = 1;
726f6388
JA
995 }
996 else
997 {
998 temp = strrchr (val, '/');
999
1000 if (temp)
1001 {
1002 temp++;
d166f048 1003 freetemp = match = strncmp (temp, hint, hint_len) == 0;
726f6388
JA
1004 if (match)
1005 temp = savestring (temp);
1006 }
1007 else
d166f048 1008 freetemp = match = 0;
726f6388
JA
1009 }
1010
ccc6cda3
JA
1011 /* 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)))
726f6388
JA
1014 {
1015 free (val);
1016 val = ""; /* So it won't be NULL. */
1017 return (temp);
1018 }
1019 else
1020 {
d166f048
JA
1021 if (freetemp)
1022 free (temp);
726f6388
JA
1023 free (val);
1024 goto inner;
1025 }
1026 }
1027}
1028
d166f048 1029/* Completion inside an unterminated command substitution. */
726f6388
JA
1030static char *
1031command_subst_completion_function (text, state)
726f6388 1032 char *text;
ccc6cda3 1033 int state;
726f6388
JA
1034{
1035 static char **matches = (char **)NULL;
1036 static char *orig_start, *filename_text = (char *)NULL;
1037 static int cmd_index, start_len;
ccc6cda3 1038 char *value;
726f6388
JA
1039
1040 if (state == 0)
1041 {
1042 if (filename_text)
1043 free (filename_text);
1044 orig_start = text;
1045 if (*text == '`')
1046 text++;
cce855bc 1047 else if (*text == '$' && text[1] == '(') /* ) */
726f6388
JA
1048 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 {
726f6388
JA
1064 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
ccc6cda3
JA
1102 if (text[first_char_loc] == '{')
1103 first_char_loc++;
1104
726f6388
JA
1105 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 {
ccc6cda3 1131 char *value = xmalloc (4 + strlen (var->name));
726f6388
JA
1132
1133 if (first_char_loc)
ccc6cda3
JA
1134 {
1135 value[0] = first_char;
1136 if (first_char_loc == 2)
1137 value[1] = '{';
1138 }
726f6388
JA
1139
1140 strcpy (&value[first_char_loc], var->name);
ccc6cda3
JA
1141 if (first_char_loc == 2)
1142 strcat (value, "}");
726f6388
JA
1143
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. */
ccc6cda3 1160 if (state == 0)
726f6388 1161 {
ccc6cda3 1162 FREE (list);
726f6388
JA
1163
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 {
ccc6cda3 1178 char *t;
726f6388 1179
ccc6cda3 1180 t = xmalloc (2 + strlen (list[list_index]));
726f6388
JA
1181 *t = first_char;
1182 strcpy (t + first_char_loc, list[list_index]);
1183 list_index++;
1184 return (t);
1185 }
ccc6cda3
JA
1186
1187 return ((char *)NULL);
726f6388
JA
1188}
1189
cce855bc
JA
1190/* 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. */
726f6388
JA
1196static char *
1197history_expand_line_internal (line)
1198 char *line;
1199{
1200 char *new_line;
1201
1202 new_line = pre_process_line (line, 0, 0);
d166f048 1203 return (new_line == line) ? savestring (line) : new_line;
726f6388 1204}
726f6388
JA
1205#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);
d166f048
JA
1216 if (to_free != rl_line_buffer)
1217 free (to_free);
726f6388
JA
1218 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]))
1261 rl_forward_word (1);
1262 }
1263}
1264
cce855bc
JA
1265#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)
726f6388 1289/* History expand the line. */
cce855bc 1290static int
726f6388
JA
1291history_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)
cce855bc
JA
1299 {
1300 set_up_new_line (new_line);
1301 return (0);
1302 }
726f6388 1303 else
cce855bc
JA
1304 {
1305 cleanup_expansion_error ();
1306 return (1);
1307 }
1308}
1309
1310/* 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);
726f6388 1323}
cce855bc 1324#endif
ccc6cda3 1325
726f6388 1326/* History and alias expand the line. */
cce855bc 1327static int
726f6388
JA
1328history_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);
d166f048
JA
1334 if (new_line == rl_line_buffer)
1335 new_line = savestring (new_line);
726f6388
JA
1336
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)
cce855bc
JA
1349 {
1350 set_up_new_line (new_line);
1351 return (0);
1352 }
726f6388 1353 else
cce855bc
JA
1354 {
1355 cleanup_expansion_error ();
1356 return (1);
1357 }
726f6388
JA
1358}
1359
1360/* History and alias expand the line, then perform the shell word
cce855bc
JA
1361 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. */
726f6388
JA
1364static void
1365shell_expand_line (ignore)
1366 int ignore;
1367{
1368 char *new_line;
ccc6cda3 1369 WORD_LIST *expanded_string;
726f6388
JA
1370
1371 new_line = pre_process_line (rl_line_buffer, 0, 0);
d166f048
JA
1372 if (new_line == rl_line_buffer)
1373 new_line = savestring (new_line);
726f6388
JA
1374
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. */
d166f048
JA
1398 new_line = savestring (rl_line_buffer);
1399 expanded_string = expand_string (new_line, 0);
1400 FREE (new_line);
ccc6cda3
JA
1401 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 }
726f6388 1411
ccc6cda3
JA
1412 maybe_make_readline_line (new_line);
1413 free (new_line);
726f6388 1414
ccc6cda3
JA
1415 /* 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]))
1422 rl_forward_word (1);
1423 }
726f6388
JA
1424 }
1425 else
1426 cleanup_expansion_error ();
1427}
1428
cce855bc
JA
1429/* 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
ccc6cda3
JA
1433/* 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
726f6388
JA
1435 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"
ccc6cda3 1439 completion types, such as hostnames or commands. */
726f6388 1440
ccc6cda3 1441static struct ignorevar fignore =
726f6388 1442{
ccc6cda3
JA
1443 "FIGNORE",
1444 (struct ign *)0,
1445 0,
1446 (char *)0,
1447 (Function *) 0,
1448};
726f6388 1449
726f6388 1450static void
ccc6cda3 1451_ignore_completion_names (names, name_func)
726f6388
JA
1452 char **names;
1453 Function *name_func;
1454{
1455 char **newnames;
1456 int idx, nidx;
cce855bc
JA
1457#ifdef NO_FORCE_FIGNORE
1458 char **oldnames;
1459 int oidx;
1460#endif
726f6388
JA
1461
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 {
cce855bc 1468#ifndef NO_FORCE_FIGNORE
726f6388
JA
1469 if ((*name_func) (names[0]) == 0)
1470 {
1471 free (names[0]);
1472 names[0] = (char *)NULL;
1473 }
cce855bc 1474#endif
726f6388
JA
1475 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 *)));
cce855bc
JA
1483#ifdef NO_FORCE_FIGNORE
1484 oldnames = (char **)xmalloc ((nidx - 1) * (sizeof (char *)));
1485 oidx = 0;
1486#endif
726f6388
JA
1487
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
cce855bc 1494#ifndef NO_FORCE_FIGNORE
ccc6cda3 1495 free (names[idx]);
cce855bc
JA
1496#else
1497 oldnames[oidx++] = names[idx];
1498#endif
726f6388
JA
1499 }
1500
1501 newnames[nidx] = (char *)NULL;
1502
1503 /* If none are acceptable then let the completer handle it. */
1504 if (nidx == 1)
1505 {
cce855bc 1506#ifndef NO_FORCE_FIGNORE
726f6388
JA
1507 free (names[0]);
1508 names[0] = (char *)NULL;
cce855bc
JA
1509#else
1510 free (oldnames);
1511#endif
726f6388
JA
1512 free (newnames);
1513 return;
1514 }
1515
cce855bc
JA
1516#ifdef NO_FORCE_FIGNORE
1517 while (oidx)
1518 free (oldnames[--oidx]);
1519 free (oldnames);
1520#endif
1521
726f6388
JA
1522 /* 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 }
ccc6cda3 1531
726f6388
JA
1532 /* 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;
ccc6cda3
JA
1537 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);
726f6388
JA
1554}
1555
1556static void
1557filename_completion_ignore (names)
1558 char **names;
1559{
ccc6cda3 1560 setup_ignore_patterns (&fignore);
726f6388 1561
ccc6cda3 1562 if (fignore.num_ignores == 0)
726f6388
JA
1563 return;
1564
ccc6cda3 1565 _ignore_completion_names (names, name_is_acceptable);
726f6388
JA
1566}
1567
1568/* Return 1 if NAME is a directory. */
1569static int
1570test_for_directory (name)
1571 char *name;
1572{
1573 struct stat finfo;
1574 char *fn;
1575
ccc6cda3 1576 fn = bash_tilde_expand (name);
726f6388
JA
1577 if (stat (fn, &finfo) != 0)
1578 {
1579 free (fn);
1580 return 0;
1581 }
1582 free (fn);
1583 return (S_ISDIR (finfo.st_mode));
1584}
1585
1586/* Remove files from NAMES, leaving directories. */
1587static void
1588bash_ignore_filenames (names)
1589 char **names;
1590{
ccc6cda3 1591 _ignore_completion_names (names, test_for_directory);
726f6388
JA
1592}
1593
1594/* Handle symbolic link references and other directory name
1595 expansions while hacking completion. */
1596static int
1597bash_directory_completion_hook (dirname)
1598 char **dirname;
1599{
1600 char *local_dirname, *t;
1601 int return_value = 0;
1602 WORD_LIST *wl;
1603
1604 local_dirname = *dirname;
1605 if (strchr (local_dirname, '$') || strchr (local_dirname, '`'))
1606 {
1607 wl = expand_string (local_dirname, 0);
1608 if (wl)
1609 {
1610 *dirname = string_list (wl);
1611 /* Tell the completer to replace the directory name only if we
1612 actually expanded something. */
1613 return_value = STREQ (local_dirname, *dirname) == 0;
1614 free (local_dirname);
1615 dispose_words (wl);
1616 local_dirname = *dirname;
1617 }
1618 else
1619 {
1620 free (local_dirname);
ccc6cda3
JA
1621 *dirname = xmalloc (1);
1622 **dirname = '\0';
726f6388
JA
1623 return 1;
1624 }
1625 }
1626
1627 if (!no_symbolic_links && (local_dirname[0] != '.' || local_dirname[1]))
1628 {
1629 char *temp1, *temp2;
1630 int len1, len2;
1631
1632 t = get_working_directory ("symlink-hook");
1633 temp1 = make_absolute (local_dirname, t);
1634 free (t);
1635 temp2 = canonicalize_pathname (temp1);
ccc6cda3
JA
1636 /* If we can't canonicalize, bail. */
1637 if (temp2 == 0)
1638 {
1639 free (temp1);
1640 return 1;
1641 }
726f6388
JA
1642 len1 = strlen (temp1);
1643 if (temp1[len1 - 1] == '/')
1644 {
1645 len2 = strlen (temp2);
1646 temp2 = xrealloc (temp2, len2 + 2);
1647 temp2[len2] = '/';
1648 temp2[len2 + 1] = '\0';
1649 }
1650 free (local_dirname);
1651 *dirname = temp2;
1652 free (temp1);
1653 }
1654 return (return_value);
1655}
1656
726f6388 1657static char **history_completion_array = (char **)NULL;
ccc6cda3
JA
1658static int harry_size;
1659static int harry_len;
726f6388
JA
1660
1661static void
1662build_history_completion_array ()
1663{
ccc6cda3
JA
1664 register int i, j;
1665 HIST_ENTRY **hlist;
1666 char **tokens;
726f6388
JA
1667
1668 /* First, clear out the current dynamic history completion list. */
1669 if (harry_size)
1670 {
1671 for (i = 0; history_completion_array[i]; i++)
1672 free (history_completion_array[i]);
1673
1674 free (history_completion_array);
1675
1676 history_completion_array = (char **)NULL;
1677 harry_size = 0;
1678 harry_len = 0;
1679 }
1680
1681 /* Next, grovel each line of history, making each shell-sized token
1682 a separate entry in the history_completion_array. */
ccc6cda3 1683 hlist = history_list ();
726f6388 1684
ccc6cda3
JA
1685 if (hlist)
1686 {
1687 for (i = 0; hlist[i]; i++)
1688 {
1689 /* Separate each token, and place into an array. */
1690 tokens = history_tokenize (hlist[i]->line);
726f6388 1691
ccc6cda3
JA
1692 for (j = 0; tokens && tokens[j]; j++)
1693 {
1694 if (harry_len + 2 > harry_size)
1695 {
1696 harry_size += 10;
726f6388 1697 history_completion_array = (char **) xrealloc
ccc6cda3
JA
1698 (history_completion_array, harry_size * sizeof (char *));
1699 }
726f6388 1700
ccc6cda3
JA
1701 history_completion_array[harry_len++] = tokens[j];
1702 history_completion_array[harry_len] = (char *)NULL;
1703 }
1704 free (tokens);
1705 }
726f6388 1706
ccc6cda3
JA
1707 /* Sort the complete list of tokens. */
1708 qsort (history_completion_array, harry_len, sizeof (char *), (Function *)qsort_string_compare);
1709 }
726f6388
JA
1710}
1711
1712static char *
1713history_completion_generator (hint_text, state)
1714 char *hint_text;
1715 int state;
1716{
ccc6cda3
JA
1717 static int local_index, len;
1718 static char *text;
726f6388
JA
1719
1720 /* If this is the first call to the generator, then initialize the
1721 list of strings to complete over. */
ccc6cda3 1722 if (state == 0)
726f6388
JA
1723 {
1724 local_index = 0;
1725 build_history_completion_array ();
1726 text = hint_text;
1727 len = strlen (text);
1728 }
1729
1730 while (history_completion_array && history_completion_array[local_index])
1731 {
1732 if (strncmp (text, history_completion_array[local_index++], len) == 0)
1733 return (savestring (history_completion_array[local_index - 1]));
1734 }
1735 return ((char *)NULL);
1736}
1737
1738static void
1739dynamic_complete_history (count, key)
1740 int count, key;
1741{
1742 Function *orig_func;
1743 CPPFunction *orig_attempt_func;
1744
1745 orig_func = rl_completion_entry_function;
1746 orig_attempt_func = rl_attempted_completion_function;
1747 rl_completion_entry_function = (Function *)history_completion_generator;
1748 rl_attempted_completion_function = (CPPFunction *)NULL;
1749
1750 if (rl_last_func == (Function *)dynamic_complete_history)
1751 rl_complete_internal ('?');
1752 else
1753 rl_complete_internal (TAB);
1754
1755 rl_completion_entry_function = orig_func;
1756 rl_attempted_completion_function = orig_attempt_func;
1757}
1758
726f6388
JA
1759#if defined (SPECIFIC_COMPLETION_FUNCTIONS)
1760static void
1761bash_complete_username (ignore, ignore2)
1762 int ignore, ignore2;
1763{
1764 bash_complete_username_internal (TAB);
1765}
1766
1767static void
1768bash_possible_username_completions (ignore, ignore2)
1769 int ignore, ignore2;
1770{
1771 bash_complete_username_internal ('?');
1772}
1773
1774static void
1775bash_complete_username_internal (what_to_do)
1776 int what_to_do;
1777{
1778 bash_specific_completion
1779 (what_to_do, (Function *)username_completion_function);
1780}
1781
1782static void
1783bash_complete_filename (ignore, ignore2)
1784 int ignore, ignore2;
1785{
1786 bash_complete_filename_internal (TAB);
1787}
1788
1789static void
1790bash_possible_filename_completions (ignore, ignore2)
1791 int ignore, ignore2;
1792{
1793 bash_complete_filename_internal ('?');
1794}
1795
1796static void
1797bash_complete_filename_internal (what_to_do)
1798 int what_to_do;
1799{
1800 Function *orig_func, *orig_dir_func;
1801 CPPFunction *orig_attempt_func;
1802 char *orig_rl_completer_word_break_characters;
1803
1804 orig_func = rl_completion_entry_function;
1805 orig_attempt_func = rl_attempted_completion_function;
1806 orig_dir_func = rl_directory_completion_hook;
1807 orig_rl_completer_word_break_characters = rl_completer_word_break_characters;
1808 rl_completion_entry_function = (Function *)filename_completion_function;
1809 rl_attempted_completion_function = (CPPFunction *)NULL;
1810 rl_directory_completion_hook = (Function *)NULL;
1811 rl_completer_word_break_characters = " \t\n\"\'";
1812
1813 rl_complete_internal (what_to_do);
1814
1815 rl_completion_entry_function = orig_func;
1816 rl_attempted_completion_function = orig_attempt_func;
1817 rl_directory_completion_hook = orig_dir_func;
1818 rl_completer_word_break_characters = orig_rl_completer_word_break_characters;
1819}
1820
1821static void
1822bash_complete_hostname (ignore, ignore2)
1823 int ignore, ignore2;
1824{
1825 bash_complete_hostname_internal (TAB);
1826}
1827
1828static void
1829bash_possible_hostname_completions (ignore, ignore2)
1830 int ignore, ignore2;
1831{
1832 bash_complete_hostname_internal ('?');
1833}
1834
1835static void
1836bash_complete_variable (ignore, ignore2)
1837 int ignore, ignore2;
1838{
1839 bash_complete_variable_internal (TAB);
1840}
1841
1842static void
1843bash_possible_variable_completions (ignore, ignore2)
1844 int ignore, ignore2;
1845{
1846 bash_complete_variable_internal ('?');
1847}
1848
1849static void
1850bash_complete_command (ignore, ignore2)
1851 int ignore, ignore2;
1852{
1853 bash_complete_command_internal (TAB);
1854}
1855
1856static void
1857bash_possible_command_completions (ignore, ignore2)
1858 int ignore, ignore2;
1859{
1860 bash_complete_command_internal ('?');
1861}
1862
1863static void
1864bash_complete_hostname_internal (what_to_do)
1865 int what_to_do;
1866{
1867 bash_specific_completion
1868 (what_to_do, (Function *)hostname_completion_function);
1869}
1870
1871static void
1872bash_complete_variable_internal (what_to_do)
1873 int what_to_do;
1874{
1875 bash_specific_completion
1876 (what_to_do, (Function *)variable_completion_function);
1877}
1878
1879static void
1880bash_complete_command_internal (what_to_do)
1881 int what_to_do;
1882{
1883 bash_specific_completion
1884 (what_to_do, (Function *)command_word_completion_function);
1885}
1886
ccc6cda3
JA
1887static char *
1888glob_complete_word (text, state)
1889 char *text;
1890 int state;
1891{
1892 static char **matches = (char **)NULL;
1893 static int ind;
1894 char *ret;
1895
1896 if (state == 0)
1897 {
e8ce775d 1898 rl_filename_completion_desired = 1;
ccc6cda3
JA
1899 if (matches)
1900 free (matches);
1901 matches = shell_glob_filename (text);
1902 if (GLOB_FAILED (matches))
1903 matches = (char **)NULL;
1904 ind = 0;
1905 }
1906
1907 ret = matches ? matches[ind] : (char *)NULL;
1908 ind++;
1909 return ret;
1910}
1911
1912static void
1913bash_glob_completion_internal (what_to_do)
1914 int what_to_do;
1915{
1916 bash_specific_completion (what_to_do, (Function *)glob_complete_word);
1917}
1918
1919static void
1920bash_glob_expand_word (count, key)
1921 int count, key;
1922{
1923 bash_glob_completion_internal ('*');
1924}
1925
1926static void
1927bash_glob_list_expansions (count, key)
1928 int count, key;
1929{
1930 bash_glob_completion_internal ('?');
1931}
1932
726f6388
JA
1933static void
1934bash_specific_completion (what_to_do, generator)
1935 int what_to_do;
1936 Function *generator;
1937{
1938 Function *orig_func;
1939 CPPFunction *orig_attempt_func;
1940
1941 orig_func = rl_completion_entry_function;
1942 orig_attempt_func = rl_attempted_completion_function;
1943 rl_completion_entry_function = generator;
1944 rl_attempted_completion_function = (CPPFunction *)NULL;
1945
1946 rl_complete_internal (what_to_do);
1947
1948 rl_completion_entry_function = orig_func;
1949 rl_attempted_completion_function = orig_attempt_func;
1950}
1951
1952#endif /* SPECIFIC_COMPLETION_FUNCTIONS */
ccc6cda3
JA
1953
1954/* Filename quoting for completion. */
1955/* A function to strip quotes that are not protected by backquotes. It
1956 allows single quotes to appear within double quotes, and vice versa.
1957 It should be smarter. */
1958static char *
1959bash_dequote_filename (text, quote_char)
1960 char *text;
1961{
1962 char *ret, *p, *r;
1963 int l, quoted;
1964
1965 l = strlen (text);
1966 ret = xmalloc (l + 1);
1967 for (quoted = quote_char, p = text, r = ret; p && *p; p++)
1968 {
1969 /* Allow backslash-quoted characters to pass through unscathed. */
1970 if (*p == '\\')
1971 {
1972 *r++ = *++p;
1973 if (*p == '\0')
1974 break;
1975 continue;
1976 }
1977 /* Close quote. */
1978 if (quoted && *p == quoted)
1979 {
1980 quoted = 0;
1981 continue;
1982 }
1983 /* Open quote. */
1984 if (quoted == 0 && (*p == '\'' || *p == '"'))
1985 {
1986 quoted = *p;
1987 continue;
1988 }
1989 *r++ = *p;
1990 }
1991 *r = '\0';
1992 return ret;
1993}
1994
d166f048
JA
1995/* Quote characters that the readline completion code would treat as
1996 word break characters with backslashes. Pass backslash-quoted
1997 characters through without examination. */
1998static char *
1999quote_word_break_chars (text)
2000 char *text;
2001{
2002 char *ret, *r, *s;
2003 int l;
2004
2005 l = strlen (text);
2006 ret = xmalloc ((2 * l) + 1);
2007 for (s = text, r = ret; *s; s++)
2008 {
2009 /* Pass backslash-quoted characters through, including the backslash. */
2010 if (*s == '\\')
2011 {
2012 *r++ = '\\';
2013 *r++ = *++s;
2014 if (*s == '\0')
2015 break;
2016 continue;
2017 }
2018 /* OK, we have an unquoted character. Check its presence in
2019 rl_completer_word_break_characters. */
2020 if (strchr (rl_completer_word_break_characters, *s))
2021 *r++ = '\\';
2022 *r++ = *s;
2023 }
2024 *r = '\0';
2025 return ret;
2026}
2027
2028/* Quote a filename using double quotes, single quotes, or backslashes
2029 depending on the value of completion_quoting_style. If we're
2030 completing using backslashes, we need to quote some additional
2031 characters (those that readline treats as word breaks), so we call
2032 quote_word_break_chars on the result. */
ccc6cda3
JA
2033static char *
2034bash_quote_filename (s, rtype, qcp)
2035 char *s;
2036 int rtype;
2037 char *qcp;
2038{
2039 char *rtext, *mtext, *ret;
2040 int rlen, cs;
2041
2042 rtext = (char *)NULL;
2043
2044 /* If RTYPE == MULT_MATCH, it means that there is
2045 more than one match. In this case, we do not add
2046 the closing quote or attempt to perform tilde
2047 expansion. If RTYPE == SINGLE_MATCH, we try
2048 to perform tilde expansion, because single and double
2049 quotes inhibit tilde expansion by the shell. */
2050
2051 mtext = s;
2052 if (mtext[0] == '~' && rtype == SINGLE_MATCH)
2053 mtext = bash_tilde_expand (s);
2054
2055 cs = completion_quoting_style;
2056 /* Might need to modify the default completion style based on *qcp,
2057 since it's set to any user-provided opening quote. */
2058 if (*qcp == '"')
2059 cs = COMPLETE_DQUOTE;
2060 else if (*qcp == '\'')
2061 cs = COMPLETE_SQUOTE;
2062#if defined (BANG_HISTORY)
2063 else if (*qcp == '\0' && history_expansion && cs == COMPLETE_DQUOTE &&
2064 history_expansion_inhibited == 0 && strchr (mtext, '!'))
2065 cs = COMPLETE_BSQUOTE;
d166f048
JA
2066
2067 if (*qcp == '"' && history_expansion && cs == COMPLETE_DQUOTE &&
2068 history_expansion_inhibited == 0 && strchr (mtext, '!'))
2069 {
2070 cs = COMPLETE_BSQUOTE;
2071 *qcp = '\0';
2072 }
ccc6cda3
JA
2073#endif
2074
2075 switch (cs)
2076 {
2077 case COMPLETE_DQUOTE:
2078 rtext = double_quote (mtext);
2079 break;
2080 case COMPLETE_SQUOTE:
2081 rtext = single_quote (mtext);
2082 break;
2083 case COMPLETE_BSQUOTE:
2084 rtext = backslash_quote (mtext);
2085 break;
2086 }
2087
2088 if (mtext != s)
2089 free (mtext);
2090
d166f048
JA
2091 /* We may need to quote additional characters: those that readline treats
2092 as word breaks that are not quoted by backslash_quote. */
2093 if (rtext && cs == COMPLETE_BSQUOTE)
2094 {
2095 mtext = quote_word_break_chars (rtext);
2096 free (rtext);
2097 rtext = mtext;
2098 }
2099
ccc6cda3
JA
2100 /* Leave the opening quote intact. The readline completion code takes
2101 care of avoiding doubled opening quotes. */
2102 rlen = strlen (rtext);
2103 ret = xmalloc (rlen + 1);
2104 strcpy (ret, rtext);
2105
2106 /* If there are multiple matches, cut off the closing quote. */
2107 if (rtype == MULT_MATCH && cs != COMPLETE_BSQUOTE)
2108 ret[rlen - 1] = '\0';
2109 free (rtext);
2110 return ret;
2111}
2112
2113#endif /* READLINE */