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 || c < 0) |
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; |
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 |
/* XXX -- filename dequoting moved into rl_filename_completion_function */ |
973 |
|
974 |
matches = rl_completion_matches (text, our_func); |
975 |
return matches; |
976 |
} |
977 |
|
978 |
/* Filter out duplicates in MATCHES. This frees up the strings in |
979 |
MATCHES. */ |
980 |
static char ** |
981 |
remove_duplicate_matches (matches) |
982 |
char **matches; |
983 |
{ |
984 |
char *lowest_common; |
985 |
int i, j, newlen; |
986 |
char dead_slot; |
987 |
char **temp_array; |
988 |
|
989 |
/* Sort the items. */ |
990 |
for (i = 0; matches[i]; i++) |
991 |
; |
992 |
|
993 |
/* Sort the array without matches[0], since we need it to |
994 |
stay in place no matter what. */ |
995 |
if (i) |
996 |
qsort (matches+1, i-1, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare); |
997 |
|
998 |
/* Remember the lowest common denominator for it may be unique. */ |
999 |
lowest_common = savestring (matches[0]); |
1000 |
|
1001 |
for (i = newlen = 0; matches[i + 1]; i++) |
1002 |
{ |
1003 |
if (strcmp (matches[i], matches[i + 1]) == 0) |
1004 |
{ |
1005 |
free (matches[i]); |
1006 |
matches[i] = (char *)&dead_slot; |
1007 |
} |
1008 |
else |
1009 |
newlen++; |
1010 |
} |
1011 |
|
1012 |
/* We have marked all the dead slots with (char *)&dead_slot. |
1013 |
Copy all the non-dead entries into a new array. */ |
1014 |
temp_array = (char **)xmalloc ((3 + newlen) * sizeof (char *)); |
1015 |
for (i = j = 1; matches[i]; i++) |
1016 |
{ |
1017 |
if (matches[i] != (char *)&dead_slot) |
1018 |
temp_array[j++] = matches[i]; |
1019 |
} |
1020 |
temp_array[j] = (char *)NULL; |
1021 |
|
1022 |
if (matches[0] != (char *)&dead_slot) |
1023 |
free (matches[0]); |
1024 |
|
1025 |
/* Place the lowest common denominator back in [0]. */ |
1026 |
temp_array[0] = lowest_common; |
1027 |
|
1028 |
/* If there is one string left, and it is identical to the |
1029 |
lowest common denominator, then the LCD is the string to |
1030 |
insert. */ |
1031 |
if (j == 2 && strcmp (temp_array[0], temp_array[1]) == 0) |
1032 |
{ |
1033 |
free (temp_array[1]); |
1034 |
temp_array[1] = (char *)NULL; |
1035 |
} |
1036 |
return (temp_array); |
1037 |
} |
1038 |
|
1039 |
/* Find the common prefix of the list of matches, and put it into |
1040 |
matches[0]. */ |
1041 |
static int |
1042 |
compute_lcd_of_matches (match_list, matches, text) |
1043 |
char **match_list; |
1044 |
int matches; |
1045 |
const char *text; |
1046 |
{ |
1047 |
register int i, c1, c2, si; |
1048 |
int low; /* Count of max-matched characters. */ |
1049 |
char *dtext; /* dequoted TEXT, if needed */ |
1050 |
#if defined (HANDLE_MULTIBYTE) |
1051 |
int v; |
1052 |
mbstate_t ps1, ps2; |
1053 |
wchar_t wc1, wc2; |
1054 |
#endif |
1055 |
|
1056 |
/* If only one match, just use that. Otherwise, compare each |
1057 |
member of the list with the next, finding out where they |
1058 |
stop matching. */ |
1059 |
if (matches == 1) |
1060 |
{ |
1061 |
match_list[0] = match_list[1]; |
1062 |
match_list[1] = (char *)NULL; |
1063 |
return 1; |
1064 |
} |
1065 |
|
1066 |
for (i = 1, low = 100000; i < matches; i++) |
1067 |
{ |
1068 |
#if defined (HANDLE_MULTIBYTE) |
1069 |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) |
1070 |
{ |
1071 |
memset (&ps1, 0, sizeof (mbstate_t)); |
1072 |
memset (&ps2, 0, sizeof (mbstate_t)); |
1073 |
} |
1074 |
#endif |
1075 |
if (_rl_completion_case_fold) |
1076 |
{ |
1077 |
for (si = 0; |
1078 |
(c1 = _rl_to_lower(match_list[i][si])) && |
1079 |
(c2 = _rl_to_lower(match_list[i + 1][si])); |
1080 |
si++) |
1081 |
#if defined (HANDLE_MULTIBYTE) |
1082 |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) |
1083 |
{ |
1084 |
v = mbrtowc (&wc1, match_list[i]+si, strlen (match_list[i]+si), &ps1); |
1085 |
mbrtowc (&wc2, match_list[i+1]+si, strlen (match_list[i+1]+si), &ps2); |
1086 |
wc1 = towlower (wc1); |
1087 |
wc2 = towlower (wc2); |
1088 |
if (wc1 != wc2) |
1089 |
break; |
1090 |
else if (v > 1) |
1091 |
si += v - 1; |
1092 |
} |
1093 |
else |
1094 |
#endif |
1095 |
if (c1 != c2) |
1096 |
break; |
1097 |
} |
1098 |
else |
1099 |
{ |
1100 |
for (si = 0; |
1101 |
(c1 = match_list[i][si]) && |
1102 |
(c2 = match_list[i + 1][si]); |
1103 |
si++) |
1104 |
#if defined (HANDLE_MULTIBYTE) |
1105 |
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) |
1106 |
{ |
1107 |
mbstate_t ps_back; |
1108 |
ps_back = ps1; |
1109 |
if (!_rl_compare_chars (match_list[i], si, &ps1, match_list[i+1], si, &ps2)) |
1110 |
break; |
1111 |
else if ((v = _rl_get_char_len (&match_list[i][si], &ps_back)) > 1) |
1112 |
si += v - 1; |
1113 |
} |
1114 |
else |
1115 |
#endif |
1116 |
if (c1 != c2) |
1117 |
break; |
1118 |
} |
1119 |
|
1120 |
if (low > si) |
1121 |
low = si; |
1122 |
} |
1123 |
|
1124 |
/* If there were multiple matches, but none matched up to even the |
1125 |
first character, and the user typed something, use that as the |
1126 |
value of matches[0]. */ |
1127 |
if (low == 0 && text && *text) |
1128 |
{ |
1129 |
match_list[0] = (char *)xmalloc (strlen (text) + 1); |
1130 |
strcpy (match_list[0], text); |
1131 |
} |
1132 |
else |
1133 |
{ |
1134 |
match_list[0] = (char *)xmalloc (low + 1); |
1135 |
|
1136 |
/* XXX - this might need changes in the presence of multibyte chars */ |
1137 |
|
1138 |
/* If we are ignoring case, try to preserve the case of the string |
1139 |
the user typed in the face of multiple matches differing in case. */ |
1140 |
if (_rl_completion_case_fold) |
1141 |
{ |
1142 |
/* We're making an assumption here: |
1143 |
IF we're completing filenames AND |
1144 |
the application has defined a filename dequoting function AND |
1145 |
we found a quote character AND |
1146 |
the application has requested filename quoting |
1147 |
THEN |
1148 |
we assume that TEXT was dequoted before checking against |
1149 |
the file system and needs to be dequoted here before we |
1150 |
check against the list of matches |
1151 |
FI */ |
1152 |
dtext = (char *)NULL; |
1153 |
if (rl_filename_completion_desired && |
1154 |
rl_filename_dequoting_function && |
1155 |
rl_completion_found_quote && |
1156 |
rl_filename_quoting_desired) |
1157 |
{ |
1158 |
dtext = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character); |
1159 |
text = dtext; |
1160 |
} |
1161 |
|
1162 |
/* sort the list to get consistent answers. */ |
1163 |
qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare); |
1164 |
|
1165 |
si = strlen (text); |
1166 |
if (si <= low) |
1167 |
{ |
1168 |
for (i = 1; i <= matches; i++) |
1169 |
if (strncmp (match_list[i], text, si) == 0) |
1170 |
{ |
1171 |
strncpy (match_list[0], match_list[i], low); |
1172 |
break; |
1173 |
} |
1174 |
/* no casematch, use first entry */ |
1175 |
if (i > matches) |
1176 |
strncpy (match_list[0], match_list[1], low); |
1177 |
} |
1178 |
else |
1179 |
/* otherwise, just use the text the user typed. */ |
1180 |
strncpy (match_list[0], text, low); |
1181 |
|
1182 |
FREE (dtext); |
1183 |
} |
1184 |
else |
1185 |
strncpy (match_list[0], match_list[1], low); |
1186 |
|
1187 |
match_list[0][low] = '\0'; |
1188 |
} |
1189 |
|
1190 |
return matches; |
1191 |
} |
1192 |
|
1193 |
static int |
1194 |
postprocess_matches (matchesp, matching_filenames) |
1195 |
char ***matchesp; |
1196 |
int matching_filenames; |
1197 |
{ |
1198 |
char *t, **matches, **temp_matches; |
1199 |
int nmatch, i; |
1200 |
|
1201 |
matches = *matchesp; |
1202 |
|
1203 |
if (matches == 0) |
1204 |
return 0; |
1205 |
|
1206 |
/* It seems to me that in all the cases we handle we would like |
1207 |
to ignore duplicate possiblilities. Scan for the text to |
1208 |
insert being identical to the other completions. */ |
1209 |
if (rl_ignore_completion_duplicates) |
1210 |
{ |
1211 |
temp_matches = remove_duplicate_matches (matches); |
1212 |
free (matches); |
1213 |
matches = temp_matches; |
1214 |
} |
1215 |
|
1216 |
/* If we are matching filenames, then here is our chance to |
1217 |
do clever processing by re-examining the list. Call the |
1218 |
ignore function with the array as a parameter. It can |
1219 |
munge the array, deleting matches as it desires. */ |
1220 |
if (rl_ignore_some_completions_function && matching_filenames) |
1221 |
{ |
1222 |
for (nmatch = 1; matches[nmatch]; nmatch++) |
1223 |
; |
1224 |
(void)(*rl_ignore_some_completions_function) (matches); |
1225 |
if (matches == 0 || matches[0] == 0) |
1226 |
{ |
1227 |
FREE (matches); |
1228 |
*matchesp = (char **)0; |
1229 |
return 0; |
1230 |
} |
1231 |
else |
1232 |
{ |
1233 |
/* If we removed some matches, recompute the common prefix. */ |
1234 |
for (i = 1; matches[i]; i++) |
1235 |
; |
1236 |
if (i > 1 && i < nmatch) |
1237 |
{ |
1238 |
t = matches[0]; |
1239 |
compute_lcd_of_matches (matches, i - 1, t); |
1240 |
FREE (t); |
1241 |
} |
1242 |
} |
1243 |
} |
1244 |
|
1245 |
*matchesp = matches; |
1246 |
return (1); |
1247 |
} |
1248 |
|
1249 |
/* A convenience function for displaying a list of strings in |
1250 |
columnar format on readline's output stream. MATCHES is the list |
1251 |
of strings, in argv format, LEN is the number of strings in MATCHES, |
1252 |
and MAX is the length of the longest string in MATCHES. */ |
1253 |
void |
1254 |
rl_display_match_list (matches, len, max) |
1255 |
char **matches; |
1256 |
int len, max; |
1257 |
{ |
1258 |
int count, limit, printed_len, lines; |
1259 |
int i, j, k, l; |
1260 |
char *temp; |
1261 |
|
1262 |
/* How many items of MAX length can we fit in the screen window? */ |
1263 |
max += 2; |
1264 |
limit = _rl_screenwidth / max; |
1265 |
if (limit != 1 && (limit * max == _rl_screenwidth)) |
1266 |
limit--; |
1267 |
|
1268 |
/* Avoid a possible floating exception. If max > _rl_screenwidth, |
1269 |
limit will be 0 and a divide-by-zero fault will result. */ |
1270 |
if (limit == 0) |
1271 |
limit = 1; |
1272 |
|
1273 |
/* How many iterations of the printing loop? */ |
1274 |
count = (len + (limit - 1)) / limit; |
1275 |
|
1276 |
/* Watch out for special case. If LEN is less than LIMIT, then |
1277 |
just do the inner printing loop. |
1278 |
0 < len <= limit implies count = 1. */ |
1279 |
|
1280 |
/* Sort the items if they are not already sorted. */ |
1281 |
if (rl_ignore_completion_duplicates == 0) |
1282 |
qsort (matches + 1, len, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare); |
1283 |
|
1284 |
rl_crlf (); |
1285 |
|
1286 |
lines = 0; |
1287 |
if (_rl_print_completions_horizontally == 0) |
1288 |
{ |
1289 |
/* Print the sorted items, up-and-down alphabetically, like ls. */ |
1290 |
for (i = 1; i <= count; i++) |
1291 |
{ |
1292 |
for (j = 0, l = i; j < limit; j++) |
1293 |
{ |
1294 |
if (l > len || matches[l] == 0) |
1295 |
break; |
1296 |
else |
1297 |
{ |
1298 |
temp = printable_part (matches[l]); |
1299 |
printed_len = print_filename (temp, matches[l]); |
1300 |
|
1301 |
if (j + 1 < limit) |
1302 |
for (k = 0; k < max - printed_len; k++) |
1303 |
putc (' ', rl_outstream); |
1304 |
} |
1305 |
l += count; |
1306 |
} |
1307 |
rl_crlf (); |
1308 |
lines++; |
1309 |
if (_rl_page_completions && lines >= (_rl_screenheight - 1) && i < count) |
1310 |
{ |
1311 |
lines = _rl_internal_pager (lines); |
1312 |
if (lines < 0) |
1313 |
return; |
1314 |
} |
1315 |
} |
1316 |
} |
1317 |
else |
1318 |
{ |
1319 |
/* Print the sorted items, across alphabetically, like ls -x. */ |
1320 |
for (i = 1; matches[i]; i++) |
1321 |
{ |
1322 |
temp = printable_part (matches[i]); |
1323 |
printed_len = print_filename (temp, matches[i]); |
1324 |
/* Have we reached the end of this line? */ |
1325 |
if (matches[i+1]) |
1326 |
{ |
1327 |
if (i && (limit > 1) && (i % limit) == 0) |
1328 |
{ |
1329 |
rl_crlf (); |
1330 |
lines++; |
1331 |
if (_rl_page_completions && lines >= _rl_screenheight - 1) |
1332 |
{ |
1333 |
lines = _rl_internal_pager (lines); |
1334 |
if (lines < 0) |
1335 |
return; |
1336 |
} |
1337 |
} |
1338 |
else |
1339 |
for (k = 0; k < max - printed_len; k++) |
1340 |
putc (' ', rl_outstream); |
1341 |
} |
1342 |
} |
1343 |
rl_crlf (); |
1344 |
} |
1345 |
} |
1346 |
|
1347 |
/* Display MATCHES, a list of matching filenames in argv format. This |
1348 |
handles the simple case -- a single match -- first. If there is more |
1349 |
than one match, we compute the number of strings in the list and the |
1350 |
length of the longest string, which will be needed by the display |
1351 |
function. If the application wants to handle displaying the list of |
1352 |
matches itself, it sets RL_COMPLETION_DISPLAY_MATCHES_HOOK to the |
1353 |
address of a function, and we just call it. If we're handling the |
1354 |
display ourselves, we just call rl_display_match_list. We also check |
1355 |
that the list of matches doesn't exceed the user-settable threshold, |
1356 |
and ask the user if he wants to see the list if there are more matches |
1357 |
than RL_COMPLETION_QUERY_ITEMS. */ |
1358 |
static void |
1359 |
display_matches (matches) |
1360 |
char **matches; |
1361 |
{ |
1362 |
int len, max, i; |
1363 |
char *temp; |
1364 |
|
1365 |
/* Move to the last visible line of a possibly-multiple-line command. */ |
1366 |
_rl_move_vert (_rl_vis_botlin); |
1367 |
|
1368 |
/* Handle simple case first. What if there is only one answer? */ |
1369 |
if (matches[1] == 0) |
1370 |
{ |
1371 |
temp = printable_part (matches[0]); |
1372 |
rl_crlf (); |
1373 |
print_filename (temp, matches[0]); |
1374 |
rl_crlf (); |
1375 |
|
1376 |
rl_forced_update_display (); |
1377 |
rl_display_fixed = 1; |
1378 |
|
1379 |
return; |
1380 |
} |
1381 |
|
1382 |
/* There is more than one answer. Find out how many there are, |
1383 |
and find the maximum printed length of a single entry. */ |
1384 |
for (max = 0, i = 1; matches[i]; i++) |
1385 |
{ |
1386 |
temp = printable_part (matches[i]); |
1387 |
len = fnwidth (temp); |
1388 |
|
1389 |
if (len > max) |
1390 |
max = len; |
1391 |
} |
1392 |
|
1393 |
len = i - 1; |
1394 |
|
1395 |
/* If the caller has defined a display hook, then call that now. */ |
1396 |
if (rl_completion_display_matches_hook) |
1397 |
{ |
1398 |
(*rl_completion_display_matches_hook) (matches, len, max); |
1399 |
return; |
1400 |
} |
1401 |
|
1402 |
/* If there are many items, then ask the user if she really wants to |
1403 |
see them all. */ |
1404 |
if (rl_completion_query_items > 0 && len >= rl_completion_query_items) |
1405 |
{ |
1406 |
rl_crlf (); |
1407 |
fprintf (rl_outstream, "Display all %d possibilities? (y or n)", len); |
1408 |
fflush (rl_outstream); |
1409 |
if (get_y_or_n (0) == 0) |
1410 |
{ |
1411 |
rl_crlf (); |
1412 |
|
1413 |
rl_forced_update_display (); |
1414 |
rl_display_fixed = 1; |
1415 |
|
1416 |
return; |
1417 |
} |
1418 |
} |
1419 |
|
1420 |
rl_display_match_list (matches, len, max); |
1421 |
|
1422 |
rl_forced_update_display (); |
1423 |
rl_display_fixed = 1; |
1424 |
} |
1425 |
|
1426 |
static char * |
1427 |
make_quoted_replacement (match, mtype, qc) |
1428 |
char *match; |
1429 |
int mtype; |
1430 |
char *qc; /* Pointer to quoting character, if any */ |
1431 |
{ |
1432 |
int should_quote, do_replace; |
1433 |
char *replacement; |
1434 |
|
1435 |
/* If we are doing completion on quoted substrings, and any matches |
1436 |
contain any of the completer_word_break_characters, then auto- |
1437 |
matically prepend the substring with a quote character (just pick |
1438 |
the first one from the list of such) if it does not already begin |
1439 |
with a quote string. FIXME: Need to remove any such automatically |
1440 |
inserted quote character when it no longer is necessary, such as |
1441 |
if we change the string we are completing on and the new set of |
1442 |
matches don't require a quoted substring. */ |
1443 |
replacement = match; |
1444 |
|
1445 |
should_quote = match && rl_completer_quote_characters && |
1446 |
rl_filename_completion_desired && |
1447 |
rl_filename_quoting_desired; |
1448 |
|
1449 |
if (should_quote) |
1450 |
should_quote = should_quote && (!qc || !*qc || |
1451 |
(rl_completer_quote_characters && strchr (rl_completer_quote_characters, *qc))); |
1452 |
|
1453 |
if (should_quote) |
1454 |
{ |
1455 |
/* If there is a single match, see if we need to quote it. |
1456 |
This also checks whether the common prefix of several |
1457 |
matches needs to be quoted. */ |
1458 |
should_quote = rl_filename_quote_characters |
1459 |
? (_rl_strpbrk (match, rl_filename_quote_characters) != 0) |
1460 |
: 0; |
1461 |
|
1462 |
do_replace = should_quote ? mtype : NO_MATCH; |
1463 |
/* Quote the replacement, since we found an embedded |
1464 |
word break character in a potential match. */ |
1465 |
if (do_replace != NO_MATCH && rl_filename_quoting_function) |
1466 |
replacement = (*rl_filename_quoting_function) (match, do_replace, qc); |
1467 |
} |
1468 |
return (replacement); |
1469 |
} |
1470 |
|
1471 |
static void |
1472 |
insert_match (match, start, mtype, qc) |
1473 |
char *match; |
1474 |
int start, mtype; |
1475 |
char *qc; |
1476 |
{ |
1477 |
char *replacement; |
1478 |
char oqc; |
1479 |
|
1480 |
oqc = qc ? *qc : '\0'; |
1481 |
replacement = make_quoted_replacement (match, mtype, qc); |
1482 |
|
1483 |
/* Now insert the match. */ |
1484 |
if (replacement) |
1485 |
{ |
1486 |
/* Don't double an opening quote character. */ |
1487 |
if (qc && *qc && start && rl_line_buffer[start - 1] == *qc && |
1488 |
replacement[0] == *qc) |
1489 |
start--; |
1490 |
/* If make_quoted_replacement changed the quoting character, remove |
1491 |
the opening quote and insert the (fully-quoted) replacement. */ |
1492 |
else if (qc && (*qc != oqc) && start && rl_line_buffer[start - 1] == oqc && |
1493 |
replacement[0] != oqc) |
1494 |
start--; |
1495 |
_rl_replace_text (replacement, start, rl_point - 1); |
1496 |
if (replacement != match) |
1497 |
free (replacement); |
1498 |
} |
1499 |
} |
1500 |
|
1501 |
/* Append any necessary closing quote and a separator character to the |
1502 |
just-inserted match. If the user has specified that directories |
1503 |
should be marked by a trailing `/', append one of those instead. The |
1504 |
default trailing character is a space. Returns the number of characters |
1505 |
appended. If NONTRIVIAL_MATCH is set, we test for a symlink (if the OS |
1506 |
has them) and don't add a suffix for a symlink to a directory. A |
1507 |
nontrivial match is one that actually adds to the word being completed. |
1508 |
The variable rl_completion_mark_symlink_dirs controls this behavior |
1509 |
(it's initially set to the what the user has chosen, indicated by the |
1510 |
value of _rl_complete_mark_symlink_dirs, but may be modified by an |
1511 |
application's completion function). */ |
1512 |
static int |
1513 |
append_to_match (text, delimiter, quote_char, nontrivial_match) |
1514 |
char *text; |
1515 |
int delimiter, quote_char, nontrivial_match; |
1516 |
{ |
1517 |
char temp_string[4], *filename; |
1518 |
int temp_string_index, s; |
1519 |
struct stat finfo; |
1520 |
|
1521 |
temp_string_index = 0; |
1522 |
if (quote_char && rl_point && rl_completion_suppress_quote == 0 && |
1523 |
rl_line_buffer[rl_point - 1] != quote_char) |
1524 |
temp_string[temp_string_index++] = quote_char; |
1525 |
|
1526 |
if (delimiter) |
1527 |
temp_string[temp_string_index++] = delimiter; |
1528 |
else if (rl_completion_suppress_append == 0 && rl_completion_append_character) |
1529 |
temp_string[temp_string_index++] = rl_completion_append_character; |
1530 |
|
1531 |
temp_string[temp_string_index++] = '\0'; |
1532 |
|
1533 |
if (rl_filename_completion_desired) |
1534 |
{ |
1535 |
filename = tilde_expand (text); |
1536 |
s = (nontrivial_match && rl_completion_mark_symlink_dirs == 0) |
1537 |
? LSTAT (filename, &finfo) |
1538 |
: stat (filename, &finfo); |
1539 |
if (s == 0 && S_ISDIR (finfo.st_mode)) |
1540 |
{ |
1541 |
if (_rl_complete_mark_directories /* && rl_completion_suppress_append == 0 */) |
1542 |
{ |
1543 |
/* This is clumsy. Avoid putting in a double slash if point |
1544 |
is at the end of the line and the previous character is a |
1545 |
slash. */ |
1546 |
if (rl_point && rl_line_buffer[rl_point] == '\0' && rl_line_buffer[rl_point - 1] == '/') |
1547 |
; |
1548 |
else if (rl_line_buffer[rl_point] != '/') |
1549 |
rl_insert_text ("/"); |
1550 |
} |
1551 |
} |
1552 |
#ifdef S_ISLNK |
1553 |
/* Don't add anything if the filename is a symlink and resolves to a |
1554 |
directory. */ |
1555 |
else if (s == 0 && S_ISLNK (finfo.st_mode) && |
1556 |
stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode)) |
1557 |
; |
1558 |
#endif |
1559 |
else |
1560 |
{ |
1561 |
if (rl_point == rl_end && temp_string_index) |
1562 |
rl_insert_text (temp_string); |
1563 |
} |
1564 |
free (filename); |
1565 |
} |
1566 |
else |
1567 |
{ |
1568 |
if (rl_point == rl_end && temp_string_index) |
1569 |
rl_insert_text (temp_string); |
1570 |
} |
1571 |
|
1572 |
return (temp_string_index); |
1573 |
} |
1574 |
|
1575 |
static void |
1576 |
insert_all_matches (matches, point, qc) |
1577 |
char **matches; |
1578 |
int point; |
1579 |
char *qc; |
1580 |
{ |
1581 |
int i; |
1582 |
char *rp; |
1583 |
|
1584 |
rl_begin_undo_group (); |
1585 |
/* remove any opening quote character; make_quoted_replacement will add |
1586 |
it back. */ |
1587 |
if (qc && *qc && point && rl_line_buffer[point - 1] == *qc) |
1588 |
point--; |
1589 |
rl_delete_text (point, rl_point); |
1590 |
rl_point = point; |
1591 |
|
1592 |
if (matches[1]) |
1593 |
{ |
1594 |
for (i = 1; matches[i]; i++) |
1595 |
{ |
1596 |
rp = make_quoted_replacement (matches[i], SINGLE_MATCH, qc); |
1597 |
rl_insert_text (rp); |
1598 |
rl_insert_text (" "); |
1599 |
if (rp != matches[i]) |
1600 |
free (rp); |
1601 |
} |
1602 |
} |
1603 |
else |
1604 |
{ |
1605 |
rp = make_quoted_replacement (matches[0], SINGLE_MATCH, qc); |
1606 |
rl_insert_text (rp); |
1607 |
rl_insert_text (" "); |
1608 |
if (rp != matches[0]) |
1609 |
free (rp); |
1610 |
} |
1611 |
rl_end_undo_group (); |
1612 |
} |
1613 |
|
1614 |
void |
1615 |
_rl_free_match_list (matches) |
1616 |
char **matches; |
1617 |
{ |
1618 |
register int i; |
1619 |
|
1620 |
if (matches == 0) |
1621 |
return; |
1622 |
|
1623 |
for (i = 0; matches[i]; i++) |
1624 |
free (matches[i]); |
1625 |
free (matches); |
1626 |
} |
1627 |
|
1628 |
/* Complete the word at or before point. |
1629 |
WHAT_TO_DO says what to do with the completion. |
1630 |
`?' means list the possible completions. |
1631 |
TAB means do standard completion. |
1632 |
`*' means insert all of the possible completions. |
1633 |
`!' means to do standard completion, and list all possible completions if |
1634 |
there is more than one. |
1635 |
`@' means to do standard completion, and list all possible completions if |
1636 |
there is more than one and partial completion is not possible. */ |
1637 |
int |
1638 |
rl_complete_internal (what_to_do) |
1639 |
int what_to_do; |
1640 |
{ |
1641 |
char **matches; |
1642 |
rl_compentry_func_t *our_func; |
1643 |
int start, end, delimiter, found_quote, i, nontrivial_lcd; |
1644 |
char *text, *saved_line_buffer; |
1645 |
char quote_char; |
1646 |
|
1647 |
RL_SETSTATE(RL_STATE_COMPLETING); |
1648 |
|
1649 |
set_completion_defaults (what_to_do); |
1650 |
|
1651 |
saved_line_buffer = rl_line_buffer ? savestring (rl_line_buffer) : (char *)NULL; |
1652 |
our_func = rl_completion_entry_function |
1653 |
? rl_completion_entry_function |
1654 |
: rl_filename_completion_function; |
1655 |
/* We now look backwards for the start of a filename/variable word. */ |
1656 |
end = rl_point; |
1657 |
found_quote = delimiter = 0; |
1658 |
quote_char = '\0'; |
1659 |
|
1660 |
if (rl_point) |
1661 |
/* This (possibly) changes rl_point. If it returns a non-zero char, |
1662 |
we know we have an open quote. */ |
1663 |
quote_char = _rl_find_completion_word (&found_quote, &delimiter); |
1664 |
|
1665 |
start = rl_point; |
1666 |
rl_point = end; |
1667 |
|
1668 |
text = rl_copy_text (start, end); |
1669 |
matches = gen_completion_matches (text, start, end, our_func, found_quote, quote_char); |
1670 |
/* nontrivial_lcd is set if the common prefix adds something to the word |
1671 |
being completed. */ |
1672 |
nontrivial_lcd = matches && strcmp (text, matches[0]) != 0; |
1673 |
free (text); |
1674 |
|
1675 |
if (matches == 0) |
1676 |
{ |
1677 |
rl_ding (); |
1678 |
FREE (saved_line_buffer); |
1679 |
completion_changed_buffer = 0; |
1680 |
RL_UNSETSTATE(RL_STATE_COMPLETING); |
1681 |
return (0); |
1682 |
} |
1683 |
|
1684 |
/* If we are matching filenames, the attempted completion function will |
1685 |
have set rl_filename_completion_desired to a non-zero value. The basic |
1686 |
rl_filename_completion_function does this. */ |
1687 |
i = rl_filename_completion_desired; |
1688 |
|
1689 |
if (postprocess_matches (&matches, i) == 0) |
1690 |
{ |
1691 |
rl_ding (); |
1692 |
FREE (saved_line_buffer); |
1693 |
completion_changed_buffer = 0; |
1694 |
RL_UNSETSTATE(RL_STATE_COMPLETING); |
1695 |
return (0); |
1696 |
} |
1697 |
|
1698 |
switch (what_to_do) |
1699 |
{ |
1700 |
case TAB: |
1701 |
case '!': |
1702 |
case '@': |
1703 |
/* Insert the first match with proper quoting. */ |
1704 |
if (*matches[0]) |
1705 |
insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, "e_char); |
1706 |
|
1707 |
/* If there are more matches, ring the bell to indicate. |
1708 |
If we are in vi mode, Posix.2 says to not ring the bell. |
1709 |
If the `show-all-if-ambiguous' variable is set, display |
1710 |
all the matches immediately. Otherwise, if this was the |
1711 |
only match, and we are hacking files, check the file to |
1712 |
see if it was a directory. If so, and the `mark-directories' |
1713 |
variable is set, add a '/' to the name. If not, and we |
1714 |
are at the end of the line, then add a space. */ |
1715 |
if (matches[1]) |
1716 |
{ |
1717 |
if (what_to_do == '!') |
1718 |
{ |
1719 |
display_matches (matches); |
1720 |
break; |
1721 |
} |
1722 |
else if (what_to_do == '@') |
1723 |
{ |
1724 |
if (nontrivial_lcd == 0) |
1725 |
display_matches (matches); |
1726 |
break; |
1727 |
} |
1728 |
else if (rl_editing_mode != vi_mode) |
1729 |
rl_ding (); /* There are other matches remaining. */ |
1730 |
} |
1731 |
else |
1732 |
append_to_match (matches[0], delimiter, quote_char, nontrivial_lcd); |
1733 |
|
1734 |
break; |
1735 |
|
1736 |
case '*': |
1737 |
insert_all_matches (matches, start, "e_char); |
1738 |
break; |
1739 |
|
1740 |
case '?': |
1741 |
display_matches (matches); |
1742 |
break; |
1743 |
|
1744 |
default: |
1745 |
fprintf (stderr, "\r\nreadline: bad value %d for what_to_do in rl_complete\n", what_to_do); |
1746 |
rl_ding (); |
1747 |
FREE (saved_line_buffer); |
1748 |
RL_UNSETSTATE(RL_STATE_COMPLETING); |
1749 |
return 1; |
1750 |
} |
1751 |
|
1752 |
_rl_free_match_list (matches); |
1753 |
|
1754 |
/* Check to see if the line has changed through all of this manipulation. */ |
1755 |
if (saved_line_buffer) |
1756 |
{ |
1757 |
completion_changed_buffer = strcmp (rl_line_buffer, saved_line_buffer) != 0; |
1758 |
free (saved_line_buffer); |
1759 |
} |
1760 |
|
1761 |
RL_UNSETSTATE(RL_STATE_COMPLETING); |
1762 |
return 0; |
1763 |
} |
1764 |
|
1765 |
/***************************************************************/ |
1766 |
/* */ |
1767 |
/* Application-callable completion match generator functions */ |
1768 |
/* */ |
1769 |
/***************************************************************/ |
1770 |
|
1771 |
/* Return an array of (char *) which is a list of completions for TEXT. |
1772 |
If there are no completions, return a NULL pointer. |
1773 |
The first entry in the returned array is the substitution for TEXT. |
1774 |
The remaining entries are the possible completions. |
1775 |
The array is terminated with a NULL pointer. |
1776 |
|
1777 |
ENTRY_FUNCTION is a function of two args, and returns a (char *). |
1778 |
The first argument is TEXT. |
1779 |
The second is a state argument; it should be zero on the first call, and |
1780 |
non-zero on subsequent calls. It returns a NULL pointer to the caller |
1781 |
when there are no more matches. |
1782 |
*/ |
1783 |
char ** |
1784 |
rl_completion_matches (text, entry_function) |
1785 |
const char *text; |
1786 |
rl_compentry_func_t *entry_function; |
1787 |
{ |
1788 |
/* Number of slots in match_list. */ |
1789 |
int match_list_size; |
1790 |
|
1791 |
/* The list of matches. */ |
1792 |
char **match_list; |
1793 |
|
1794 |
/* Number of matches actually found. */ |
1795 |
int matches; |
1796 |
|
1797 |
/* Temporary string binder. */ |
1798 |
char *string; |
1799 |
|
1800 |
matches = 0; |
1801 |
match_list_size = 10; |
1802 |
match_list = (char **)xmalloc ((match_list_size + 1) * sizeof (char *)); |
1803 |
match_list[1] = (char *)NULL; |
1804 |
|
1805 |
while (string = (*entry_function) (text, matches)) |
1806 |
{ |
1807 |
if (matches + 1 == match_list_size) |
1808 |
match_list = (char **)xrealloc |
1809 |
(match_list, ((match_list_size += 10) + 1) * sizeof (char *)); |
1810 |
|
1811 |
match_list[++matches] = string; |
1812 |
match_list[matches + 1] = (char *)NULL; |
1813 |
} |
1814 |
|
1815 |
/* If there were any matches, then look through them finding out the |
1816 |
lowest common denominator. That then becomes match_list[0]. */ |
1817 |
if (matches) |
1818 |
compute_lcd_of_matches (match_list, matches, text); |
1819 |
else /* There were no matches. */ |
1820 |
{ |
1821 |
free (match_list); |
1822 |
match_list = (char **)NULL; |
1823 |
} |
1824 |
return (match_list); |
1825 |
} |
1826 |
|
1827 |
/* A completion function for usernames. |
1828 |
TEXT contains a partial username preceded by a random |
1829 |
character (usually `~'). */ |
1830 |
char * |
1831 |
rl_username_completion_function (text, state) |
1832 |
const char *text; |
1833 |
int state; |
1834 |
{ |
1835 |
#if defined (__WIN32__) || defined (__OPENNT) |
1836 |
return (char *)NULL; |
1837 |
#else /* !__WIN32__ && !__OPENNT) */ |
1838 |
static char *username = (char *)NULL; |
1839 |
static struct passwd *entry; |
1840 |
static int namelen, first_char, first_char_loc; |
1841 |
char *value; |
1842 |
|
1843 |
if (state == 0) |
1844 |
{ |
1845 |
FREE (username); |
1846 |
|
1847 |
first_char = *text; |
1848 |
first_char_loc = first_char == '~'; |
1849 |
|
1850 |
username = savestring (&text[first_char_loc]); |
1851 |
namelen = strlen (username); |
1852 |
setpwent (); |
1853 |
} |
1854 |
|
1855 |
#if defined (HAVE_GETPWENT) |
1856 |
while (entry = getpwent ()) |
1857 |
{ |
1858 |
/* Null usernames should result in all users as possible completions. */ |
1859 |
if (namelen == 0 || (STREQN (username, entry->pw_name, namelen))) |
1860 |
break; |
1861 |
} |
1862 |
#endif |
1863 |
|
1864 |
if (entry == 0) |
1865 |
{ |
1866 |
#if defined (HAVE_GETPWENT) |
1867 |
endpwent (); |
1868 |
#endif |
1869 |
return ((char *)NULL); |
1870 |
} |
1871 |
else |
1872 |
{ |
1873 |
value = (char *)xmalloc (2 + strlen (entry->pw_name)); |
1874 |
|
1875 |
*value = *text; |
1876 |
|
1877 |
strcpy (value + first_char_loc, entry->pw_name); |
1878 |
|
1879 |
if (first_char == '~') |
1880 |
rl_filename_completion_desired = 1; |
1881 |
|
1882 |
return (value); |
1883 |
} |
1884 |
#endif /* !__WIN32__ && !__OPENNT */ |
1885 |
} |
1886 |
|
1887 |
/* Okay, now we write the entry_function for filename completion. In the |
1888 |
general case. Note that completion in the shell is a little different |
1889 |
because of all the pathnames that must be followed when looking up the |
1890 |
completion for a command. */ |
1891 |
char * |
1892 |
rl_filename_completion_function (text, state) |
1893 |
const char *text; |
1894 |
int state; |
1895 |
{ |
1896 |
static DIR *directory = (DIR *)NULL; |
1897 |
static char *filename = (char *)NULL; |
1898 |
static char *dirname = (char *)NULL; |
1899 |
static char *users_dirname = (char *)NULL; |
1900 |
static int filename_len; |
1901 |
char *temp; |
1902 |
int dirlen; |
1903 |
struct dirent *entry; |
1904 |
|
1905 |
/* If we don't have any state, then do some initialization. */ |
1906 |
if (state == 0) |
1907 |
{ |
1908 |
/* If we were interrupted before closing the directory or reading |
1909 |
all of its contents, close it. */ |
1910 |
if (directory) |
1911 |
{ |
1912 |
closedir (directory); |
1913 |
directory = (DIR *)NULL; |
1914 |
} |
1915 |
FREE (dirname); |
1916 |
FREE (filename); |
1917 |
FREE (users_dirname); |
1918 |
|
1919 |
filename = savestring (text); |
1920 |
if (*text == 0) |
1921 |
text = "."; |
1922 |
dirname = savestring (text); |
1923 |
|
1924 |
temp = strrchr (dirname, '/'); |
1925 |
|
1926 |
#if defined (__MSDOS__) |
1927 |
/* special hack for //X/... */ |
1928 |
if (dirname[0] == '/' && dirname[1] == '/' && ISALPHA ((unsigned char)dirname[2]) && dirname[3] == '/') |
1929 |
temp = strrchr (dirname + 3, '/'); |
1930 |
#endif |
1931 |
|
1932 |
if (temp) |
1933 |
{ |
1934 |
strcpy (filename, ++temp); |
1935 |
*temp = '\0'; |
1936 |
} |
1937 |
#if defined (__MSDOS__) |
1938 |
/* searches from current directory on the drive */ |
1939 |
else if (ISALPHA ((unsigned char)dirname[0]) && dirname[1] == ':') |
1940 |
{ |
1941 |
strcpy (filename, dirname + 2); |
1942 |
dirname[2] = '\0'; |
1943 |
} |
1944 |
#endif |
1945 |
else |
1946 |
{ |
1947 |
dirname[0] = '.'; |
1948 |
dirname[1] = '\0'; |
1949 |
} |
1950 |
|
1951 |
/* We aren't done yet. We also support the "~user" syntax. */ |
1952 |
|
1953 |
/* Save the version of the directory that the user typed. */ |
1954 |
users_dirname = savestring (dirname); |
1955 |
|
1956 |
if (*dirname == '~') |
1957 |
{ |
1958 |
temp = tilde_expand (dirname); |
1959 |
free (dirname); |
1960 |
dirname = temp; |
1961 |
} |
1962 |
|
1963 |
if (rl_directory_rewrite_hook) |
1964 |
(*rl_directory_rewrite_hook) (&dirname); |
1965 |
|
1966 |
/* The directory completion hook should perform any necessary |
1967 |
dequoting. */ |
1968 |
if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&dirname)) |
1969 |
{ |
1970 |
free (users_dirname); |
1971 |
users_dirname = savestring (dirname); |
1972 |
} |
1973 |
else if (rl_completion_found_quote && rl_filename_dequoting_function) |
1974 |
{ |
1975 |
/* delete single and double quotes */ |
1976 |
temp = (*rl_filename_dequoting_function) (users_dirname, rl_completion_quote_character); |
1977 |
free (users_dirname); |
1978 |
users_dirname = temp; |
1979 |
} |
1980 |
directory = opendir (dirname); |
1981 |
|
1982 |
/* Now dequote a non-null filename. */ |
1983 |
if (filename && *filename && rl_completion_found_quote && rl_filename_dequoting_function) |
1984 |
{ |
1985 |
/* delete single and double quotes */ |
1986 |
temp = (*rl_filename_dequoting_function) (filename, rl_completion_quote_character); |
1987 |
free (filename); |
1988 |
filename = temp; |
1989 |
} |
1990 |
filename_len = strlen (filename); |
1991 |
|
1992 |
rl_filename_completion_desired = 1; |
1993 |
} |
1994 |
|
1995 |
/* At this point we should entertain the possibility of hacking wildcarded |
1996 |
filenames, like /usr/man/man<WILD>/te<TAB>. If the directory name |
1997 |
contains globbing characters, then build an array of directories, and |
1998 |
then map over that list while completing. */ |
1999 |
/* *** UNIMPLEMENTED *** */ |
2000 |
|
2001 |
/* Now that we have some state, we can read the directory. */ |
2002 |
|
2003 |
entry = (struct dirent *)NULL; |
2004 |
while (directory && (entry = readdir (directory))) |
2005 |
{ |
2006 |
/* Special case for no filename. If the user has disabled the |
2007 |
`match-hidden-files' variable, skip filenames beginning with `.'. |
2008 |
All other entries except "." and ".." match. */ |
2009 |
if (filename_len == 0) |
2010 |
{ |
2011 |
if (_rl_match_hidden_files == 0 && HIDDEN_FILE (entry->d_name)) |
2012 |
continue; |
2013 |
|
2014 |
if (entry->d_name[0] != '.' || |
2015 |
(entry->d_name[1] && |
2016 |
(entry->d_name[1] != '.' || entry->d_name[2]))) |
2017 |
break; |
2018 |
} |
2019 |
else |
2020 |
{ |
2021 |
/* Otherwise, if these match up to the length of filename, then |
2022 |
it is a match. */ |
2023 |
if (_rl_completion_case_fold) |
2024 |
{ |
2025 |
if ((_rl_to_lower (entry->d_name[0]) == _rl_to_lower (filename[0])) && |
2026 |
(((int)D_NAMLEN (entry)) >= filename_len) && |
2027 |
(_rl_strnicmp (filename, entry->d_name, filename_len) == 0)) |
2028 |
break; |
2029 |
} |
2030 |
else |
2031 |
{ |
2032 |
if ((entry->d_name[0] == filename[0]) && |
2033 |
(((int)D_NAMLEN (entry)) >= filename_len) && |
2034 |
(strncmp (filename, entry->d_name, filename_len) == 0)) |
2035 |
break; |
2036 |
} |
2037 |
} |
2038 |
} |
2039 |
|
2040 |
if (entry == 0) |
2041 |
{ |
2042 |
if (directory) |
2043 |
{ |
2044 |
closedir (directory); |
2045 |
directory = (DIR *)NULL; |
2046 |
} |
2047 |
if (dirname) |
2048 |
{ |
2049 |
free (dirname); |
2050 |
dirname = (char *)NULL; |
2051 |
} |
2052 |
if (filename) |
2053 |
{ |
2054 |
free (filename); |
2055 |
filename = (char *)NULL; |
2056 |
} |
2057 |
if (users_dirname) |
2058 |
{ |
2059 |
free (users_dirname); |
2060 |
users_dirname = (char *)NULL; |
2061 |
} |
2062 |
|
2063 |
return (char *)NULL; |
2064 |
} |
2065 |
else |
2066 |
{ |
2067 |
/* dirname && (strcmp (dirname, ".") != 0) */ |
2068 |
if (dirname && (dirname[0] != '.' || dirname[1])) |
2069 |
{ |
2070 |
if (rl_complete_with_tilde_expansion && *users_dirname == '~') |
2071 |
{ |
2072 |
dirlen = strlen (dirname); |
2073 |
temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry)); |
2074 |
strcpy (temp, dirname); |
2075 |
/* Canonicalization cuts off any final slash present. We |
2076 |
may need to add it back. */ |
2077 |
if (dirname[dirlen - 1] != '/') |
2078 |
{ |
2079 |
temp[dirlen++] = '/'; |
2080 |
temp[dirlen] = '\0'; |
2081 |
} |
2082 |
} |
2083 |
else |
2084 |
{ |
2085 |
dirlen = strlen (users_dirname); |
2086 |
temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry)); |
2087 |
strcpy (temp, users_dirname); |
2088 |
/* Make sure that temp has a trailing slash here. */ |
2089 |
if (users_dirname[dirlen - 1] != '/') |
2090 |
temp[dirlen++] = '/'; |
2091 |
} |
2092 |
|
2093 |
strcpy (temp + dirlen, entry->d_name); |
2094 |
} |
2095 |
else |
2096 |
temp = savestring (entry->d_name); |
2097 |
|
2098 |
return (temp); |
2099 |
} |
2100 |
} |
2101 |
|
2102 |
/* An initial implementation of a menu completion function a la tcsh. The |
2103 |
first time (if the last readline command was not rl_menu_complete), we |
2104 |
generate the list of matches. This code is very similar to the code in |
2105 |
rl_complete_internal -- there should be a way to combine the two. Then, |
2106 |
for each item in the list of matches, we insert the match in an undoable |
2107 |
fashion, with the appropriate character appended (this happens on the |
2108 |
second and subsequent consecutive calls to rl_menu_complete). When we |
2109 |
hit the end of the match list, we restore the original unmatched text, |
2110 |
ring the bell, and reset the counter to zero. */ |
2111 |
int |
2112 |
rl_menu_complete (count, ignore) |
2113 |
int count, ignore; |
2114 |
{ |
2115 |
rl_compentry_func_t *our_func; |
2116 |
int matching_filenames, found_quote; |
2117 |
|
2118 |
static char *orig_text; |
2119 |
static char **matches = (char **)0; |
2120 |
static int match_list_index = 0; |
2121 |
static int match_list_size = 0; |
2122 |
static int orig_start, orig_end; |
2123 |
static char quote_char; |
2124 |
static int delimiter; |
2125 |
|
2126 |
/* The first time through, we generate the list of matches and set things |
2127 |
up to insert them. */ |
2128 |
if (rl_last_func != rl_menu_complete) |
2129 |
{ |
2130 |
/* Clean up from previous call, if any. */ |
2131 |
FREE (orig_text); |
2132 |
if (matches) |
2133 |
_rl_free_match_list (matches); |
2134 |
|
2135 |
match_list_index = match_list_size = 0; |
2136 |
matches = (char **)NULL; |
2137 |
|
2138 |
/* Only the completion entry function can change these. */ |
2139 |
set_completion_defaults ('%'); |
2140 |
|
2141 |
our_func = rl_completion_entry_function |
2142 |
? rl_completion_entry_function |
2143 |
: rl_filename_completion_function; |
2144 |
|
2145 |
/* We now look backwards for the start of a filename/variable word. */ |
2146 |
orig_end = rl_point; |
2147 |
found_quote = delimiter = 0; |
2148 |
quote_char = '\0'; |
2149 |
|
2150 |
if (rl_point) |
2151 |
/* This (possibly) changes rl_point. If it returns a non-zero char, |
2152 |
we know we have an open quote. */ |
2153 |
quote_char = _rl_find_completion_word (&found_quote, &delimiter); |
2154 |
|
2155 |
orig_start = rl_point; |
2156 |
rl_point = orig_end; |
2157 |
|
2158 |
orig_text = rl_copy_text (orig_start, orig_end); |
2159 |
matches = gen_completion_matches (orig_text, orig_start, orig_end, |
2160 |
our_func, found_quote, quote_char); |
2161 |
|
2162 |
/* If we are matching filenames, the attempted completion function will |
2163 |
have set rl_filename_completion_desired to a non-zero value. The basic |
2164 |
rl_filename_completion_function does this. */ |
2165 |
matching_filenames = rl_filename_completion_desired; |
2166 |
|
2167 |
if (matches == 0 || postprocess_matches (&matches, matching_filenames) == 0) |
2168 |
{ |
2169 |
rl_ding (); |
2170 |
FREE (matches); |
2171 |
matches = (char **)0; |
2172 |
FREE (orig_text); |
2173 |
orig_text = (char *)0; |
2174 |
completion_changed_buffer = 0; |
2175 |
return (0); |
2176 |
} |
2177 |
|
2178 |
for (match_list_size = 0; matches[match_list_size]; match_list_size++) |
2179 |
; |
2180 |
/* matches[0] is lcd if match_list_size > 1, but the circular buffer |
2181 |
code below should take care of it. */ |
2182 |
} |
2183 |
|
2184 |
/* Now we have the list of matches. Replace the text between |
2185 |
rl_line_buffer[orig_start] and rl_line_buffer[rl_point] with |
2186 |
matches[match_list_index], and add any necessary closing char. */ |
2187 |
|
2188 |
if (matches == 0 || match_list_size == 0) |
2189 |
{ |
2190 |
rl_ding (); |
2191 |
FREE (matches); |
2192 |
matches = (char **)0; |
2193 |
completion_changed_buffer = 0; |
2194 |
return (0); |
2195 |
} |
2196 |
|
2197 |
match_list_index += count; |
2198 |
if (match_list_index < 0) |
2199 |
match_list_index += match_list_size; |
2200 |
else |
2201 |
match_list_index %= match_list_size; |
2202 |
|
2203 |
if (match_list_index == 0 && match_list_size > 1) |
2204 |
{ |
2205 |
rl_ding (); |
2206 |
insert_match (orig_text, orig_start, MULT_MATCH, "e_char); |
2207 |
} |
2208 |
else |
2209 |
{ |
2210 |
insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, "e_char); |
2211 |
append_to_match (matches[match_list_index], delimiter, quote_char, |
2212 |
strcmp (orig_text, matches[match_list_index])); |
2213 |
} |
2214 |
|
2215 |
completion_changed_buffer = 1; |
2216 |
return (0); |
2217 |
} |