1 | /* complete.c -- filename completion for readline. */
|
---|
2 |
|
---|
3 | /* Copyright (C) 1987-2005 Free Software Foundation, Inc.
|
---|
4 |
|
---|
5 | This file is part of the GNU Readline Library, a library for
|
---|
6 | reading lines of text with interactive input and history editing.
|
---|
7 |
|
---|
8 | The GNU Readline Library is free software; you can redistribute it
|
---|
9 | and/or modify it under the terms of the GNU General Public License
|
---|
10 | as published by the Free Software Foundation; either version 2, or
|
---|
11 | (at your option) any later version.
|
---|
12 |
|
---|
13 | The GNU Readline Library is distributed in the hope that it will be
|
---|
14 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
---|
15 | of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
16 | GNU General Public License for more details.
|
---|
17 |
|
---|
18 | The GNU General Public License is often shipped with GNU software, and
|
---|
19 | is generally kept in a file called COPYING or LICENSE. If you do not
|
---|
20 | have a copy of the license, write to the Free Software Foundation,
|
---|
21 | 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
---|
22 | #define READLINE_LIBRARY
|
---|
23 |
|
---|
24 | #if defined (HAVE_CONFIG_H)
|
---|
25 | # include <config.h>
|
---|
26 | #endif
|
---|
27 |
|
---|
28 | #include <sys/types.h>
|
---|
29 | #include <fcntl.h>
|
---|
30 | #if defined (HAVE_SYS_FILE_H)
|
---|
31 | # include <sys/file.h>
|
---|
32 | #endif
|
---|
33 |
|
---|
34 | #if defined (HAVE_UNISTD_H)
|
---|
35 | # include <unistd.h>
|
---|
36 | #endif /* HAVE_UNISTD_H */
|
---|
37 |
|
---|
38 | #if defined (HAVE_STDLIB_H)
|
---|
39 | # include <stdlib.h>
|
---|
40 | #else
|
---|
41 | # include "ansi_stdlib.h"
|
---|
42 | #endif /* HAVE_STDLIB_H */
|
---|
43 |
|
---|
44 | #include <stdio.h>
|
---|
45 |
|
---|
46 | #include <errno.h>
|
---|
47 | #if !defined (errno)
|
---|
48 | extern int errno;
|
---|
49 | #endif /* !errno */
|
---|
50 |
|
---|
51 | #if defined (HAVE_PWD_H)
|
---|
52 | #include <pwd.h>
|
---|
53 | #endif
|
---|
54 |
|
---|
55 | #include "posixdir.h"
|
---|
56 | #include "posixstat.h"
|
---|
57 |
|
---|
58 | /* System-specific feature definitions and include files. */
|
---|
59 | #include "rldefs.h"
|
---|
60 | #include "rlmbutil.h"
|
---|
61 |
|
---|
62 | /* Some standard library routines. */
|
---|
63 | #include "readline.h"
|
---|
64 | #include "xmalloc.h"
|
---|
65 | #include "rlprivate.h"
|
---|
66 |
|
---|
67 | #ifdef __STDC__
|
---|
68 | typedef int QSFUNC (const void *, const void *);
|
---|
69 | #else
|
---|
70 | typedef int QSFUNC ();
|
---|
71 | #endif
|
---|
72 |
|
---|
73 | #ifdef HAVE_LSTAT
|
---|
74 | # define LSTAT lstat
|
---|
75 | #else
|
---|
76 | # define LSTAT stat
|
---|
77 | #endif
|
---|
78 |
|
---|
79 | /* Unix version of a hidden file. Could be different on other systems. */
|
---|
80 | #define HIDDEN_FILE(fname) ((fname)[0] == '.')
|
---|
81 |
|
---|
82 | /* Most systems don't declare getpwent in <pwd.h> if _POSIX_SOURCE is
|
---|
83 | defined. */
|
---|
84 | #if defined (HAVE_GETPWENT) && (!defined (HAVE_GETPW_DECLS) || defined (_POSIX_SOURCE))
|
---|
85 | extern struct passwd *getpwent PARAMS((void));
|
---|
86 | #endif /* HAVE_GETPWENT && (!HAVE_GETPW_DECLS || _POSIX_SOURCE) */
|
---|
87 |
|
---|
88 | /* If non-zero, then this is the address of a function to call when
|
---|
89 | completing a word would normally display the list of possible matches.
|
---|
90 | This function is called instead of actually doing the display.
|
---|
91 | It takes three arguments: (char **matches, int num_matches, int max_length)
|
---|
92 | where MATCHES is the array of strings that matched, NUM_MATCHES is the
|
---|
93 | number of strings in that array, and MAX_LENGTH is the length of the
|
---|
94 | longest string in that array. */
|
---|
95 | rl_compdisp_func_t *rl_completion_display_matches_hook = (rl_compdisp_func_t *)NULL;
|
---|
96 |
|
---|
97 | #if defined (VISIBLE_STATS)
|
---|
98 | # if !defined (X_OK)
|
---|
99 | # define X_OK 1
|
---|
100 | # endif
|
---|
101 | static int stat_char PARAMS((char *));
|
---|
102 | #endif
|
---|
103 |
|
---|
104 | static int path_isdir PARAMS((const char *));
|
---|
105 |
|
---|
106 | static char *rl_quote_filename PARAMS((char *, int, char *));
|
---|
107 |
|
---|
108 | static void set_completion_defaults PARAMS((int));
|
---|
109 | static int get_y_or_n PARAMS((int));
|
---|
110 | static int _rl_internal_pager PARAMS((int));
|
---|
111 | static char *printable_part PARAMS((char *));
|
---|
112 | static int fnwidth PARAMS((const char *));
|
---|
113 | static int fnprint PARAMS((const char *));
|
---|
114 | static int print_filename PARAMS((char *, char *));
|
---|
115 |
|
---|
116 | static char **gen_completion_matches PARAMS((char *, int, int, rl_compentry_func_t *, int, int));
|
---|
117 |
|
---|
118 | static char **remove_duplicate_matches PARAMS((char **));
|
---|
119 | static void insert_match PARAMS((char *, int, int, char *));
|
---|
120 | static int append_to_match PARAMS((char *, int, int, int));
|
---|
121 | static void insert_all_matches PARAMS((char **, int, char *));
|
---|
122 | static void display_matches PARAMS((char **));
|
---|
123 | static int compute_lcd_of_matches PARAMS((char **, int, const char *));
|
---|
124 | static int postprocess_matches PARAMS((char ***, int));
|
---|
125 |
|
---|
126 | static char *make_quoted_replacement PARAMS((char *, int, char *));
|
---|
127 |
|
---|
128 | /* **************************************************************** */
|
---|
129 | /* */
|
---|
130 | /* Completion matching, from readline's point of view. */
|
---|
131 | /* */
|
---|
132 | /* **************************************************************** */
|
---|
133 |
|
---|
134 | /* Variables known only to the readline library. */
|
---|
135 |
|
---|
136 | /* If non-zero, non-unique completions always show the list of matches. */
|
---|
137 | int _rl_complete_show_all = 0;
|
---|
138 |
|
---|
139 | /* If non-zero, non-unique completions show the list of matches, unless it
|
---|
140 | is not possible to do partial completion and modify the line. */
|
---|
141 | int _rl_complete_show_unmodified = 0;
|
---|
142 |
|
---|
143 | /* If non-zero, completed directory names have a slash appended. */
|
---|
144 | int _rl_complete_mark_directories = 1;
|
---|
145 |
|
---|
146 | /* If non-zero, the symlinked directory completion behavior introduced in
|
---|
147 | readline-4.2a is disabled, and symlinks that point to directories have
|
---|
148 | a slash appended (subject to the value of _rl_complete_mark_directories).
|
---|
149 | This is user-settable via the mark-symlinked-directories variable. */
|
---|
150 | int _rl_complete_mark_symlink_dirs = 0;
|
---|
151 |
|
---|
152 | /* If non-zero, completions are printed horizontally in alphabetical order,
|
---|
153 | like `ls -x'. */
|
---|
154 | int _rl_print_completions_horizontally;
|
---|
155 |
|
---|
156 | /* Non-zero means that case is not significant in filename completion. */
|
---|
157 | #if defined (__MSDOS__) && !defined (__DJGPP__)
|
---|
158 | int _rl_completion_case_fold = 1;
|
---|
159 | #else
|
---|
160 | int _rl_completion_case_fold;
|
---|
161 | #endif
|
---|
162 |
|
---|
163 | /* If non-zero, don't match hidden files (filenames beginning with a `.' on
|
---|
164 | Unix) when doing filename completion. */
|
---|
165 | int _rl_match_hidden_files = 1;
|
---|
166 |
|
---|
167 | /* Global variables available to applications using readline. */
|
---|
168 |
|
---|
169 | #if defined (VISIBLE_STATS)
|
---|
170 | /* Non-zero means add an additional character to each filename displayed
|
---|
171 | during listing completion iff rl_filename_completion_desired which helps
|
---|
172 | to indicate the type of file being listed. */
|
---|
173 | int rl_visible_stats = 0;
|
---|
174 | #endif /* VISIBLE_STATS */
|
---|
175 |
|
---|
176 | /* If non-zero, then this is the address of a function to call when
|
---|
177 | completing on a directory name. The function is called with
|
---|
178 | the address of a string (the current directory name) as an arg. */
|
---|
179 | rl_icppfunc_t *rl_directory_completion_hook = (rl_icppfunc_t *)NULL;
|
---|
180 |
|
---|
181 | rl_icppfunc_t *rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL;
|
---|
182 |
|
---|
183 | /* Non-zero means readline completion functions perform tilde expansion. */
|
---|
184 | int rl_complete_with_tilde_expansion = 0;
|
---|
185 |
|
---|
186 | /* Pointer to the generator function for completion_matches ().
|
---|
187 | NULL means to use rl_filename_completion_function (), the default filename
|
---|
188 | completer. */
|
---|
189 | rl_compentry_func_t *rl_completion_entry_function = (rl_compentry_func_t *)NULL;
|
---|
190 |
|
---|
191 | /* Pointer to alternative function to create matches.
|
---|
192 | Function is called with TEXT, START, and END.
|
---|
193 | START and END are indices in RL_LINE_BUFFER saying what the boundaries
|
---|
194 | of TEXT are.
|
---|
195 | If this function exists and returns NULL then call the value of
|
---|
196 | rl_completion_entry_function to try to match, otherwise use the
|
---|
197 | array of strings returned. */
|
---|
198 | rl_completion_func_t *rl_attempted_completion_function = (rl_completion_func_t *)NULL;
|
---|
199 |
|
---|
200 | /* Non-zero means to suppress normal filename completion after the
|
---|
201 | user-specified completion function has been called. */
|
---|
202 | int rl_attempted_completion_over = 0;
|
---|
203 |
|
---|
204 | /* Set to a character indicating the type of completion being performed
|
---|
205 | by rl_complete_internal, available for use by application completion
|
---|
206 | functions. */
|
---|
207 | int rl_completion_type = 0;
|
---|
208 |
|
---|
209 | /* Up to this many items will be displayed in response to a
|
---|
210 | possible-completions call. After that, we ask the user if
|
---|
211 | she is sure she wants to see them all. A negative value means
|
---|
212 | don't ask. */
|
---|
213 | int rl_completion_query_items = 100;
|
---|
214 |
|
---|
215 | int _rl_page_completions = 1;
|
---|
216 |
|
---|
217 | /* The basic list of characters that signal a break between words for the
|
---|
218 | completer routine. The contents of this variable is what breaks words
|
---|
219 | in the shell, i.e. " \t\n\"\\'`@$><=" */
|
---|
220 | const char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{("; /* }) */
|
---|
221 |
|
---|
222 | /* List of basic quoting characters. */
|
---|
223 | const char *rl_basic_quote_characters = "\"'";
|
---|
224 |
|
---|
225 | /* The list of characters that signal a break between words for
|
---|
226 | rl_complete_internal. The default list is the contents of
|
---|
227 | rl_basic_word_break_characters. */
|
---|
228 | /*const*/ char *rl_completer_word_break_characters = (/*const*/ char *)NULL;
|
---|
229 |
|
---|
230 | /* Hook function to allow an application to set the completion word
|
---|
231 | break characters before readline breaks up the line. Allows
|
---|
232 | position-dependent word break characters. */
|
---|
233 | rl_cpvfunc_t *rl_completion_word_break_hook = (rl_cpvfunc_t *)NULL;
|
---|
234 |
|
---|
235 | /* List of characters which can be used to quote a substring of the line.
|
---|
236 | Completion occurs on the entire substring, and within the substring
|
---|
237 | rl_completer_word_break_characters are treated as any other character,
|
---|
238 | unless they also appear within this list. */
|
---|
239 | const char *rl_completer_quote_characters = (const char *)NULL;
|
---|
240 |
|
---|
241 | /* List of characters that should be quoted in filenames by the completer. */
|
---|
242 | const char *rl_filename_quote_characters = (const char *)NULL;
|
---|
243 |
|
---|
244 | /* List of characters that are word break characters, but should be left
|
---|
245 | in TEXT when it is passed to the completion function. The shell uses
|
---|
246 | this to help determine what kind of completing to do. */
|
---|
247 | const char *rl_special_prefixes = (const char *)NULL;
|
---|
248 |
|
---|
249 | /* If non-zero, then disallow duplicates in the matches. */
|
---|
250 | int rl_ignore_completion_duplicates = 1;
|
---|
251 |
|
---|
252 | /* Non-zero means that the results of the matches are to be treated
|
---|
253 | as filenames. This is ALWAYS zero on entry, and can only be changed
|
---|
254 | within a completion entry finder function. */
|
---|
255 | int rl_filename_completion_desired = 0;
|
---|
256 |
|
---|
257 | /* Non-zero means that the results of the matches are to be quoted using
|
---|
258 | double quotes (or an application-specific quoting mechanism) if the
|
---|
259 | filename contains any characters in rl_filename_quote_chars. This is
|
---|
260 | ALWAYS non-zero on entry, and can only be changed within a completion
|
---|
261 | entry finder function. */
|
---|
262 | int rl_filename_quoting_desired = 1;
|
---|
263 |
|
---|
264 | /* This function, if defined, is called by the completer when real
|
---|
265 | filename completion is done, after all the matching names have been
|
---|
266 | generated. It is passed a (char**) known as matches in the code below.
|
---|
267 | It consists of a NULL-terminated array of pointers to potential
|
---|
268 | matching strings. The 1st element (matches[0]) is the maximal
|
---|
269 | substring that is common to all matches. This function can re-arrange
|
---|
270 | the list of matches as required, but all elements of the array must be
|
---|
271 | free()'d if they are deleted. The main intent of this function is
|
---|
272 | to implement FIGNORE a la SunOS csh. */
|
---|
273 | rl_compignore_func_t *rl_ignore_some_completions_function = (rl_compignore_func_t *)NULL;
|
---|
274 |
|
---|
275 | /* Set to a function to quote a filename in an application-specific fashion.
|
---|
276 | Called with the text to quote, the type of match found (single or multiple)
|
---|
277 | and a pointer to the quoting character to be used, which the function can
|
---|
278 | reset if desired. */
|
---|
279 | rl_quote_func_t *rl_filename_quoting_function = rl_quote_filename;
|
---|
280 |
|
---|
281 | /* Function to call to remove quoting characters from a filename. Called
|
---|
282 | before completion is attempted, so the embedded quotes do not interfere
|
---|
283 | with matching names in the file system. Readline doesn't do anything
|
---|
284 | with this; it's set only by applications. */
|
---|
285 | rl_dequote_func_t *rl_filename_dequoting_function = (rl_dequote_func_t *)NULL;
|
---|
286 |
|
---|
287 | /* Function to call to decide whether or not a word break character is
|
---|
288 | quoted. If a character is quoted, it does not break words for the
|
---|
289 | completer. */
|
---|
290 | rl_linebuf_func_t *rl_char_is_quoted_p = (rl_linebuf_func_t *)NULL;
|
---|
291 |
|
---|
292 | /* If non-zero, the completion functions don't append anything except a
|
---|
293 | possible closing quote. This is set to 0 by rl_complete_internal and
|
---|
294 | may be changed by an application-specific completion function. */
|
---|
295 | int rl_completion_suppress_append = 0;
|
---|
296 |
|
---|
297 | /* Character appended to completed words when at the end of the line. The
|
---|
298 | default is a space. */
|
---|
299 | int rl_completion_append_character = ' ';
|
---|
300 |
|
---|
301 | /* If non-zero, the completion functions don't append any closing quote.
|
---|
302 | This is set to 0 by rl_complete_internal and may be changed by an
|
---|
303 | application-specific completion function. */
|
---|
304 | int rl_completion_suppress_quote = 0;
|
---|
305 |
|
---|
306 | /* Set to any quote character readline thinks it finds before any application
|
---|
307 | completion function is called. */
|
---|
308 | int rl_completion_quote_character;
|
---|
309 |
|
---|
310 | /* Set to a non-zero value if readline found quoting anywhere in the word to
|
---|
311 | be completed; set before any application completion function is called. */
|
---|
312 | int rl_completion_found_quote;
|
---|
313 |
|
---|
314 | /* If non-zero, a slash will be appended to completed filenames that are
|
---|
315 | symbolic links to directory names, subject to the value of the
|
---|
316 | mark-directories variable (which is user-settable). This exists so
|
---|
317 | that application completion functions can override the user's preference
|
---|
318 | (set via the mark-symlinked-directories variable) if appropriate.
|
---|
319 | It's set to the value of _rl_complete_mark_symlink_dirs in
|
---|
320 | rl_complete_internal before any application-specific completion
|
---|
321 | function is called, so without that function doing anything, the user's
|
---|
322 | preferences are honored. */
|
---|
323 | int rl_completion_mark_symlink_dirs;
|
---|
324 |
|
---|
325 | /* If non-zero, inhibit completion (temporarily). */
|
---|
326 | int rl_inhibit_completion;
|
---|
327 |
|
---|
328 | /* Variables local to this file. */
|
---|
329 |
|
---|
330 | /* Local variable states what happened during the last completion attempt. */
|
---|
331 | static int completion_changed_buffer;
|
---|
332 |
|
---|
333 | /*************************************/
|
---|
334 | /* */
|
---|
335 | /* Bindable completion functions */
|
---|
336 | /* */
|
---|
337 | /*************************************/
|
---|
338 |
|
---|
339 | /* Complete the word at or before point. You have supplied the function
|
---|
340 | that does the initial simple matching selection algorithm (see
|
---|
341 | rl_completion_matches ()). The default is to do filename completion. */
|
---|
342 | int
|
---|
343 | rl_complete (ignore, invoking_key)
|
---|
344 | int ignore, invoking_key;
|
---|
345 | {
|
---|
346 | if (rl_inhibit_completion)
|
---|
347 | return (_rl_insert_char (ignore, invoking_key));
|
---|
348 | else if (rl_last_func == rl_complete && !completion_changed_buffer)
|
---|
349 | return (rl_complete_internal ('?'));
|
---|
350 | else if (_rl_complete_show_all)
|
---|
351 | return (rl_complete_internal ('!'));
|
---|
352 | else if (_rl_complete_show_unmodified)
|
---|
353 | return (rl_complete_internal ('@'));
|
---|
354 | else
|
---|
355 | return (rl_complete_internal (TAB));
|
---|
356 | }
|
---|
357 |
|
---|
358 | /* List the possible completions. See description of rl_complete (). */
|
---|
359 | int
|
---|
360 | rl_possible_completions (ignore, invoking_key)
|
---|
361 | int ignore, invoking_key;
|
---|
362 | {
|
---|
363 | return (rl_complete_internal ('?'));
|
---|
364 | }
|
---|
365 |
|
---|
366 | int
|
---|
367 | rl_insert_completions (ignore, invoking_key)
|
---|
368 | int ignore, invoking_key;
|
---|
369 | {
|
---|
370 | return (rl_complete_internal ('*'));
|
---|
371 | }
|
---|
372 |
|
---|
373 | /* Return the correct value to pass to rl_complete_internal performing
|
---|
374 | the same tests as rl_complete. This allows consecutive calls to an
|
---|
375 | application's completion function to list possible completions and for
|
---|
376 | an application-specific completion function to honor the
|
---|
377 | show-all-if-ambiguous readline variable. */
|
---|
378 | int
|
---|
379 | rl_completion_mode (cfunc)
|
---|
380 | rl_command_func_t *cfunc;
|
---|
381 | {
|
---|
382 | if (rl_last_func == cfunc && !completion_changed_buffer)
|
---|
383 | return '?';
|
---|
384 | else if (_rl_complete_show_all)
|
---|
385 | return '!';
|
---|
386 | else if (_rl_complete_show_unmodified)
|
---|
387 | return '@';
|
---|
388 | else
|
---|
389 | return TAB;
|
---|
390 | }
|
---|
391 |
|
---|
392 | /************************************/
|
---|
393 | /* */
|
---|
394 | /* Completion utility functions */
|
---|
395 | /* */
|
---|
396 | /************************************/
|
---|
397 |
|
---|
398 | /* Set default values for readline word completion. These are the variables
|
---|
399 | that application completion functions can change or inspect. */
|
---|
400 | static void
|
---|
401 | set_completion_defaults (what_to_do)
|
---|
402 | int what_to_do;
|
---|
403 | {
|
---|
404 | /* Only the completion entry function can change these. */
|
---|
405 | rl_filename_completion_desired = 0;
|
---|
406 | rl_filename_quoting_desired = 1;
|
---|
407 | rl_completion_type = what_to_do;
|
---|
408 | rl_completion_suppress_append = rl_completion_suppress_quote = 0;
|
---|
409 |
|
---|
410 | /* The completion entry function may optionally change this. */
|
---|
411 | rl_completion_mark_symlink_dirs = _rl_complete_mark_symlink_dirs;
|
---|
412 | }
|
---|
413 |
|
---|
414 | /* The user must press "y" or "n". Non-zero return means "y" pressed. */
|
---|
415 | static int
|
---|
416 | get_y_or_n (for_pager)
|
---|
417 | int for_pager;
|
---|
418 | {
|
---|
419 | int c;
|
---|
420 |
|
---|
421 | for (;;)
|
---|
422 | {
|
---|
423 | RL_SETSTATE(RL_STATE_MOREINPUT);
|
---|
424 | c = rl_read_key ();
|
---|
425 | RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
---|
426 |
|
---|
427 | if (c == 'y' || c == 'Y' || c == ' ')
|
---|
428 | return (1);
|
---|
429 | if (c == 'n' || c == 'N' || c == RUBOUT)
|
---|
430 | return (0);
|
---|
431 | if (c == ABORT_CHAR)
|
---|
432 | _rl_abort_internal ();
|
---|
433 | if (for_pager && (c == NEWLINE || c == RETURN))
|
---|
434 | return (2);
|
---|
435 | if (for_pager && (c == 'q' || c == 'Q'))
|
---|
436 | return (0);
|
---|
437 | rl_ding ();
|
---|
438 | }
|
---|
439 | }
|
---|
440 |
|
---|
441 | static int
|
---|
442 | _rl_internal_pager (lines)
|
---|
443 | int lines;
|
---|
444 | {
|
---|
445 | int i;
|
---|
446 |
|
---|
447 | fprintf (rl_outstream, "--More--");
|
---|
448 | fflush (rl_outstream);
|
---|
449 | i = get_y_or_n (1);
|
---|
450 | _rl_erase_entire_line ();
|
---|
451 | if (i == 0)
|
---|
452 | return -1;
|
---|
453 | else if (i == 2)
|
---|
454 | return (lines - 1);
|
---|
455 | else
|
---|
456 | return 0;
|
---|
457 | }
|
---|
458 |
|
---|
459 | static int
|
---|
460 | path_isdir (filename)
|
---|
461 | const char *filename;
|
---|
462 | {
|
---|
463 | struct stat finfo;
|
---|
464 |
|
---|
465 | return (stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode));
|
---|
466 | }
|
---|
467 |
|
---|
468 | #if defined (VISIBLE_STATS)
|
---|
469 | /* Return the character which best describes FILENAME.
|
---|
470 | `@' for symbolic links
|
---|
471 | `/' for directories
|
---|
472 | `*' for executables
|
---|
473 | `=' for sockets
|
---|
474 | `|' for FIFOs
|
---|
475 | `%' for character special devices
|
---|
476 | `#' for block special devices */
|
---|
477 | static int
|
---|
478 | stat_char (filename)
|
---|
479 | char *filename;
|
---|
480 | {
|
---|
481 | struct stat finfo;
|
---|
482 | int character, r;
|
---|
483 |
|
---|
484 | #if defined (HAVE_LSTAT) && defined (S_ISLNK)
|
---|
485 | r = lstat (filename, &finfo);
|
---|
486 | #else
|
---|
487 | r = stat (filename, &finfo);
|
---|
488 | #endif
|
---|
489 |
|
---|
490 | if (r == -1)
|
---|
491 | return (0);
|
---|
492 |
|
---|
493 | character = 0;
|
---|
494 | if (S_ISDIR (finfo.st_mode))
|
---|
495 | character = '/';
|
---|
496 | #if defined (S_ISCHR)
|
---|
497 | else if (S_ISCHR (finfo.st_mode))
|
---|
498 | character = '%';
|
---|
499 | #endif /* S_ISCHR */
|
---|
500 | #if defined (S_ISBLK)
|
---|
501 | else if (S_ISBLK (finfo.st_mode))
|
---|
502 | character = '#';
|
---|
503 | #endif /* S_ISBLK */
|
---|
504 | #if defined (S_ISLNK)
|
---|
505 | else if (S_ISLNK (finfo.st_mode))
|
---|
506 | character = '@';
|
---|
507 | #endif /* S_ISLNK */
|
---|
508 | #if defined (S_ISSOCK)
|
---|
509 | else if (S_ISSOCK (finfo.st_mode))
|
---|
510 | character = '=';
|
---|
511 | #endif /* S_ISSOCK */
|
---|
512 | #if defined (S_ISFIFO)
|
---|
513 | else if (S_ISFIFO (finfo.st_mode))
|
---|
514 | character = '|';
|
---|
515 | #endif
|
---|
516 | else if (S_ISREG (finfo.st_mode))
|
---|
517 | {
|
---|
518 | if (access (filename, X_OK) == 0)
|
---|
519 | character = '*';
|
---|
520 | }
|
---|
521 | return (character);
|
---|
522 | }
|
---|
523 | #endif /* VISIBLE_STATS */
|
---|
524 |
|
---|
525 | /* Return the portion of PATHNAME that should be output when listing
|
---|
526 | possible completions. If we are hacking filename completion, we
|
---|
527 | are only interested in the basename, the portion following the
|
---|
528 | final slash. Otherwise, we return what we were passed. Since
|
---|
529 | printing empty strings is not very informative, if we're doing
|
---|
530 | filename completion, and the basename is the empty string, we look
|
---|
531 | for the previous slash and return the portion following that. If
|
---|
532 | there's no previous slash, we just return what we were passed. */
|
---|
533 | static char *
|
---|
534 | printable_part (pathname)
|
---|
535 | char *pathname;
|
---|
536 | {
|
---|
537 | char *temp, *x;
|
---|
538 |
|
---|
539 | if (rl_filename_completion_desired == 0) /* don't need to do anything */
|
---|
540 | return (pathname);
|
---|
541 |
|
---|
542 | temp = strrchr (pathname, '/');
|
---|
543 | #if defined (__MSDOS__)
|
---|
544 | if (temp == 0 && ISALPHA ((unsigned char)pathname[0]) && pathname[1] == ':')
|
---|
545 | temp = pathname + 1;
|
---|
546 | #endif
|
---|
547 |
|
---|
548 | if (temp == 0 || *temp == '\0')
|
---|
549 | return (pathname);
|
---|
550 | /* If the basename is NULL, we might have a pathname like '/usr/src/'.
|
---|
551 | Look for a previous slash and, if one is found, return the portion
|
---|
552 | following that slash. If there's no previous slash, just return the
|
---|
553 | pathname we were passed. */
|
---|
554 | else if (temp[1] == '\0')
|
---|
555 | {
|
---|
556 | for (x = temp - 1; x > pathname; x--)
|
---|
557 | if (*x == '/')
|
---|
558 | break;
|
---|
559 | return ((*x == '/') ? x + 1 : pathname);
|
---|
560 | }
|
---|
561 | else
|
---|
562 | return ++temp;
|
---|
563 | }
|
---|
564 |
|
---|
565 | /* Compute width of STRING when displayed on screen by print_filename */
|
---|
566 | static int
|
---|
567 | fnwidth (string)
|
---|
568 | const char *string;
|
---|
569 | {
|
---|
570 | int width, pos;
|
---|
571 | #if defined (HANDLE_MULTIBYTE)
|
---|
572 | mbstate_t ps;
|
---|
573 | int left, w;
|
---|
574 | size_t clen;
|
---|
575 | wchar_t wc;
|
---|
576 |
|
---|
577 | left = strlen (string) + 1;
|
---|
578 | memset (&ps, 0, sizeof (mbstate_t));
|
---|
579 | #endif
|
---|
580 |
|
---|
581 | width = pos = 0;
|
---|
582 | while (string[pos])
|
---|
583 | {
|
---|
584 | if (CTRL_CHAR (*string) || *string == RUBOUT)
|
---|
585 | {
|
---|
586 | width += 2;
|
---|
587 | pos++;
|
---|
588 | }
|
---|
589 | else
|
---|
590 | {
|
---|
591 | #if defined (HANDLE_MULTIBYTE)
|
---|
592 | clen = mbrtowc (&wc, string + pos, left - pos, &ps);
|
---|
593 | if (MB_INVALIDCH (clen))
|
---|
594 | {
|
---|
595 | width++;
|
---|
596 | pos++;
|
---|
597 | memset (&ps, 0, sizeof (mbstate_t));
|
---|
598 | }
|
---|
599 | else if (MB_NULLWCH (clen))
|
---|
600 | break;
|
---|
601 | else
|
---|
602 | {
|
---|
603 | pos += clen;
|
---|
604 | w = wcwidth (wc);
|
---|
605 | width += (w >= 0) ? w : 1;
|
---|
606 | }
|
---|
607 | #else
|
---|
608 | width++;
|
---|
609 | pos++;
|
---|
610 | #endif
|
---|
611 | }
|
---|
612 | }
|
---|
613 |
|
---|
614 | return width;
|
---|
615 | }
|
---|
616 |
|
---|
617 | static int
|
---|
618 | fnprint (to_print)
|
---|
619 | const char *to_print;
|
---|
620 | {
|
---|
621 | int printed_len;
|
---|
622 | const char *s;
|
---|
623 | #if defined (HANDLE_MULTIBYTE)
|
---|
624 | mbstate_t ps;
|
---|
625 | const char *end;
|
---|
626 | size_t tlen;
|
---|
627 | int width, w;
|
---|
628 | wchar_t wc;
|
---|
629 |
|
---|
630 | end = to_print + strlen (to_print) + 1;
|
---|
631 | memset (&ps, 0, sizeof (mbstate_t));
|
---|
632 | #endif
|
---|
633 |
|
---|
634 | printed_len = 0;
|
---|
635 | s = to_print;
|
---|
636 | while (*s)
|
---|
637 | {
|
---|
638 | if (CTRL_CHAR (*s))
|
---|
639 | {
|
---|
640 | putc ('^', rl_outstream);
|
---|
641 | putc (UNCTRL (*s), rl_outstream);
|
---|
642 | printed_len += 2;
|
---|
643 | s++;
|
---|
644 | #if defined (HANDLE_MULTIBYTE)
|
---|
645 | memset (&ps, 0, sizeof (mbstate_t));
|
---|
646 | #endif
|
---|
647 | }
|
---|
648 | else if (*s == RUBOUT)
|
---|
649 | {
|
---|
650 | putc ('^', rl_outstream);
|
---|
651 | putc ('?', rl_outstream);
|
---|
652 | printed_len += 2;
|
---|
653 | s++;
|
---|
654 | #if defined (HANDLE_MULTIBYTE)
|
---|
655 | memset (&ps, 0, sizeof (mbstate_t));
|
---|
656 | #endif
|
---|
657 | }
|
---|
658 | else
|
---|
659 | {
|
---|
660 | #if defined (HANDLE_MULTIBYTE)
|
---|
661 | tlen = mbrtowc (&wc, s, end - s, &ps);
|
---|
662 | if (MB_INVALIDCH (tlen))
|
---|
663 | {
|
---|
664 | tlen = 1;
|
---|
665 | width = 1;
|
---|
666 | memset (&ps, 0, sizeof (mbstate_t));
|
---|
667 | }
|
---|
668 | else if (MB_NULLWCH (tlen))
|
---|
669 | break;
|
---|
670 | else
|
---|
671 | {
|
---|
672 | w = wcwidth (wc);
|
---|
673 | width = (w >= 0) ? w : 1;
|
---|
674 | }
|
---|
675 | fwrite (s, 1, tlen, rl_outstream);
|
---|
676 | s += tlen;
|
---|
677 | printed_len += width;
|
---|
678 | #else
|
---|
679 | putc (*s, rl_outstream);
|
---|
680 | s++;
|
---|
681 | printed_len++;
|
---|
682 | #endif
|
---|
683 | }
|
---|
684 | }
|
---|
685 |
|
---|
686 | return printed_len;
|
---|
687 | }
|
---|
688 |
|
---|
689 | /* Output TO_PRINT to rl_outstream. If VISIBLE_STATS is defined and we
|
---|
690 | are using it, check for and output a single character for `special'
|
---|
691 | filenames. Return the number of characters we output. */
|
---|
692 |
|
---|
693 | static int
|
---|
694 | print_filename (to_print, full_pathname)
|
---|
695 | char *to_print, *full_pathname;
|
---|
696 | {
|
---|
697 | int printed_len, extension_char, slen, tlen;
|
---|
698 | char *s, c, *new_full_pathname, *dn;
|
---|
699 |
|
---|
700 | extension_char = 0;
|
---|
701 | printed_len = fnprint (to_print);
|
---|
702 |
|
---|
703 | #if defined (VISIBLE_STATS)
|
---|
704 | if (rl_filename_completion_desired && (rl_visible_stats || _rl_complete_mark_directories))
|
---|
705 | #else
|
---|
706 | if (rl_filename_completion_desired && _rl_complete_mark_directories)
|
---|
707 | #endif
|
---|
708 | {
|
---|
709 | /* If to_print != full_pathname, to_print is the basename of the
|
---|
710 | path passed. In this case, we try to expand the directory
|
---|
711 | name before checking for the stat character. */
|
---|
712 | if (to_print != full_pathname)
|
---|
713 | {
|
---|
714 | /* Terminate the directory name. */
|
---|
715 | c = to_print[-1];
|
---|
716 | to_print[-1] = '\0';
|
---|
717 |
|
---|
718 | /* If setting the last slash in full_pathname to a NUL results in
|
---|
719 | full_pathname being the empty string, we are trying to complete
|
---|
720 | files in the root directory. If we pass a null string to the
|
---|
721 | bash directory completion hook, for example, it will expand it
|
---|
722 | to the current directory. We just want the `/'. */
|
---|
723 | if (full_pathname == 0 || *full_pathname == 0)
|
---|
724 | dn = "/";
|
---|
725 | else if (full_pathname[0] != '/')
|
---|
726 | dn = full_pathname;
|
---|
727 | else if (full_pathname[1] == 0)
|
---|
728 | dn = "//"; /* restore trailing slash to `//' */
|
---|
729 | else if (full_pathname[1] == '/' && full_pathname[2] == 0)
|
---|
730 | dn = "/"; /* don't turn /// into // */
|
---|
731 | else
|
---|
732 | dn = full_pathname;
|
---|
733 | s = tilde_expand (dn);
|
---|
734 | if (rl_directory_completion_hook)
|
---|
735 | (*rl_directory_completion_hook) (&s);
|
---|
736 |
|
---|
737 | slen = strlen (s);
|
---|
738 | tlen = strlen (to_print);
|
---|
739 | new_full_pathname = (char *)xmalloc (slen + tlen + 2);
|
---|
740 | strcpy (new_full_pathname, s);
|
---|
741 | if (s[slen - 1] == '/')
|
---|
742 | slen--;
|
---|
743 | else
|
---|
744 | new_full_pathname[slen] = '/';
|
---|
745 | new_full_pathname[slen] = '/';
|
---|
746 | strcpy (new_full_pathname + slen + 1, to_print);
|
---|
747 |
|
---|
748 | #if defined (VISIBLE_STATS)
|
---|
749 | if (rl_visible_stats)
|
---|
750 | extension_char = stat_char (new_full_pathname);
|
---|
751 | else
|
---|
752 | #endif
|
---|
753 | if (path_isdir (new_full_pathname))
|
---|
754 | extension_char = '/';
|
---|
755 |
|
---|
756 | free (new_full_pathname);
|
---|
757 | to_print[-1] = c;
|
---|
758 | }
|
---|
759 | else
|
---|
760 | {
|
---|
761 | s = tilde_expand (full_pathname);
|
---|
762 | #if defined (VISIBLE_STATS)
|
---|
763 | if (rl_visible_stats)
|
---|
764 | extension_char = stat_char (s);
|
---|
765 | else
|
---|
766 | #endif
|
---|
767 | if (path_isdir (s))
|
---|
768 | extension_char = '/';
|
---|
769 | }
|
---|
770 |
|
---|
771 | free (s);
|
---|
772 | if (extension_char)
|
---|
773 | {
|
---|
774 | putc (extension_char, rl_outstream);
|
---|
775 | printed_len++;
|
---|
776 | }
|
---|
777 | }
|
---|
778 |
|
---|
779 | return printed_len;
|
---|
780 | }
|
---|
781 |
|
---|
782 | static char *
|
---|
783 | rl_quote_filename (s, rtype, qcp)
|
---|
784 | char *s;
|
---|
785 | int rtype;
|
---|
786 | char *qcp;
|
---|
787 | {
|
---|
788 | char *r;
|
---|
789 |
|
---|
790 | r = (char *)xmalloc (strlen (s) + 2);
|
---|
791 | *r = *rl_completer_quote_characters;
|
---|
792 | strcpy (r + 1, s);
|
---|
793 | if (qcp)
|
---|
794 | *qcp = *rl_completer_quote_characters;
|
---|
795 | return r;
|
---|
796 | }
|
---|
797 |
|
---|
798 | /* Find the bounds of the current word for completion purposes, and leave
|
---|
799 | rl_point set to the end of the word. This function skips quoted
|
---|
800 | substrings (characters between matched pairs of characters in
|
---|
801 | rl_completer_quote_characters). First we try to find an unclosed
|
---|
802 | quoted substring on which to do matching. If one is not found, we use
|
---|
803 | the word break characters to find the boundaries of the current word.
|
---|
804 | We call an application-specific function to decide whether or not a
|
---|
805 | particular word break character is quoted; if that function returns a
|
---|
806 | non-zero result, the character does not break a word. This function
|
---|
807 | returns the opening quote character if we found an unclosed quoted
|
---|
808 | substring, '\0' otherwise. FP, if non-null, is set to a value saying
|
---|
809 | which (shell-like) quote characters we found (single quote, double
|
---|
810 | quote, or backslash) anywhere in the string. DP, if non-null, is set to
|
---|
811 | the value of the delimiter character that caused a word break. */
|
---|
812 |
|
---|
813 | char
|
---|
814 | _rl_find_completion_word (fp, dp)
|
---|
815 | int *fp, *dp;
|
---|
816 | {
|
---|
817 | int scan, end, found_quote, delimiter, pass_next, isbrk;
|
---|
818 | char quote_char, *brkchars;
|
---|
819 |
|
---|
820 | end = rl_point;
|
---|
821 | found_quote = delimiter = 0;
|
---|
822 | quote_char = '\0';
|
---|
823 |
|
---|
824 | brkchars = 0;
|
---|
825 | if (rl_completion_word_break_hook)
|
---|
826 | brkchars = (*rl_completion_word_break_hook) ();
|
---|
827 | if (brkchars == 0)
|
---|
828 | brkchars = rl_completer_word_break_characters;
|
---|
829 |
|
---|
830 | if (rl_completer_quote_characters)
|
---|
831 | {
|
---|
832 | /* We have a list of characters which can be used in pairs to
|
---|
833 | quote substrings for the completer. Try to find the start
|
---|
834 | of an unclosed quoted substring. */
|
---|
835 | /* FOUND_QUOTE is set so we know what kind of quotes we found. */
|
---|
836 | for (scan = pass_next = 0; scan < end; scan = MB_NEXTCHAR (rl_line_buffer, scan, 1, MB_FIND_ANY))
|
---|
837 | {
|
---|
838 | if (pass_next)
|
---|
839 | {
|
---|
840 | pass_next = 0;
|
---|
841 | continue;
|
---|
842 | }
|
---|
843 |
|
---|
844 | /* Shell-like semantics for single quotes -- don't allow backslash
|
---|
845 | to quote anything in single quotes, especially not the closing
|
---|
846 | quote. If you don't like this, take out the check on the value
|
---|
847 | of quote_char. */
|
---|
848 | if (quote_char != '\'' && rl_line_buffer[scan] == '\\')
|
---|
849 | {
|
---|
850 | pass_next = 1;
|
---|
851 | found_quote |= RL_QF_BACKSLASH;
|
---|
852 | continue;
|
---|
853 | }
|
---|
854 |
|
---|
855 | if (quote_char != '\0')
|
---|
856 | {
|
---|
857 | /* Ignore everything until the matching close quote char. */
|
---|
858 | if (rl_line_buffer[scan] == quote_char)
|
---|
859 | {
|
---|
860 | /* Found matching close. Abandon this substring. */
|
---|
861 | quote_char = '\0';
|
---|
862 | rl_point = end;
|
---|
863 | }
|
---|
864 | }
|
---|
865 | else if (strchr (rl_completer_quote_characters, rl_line_buffer[scan]))
|
---|
866 | {
|
---|
867 | /* Found start of a quoted substring. */
|
---|
868 | quote_char = rl_line_buffer[scan];
|
---|
869 | rl_point = scan + 1;
|
---|
870 | /* Shell-like quoting conventions. */
|
---|
871 | if (quote_char == '\'')
|
---|
872 | found_quote |= RL_QF_SINGLE_QUOTE;
|
---|
873 | else if (quote_char == '"')
|
---|
874 | found_quote |= RL_QF_DOUBLE_QUOTE;
|
---|
875 | else
|
---|
876 | found_quote |= RL_QF_OTHER_QUOTE;
|
---|
877 | }
|
---|
878 | }
|
---|
879 | }
|
---|
880 |
|
---|
881 | if (rl_point == end && quote_char == '\0')
|
---|
882 | {
|
---|
883 | /* We didn't find an unclosed quoted substring upon which to do
|
---|
884 | completion, so use the word break characters to find the
|
---|
885 | substring on which to complete. */
|
---|
886 | while (rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_ANY))
|
---|
887 | {
|
---|
888 | scan = rl_line_buffer[rl_point];
|
---|
889 |
|
---|
890 | if (strchr (brkchars, scan) == 0)
|
---|
891 | continue;
|
---|
892 |
|
---|
893 | /* Call the application-specific function to tell us whether
|
---|
894 | this word break character is quoted and should be skipped. */
|
---|
895 | if (rl_char_is_quoted_p && found_quote &&
|
---|
896 | (*rl_char_is_quoted_p) (rl_line_buffer, rl_point))
|
---|
897 | continue;
|
---|
898 |
|
---|
899 | /* Convoluted code, but it avoids an n^2 algorithm with calls
|
---|
900 | to char_is_quoted. */
|
---|
901 | break;
|
---|
902 | }
|
---|
903 | }
|
---|
904 |
|
---|
905 | /* If we are at an unquoted word break, then advance past it. */
|
---|
906 | scan = rl_line_buffer[rl_point];
|
---|
907 |
|
---|
908 | /* If there is an application-specific function to say whether or not
|
---|
909 | a character is quoted and we found a quote character, let that
|
---|
910 | function decide whether or not a character is a word break, even
|
---|
911 | if it is found in rl_completer_word_break_characters. Don't bother
|
---|
912 | if we're at the end of the line, though. */
|
---|
913 | if (scan)
|
---|
914 | {
|
---|
915 | if (rl_char_is_quoted_p)
|
---|
916 | isbrk = (found_quote == 0 ||
|
---|
917 | (*rl_char_is_quoted_p) (rl_line_buffer, rl_point) == 0) &&
|
---|
918 | strchr (brkchars, scan) != 0;
|
---|
919 | else
|
---|
920 | isbrk = strchr (brkchars, scan) != 0;
|
---|
921 |
|
---|
922 | if (isbrk)
|
---|
923 | {
|
---|
924 | /* If the character that caused the word break was a quoting
|
---|
925 | character, then remember it as the delimiter. */
|
---|
926 | if (rl_basic_quote_characters &&
|
---|
927 | strchr (rl_basic_quote_characters, scan) &&
|
---|
928 | (end - rl_point) > 1)
|
---|
929 | delimiter = scan;
|
---|
930 |
|
---|
931 | /* If the character isn't needed to determine something special
|
---|
932 | about what kind of completion to perform, then advance past it. */
|
---|
933 | if (rl_special_prefixes == 0 || strchr (rl_special_prefixes, scan) == 0)
|
---|
934 | rl_point++;
|
---|
935 | }
|
---|
936 | }
|
---|
937 |
|
---|
938 | if (fp)
|
---|
939 | *fp = found_quote;
|
---|
940 | if (dp)
|
---|
941 | *dp = delimiter;
|
---|
942 |
|
---|
943 | return (quote_char);
|
---|
944 | }
|
---|
945 |
|
---|
946 | static char **
|
---|
947 | gen_completion_matches (text, start, end, our_func, found_quote, quote_char)
|
---|
948 | char *text;
|
---|
949 | int start, end;
|
---|
950 | rl_compentry_func_t *our_func;
|
---|
951 | int found_quote, quote_char;
|
---|
952 | {
|
---|
953 | char **matches, *temp;
|
---|
954 |
|
---|
955 | rl_completion_found_quote = found_quote;
|
---|
956 | rl_completion_quote_character = quote_char;
|
---|
957 |
|
---|
958 | /* If the user wants to TRY to complete, but then wants to give
|
---|
959 | up and use the default completion function, they set the
|
---|
960 | variable rl_attempted_completion_function. */
|
---|
961 | if (rl_attempted_completion_function)
|
---|
962 | {
|
---|
963 | matches = (*rl_attempted_completion_function) (text, start, end);
|
---|
964 |
|
---|
965 | if (matches || rl_attempted_completion_over)
|
---|
966 | {
|
---|
967 | rl_attempted_completion_over = 0;
|
---|
968 | return (matches);
|
---|
969 | }
|
---|
970 | }
|
---|
971 |
|
---|
972 | /* Beware -- we're stripping the quotes here. Do this only if we know
|
---|
973 | we are doing filename completion and the application has defined a
|
---|
974 | filename dequoting function. */
|
---|
975 | temp = (char *)NULL;
|
---|
976 |
|
---|
977 | if (found_quote && our_func == rl_filename_completion_function &&
|
---|
978 | rl_filename_dequoting_function)
|
---|
979 | {
|
---|
980 | /* delete single and double quotes */
|
---|
981 | temp = (*rl_filename_dequoting_function) (text, quote_char);
|
---|
982 | text = temp; /* not freeing text is not a memory leak */
|
---|
983 | }
|
---|
984 |
|
---|
985 | matches = rl_completion_matches (text, our_func);
|
---|
986 | FREE (temp);
|
---|
987 | return matches;
|
---|
988 | }
|
---|
989 |
|
---|
990 | /* Filter out duplicates in MATCHES. This frees up the strings in
|
---|
991 | MATCHES. */
|
---|
992 | static char **
|
---|
993 | remove_duplicate_matches (matches)
|
---|
994 | char **matches;
|
---|
995 | {
|
---|
996 | char *lowest_common;
|
---|
997 | int i, j, newlen;
|
---|
998 | char dead_slot;
|
---|
999 | char **temp_array;
|
---|
1000 |
|
---|
1001 | /* Sort the items. */
|
---|
1002 | for (i = 0; matches[i]; i++)
|
---|
1003 | ;
|
---|
1004 |
|
---|
1005 | /* Sort the array without matches[0], since we need it to
|
---|
1006 | stay in place no matter what. */
|
---|
1007 | if (i)
|
---|
1008 | qsort (matches+1, i-1, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
|
---|
1009 |
|
---|
1010 | /* Remember the lowest common denominator for it may be unique. */
|
---|
1011 | lowest_common = savestring (matches[0]);
|
---|
1012 |
|
---|
1013 | for (i = newlen = 0; matches[i + 1]; i++)
|
---|
1014 | {
|
---|
1015 | if (strcmp (matches[i], matches[i + 1]) == 0)
|
---|
1016 | {
|
---|
1017 | free (matches[i]);
|
---|
1018 | matches[i] = (char *)&dead_slot;
|
---|
1019 | }
|
---|
1020 | else
|
---|
1021 | newlen++;
|
---|
1022 | }
|
---|
1023 |
|
---|
1024 | /* We have marked all the dead slots with (char *)&dead_slot.
|
---|
1025 | Copy all the non-dead entries into a new array. */
|
---|
1026 | temp_array = (char **)xmalloc ((3 + newlen) * sizeof (char *));
|
---|
1027 | for (i = j = 1; matches[i]; i++)
|
---|
1028 | {
|
---|
1029 | if (matches[i] != (char *)&dead_slot)
|
---|
1030 | temp_array[j++] = matches[i];
|
---|
1031 | }
|
---|
1032 | temp_array[j] = (char *)NULL;
|
---|
1033 |
|
---|
1034 | if (matches[0] != (char *)&dead_slot)
|
---|
1035 | free (matches[0]);
|
---|
1036 |
|
---|
1037 | /* Place the lowest common denominator back in [0]. */
|
---|
1038 | temp_array[0] = lowest_common;
|
---|
1039 |
|
---|
1040 | /* If there is one string left, and it is identical to the
|
---|
1041 | lowest common denominator, then the LCD is the string to
|
---|
1042 | insert. */
|
---|
1043 | if (j == 2 && strcmp (temp_array[0], temp_array[1]) == 0)
|
---|
1044 | {
|
---|
1045 | free (temp_array[1]);
|
---|
1046 | temp_array[1] = (char *)NULL;
|
---|
1047 | }
|
---|
1048 | return (temp_array);
|
---|
1049 | }
|
---|
1050 |
|
---|
1051 | /* Find the common prefix of the list of matches, and put it into
|
---|
1052 | matches[0]. */
|
---|
1053 | static int
|
---|
1054 | compute_lcd_of_matches (match_list, matches, text)
|
---|
1055 | char **match_list;
|
---|
1056 | int matches;
|
---|
1057 | const char *text;
|
---|
1058 | {
|
---|
1059 | register int i, c1, c2, si;
|
---|
1060 | int low; /* Count of max-matched characters. */
|
---|
1061 | char *dtext; /* dequoted TEXT, if needed */
|
---|
1062 | #if defined (HANDLE_MULTIBYTE)
|
---|
1063 | int v;
|
---|
1064 | mbstate_t ps1, ps2;
|
---|
1065 | wchar_t wc1, wc2;
|
---|
1066 | #endif
|
---|
1067 |
|
---|
1068 | /* If only one match, just use that. Otherwise, compare each
|
---|
1069 | member of the list with the next, finding out where they
|
---|
1070 | stop matching. */
|
---|
1071 | if (matches == 1)
|
---|
1072 | {
|
---|
1073 | match_list[0] = match_list[1];
|
---|
1074 | match_list[1] = (char *)NULL;
|
---|
1075 | return 1;
|
---|
1076 | }
|
---|
1077 |
|
---|
1078 | for (i = 1, low = 100000; i < matches; i++)
|
---|
1079 | {
|
---|
1080 | #if defined (HANDLE_MULTIBYTE)
|
---|
1081 | if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
1082 | {
|
---|
1083 | memset (&ps1, 0, sizeof (mbstate_t));
|
---|
1084 | memset (&ps2, 0, sizeof (mbstate_t));
|
---|
1085 | }
|
---|
1086 | #endif
|
---|
1087 | if (_rl_completion_case_fold)
|
---|
1088 | {
|
---|
1089 | for (si = 0;
|
---|
1090 | (c1 = _rl_to_lower(match_list[i][si])) &&
|
---|
1091 | (c2 = _rl_to_lower(match_list[i + 1][si]));
|
---|
1092 | si++)
|
---|
1093 | #if defined (HANDLE_MULTIBYTE)
|
---|
1094 | if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
1095 | {
|
---|
1096 | v = mbrtowc (&wc1, match_list[i]+si, strlen (match_list[i]+si), &ps1);
|
---|
1097 | mbrtowc (&wc2, match_list[i+1]+si, strlen (match_list[i+1]+si), &ps2);
|
---|
1098 | wc1 = towlower (wc1);
|
---|
1099 | wc2 = towlower (wc2);
|
---|
1100 | if (wc1 != wc2)
|
---|
1101 | break;
|
---|
1102 | else if (v > 1)
|
---|
1103 | si += v - 1;
|
---|
1104 | }
|
---|
1105 | else
|
---|
1106 | #endif
|
---|
1107 | if (c1 != c2)
|
---|
1108 | break;
|
---|
1109 | }
|
---|
1110 | else
|
---|
1111 | {
|
---|
1112 | for (si = 0;
|
---|
1113 | (c1 = match_list[i][si]) &&
|
---|
1114 | (c2 = match_list[i + 1][si]);
|
---|
1115 | si++)
|
---|
1116 | #if defined (HANDLE_MULTIBYTE)
|
---|
1117 | if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
---|
1118 | {
|
---|
1119 | mbstate_t ps_back = ps1;
|
---|
1120 | if (!_rl_compare_chars (match_list[i], si, &ps1, match_list[i+1], si, &ps2))
|
---|
1121 | break;
|
---|
1122 | else if ((v = _rl_get_char_len (&match_list[i][si], &ps_back)) > 1)
|
---|
1123 | si += v - 1;
|
---|
1124 | }
|
---|
1125 | else
|
---|
1126 | #endif
|
---|
1127 | if (c1 != c2)
|
---|
1128 | break;
|
---|
1129 | }
|
---|
1130 |
|
---|
1131 | if (low > si)
|
---|
1132 | low = si;
|
---|
1133 | }
|
---|
1134 |
|
---|
1135 | /* If there were multiple matches, but none matched up to even the
|
---|
1136 | first character, and the user typed something, use that as the
|
---|
1137 | value of matches[0]. */
|
---|
1138 | if (low == 0 && text && *text)
|
---|
1139 | {
|
---|
1140 | match_list[0] = (char *)xmalloc (strlen (text) + 1);
|
---|
1141 | strcpy (match_list[0], text);
|
---|
1142 | }
|
---|
1143 | else
|
---|
1144 | {
|
---|
1145 | match_list[0] = (char *)xmalloc (low + 1);
|
---|
1146 |
|
---|
1147 | /* XXX - this might need changes in the presence of multibyte chars */
|
---|
1148 |
|
---|
1149 | /* If we are ignoring case, try to preserve the case of the string
|
---|
1150 | the user typed in the face of multiple matches differing in case. */
|
---|
1151 | if (_rl_completion_case_fold)
|
---|
1152 | {
|
---|
1153 | /* We're making an assumption here:
|
---|
1154 | IF we're completing filenames AND
|
---|
1155 | the application has defined a filename dequoting function AND
|
---|
1156 | we found a quote character AND
|
---|
1157 | the application has requested filename quoting
|
---|
1158 | THEN
|
---|
1159 | we assume that TEXT was dequoted before checking against
|
---|
1160 | the file system and needs to be dequoted here before we
|
---|
1161 | check against the list of matches
|
---|
1162 | FI */
|
---|
1163 | dtext = (char *)NULL;
|
---|
1164 | if (rl_filename_completion_desired &&
|
---|
1165 | rl_filename_dequoting_function &&
|
---|
1166 | rl_completion_found_quote &&
|
---|
1167 | rl_filename_quoting_desired)
|
---|
1168 | {
|
---|
1169 | dtext = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character);
|
---|
1170 | text = dtext;
|
---|
1171 | }
|
---|
1172 |
|
---|
1173 | /* sort the list to get consistent answers. */
|
---|
1174 | qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare);
|
---|
1175 |
|
---|
1176 | si = strlen (text);
|
---|
1177 | if (si <= low)
|
---|
1178 | {
|
---|
1179 | for (i = 1; i <= matches; i++)
|
---|
1180 | if (strncmp (match_list[i], text, si) == 0)
|
---|
1181 | {
|
---|
1182 | strncpy (match_list[0], match_list[i], low);
|
---|
1183 | break;
|
---|
1184 | }
|
---|
1185 | /* no casematch, use first entry */
|
---|
1186 | if (i > matches)
|
---|
1187 | strncpy (match_list[0], match_list[1], low);
|
---|
1188 | }
|
---|
1189 | else
|
---|
1190 | /* otherwise, just use the text the user typed. */
|
---|
1191 | strncpy (match_list[0], text, low);
|
---|
1192 |
|
---|
1193 | FREE (dtext);
|
---|
1194 | }
|
---|
1195 | else
|
---|
1196 | strncpy (match_list[0], match_list[1], low);
|
---|
1197 |
|
---|
1198 | match_list[0][low] = '\0';
|
---|
1199 | }
|
---|
1200 |
|
---|
1201 | return matches;
|
---|
1202 | }
|
---|
1203 |
|
---|
1204 | static int
|
---|
1205 | postprocess_matches (matchesp, matching_filenames)
|
---|
1206 | char ***matchesp;
|
---|
1207 | int matching_filenames;
|
---|
1208 | {
|
---|
1209 | char *t, **matches, **temp_matches;
|
---|
1210 | int nmatch, i;
|
---|
1211 |
|
---|
1212 | matches = *matchesp;
|
---|
1213 |
|
---|
1214 | if (matches == 0)
|
---|
1215 | return 0;
|
---|
1216 |
|
---|
1217 | /* It seems to me that in all the cases we handle we would like
|
---|
1218 | to ignore duplicate possiblilities. Scan for the text to
|
---|
1219 | insert being identical to the other completions. */
|
---|
1220 | if (rl_ignore_completion_duplicates)
|
---|
1221 | {
|
---|
1222 | temp_matches = remove_duplicate_matches (matches);
|
---|
1223 | free (matches);
|
---|
1224 | matches = temp_matches;
|
---|
1225 | }
|
---|
1226 |
|
---|
1227 | /* If we are matching filenames, then here is our chance to
|
---|
1228 | do clever processing by re-examining the list. Call the
|
---|
1229 | ignore function with the array as a parameter. It can
|
---|
1230 | munge the array, deleting matches as it desires. */
|
---|
1231 | if (rl_ignore_some_completions_function && matching_filenames)
|
---|
1232 | {
|
---|
1233 | for (nmatch = 1; matches[nmatch]; nmatch++)
|
---|
1234 | ;
|
---|
1235 | (void)(*rl_ignore_some_completions_function) (matches);
|
---|
1236 | if (matches == 0 || matches[0] == 0)
|
---|
1237 | {
|
---|
1238 | FREE (matches);
|
---|
1239 | *matchesp = (char **)0;
|
---|
1240 | return 0;
|
---|
1241 | }
|
---|
1242 | else
|
---|
1243 | {
|
---|
1244 | /* If we removed some matches, recompute the common prefix. */
|
---|
1245 | for (i = 1; matches[i]; i++)
|
---|
1246 | ;
|
---|
1247 | if (i > 1 && i < nmatch)
|
---|
1248 | {
|
---|
1249 | t = matches[0];
|
---|
1250 | compute_lcd_of_matches (matches, i - 1, t);
|
---|
1251 | FREE (t);
|
---|
1252 | }
|
---|
1253 | }
|
---|
1254 | }
|
---|
1255 |
|
---|
1256 | *matchesp = matches;
|
---|
1257 | return (1);
|
---|
1258 | }
|
---|
1259 |
|
---|
1260 | /* A convenience function for displaying a list of strings in
|
---|
1261 | columnar format on readline's output stream. MATCHES is the list
|
---|
1262 | of strings, in argv format, LEN is the number of strings in MATCHES,
|
---|
1263 | and MAX is the length of the longest string in MATCHES. */
|
---|
1264 | void
|
---|
1265 | rl_display_match_list (matches, len, max)
|
---|
1266 | char **matches;
|
---|
1267 | int len, max;
|
---|
1268 | {
|
---|
1269 | int count, limit, printed_len, lines;
|
---|
1270 | int i, j, k, l;
|
---|
1271 | char *temp;
|
---|
1272 |
|
---|
1273 | /* How many items of MAX length can we fit in the screen window? */
|
---|
1274 | max += 2;
|
---|
1275 | limit = _rl_screenwidth / max;
|
---|
1276 | if (limit != 1 && (limit * max == _rl_screenwidth))
|
---|
1277 | limit--;
|
---|
1278 |
|
---|
1279 | /* Avoid a possible floating exception. If max > _rl_screenwidth,
|
---|
1280 | limit will be 0 and a divide-by-zero fault will result. */
|
---|
1281 | if (limit == 0)
|
---|
1282 | limit = 1;
|
---|
1283 |
|
---|
1284 | /* How many iterations of the printing loop? */
|
---|
1285 | count = (len + (limit - 1)) / limit;
|
---|
1286 |
|
---|
1287 | /* Watch out for special case. If LEN is less than LIMIT, then
|
---|
1288 | just do the inner printing loop.
|
---|
1289 | 0 < len <= limit implies count = 1. */
|
---|
1290 |
|
---|
1291 | /* Sort the items if they are not already sorted. */
|
---|
1292 | if (rl_ignore_completion_duplicates == 0)
|
---|
1293 | qsort (matches + 1, len, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
|
---|
1294 |
|
---|
1295 | rl_crlf ();
|
---|
1296 |
|
---|
1297 | lines = 0;
|
---|
1298 | if (_rl_print_completions_horizontally == 0)
|
---|
1299 | {
|
---|
1300 | /* Print the sorted items, up-and-down alphabetically, like ls. */
|
---|
1301 | for (i = 1; i <= count; i++)
|
---|
1302 | {
|
---|
1303 | for (j = 0, l = i; j < limit; j++)
|
---|
1304 | {
|
---|
1305 | if (l > len || matches[l] == 0)
|
---|
1306 | break;
|
---|
1307 | else
|
---|
1308 | {
|
---|
1309 | temp = printable_part (matches[l]);
|
---|
1310 | printed_len = print_filename (temp, matches[l]);
|
---|
1311 |
|
---|
1312 | if (j + 1 < limit)
|
---|
1313 | for (k = 0; k < max - printed_len; k++)
|
---|
1314 | putc (' ', rl_outstream);
|
---|
1315 | }
|
---|
1316 | l += count;
|
---|
1317 | }
|
---|
1318 | rl_crlf ();
|
---|
1319 | lines++;
|
---|
1320 | if (_rl_page_completions && lines >= (_rl_screenheight - 1) && i < count)
|
---|
1321 | {
|
---|
1322 | lines = _rl_internal_pager (lines);
|
---|
1323 | if (lines < 0)
|
---|
1324 | return;
|
---|
1325 | }
|
---|
1326 | }
|
---|
1327 | }
|
---|
1328 | else
|
---|
1329 | {
|
---|
1330 | /* Print the sorted items, across alphabetically, like ls -x. */
|
---|
1331 | for (i = 1; matches[i]; i++)
|
---|
1332 | {
|
---|
1333 | temp = printable_part (matches[i]);
|
---|
1334 | printed_len = print_filename (temp, matches[i]);
|
---|
1335 | /* Have we reached the end of this line? */
|
---|
1336 | if (matches[i+1])
|
---|
1337 | {
|
---|
1338 | if (i && (limit > 1) && (i % limit) == 0)
|
---|
1339 | {
|
---|
1340 | rl_crlf ();
|
---|
1341 | lines++;
|
---|
1342 | if (_rl_page_completions && lines >= _rl_screenheight - 1)
|
---|
1343 | {
|
---|
1344 | lines = _rl_internal_pager (lines);
|
---|
1345 | if (lines < 0)
|
---|
1346 | return;
|
---|
1347 | }
|
---|
1348 | }
|
---|
1349 | else
|
---|
1350 | for (k = 0; k < max - printed_len; k++)
|
---|
1351 | putc (' ', rl_outstream);
|
---|
1352 | }
|
---|
1353 | }
|
---|
1354 | rl_crlf ();
|
---|
1355 | }
|
---|
1356 | }
|
---|
1357 |
|
---|
1358 | /* Display MATCHES, a list of matching filenames in argv format. This
|
---|
1359 | handles the simple case -- a single match -- first. If there is more
|
---|
1360 | than one match, we compute the number of strings in the list and the
|
---|
1361 | length of the longest string, which will be needed by the display
|
---|
1362 | function. If the application wants to handle displaying the list of
|
---|
1363 | matches itself, it sets RL_COMPLETION_DISPLAY_MATCHES_HOOK to the
|
---|
1364 | address of a function, and we just call it. If we're handling the
|
---|
1365 | display ourselves, we just call rl_display_match_list. We also check
|
---|
1366 | that the list of matches doesn't exceed the user-settable threshold,
|
---|
1367 | and ask the user if he wants to see the list if there are more matches
|
---|
1368 | than RL_COMPLETION_QUERY_ITEMS. */
|
---|
1369 | static void
|
---|
1370 | display_matches (matches)
|
---|
1371 | char **matches;
|
---|
1372 | {
|
---|
1373 | int len, max, i;
|
---|
1374 | char *temp;
|
---|
1375 |
|
---|
1376 | /* Move to the last visible line of a possibly-multiple-line command. */
|
---|
1377 | _rl_move_vert (_rl_vis_botlin);
|
---|
1378 |
|
---|
1379 | /* Handle simple case first. What if there is only one answer? */
|
---|
1380 | if (matches[1] == 0)
|
---|
1381 | {
|
---|
1382 | temp = printable_part (matches[0]);
|
---|
1383 | rl_crlf ();
|
---|
1384 | print_filename (temp, matches[0]);
|
---|
1385 | rl_crlf ();
|
---|
1386 |
|
---|
1387 | rl_forced_update_display ();
|
---|
1388 | rl_display_fixed = 1;
|
---|
1389 |
|
---|
1390 | return;
|
---|
1391 | }
|
---|
1392 |
|
---|
1393 | /* There is more than one answer. Find out how many there are,
|
---|
1394 | and find the maximum printed length of a single entry. */
|
---|
1395 | for (max = 0, i = 1; matches[i]; i++)
|
---|
1396 | {
|
---|
1397 | temp = printable_part (matches[i]);
|
---|
1398 | len = fnwidth (temp);
|
---|
1399 |
|
---|
1400 | if (len > max)
|
---|
1401 | max = len;
|
---|
1402 | }
|
---|
1403 |
|
---|
1404 | len = i - 1;
|
---|
1405 |
|
---|
1406 | /* If the caller has defined a display hook, then call that now. */
|
---|
1407 | if (rl_completion_display_matches_hook)
|
---|
1408 | {
|
---|
1409 | (*rl_completion_display_matches_hook) (matches, len, max);
|
---|
1410 | return;
|
---|
1411 | }
|
---|
1412 |
|
---|
1413 | /* If there are many items, then ask the user if she really wants to
|
---|
1414 | see them all. */
|
---|
1415 | if (rl_completion_query_items > 0 && len >= rl_completion_query_items)
|
---|
1416 | {
|
---|
1417 | rl_crlf ();
|
---|
1418 | fprintf (rl_outstream, "Display all %d possibilities? (y or n)", len);
|
---|
1419 | fflush (rl_outstream);
|
---|
1420 | if (get_y_or_n (0) == 0)
|
---|
1421 | {
|
---|
1422 | rl_crlf ();
|
---|
1423 |
|
---|
1424 | rl_forced_update_display ();
|
---|
1425 | rl_display_fixed = 1;
|
---|
1426 |
|
---|
1427 | return;
|
---|
1428 | }
|
---|
1429 | }
|
---|
1430 |
|
---|
1431 | rl_display_match_list (matches, len, max);
|
---|
1432 |
|
---|
1433 | rl_forced_update_display ();
|
---|
1434 | rl_display_fixed = 1;
|
---|
1435 | }
|
---|
1436 |
|
---|
1437 | static char *
|
---|
1438 | make_quoted_replacement (match, mtype, qc)
|
---|
1439 | char *match;
|
---|
1440 | int mtype;
|
---|
1441 | char *qc; /* Pointer to quoting character, if any */
|
---|
1442 | {
|
---|
1443 | int should_quote, do_replace;
|
---|
1444 | char *replacement;
|
---|
1445 |
|
---|
1446 | /* If we are doing completion on quoted substrings, and any matches
|
---|
1447 | contain any of the completer_word_break_characters, then auto-
|
---|
1448 | matically prepend the substring with a quote character (just pick
|
---|
1449 | the first one from the list of such) if it does not already begin
|
---|
1450 | with a quote string. FIXME: Need to remove any such automatically
|
---|
1451 | inserted quote character when it no longer is necessary, such as
|
---|
1452 | if we change the string we are completing on and the new set of
|
---|
1453 | matches don't require a quoted substring. */
|
---|
1454 | replacement = match;
|
---|
1455 |
|
---|
1456 | should_quote = match && rl_completer_quote_characters &&
|
---|
1457 | rl_filename_completion_desired &&
|
---|
1458 | rl_filename_quoting_desired;
|
---|
1459 |
|
---|
1460 | if (should_quote)
|
---|
1461 | should_quote = should_quote && (!qc || !*qc ||
|
---|
1462 | (rl_completer_quote_characters && strchr (rl_completer_quote_characters, *qc)));
|
---|
1463 |
|
---|
1464 | if (should_quote)
|
---|
1465 | {
|
---|
1466 | /* If there is a single match, see if we need to quote it.
|
---|
1467 | This also checks whether the common prefix of several
|
---|
1468 | matches needs to be quoted. */
|
---|
1469 | should_quote = rl_filename_quote_characters
|
---|
1470 | ? (_rl_strpbrk (match, rl_filename_quote_characters) != 0)
|
---|
1471 | : 0;
|
---|
1472 |
|
---|
1473 | do_replace = should_quote ? mtype : NO_MATCH;
|
---|
1474 | /* Quote the replacement, since we found an embedded
|
---|
1475 | word break character in a potential match. */
|
---|
1476 | if (do_replace != NO_MATCH && rl_filename_quoting_function)
|
---|
1477 | replacement = (*rl_filename_quoting_function) (match, do_replace, qc);
|
---|
1478 | }
|
---|
1479 | return (replacement);
|
---|
1480 | }
|
---|
1481 |
|
---|
1482 | static void
|
---|
1483 | insert_match (match, start, mtype, qc)
|
---|
1484 | char *match;
|
---|
1485 | int start, mtype;
|
---|
1486 | char *qc;
|
---|
1487 | {
|
---|
1488 | char *replacement;
|
---|
1489 | char oqc;
|
---|
1490 |
|
---|
1491 | oqc = qc ? *qc : '\0';
|
---|
1492 | replacement = make_quoted_replacement (match, mtype, qc);
|
---|
1493 |
|
---|
1494 | /* Now insert the match. */
|
---|
1495 | if (replacement)
|
---|
1496 | {
|
---|
1497 | /* Don't double an opening quote character. */
|
---|
1498 | if (qc && *qc && start && rl_line_buffer[start - 1] == *qc &&
|
---|
1499 | replacement[0] == *qc)
|
---|
1500 | start--;
|
---|
1501 | /* If make_quoted_replacement changed the quoting character, remove
|
---|
1502 | the opening quote and insert the (fully-quoted) replacement. */
|
---|
1503 | else if (qc && (*qc != oqc) && start && rl_line_buffer[start - 1] == oqc &&
|
---|
1504 | replacement[0] != oqc)
|
---|
1505 | start--;
|
---|
1506 | _rl_replace_text (replacement, start, rl_point - 1);
|
---|
1507 | if (replacement != match)
|
---|
1508 | free (replacement);
|
---|
1509 | }
|
---|
1510 | }
|
---|
1511 |
|
---|
1512 | /* Append any necessary closing quote and a separator character to the
|
---|
1513 | just-inserted match. If the user has specified that directories
|
---|
1514 | should be marked by a trailing `/', append one of those instead. The
|
---|
1515 | default trailing character is a space. Returns the number of characters
|
---|
1516 | appended. If NONTRIVIAL_MATCH is set, we test for a symlink (if the OS
|
---|
1517 | has them) and don't add a suffix for a symlink to a directory. A
|
---|
1518 | nontrivial match is one that actually adds to the word being completed.
|
---|
1519 | The variable rl_completion_mark_symlink_dirs controls this behavior
|
---|
1520 | (it's initially set to the what the user has chosen, indicated by the
|
---|
1521 | value of _rl_complete_mark_symlink_dirs, but may be modified by an
|
---|
1522 | application's completion function). */
|
---|
1523 | static int
|
---|
1524 | append_to_match (text, delimiter, quote_char, nontrivial_match)
|
---|
1525 | char *text;
|
---|
1526 | int delimiter, quote_char, nontrivial_match;
|
---|
1527 | {
|
---|
1528 | char temp_string[4], *filename;
|
---|
1529 | int temp_string_index, s;
|
---|
1530 | struct stat finfo;
|
---|
1531 |
|
---|
1532 | temp_string_index = 0;
|
---|
1533 | if (quote_char && rl_point && rl_completion_suppress_quote == 0 &&
|
---|
1534 | rl_line_buffer[rl_point - 1] != quote_char)
|
---|
1535 | temp_string[temp_string_index++] = quote_char;
|
---|
1536 |
|
---|
1537 | if (delimiter)
|
---|
1538 | temp_string[temp_string_index++] = delimiter;
|
---|
1539 | else if (rl_completion_suppress_append == 0 && rl_completion_append_character)
|
---|
1540 | temp_string[temp_string_index++] = rl_completion_append_character;
|
---|
1541 |
|
---|
1542 | temp_string[temp_string_index++] = '\0';
|
---|
1543 |
|
---|
1544 | if (rl_filename_completion_desired)
|
---|
1545 | {
|
---|
1546 | filename = tilde_expand (text);
|
---|
1547 | s = (nontrivial_match && rl_completion_mark_symlink_dirs == 0)
|
---|
1548 | ? LSTAT (filename, &finfo)
|
---|
1549 | : stat (filename, &finfo);
|
---|
1550 | if (s == 0 && S_ISDIR (finfo.st_mode))
|
---|
1551 | {
|
---|
1552 | if (_rl_complete_mark_directories /* && rl_completion_suppress_append == 0 */)
|
---|
1553 | {
|
---|
1554 | /* This is clumsy. Avoid putting in a double slash if point
|
---|
1555 | is at the end of the line and the previous character is a
|
---|
1556 | slash. */
|
---|
1557 | if (rl_point && rl_line_buffer[rl_point] == '\0' && rl_line_buffer[rl_point - 1] == '/')
|
---|
1558 | ;
|
---|
1559 | else if (rl_line_buffer[rl_point] != '/')
|
---|
1560 | rl_insert_text ("/");
|
---|
1561 | }
|
---|
1562 | }
|
---|
1563 | #ifdef S_ISLNK
|
---|
1564 | /* Don't add anything if the filename is a symlink and resolves to a
|
---|
1565 | directory. */
|
---|
1566 | else if (s == 0 && S_ISLNK (finfo.st_mode) &&
|
---|
1567 | stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode))
|
---|
1568 | ;
|
---|
1569 | #endif
|
---|
1570 | else
|
---|
1571 | {
|
---|
1572 | if (rl_point == rl_end && temp_string_index)
|
---|
1573 | rl_insert_text (temp_string);
|
---|
1574 | }
|
---|
1575 | free (filename);
|
---|
1576 | }
|
---|
1577 | else
|
---|
1578 | {
|
---|
1579 | if (rl_point == rl_end && temp_string_index)
|
---|
1580 | rl_insert_text (temp_string);
|
---|
1581 | }
|
---|
1582 |
|
---|
1583 | return (temp_string_index);
|
---|
1584 | }
|
---|
1585 |
|
---|
1586 | static void
|
---|
1587 | insert_all_matches (matches, point, qc)
|
---|
1588 | char **matches;
|
---|
1589 | int point;
|
---|
1590 | char *qc;
|
---|
1591 | {
|
---|
1592 | int i;
|
---|
1593 | char *rp;
|
---|
1594 |
|
---|
1595 | rl_begin_undo_group ();
|
---|
1596 | /* remove any opening quote character; make_quoted_replacement will add
|
---|
1597 | it back. */
|
---|
1598 | if (qc && *qc && point && rl_line_buffer[point - 1] == *qc)
|
---|
1599 | point--;
|
---|
1600 | rl_delete_text (point, rl_point);
|
---|
1601 | rl_point = point;
|
---|
1602 |
|
---|
1603 | if (matches[1])
|
---|
1604 | {
|
---|
1605 | for (i = 1; matches[i]; i++)
|
---|
1606 | {
|
---|
1607 | rp = make_quoted_replacement (matches[i], SINGLE_MATCH, qc);
|
---|
1608 | rl_insert_text (rp);
|
---|
1609 | rl_insert_text (" ");
|
---|
1610 | if (rp != matches[i])
|
---|
1611 | free (rp);
|
---|
1612 | }
|
---|
1613 | }
|
---|
1614 | else
|
---|
1615 | {
|
---|
1616 | rp = make_quoted_replacement (matches[0], SINGLE_MATCH, qc);
|
---|
1617 | rl_insert_text (rp);
|
---|
1618 | rl_insert_text (" ");
|
---|
1619 | if (rp != matches[0])
|
---|
1620 | free (rp);
|
---|
1621 | }
|
---|
1622 | rl_end_undo_group ();
|
---|
1623 | }
|
---|
1624 |
|
---|
1625 | void
|
---|
1626 | _rl_free_match_list (matches)
|
---|
1627 | char **matches;
|
---|
1628 | {
|
---|
1629 | register int i;
|
---|
1630 |
|
---|
1631 | if (matches == 0)
|
---|
1632 | return;
|
---|
1633 |
|
---|
1634 | for (i = 0; matches[i]; i++)
|
---|
1635 | free (matches[i]);
|
---|
1636 | free (matches);
|
---|
1637 | }
|
---|
1638 |
|
---|
1639 | /* Complete the word at or before point.
|
---|
1640 | WHAT_TO_DO says what to do with the completion.
|
---|
1641 | `?' means list the possible completions.
|
---|
1642 | TAB means do standard completion.
|
---|
1643 | `*' means insert all of the possible completions.
|
---|
1644 | `!' means to do standard completion, and list all possible completions if
|
---|
1645 | there is more than one.
|
---|
1646 | `@' means to do standard completion, and list all possible completions if
|
---|
1647 | there is more than one and partial completion is not possible. */
|
---|
1648 | int
|
---|
1649 | rl_complete_internal (what_to_do)
|
---|
1650 | int what_to_do;
|
---|
1651 | {
|
---|
1652 | char **matches;
|
---|
1653 | rl_compentry_func_t *our_func;
|
---|
1654 | int start, end, delimiter, found_quote, i, nontrivial_lcd;
|
---|
1655 | char *text, *saved_line_buffer;
|
---|
1656 | char quote_char;
|
---|
1657 |
|
---|
1658 | RL_SETSTATE(RL_STATE_COMPLETING);
|
---|
1659 |
|
---|
1660 | set_completion_defaults (what_to_do);
|
---|
1661 |
|
---|
1662 | saved_line_buffer = rl_line_buffer ? savestring (rl_line_buffer) : (char *)NULL;
|
---|
1663 | our_func = rl_completion_entry_function
|
---|
1664 | ? rl_completion_entry_function
|
---|
1665 | : rl_filename_completion_function;
|
---|
1666 | /* We now look backwards for the start of a filename/variable word. */
|
---|
1667 | end = rl_point;
|
---|
1668 | found_quote = delimiter = 0;
|
---|
1669 | quote_char = '\0';
|
---|
1670 |
|
---|
1671 | if (rl_point)
|
---|
1672 | /* This (possibly) changes rl_point. If it returns a non-zero char,
|
---|
1673 | we know we have an open quote. */
|
---|
1674 | quote_char = _rl_find_completion_word (&found_quote, &delimiter);
|
---|
1675 |
|
---|
1676 | start = rl_point;
|
---|
1677 | rl_point = end;
|
---|
1678 |
|
---|
1679 | text = rl_copy_text (start, end);
|
---|
1680 | matches = gen_completion_matches (text, start, end, our_func, found_quote, quote_char);
|
---|
1681 | /* nontrivial_lcd is set if the common prefix adds something to the word
|
---|
1682 | being completed. */
|
---|
1683 | nontrivial_lcd = matches && strcmp (text, matches[0]) != 0;
|
---|
1684 | free (text);
|
---|
1685 |
|
---|
1686 | if (matches == 0)
|
---|
1687 | {
|
---|
1688 | rl_ding ();
|
---|
1689 | FREE (saved_line_buffer);
|
---|
1690 | completion_changed_buffer = 0;
|
---|
1691 | RL_UNSETSTATE(RL_STATE_COMPLETING);
|
---|
1692 | return (0);
|
---|
1693 | }
|
---|
1694 |
|
---|
1695 | /* If we are matching filenames, the attempted completion function will
|
---|
1696 | have set rl_filename_completion_desired to a non-zero value. The basic
|
---|
1697 | rl_filename_completion_function does this. */
|
---|
1698 | i = rl_filename_completion_desired;
|
---|
1699 |
|
---|
1700 | if (postprocess_matches (&matches, i) == 0)
|
---|
1701 | {
|
---|
1702 | rl_ding ();
|
---|
1703 | FREE (saved_line_buffer);
|
---|
1704 | completion_changed_buffer = 0;
|
---|
1705 | RL_UNSETSTATE(RL_STATE_COMPLETING);
|
---|
1706 | return (0);
|
---|
1707 | }
|
---|
1708 |
|
---|
1709 | switch (what_to_do)
|
---|
1710 | {
|
---|
1711 | case TAB:
|
---|
1712 | case '!':
|
---|
1713 | case '@':
|
---|
1714 | /* Insert the first match with proper quoting. */
|
---|
1715 | if (*matches[0])
|
---|
1716 | insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, "e_char);
|
---|
1717 |
|
---|
1718 | /* If there are more matches, ring the bell to indicate.
|
---|
1719 | If we are in vi mode, Posix.2 says to not ring the bell.
|
---|
1720 | If the `show-all-if-ambiguous' variable is set, display
|
---|
1721 | all the matches immediately. Otherwise, if this was the
|
---|
1722 | only match, and we are hacking files, check the file to
|
---|
1723 | see if it was a directory. If so, and the `mark-directories'
|
---|
1724 | variable is set, add a '/' to the name. If not, and we
|
---|
1725 | are at the end of the line, then add a space. */
|
---|
1726 | if (matches[1])
|
---|
1727 | {
|
---|
1728 | if (what_to_do == '!')
|
---|
1729 | {
|
---|
1730 | display_matches (matches);
|
---|
1731 | break;
|
---|
1732 | }
|
---|
1733 | else if (what_to_do == '@')
|
---|
1734 | {
|
---|
1735 | if (nontrivial_lcd == 0)
|
---|
1736 | display_matches (matches);
|
---|
1737 | break;
|
---|
1738 | }
|
---|
1739 | else if (rl_editing_mode != vi_mode)
|
---|
1740 | rl_ding (); /* There are other matches remaining. */
|
---|
1741 | }
|
---|
1742 | else
|
---|
1743 | append_to_match (matches[0], delimiter, quote_char, nontrivial_lcd);
|
---|
1744 |
|
---|
1745 | break;
|
---|
1746 |
|
---|
1747 | case '*':
|
---|
1748 | insert_all_matches (matches, start, "e_char);
|
---|
1749 | break;
|
---|
1750 |
|
---|
1751 | case '?':
|
---|
1752 | display_matches (matches);
|
---|
1753 | break;
|
---|
1754 |
|
---|
1755 | default:
|
---|
1756 | fprintf (stderr, "\r\nreadline: bad value %d for what_to_do in rl_complete\n", what_to_do);
|
---|
1757 | rl_ding ();
|
---|
1758 | FREE (saved_line_buffer);
|
---|
1759 | RL_UNSETSTATE(RL_STATE_COMPLETING);
|
---|
1760 | return 1;
|
---|
1761 | }
|
---|
1762 |
|
---|
1763 | _rl_free_match_list (matches);
|
---|
1764 |
|
---|
1765 | /* Check to see if the line has changed through all of this manipulation. */
|
---|
1766 | if (saved_line_buffer)
|
---|
1767 | {
|
---|
1768 | completion_changed_buffer = strcmp (rl_line_buffer, saved_line_buffer) != 0;
|
---|
1769 | free (saved_line_buffer);
|
---|
1770 | }
|
---|
1771 |
|
---|
1772 | RL_UNSETSTATE(RL_STATE_COMPLETING);
|
---|
1773 | return 0;
|
---|
1774 | }
|
---|
1775 |
|
---|
1776 | /***************************************************************/
|
---|
1777 | /* */
|
---|
1778 | /* Application-callable completion match generator functions */
|
---|
1779 | /* */
|
---|
1780 | /***************************************************************/
|
---|
1781 |
|
---|
1782 | /* Return an array of (char *) which is a list of completions for TEXT.
|
---|
1783 | If there are no completions, return a NULL pointer.
|
---|
1784 | The first entry in the returned array is the substitution for TEXT.
|
---|
1785 | The remaining entries are the possible completions.
|
---|
1786 | The array is terminated with a NULL pointer.
|
---|
1787 |
|
---|
1788 | ENTRY_FUNCTION is a function of two args, and returns a (char *).
|
---|
1789 | The first argument is TEXT.
|
---|
1790 | The second is a state argument; it should be zero on the first call, and
|
---|
1791 | non-zero on subsequent calls. It returns a NULL pointer to the caller
|
---|
1792 | when there are no more matches.
|
---|
1793 | */
|
---|
1794 | char **
|
---|
1795 | rl_completion_matches (text, entry_function)
|
---|
1796 | const char *text;
|
---|
1797 | rl_compentry_func_t *entry_function;
|
---|
1798 | {
|
---|
1799 | /* Number of slots in match_list. */
|
---|
1800 | int match_list_size;
|
---|
1801 |
|
---|
1802 | /* The list of matches. */
|
---|
1803 | char **match_list;
|
---|
1804 |
|
---|
1805 | /* Number of matches actually found. */
|
---|
1806 | int matches;
|
---|
1807 |
|
---|
1808 | /* Temporary string binder. */
|
---|
1809 | char *string;
|
---|
1810 |
|
---|
1811 | matches = 0;
|
---|
1812 | match_list_size = 10;
|
---|
1813 | match_list = (char **)xmalloc ((match_list_size + 1) * sizeof (char *));
|
---|
1814 | match_list[1] = (char *)NULL;
|
---|
1815 |
|
---|
1816 | while (string = (*entry_function) (text, matches))
|
---|
1817 | {
|
---|
1818 | if (matches + 1 == match_list_size)
|
---|
1819 | match_list = (char **)xrealloc
|
---|
1820 | (match_list, ((match_list_size += 10) + 1) * sizeof (char *));
|
---|
1821 |
|
---|
1822 | match_list[++matches] = string;
|
---|
1823 | match_list[matches + 1] = (char *)NULL;
|
---|
1824 | }
|
---|
1825 |
|
---|
1826 | /* If there were any matches, then look through them finding out the
|
---|
1827 | lowest common denominator. That then becomes match_list[0]. */
|
---|
1828 | if (matches)
|
---|
1829 | compute_lcd_of_matches (match_list, matches, text);
|
---|
1830 | else /* There were no matches. */
|
---|
1831 | {
|
---|
1832 | free (match_list);
|
---|
1833 | match_list = (char **)NULL;
|
---|
1834 | }
|
---|
1835 | return (match_list);
|
---|
1836 | }
|
---|
1837 |
|
---|
1838 | /* A completion function for usernames.
|
---|
1839 | TEXT contains a partial username preceded by a random
|
---|
1840 | character (usually `~'). */
|
---|
1841 | char *
|
---|
1842 | rl_username_completion_function (text, state)
|
---|
1843 | const char *text;
|
---|
1844 | int state;
|
---|
1845 | {
|
---|
1846 | #if defined (__WIN32__) || defined (__OPENNT)
|
---|
1847 | return (char *)NULL;
|
---|
1848 | #else /* !__WIN32__ && !__OPENNT) */
|
---|
1849 | static char *username = (char *)NULL;
|
---|
1850 | static struct passwd *entry;
|
---|
1851 | static int namelen, first_char, first_char_loc;
|
---|
1852 | char *value;
|
---|
1853 |
|
---|
1854 | if (state == 0)
|
---|
1855 | {
|
---|
1856 | FREE (username);
|
---|
1857 |
|
---|
1858 | first_char = *text;
|
---|
1859 | first_char_loc = first_char == '~';
|
---|
1860 |
|
---|
1861 | username = savestring (&text[first_char_loc]);
|
---|
1862 | namelen = strlen (username);
|
---|
1863 | setpwent ();
|
---|
1864 | }
|
---|
1865 |
|
---|
1866 | #if defined (HAVE_GETPWENT)
|
---|
1867 | while (entry = getpwent ())
|
---|
1868 | {
|
---|
1869 | /* Null usernames should result in all users as possible completions. */
|
---|
1870 | if (namelen == 0 || (STREQN (username, entry->pw_name, namelen)))
|
---|
1871 | break;
|
---|
1872 | }
|
---|
1873 | #endif
|
---|
1874 |
|
---|
1875 | if (entry == 0)
|
---|
1876 | {
|
---|
1877 | #if defined (HAVE_GETPWENT)
|
---|
1878 | endpwent ();
|
---|
1879 | #endif
|
---|
1880 | return ((char *)NULL);
|
---|
1881 | }
|
---|
1882 | else
|
---|
1883 | {
|
---|
1884 | value = (char *)xmalloc (2 + strlen (entry->pw_name));
|
---|
1885 |
|
---|
1886 | *value = *text;
|
---|
1887 |
|
---|
1888 | strcpy (value + first_char_loc, entry->pw_name);
|
---|
1889 |
|
---|
1890 | if (first_char == '~')
|
---|
1891 | rl_filename_completion_desired = 1;
|
---|
1892 |
|
---|
1893 | return (value);
|
---|
1894 | }
|
---|
1895 | #endif /* !__WIN32__ && !__OPENNT */
|
---|
1896 | }
|
---|
1897 |
|
---|
1898 | /* Okay, now we write the entry_function for filename completion. In the
|
---|
1899 | general case. Note that completion in the shell is a little different
|
---|
1900 | because of all the pathnames that must be followed when looking up the
|
---|
1901 | completion for a command. */
|
---|
1902 | char *
|
---|
1903 | rl_filename_completion_function (text, state)
|
---|
1904 | const char *text;
|
---|
1905 | int state;
|
---|
1906 | {
|
---|
1907 | static DIR *directory = (DIR *)NULL;
|
---|
1908 | static char *filename = (char *)NULL;
|
---|
1909 | static char *dirname = (char *)NULL;
|
---|
1910 | static char *users_dirname = (char *)NULL;
|
---|
1911 | static int filename_len;
|
---|
1912 | char *temp;
|
---|
1913 | int dirlen;
|
---|
1914 | struct dirent *entry;
|
---|
1915 |
|
---|
1916 | /* If we don't have any state, then do some initialization. */
|
---|
1917 | if (state == 0)
|
---|
1918 | {
|
---|
1919 | /* If we were interrupted before closing the directory or reading
|
---|
1920 | all of its contents, close it. */
|
---|
1921 | if (directory)
|
---|
1922 | {
|
---|
1923 | closedir (directory);
|
---|
1924 | directory = (DIR *)NULL;
|
---|
1925 | }
|
---|
1926 | FREE (dirname);
|
---|
1927 | FREE (filename);
|
---|
1928 | FREE (users_dirname);
|
---|
1929 |
|
---|
1930 | filename = savestring (text);
|
---|
1931 | if (*text == 0)
|
---|
1932 | text = ".";
|
---|
1933 | dirname = savestring (text);
|
---|
1934 |
|
---|
1935 | temp = strrchr (dirname, '/');
|
---|
1936 |
|
---|
1937 | #if defined (__MSDOS__)
|
---|
1938 | /* special hack for //X/... */
|
---|
1939 | if (dirname[0] == '/' && dirname[1] == '/' && ISALPHA ((unsigned char)dirname[2]) && dirname[3] == '/')
|
---|
1940 | temp = strrchr (dirname + 3, '/');
|
---|
1941 | #endif
|
---|
1942 |
|
---|
1943 | if (temp)
|
---|
1944 | {
|
---|
1945 | strcpy (filename, ++temp);
|
---|
1946 | *temp = '\0';
|
---|
1947 | }
|
---|
1948 | #if defined (__MSDOS__)
|
---|
1949 | /* searches from current directory on the drive */
|
---|
1950 | else if (ISALPHA ((unsigned char)dirname[0]) && dirname[1] == ':')
|
---|
1951 | {
|
---|
1952 | strcpy (filename, dirname + 2);
|
---|
1953 | dirname[2] = '\0';
|
---|
1954 | }
|
---|
1955 | #endif
|
---|
1956 | else
|
---|
1957 | {
|
---|
1958 | dirname[0] = '.';
|
---|
1959 | dirname[1] = '\0';
|
---|
1960 | }
|
---|
1961 |
|
---|
1962 | /* We aren't done yet. We also support the "~user" syntax. */
|
---|
1963 |
|
---|
1964 | /* Save the version of the directory that the user typed. */
|
---|
1965 | users_dirname = savestring (dirname);
|
---|
1966 |
|
---|
1967 | if (*dirname == '~')
|
---|
1968 | {
|
---|
1969 | temp = tilde_expand (dirname);
|
---|
1970 | free (dirname);
|
---|
1971 | dirname = temp;
|
---|
1972 | }
|
---|
1973 |
|
---|
1974 | if (rl_directory_rewrite_hook)
|
---|
1975 | (*rl_directory_rewrite_hook) (&dirname);
|
---|
1976 |
|
---|
1977 | if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&dirname))
|
---|
1978 | {
|
---|
1979 | free (users_dirname);
|
---|
1980 | users_dirname = savestring (dirname);
|
---|
1981 | }
|
---|
1982 |
|
---|
1983 | directory = opendir (dirname);
|
---|
1984 | filename_len = strlen (filename);
|
---|
1985 |
|
---|
1986 | rl_filename_completion_desired = 1;
|
---|
1987 | }
|
---|
1988 |
|
---|
1989 | /* At this point we should entertain the possibility of hacking wildcarded
|
---|
1990 | filenames, like /usr/man/man<WILD>/te<TAB>. If the directory name
|
---|
1991 | contains globbing characters, then build an array of directories, and
|
---|
1992 | then map over that list while completing. */
|
---|
1993 | /* *** UNIMPLEMENTED *** */
|
---|
1994 |
|
---|
1995 | /* Now that we have some state, we can read the directory. */
|
---|
1996 |
|
---|
1997 | entry = (struct dirent *)NULL;
|
---|
1998 | while (directory && (entry = readdir (directory)))
|
---|
1999 | {
|
---|
2000 | /* Special case for no filename. If the user has disabled the
|
---|
2001 | `match-hidden-files' variable, skip filenames beginning with `.'.
|
---|
2002 | All other entries except "." and ".." match. */
|
---|
2003 | if (filename_len == 0)
|
---|
2004 | {
|
---|
2005 | if (_rl_match_hidden_files == 0 && HIDDEN_FILE (entry->d_name))
|
---|
2006 | continue;
|
---|
2007 |
|
---|
2008 | if (entry->d_name[0] != '.' ||
|
---|
2009 | (entry->d_name[1] &&
|
---|
2010 | (entry->d_name[1] != '.' || entry->d_name[2])))
|
---|
2011 | break;
|
---|
2012 | }
|
---|
2013 | else
|
---|
2014 | {
|
---|
2015 | /* Otherwise, if these match up to the length of filename, then
|
---|
2016 | it is a match. */
|
---|
2017 | if (_rl_completion_case_fold)
|
---|
2018 | {
|
---|
2019 | if ((_rl_to_lower (entry->d_name[0]) == _rl_to_lower (filename[0])) &&
|
---|
2020 | (((int)D_NAMLEN (entry)) >= filename_len) &&
|
---|
2021 | (_rl_strnicmp (filename, entry->d_name, filename_len) == 0))
|
---|
2022 | break;
|
---|
2023 | }
|
---|
2024 | else
|
---|
2025 | {
|
---|
2026 | if ((entry->d_name[0] == filename[0]) &&
|
---|
2027 | (((int)D_NAMLEN (entry)) >= filename_len) &&
|
---|
2028 | (strncmp (filename, entry->d_name, filename_len) == 0))
|
---|
2029 | break;
|
---|
2030 | }
|
---|
2031 | }
|
---|
2032 | }
|
---|
2033 |
|
---|
2034 | if (entry == 0)
|
---|
2035 | {
|
---|
2036 | if (directory)
|
---|
2037 | {
|
---|
2038 | closedir (directory);
|
---|
2039 | directory = (DIR *)NULL;
|
---|
2040 | }
|
---|
2041 | if (dirname)
|
---|
2042 | {
|
---|
2043 | free (dirname);
|
---|
2044 | dirname = (char *)NULL;
|
---|
2045 | }
|
---|
2046 | if (filename)
|
---|
2047 | {
|
---|
2048 | free (filename);
|
---|
2049 | filename = (char *)NULL;
|
---|
2050 | }
|
---|
2051 | if (users_dirname)
|
---|
2052 | {
|
---|
2053 | free (users_dirname);
|
---|
2054 | users_dirname = (char *)NULL;
|
---|
2055 | }
|
---|
2056 |
|
---|
2057 | return (char *)NULL;
|
---|
2058 | }
|
---|
2059 | else
|
---|
2060 | {
|
---|
2061 | /* dirname && (strcmp (dirname, ".") != 0) */
|
---|
2062 | if (dirname && (dirname[0] != '.' || dirname[1]))
|
---|
2063 | {
|
---|
2064 | if (rl_complete_with_tilde_expansion && *users_dirname == '~')
|
---|
2065 | {
|
---|
2066 | dirlen = strlen (dirname);
|
---|
2067 | temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry));
|
---|
2068 | strcpy (temp, dirname);
|
---|
2069 | /* Canonicalization cuts off any final slash present. We
|
---|
2070 | may need to add it back. */
|
---|
2071 | if (dirname[dirlen - 1] != '/')
|
---|
2072 | {
|
---|
2073 | temp[dirlen++] = '/';
|
---|
2074 | temp[dirlen] = '\0';
|
---|
2075 | }
|
---|
2076 | }
|
---|
2077 | else
|
---|
2078 | {
|
---|
2079 | dirlen = strlen (users_dirname);
|
---|
2080 | temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry));
|
---|
2081 | strcpy (temp, users_dirname);
|
---|
2082 | /* Make sure that temp has a trailing slash here. */
|
---|
2083 | if (users_dirname[dirlen - 1] != '/')
|
---|
2084 | temp[dirlen++] = '/';
|
---|
2085 | }
|
---|
2086 |
|
---|
2087 | strcpy (temp + dirlen, entry->d_name);
|
---|
2088 | }
|
---|
2089 | else
|
---|
2090 | temp = savestring (entry->d_name);
|
---|
2091 |
|
---|
2092 | return (temp);
|
---|
2093 | }
|
---|
2094 | }
|
---|
2095 |
|
---|
2096 | /* An initial implementation of a menu completion function a la tcsh. The
|
---|
2097 | first time (if the last readline command was not rl_menu_complete), we
|
---|
2098 | generate the list of matches. This code is very similar to the code in
|
---|
2099 | rl_complete_internal -- there should be a way to combine the two. Then,
|
---|
2100 | for each item in the list of matches, we insert the match in an undoable
|
---|
2101 | fashion, with the appropriate character appended (this happens on the
|
---|
2102 | second and subsequent consecutive calls to rl_menu_complete). When we
|
---|
2103 | hit the end of the match list, we restore the original unmatched text,
|
---|
2104 | ring the bell, and reset the counter to zero. */
|
---|
2105 | int
|
---|
2106 | rl_menu_complete (count, ignore)
|
---|
2107 | int count, ignore;
|
---|
2108 | {
|
---|
2109 | rl_compentry_func_t *our_func;
|
---|
2110 | int matching_filenames, found_quote;
|
---|
2111 |
|
---|
2112 | static char *orig_text;
|
---|
2113 | static char **matches = (char **)0;
|
---|
2114 | static int match_list_index = 0;
|
---|
2115 | static int match_list_size = 0;
|
---|
2116 | static int orig_start, orig_end;
|
---|
2117 | static char quote_char;
|
---|
2118 | static int delimiter;
|
---|
2119 |
|
---|
2120 | /* The first time through, we generate the list of matches and set things
|
---|
2121 | up to insert them. */
|
---|
2122 | if (rl_last_func != rl_menu_complete)
|
---|
2123 | {
|
---|
2124 | /* Clean up from previous call, if any. */
|
---|
2125 | FREE (orig_text);
|
---|
2126 | if (matches)
|
---|
2127 | _rl_free_match_list (matches);
|
---|
2128 |
|
---|
2129 | match_list_index = match_list_size = 0;
|
---|
2130 | matches = (char **)NULL;
|
---|
2131 |
|
---|
2132 | /* Only the completion entry function can change these. */
|
---|
2133 | set_completion_defaults ('%');
|
---|
2134 |
|
---|
2135 | our_func = rl_completion_entry_function
|
---|
2136 | ? rl_completion_entry_function
|
---|
2137 | : rl_filename_completion_function;
|
---|
2138 |
|
---|
2139 | /* We now look backwards for the start of a filename/variable word. */
|
---|
2140 | orig_end = rl_point;
|
---|
2141 | found_quote = delimiter = 0;
|
---|
2142 | quote_char = '\0';
|
---|
2143 |
|
---|
2144 | if (rl_point)
|
---|
2145 | /* This (possibly) changes rl_point. If it returns a non-zero char,
|
---|
2146 | we know we have an open quote. */
|
---|
2147 | quote_char = _rl_find_completion_word (&found_quote, &delimiter);
|
---|
2148 |
|
---|
2149 | orig_start = rl_point;
|
---|
2150 | rl_point = orig_end;
|
---|
2151 |
|
---|
2152 | orig_text = rl_copy_text (orig_start, orig_end);
|
---|
2153 | matches = gen_completion_matches (orig_text, orig_start, orig_end,
|
---|
2154 | our_func, found_quote, quote_char);
|
---|
2155 |
|
---|
2156 | /* If we are matching filenames, the attempted completion function will
|
---|
2157 | have set rl_filename_completion_desired to a non-zero value. The basic
|
---|
2158 | rl_filename_completion_function does this. */
|
---|
2159 | matching_filenames = rl_filename_completion_desired;
|
---|
2160 |
|
---|
2161 | if (matches == 0 || postprocess_matches (&matches, matching_filenames) == 0)
|
---|
2162 | {
|
---|
2163 | rl_ding ();
|
---|
2164 | FREE (matches);
|
---|
2165 | matches = (char **)0;
|
---|
2166 | FREE (orig_text);
|
---|
2167 | orig_text = (char *)0;
|
---|
2168 | completion_changed_buffer = 0;
|
---|
2169 | return (0);
|
---|
2170 | }
|
---|
2171 |
|
---|
2172 | for (match_list_size = 0; matches[match_list_size]; match_list_size++)
|
---|
2173 | ;
|
---|
2174 | /* matches[0] is lcd if match_list_size > 1, but the circular buffer
|
---|
2175 | code below should take care of it. */
|
---|
2176 | }
|
---|
2177 |
|
---|
2178 | /* Now we have the list of matches. Replace the text between
|
---|
2179 | rl_line_buffer[orig_start] and rl_line_buffer[rl_point] with
|
---|
2180 | matches[match_list_index], and add any necessary closing char. */
|
---|
2181 |
|
---|
2182 | if (matches == 0 || match_list_size == 0)
|
---|
2183 | {
|
---|
2184 | rl_ding ();
|
---|
2185 | FREE (matches);
|
---|
2186 | matches = (char **)0;
|
---|
2187 | completion_changed_buffer = 0;
|
---|
2188 | return (0);
|
---|
2189 | }
|
---|
2190 |
|
---|
2191 | match_list_index += count;
|
---|
2192 | if (match_list_index < 0)
|
---|
2193 | match_list_index += match_list_size;
|
---|
2194 | else
|
---|
2195 | match_list_index %= match_list_size;
|
---|
2196 |
|
---|
2197 | if (match_list_index == 0 && match_list_size > 1)
|
---|
2198 | {
|
---|
2199 | rl_ding ();
|
---|
2200 | insert_match (orig_text, orig_start, MULT_MATCH, "e_char);
|
---|
2201 | }
|
---|
2202 | else
|
---|
2203 | {
|
---|
2204 | insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, "e_char);
|
---|
2205 | append_to_match (matches[match_list_index], delimiter, quote_char,
|
---|
2206 | strcmp (orig_text, matches[match_list_index]));
|
---|
2207 | }
|
---|
2208 |
|
---|
2209 | completion_changed_buffer = 1;
|
---|
2210 | return (0);
|
---|
2211 | }
|
---|