complete.c revision 157188
1218822Sdim/* $FreeBSD: head/contrib/libreadline/complete.c 157188 2006-03-27 23:11:32Z ache $ */
238889Sjdp/* complete.c -- filename completion for readline. */
3218822Sdim
4218822Sdim/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
5218822Sdim
6218822Sdim   This file is part of the GNU Readline Library, a library for
7218822Sdim   reading lines of text with interactive input and history editing.
838889Sjdp
9218822Sdim   The GNU Readline Library is free software; you can redistribute it
10218822Sdim   and/or modify it under the terms of the GNU General Public License
11218822Sdim   as published by the Free Software Foundation; either version 2, or
12218822Sdim   (at your option) any later version.
1338889Sjdp
14218822Sdim   The GNU Readline Library is distributed in the hope that it will be
15218822Sdim   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
16218822Sdim   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17218822Sdim   GNU General Public License for more details.
18218822Sdim
19130561Sobrien   The GNU General Public License is often shipped with GNU software, and
20218822Sdim   is generally kept in a file called COPYING or LICENSE.  If you do not
21218822Sdim   have a copy of the license, write to the Free Software Foundation,
22218822Sdim   59 Temple Place, Suite 330, Boston, MA 02111 USA. */
23218822Sdim#define READLINE_LIBRARY
24218822Sdim
2533965Sjdp#if defined (HAVE_CONFIG_H)
26218822Sdim#  include <config.h>
27218822Sdim#endif
28218822Sdim
29218822Sdim#include <sys/types.h>
30218822Sdim#include <fcntl.h>
31218822Sdim#if defined (HAVE_SYS_FILE_H)
3233965Sjdp#  include <sys/file.h>
33218822Sdim#endif
3438889Sjdp
35218822Sdim#if defined (HAVE_UNISTD_H)
36218822Sdim#  include <unistd.h>
37218822Sdim#endif /* HAVE_UNISTD_H */
38218822Sdim
39218822Sdim#if defined (HAVE_STDLIB_H)
4060484Sobrien#  include <stdlib.h>
41218822Sdim#else
42218822Sdim#  include "ansi_stdlib.h"
43218822Sdim#endif /* HAVE_STDLIB_H */
44218822Sdim
45218822Sdim#include <stdio.h>
46218822Sdim
47218822Sdim#include <errno.h>
48218822Sdim#if !defined (errno)
49218822Sdimextern int errno;
50218822Sdim#endif /* !errno */
51218822Sdim
52218822Sdim#if defined (HAVE_PWD_H)
53218822Sdim#include <pwd.h>
54218822Sdim#endif
55218822Sdim
56218822Sdim#include "posixdir.h"
57218822Sdim#include "posixstat.h"
58218822Sdim
59218822Sdim/* System-specific feature definitions and include files. */
60218822Sdim#include "rldefs.h"
61218822Sdim#include "rlmbutil.h"
62218822Sdim
63218822Sdim/* Some standard library routines. */
64218822Sdim#include "readline.h"
65218822Sdim#include "xmalloc.h"
66218822Sdim#include "rlprivate.h"
67218822Sdim
68218822Sdim#ifdef __STDC__
69218822Sdimtypedef int QSFUNC (const void *, const void *);
70218822Sdim#else
71218822Sdimtypedef int QSFUNC ();
72218822Sdim#endif
73218822Sdim
74218822Sdim#ifdef HAVE_LSTAT
75218822Sdim#  define LSTAT lstat
76218822Sdim#else
77218822Sdim#  define LSTAT stat
7860484Sobrien#endif
79218822Sdim
80218822Sdim/* Unix version of a hidden file.  Could be different on other systems. */
81218822Sdim#define HIDDEN_FILE(fname)	((fname)[0] == '.')
82218822Sdim
83218822Sdim/* Most systems don't declare getpwent in <pwd.h> if _POSIX_SOURCE is
8460484Sobrien   defined. */
8560484Sobrien#if defined (HAVE_GETPWENT) && (!defined (HAVE_GETPW_DECLS) || defined (_POSIX_SOURCE))
86218822Sdimextern struct passwd *getpwent PARAMS((void));
8760484Sobrien#endif /* HAVE_GETPWENT && (!HAVE_GETPW_DECLS || _POSIX_SOURCE) */
88218822Sdim
89218822Sdim/* If non-zero, then this is the address of a function to call when
90218822Sdim   completing a word would normally display the list of possible matches.
91218822Sdim   This function is called instead of actually doing the display.
92218822Sdim   It takes three arguments: (char **matches, int num_matches, int max_length)
93218822Sdim   where MATCHES is the array of strings that matched, NUM_MATCHES is the
9460484Sobrien   number of strings in that array, and MAX_LENGTH is the length of the
95218822Sdim   longest string in that array. */
96104834Sobrienrl_compdisp_func_t *rl_completion_display_matches_hook = (rl_compdisp_func_t *)NULL;
97218822Sdim
98218822Sdim#if defined (VISIBLE_STATS)
99104834Sobrien#  if !defined (X_OK)
100104834Sobrien#    define X_OK 1
101218822Sdim#  endif
102218822Sdimstatic int stat_char PARAMS((char *));
103218822Sdim#endif
104218822Sdim
105218822Sdimstatic int path_isdir PARAMS((const char *));
106104834Sobrien
107104834Sobrienstatic char *rl_quote_filename PARAMS((char *, int, char *));
108104834Sobrien
109104834Sobrienstatic void set_completion_defaults PARAMS((int));
110104834Sobrienstatic int get_y_or_n PARAMS((int));
111104834Sobrienstatic int _rl_internal_pager PARAMS((int));
112218822Sdimstatic char *printable_part PARAMS((char *));
113218822Sdimstatic int fnwidth PARAMS((const char *));
114218822Sdimstatic int fnprint PARAMS((const char *));
115218822Sdimstatic int print_filename PARAMS((char *, char *));
116218822Sdim
117218822Sdimstatic char **gen_completion_matches PARAMS((char *, int, int, rl_compentry_func_t *, int, int));
118104834Sobrien
119130561Sobrienstatic char **remove_duplicate_matches PARAMS((char **));
120218822Sdimstatic void insert_match PARAMS((char *, int, int, char *));
121218822Sdimstatic int append_to_match PARAMS((char *, int, int, int));
122218822Sdimstatic void insert_all_matches PARAMS((char **, int, char *));
123218822Sdimstatic void display_matches PARAMS((char **));
124218822Sdimstatic int compute_lcd_of_matches PARAMS((char **, int, const char *));
125218822Sdimstatic int postprocess_matches PARAMS((char ***, int));
126130561Sobrien
127218822Sdimstatic char *make_quoted_replacement PARAMS((char *, int, char *));
128130561Sobrien
129218822Sdim/* **************************************************************** */
130218822Sdim/*								    */
131218822Sdim/*	Completion matching, from readline's point of view.	    */
132218822Sdim/*								    */
133218822Sdim/* **************************************************************** */
134130561Sobrien
135130561Sobrien/* Variables known only to the readline library. */
136218822Sdim
137218822Sdim/* If non-zero, non-unique completions always show the list of matches. */
138218822Sdimint _rl_complete_show_all = 0;
139218822Sdim
140218822Sdim/* If non-zero, non-unique completions show the list of matches, unless it
141218822Sdim   is not possible to do partial completion and modify the line. */
142218822Sdimint _rl_complete_show_unmodified = 0;
143218822Sdim
144218822Sdim/* If non-zero, completed directory names have a slash appended. */
145218822Sdimint _rl_complete_mark_directories = 1;
146218822Sdim
147218822Sdim/* If non-zero, the symlinked directory completion behavior introduced in
148218822Sdim   readline-4.2a is disabled, and symlinks that point to directories have
149218822Sdim   a slash appended (subject to the value of _rl_complete_mark_directories).
150218822Sdim   This is user-settable via the mark-symlinked-directories variable. */
15138889Sjdpint _rl_complete_mark_symlink_dirs = 0;
152218822Sdim
153218822Sdim/* If non-zero, completions are printed horizontally in alphabetical order,
154218822Sdim   like `ls -x'. */
155218822Sdimint _rl_print_completions_horizontally;
156218822Sdim
15738889Sjdp/* Non-zero means that case is not significant in filename completion. */
158218822Sdim#if defined (__MSDOS__) && !defined (__DJGPP__)
159218822Sdimint _rl_completion_case_fold = 1;
160218822Sdim#else
161218822Sdimint _rl_completion_case_fold;
162218822Sdim#endif
163218822Sdim
164218822Sdim/* If non-zero, don't match hidden files (filenames beginning with a `.' on
165218822Sdim   Unix) when doing filename completion. */
166218822Sdimint _rl_match_hidden_files = 1;
167218822Sdim
168218822Sdim/* Global variables available to applications using readline. */
169218822Sdim
170218822Sdim#if defined (VISIBLE_STATS)
171218822Sdim/* Non-zero means add an additional character to each filename displayed
172218822Sdim   during listing completion iff rl_filename_completion_desired which helps
173218822Sdim   to indicate the type of file being listed. */
174218822Sdimint rl_visible_stats = 0;
175218822Sdim#endif /* VISIBLE_STATS */
176218822Sdim
177218822Sdim/* If non-zero, then this is the address of a function to call when
17838889Sjdp   completing on a directory name.  The function is called with
179218822Sdim   the address of a string (the current directory name) as an arg. */
180218822Sdimrl_icppfunc_t *rl_directory_completion_hook = (rl_icppfunc_t *)NULL;
181218822Sdim
182218822Sdimrl_icppfunc_t *rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL;
183218822Sdim
184218822Sdim/* Non-zero means readline completion functions perform tilde expansion. */
185218822Sdimint rl_complete_with_tilde_expansion = 0;
186218822Sdim
187218822Sdim/* Pointer to the generator function for completion_matches ().
188218822Sdim   NULL means to use rl_filename_completion_function (), the default filename
189218822Sdim   completer. */
190218822Sdimrl_compentry_func_t *rl_completion_entry_function = (rl_compentry_func_t *)NULL;
191218822Sdim
192218822Sdim/* Pointer to alternative function to create matches.
193218822Sdim   Function is called with TEXT, START, and END.
194218822Sdim   START and END are indices in RL_LINE_BUFFER saying what the boundaries
195218822Sdim   of TEXT are.
196218822Sdim   If this function exists and returns NULL then call the value of
197218822Sdim   rl_completion_entry_function to try to match, otherwise use the
198218822Sdim   array of strings returned. */
199218822Sdimrl_completion_func_t *rl_attempted_completion_function = (rl_completion_func_t *)NULL;
200218822Sdim
201218822Sdim/* Non-zero means to suppress normal filename completion after the
202218822Sdim   user-specified completion function has been called. */
203218822Sdimint rl_attempted_completion_over = 0;
204218822Sdim
205218822Sdim/* Set to a character indicating the type of completion being performed
206218822Sdim   by rl_complete_internal, available for use by application completion
207218822Sdim   functions. */
208218822Sdimint rl_completion_type = 0;
209218822Sdim
210218822Sdim/* Up to this many items will be displayed in response to a
211218822Sdim   possible-completions call.  After that, we ask the user if
212218822Sdim   she is sure she wants to see them all.  A negative value means
213218822Sdim   don't ask. */
214218822Sdimint rl_completion_query_items = 100;
215218822Sdim
216218822Sdimint _rl_page_completions = 1;
217218822Sdim
218218822Sdim/* The basic list of characters that signal a break between words for the
219218822Sdim   completer routine.  The contents of this variable is what breaks words
220218822Sdim   in the shell, i.e. " \t\n\"\\'`@$><=" */
221218822Sdimconst char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{("; /* }) */
222218822Sdim
223218822Sdim/* List of basic quoting characters. */
224218822Sdimconst char *rl_basic_quote_characters = "\"'";
225218822Sdim
226218822Sdim/* The list of characters that signal a break between words for
227218822Sdim   rl_complete_internal.  The default list is the contents of
228218822Sdim   rl_basic_word_break_characters.  */
229218822Sdim/*const*/ char *rl_completer_word_break_characters = (/*const*/ char *)NULL;
230218822Sdim
231218822Sdim/* Hook function to allow an application to set the completion word
232218822Sdim   break characters before readline breaks up the line.  Allows
233218822Sdim   position-dependent word break characters. */
234218822Sdimrl_cpvfunc_t *rl_completion_word_break_hook = (rl_cpvfunc_t *)NULL;
235218822Sdim
236218822Sdim/* List of characters which can be used to quote a substring of the line.
237218822Sdim   Completion occurs on the entire substring, and within the substring
238218822Sdim   rl_completer_word_break_characters are treated as any other character,
239218822Sdim   unless they also appear within this list. */
240218822Sdimconst char *rl_completer_quote_characters = (const char *)NULL;
241218822Sdim
242218822Sdim/* List of characters that should be quoted in filenames by the completer. */
243218822Sdimconst char *rl_filename_quote_characters = (const char *)NULL;
244218822Sdim
245218822Sdim/* List of characters that are word break characters, but should be left
246218822Sdim   in TEXT when it is passed to the completion function.  The shell uses
247218822Sdim   this to help determine what kind of completing to do. */
248218822Sdimconst char *rl_special_prefixes = (const char *)NULL;
249218822Sdim
250218822Sdim/* If non-zero, then disallow duplicates in the matches. */
251218822Sdimint rl_ignore_completion_duplicates = 1;
252218822Sdim
253218822Sdim/* Non-zero means that the results of the matches are to be treated
254218822Sdim   as filenames.  This is ALWAYS zero on entry, and can only be changed
255218822Sdim   within a completion entry finder function. */
256218822Sdimint rl_filename_completion_desired = 0;
257218822Sdim
258218822Sdim/* Non-zero means that the results of the matches are to be quoted using
259218822Sdim   double quotes (or an application-specific quoting mechanism) if the
260218822Sdim   filename contains any characters in rl_filename_quote_chars.  This is
261218822Sdim   ALWAYS non-zero on entry, and can only be changed within a completion
262218822Sdim   entry finder function. */
263218822Sdimint rl_filename_quoting_desired = 1;
264218822Sdim
265218822Sdim/* This function, if defined, is called by the completer when real
266218822Sdim   filename completion is done, after all the matching names have been
267218822Sdim   generated. It is passed a (char**) known as matches in the code below.
268218822Sdim   It consists of a NULL-terminated array of pointers to potential
269218822Sdim   matching strings.  The 1st element (matches[0]) is the maximal
270218822Sdim   substring that is common to all matches. This function can re-arrange
271218822Sdim   the list of matches as required, but all elements of the array must be
272218822Sdim   free()'d if they are deleted. The main intent of this function is
273218822Sdim   to implement FIGNORE a la SunOS csh. */
274218822Sdimrl_compignore_func_t *rl_ignore_some_completions_function = (rl_compignore_func_t *)NULL;
275218822Sdim
276218822Sdim/* Set to a function to quote a filename in an application-specific fashion.
277218822Sdim   Called with the text to quote, the type of match found (single or multiple)
278218822Sdim   and a pointer to the quoting character to be used, which the function can
279218822Sdim   reset if desired. */
280218822Sdimrl_quote_func_t *rl_filename_quoting_function = rl_quote_filename;
281218822Sdim
282218822Sdim/* Function to call to remove quoting characters from a filename.  Called
283218822Sdim   before completion is attempted, so the embedded quotes do not interfere
284218822Sdim   with matching names in the file system.  Readline doesn't do anything
285218822Sdim   with this; it's set only by applications. */
286218822Sdimrl_dequote_func_t *rl_filename_dequoting_function = (rl_dequote_func_t *)NULL;
287218822Sdim
288218822Sdim/* Function to call to decide whether or not a word break character is
289218822Sdim   quoted.  If a character is quoted, it does not break words for the
290218822Sdim   completer. */
291218822Sdimrl_linebuf_func_t *rl_char_is_quoted_p = (rl_linebuf_func_t *)NULL;
292218822Sdim
293218822Sdim/* If non-zero, the completion functions don't append anything except a
294218822Sdim   possible closing quote.  This is set to 0 by rl_complete_internal and
295218822Sdim   may be changed by an application-specific completion function. */
296218822Sdimint rl_completion_suppress_append = 0;
297218822Sdim
298218822Sdim/* Character appended to completed words when at the end of the line.  The
299218822Sdim   default is a space. */
300218822Sdimint rl_completion_append_character = ' ';
301218822Sdim
302218822Sdim/* If non-zero, the completion functions don't append any closing quote.
303218822Sdim   This is set to 0 by rl_complete_internal and may be changed by an
304218822Sdim   application-specific completion function. */
305218822Sdimint rl_completion_suppress_quote = 0;
306218822Sdim
307218822Sdim/* Set to any quote character readline thinks it finds before any application
308218822Sdim   completion function is called. */
309218822Sdimint rl_completion_quote_character;
310218822Sdim
311218822Sdim/* Set to a non-zero value if readline found quoting anywhere in the word to
312218822Sdim   be completed; set before any application completion function is called. */
313218822Sdimint rl_completion_found_quote;
314218822Sdim
315218822Sdim/* If non-zero, a slash will be appended to completed filenames that are
316218822Sdim   symbolic links to directory names, subject to the value of the
317218822Sdim   mark-directories variable (which is user-settable).  This exists so
318218822Sdim   that application completion functions can override the user's preference
319218822Sdim   (set via the mark-symlinked-directories variable) if appropriate.
320218822Sdim   It's set to the value of _rl_complete_mark_symlink_dirs in
321218822Sdim   rl_complete_internal before any application-specific completion
322218822Sdim   function is called, so without that function doing anything, the user's
323218822Sdim   preferences are honored. */
324218822Sdimint rl_completion_mark_symlink_dirs;
325218822Sdim
326218822Sdim/* If non-zero, inhibit completion (temporarily). */
327218822Sdimint rl_inhibit_completion;
328218822Sdim
329218822Sdim/* Variables local to this file. */
330218822Sdim
331218822Sdim/* Local variable states what happened during the last completion attempt. */
332218822Sdimstatic int completion_changed_buffer;
333218822Sdim
334218822Sdim/*************************************/
335218822Sdim/*				     */
336218822Sdim/*    Bindable completion functions  */
337218822Sdim/*				     */
338218822Sdim/*************************************/
339218822Sdim
340218822Sdim/* Complete the word at or before point.  You have supplied the function
341218822Sdim   that does the initial simple matching selection algorithm (see
342218822Sdim   rl_completion_matches ()).  The default is to do filename completion. */
343218822Sdimint
344218822Sdimrl_complete (ignore, invoking_key)
345218822Sdim     int ignore, invoking_key;
346218822Sdim{
347218822Sdim  if (rl_inhibit_completion)
348218822Sdim    return (_rl_insert_char (ignore, invoking_key));
349218822Sdim  else if (rl_last_func == rl_complete && !completion_changed_buffer)
350218822Sdim    return (rl_complete_internal ('?'));
351218822Sdim  else if (_rl_complete_show_all)
352218822Sdim    return (rl_complete_internal ('!'));
353218822Sdim  else if (_rl_complete_show_unmodified)
354218822Sdim    return (rl_complete_internal ('@'));
355218822Sdim  else
356218822Sdim    return (rl_complete_internal (TAB));
357218822Sdim}
358218822Sdim
359218822Sdim/* List the possible completions.  See description of rl_complete (). */
360218822Sdimint
361218822Sdimrl_possible_completions (ignore, invoking_key)
362218822Sdim     int ignore, invoking_key;
363218822Sdim{
364218822Sdim  return (rl_complete_internal ('?'));
365218822Sdim}
366218822Sdim
367218822Sdimint
368218822Sdimrl_insert_completions (ignore, invoking_key)
369218822Sdim     int ignore, invoking_key;
370218822Sdim{
371218822Sdim  return (rl_complete_internal ('*'));
372218822Sdim}
373218822Sdim
374218822Sdim/* Return the correct value to pass to rl_complete_internal performing
375218822Sdim   the same tests as rl_complete.  This allows consecutive calls to an
376218822Sdim   application's completion function to list possible completions and for
377218822Sdim   an application-specific completion function to honor the
378218822Sdim   show-all-if-ambiguous readline variable. */
379218822Sdimint
38094536Sobrienrl_completion_mode (cfunc)
381218822Sdim     rl_command_func_t *cfunc;
382218822Sdim{
383218822Sdim  if (rl_last_func == cfunc && !completion_changed_buffer)
384218822Sdim    return '?';
385218822Sdim  else if (_rl_complete_show_all)
386218822Sdim    return '!';
387218822Sdim  else if (_rl_complete_show_unmodified)
388218822Sdim    return '@';
389218822Sdim  else
39038889Sjdp    return TAB;
39138889Sjdp}
39238889Sjdp
393218822Sdim/************************************/
394218822Sdim/*				    */
395218822Sdim/*    Completion utility functions  */
396218822Sdim/*				    */
397218822Sdim/************************************/
398218822Sdim
399218822Sdim/* Set default values for readline word completion.  These are the variables
400218822Sdim   that application completion functions can change or inspect. */
401218822Sdimstatic void
402130561Sobrienset_completion_defaults (what_to_do)
403218822Sdim     int what_to_do;
404218822Sdim{
405218822Sdim  /* Only the completion entry function can change these. */
406218822Sdim  rl_filename_completion_desired = 0;
407218822Sdim  rl_filename_quoting_desired = 1;
408218822Sdim  rl_completion_type = what_to_do;
409218822Sdim  rl_completion_suppress_append = rl_completion_suppress_quote = 0;
410218822Sdim
411218822Sdim  /* The completion entry function may optionally change this. */
412130561Sobrien  rl_completion_mark_symlink_dirs = _rl_complete_mark_symlink_dirs;
413218822Sdim}
414218822Sdim
415218822Sdim/* The user must press "y" or "n". Non-zero return means "y" pressed. */
416130561Sobrienstatic int
417218822Sdimget_y_or_n (for_pager)
418218822Sdim     int for_pager;
419218822Sdim{
420218822Sdim  int c;
421218822Sdim
422218822Sdim  for (;;)
423218822Sdim    {
424218822Sdim      RL_SETSTATE(RL_STATE_MOREINPUT);
425218822Sdim      c = rl_read_key ();
426218822Sdim      RL_UNSETSTATE(RL_STATE_MOREINPUT);
427218822Sdim
428218822Sdim      if (c == 'y' || c == 'Y' || c == ' ')
429218822Sdim	return (1);
430218822Sdim      if (c == 'n' || c == 'N' || c == RUBOUT)
431218822Sdim	return (0);
432218822Sdim      if (c == ABORT_CHAR)
433218822Sdim	_rl_abort_internal ();
434218822Sdim      if (for_pager && (c == NEWLINE || c == RETURN))
435218822Sdim	return (2);
436218822Sdim      if (for_pager && (c == 'q' || c == 'Q'))
437218822Sdim	return (0);
438218822Sdim      rl_ding ();
439218822Sdim    }
440218822Sdim}
441218822Sdim
442218822Sdimstatic int
443218822Sdim_rl_internal_pager (lines)
444218822Sdim     int lines;
445218822Sdim{
446218822Sdim  int i;
447130561Sobrien
448130561Sobrien  fprintf (rl_outstream, "--More--");
449218822Sdim  fflush (rl_outstream);
450218822Sdim  i = get_y_or_n (1);
451218822Sdim  _rl_erase_entire_line ();
452130561Sobrien  if (i == 0)
453218822Sdim    return -1;
454218822Sdim  else if (i == 2)
455218822Sdim    return (lines - 1);
456218822Sdim  else
457218822Sdim    return 0;
458218822Sdim}
459218822Sdim
460218822Sdimstatic int
461218822Sdimpath_isdir (filename)
462218822Sdim     const char *filename;
463218822Sdim{
464218822Sdim  struct stat finfo;
465218822Sdim
466218822Sdim  return (stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode));
467218822Sdim}
468218822Sdim
469218822Sdim#if defined (VISIBLE_STATS)
47038889Sjdp/* Return the character which best describes FILENAME.
471218822Sdim     `@' for symbolic links
472218822Sdim     `/' for directories
473218822Sdim     `*' for executables
474218822Sdim     `=' for sockets
475218822Sdim     `|' for FIFOs
476218822Sdim     `%' for character special devices
477218822Sdim     `#' for block special devices */
478218822Sdimstatic int
479218822Sdimstat_char (filename)
480218822Sdim     char *filename;
481218822Sdim{
482218822Sdim  struct stat finfo;
483218822Sdim  int character, r;
484218822Sdim
485218822Sdim#if defined (HAVE_LSTAT) && defined (S_ISLNK)
486218822Sdim  r = lstat (filename, &finfo);
487218822Sdim#else
48838889Sjdp  r = stat (filename, &finfo);
489218822Sdim#endif
490218822Sdim
491218822Sdim  if (r == -1)
49238889Sjdp    return (0);
493218822Sdim
494218822Sdim  character = 0;
495218822Sdim  if (S_ISDIR (finfo.st_mode))
496218822Sdim    character = '/';
497218822Sdim#if defined (S_ISCHR)
498218822Sdim  else if (S_ISCHR (finfo.st_mode))
499218822Sdim    character = '%';
500218822Sdim#endif /* S_ISCHR */
501218822Sdim#if defined (S_ISBLK)
502218822Sdim  else if (S_ISBLK (finfo.st_mode))
503218822Sdim    character = '#';
504218822Sdim#endif /* S_ISBLK */
505218822Sdim#if defined (S_ISLNK)
506218822Sdim  else if (S_ISLNK (finfo.st_mode))
507218822Sdim    character = '@';
508218822Sdim#endif /* S_ISLNK */
509218822Sdim#if defined (S_ISSOCK)
510218822Sdim  else if (S_ISSOCK (finfo.st_mode))
511218822Sdim    character = '=';
512218822Sdim#endif /* S_ISSOCK */
513218822Sdim#if defined (S_ISFIFO)
514218822Sdim  else if (S_ISFIFO (finfo.st_mode))
515218822Sdim    character = '|';
516218822Sdim#endif
517218822Sdim  else if (S_ISREG (finfo.st_mode))
518218822Sdim    {
519218822Sdim      if (access (filename, X_OK) == 0)
520218822Sdim	character = '*';
521218822Sdim    }
522218822Sdim  return (character);
523218822Sdim}
524218822Sdim#endif /* VISIBLE_STATS */
525218822Sdim
526218822Sdim/* Return the portion of PATHNAME that should be output when listing
527218822Sdim   possible completions.  If we are hacking filename completion, we
528218822Sdim   are only interested in the basename, the portion following the
529218822Sdim   final slash.  Otherwise, we return what we were passed.  Since
530218822Sdim   printing empty strings is not very informative, if we're doing
531218822Sdim   filename completion, and the basename is the empty string, we look
532218822Sdim   for the previous slash and return the portion following that.  If
533218822Sdim   there's no previous slash, we just return what we were passed. */
534218822Sdimstatic char *
535218822Sdimprintable_part (pathname)
536218822Sdim      char *pathname;
537218822Sdim{
538218822Sdim  char *temp, *x;
539218822Sdim
540218822Sdim  if (rl_filename_completion_desired == 0)	/* don't need to do anything */
541218822Sdim    return (pathname);
542218822Sdim
543218822Sdim  temp = strrchr (pathname, '/');
544218822Sdim#if defined (__MSDOS__)
545218822Sdim  if (temp == 0 && ISALPHA ((unsigned char)pathname[0]) && pathname[1] == ':')
546218822Sdim    temp = pathname + 1;
547218822Sdim#endif
548218822Sdim
549218822Sdim  if (temp == 0 || *temp == '\0')
550218822Sdim    return (pathname);
551218822Sdim  /* If the basename is NULL, we might have a pathname like '/usr/src/'.
552218822Sdim     Look for a previous slash and, if one is found, return the portion
553218822Sdim     following that slash.  If there's no previous slash, just return the
554218822Sdim     pathname we were passed. */
555218822Sdim  else if (temp[1] == '\0')
556218822Sdim    {
557218822Sdim      for (x = temp - 1; x > pathname; x--)
558218822Sdim        if (*x == '/')
559218822Sdim          break;
560218822Sdim      return ((*x == '/') ? x + 1 : pathname);
561218822Sdim    }
562218822Sdim  else
563218822Sdim    return ++temp;
564218822Sdim}
565218822Sdim
566218822Sdim/* Compute width of STRING when displayed on screen by print_filename */
567218822Sdimstatic int
568218822Sdimfnwidth (string)
569218822Sdim     const char *string;
570218822Sdim{
571218822Sdim  int width, pos;
572218822Sdim#if defined (HANDLE_MULTIBYTE)
573218822Sdim  mbstate_t ps;
574218822Sdim  int left, w;
575218822Sdim  size_t clen;
576218822Sdim  wchar_t wc;
577218822Sdim
578218822Sdim  left = strlen (string) + 1;
579218822Sdim  memset (&ps, 0, sizeof (mbstate_t));
580218822Sdim#endif
581218822Sdim
582218822Sdim  width = pos = 0;
583218822Sdim  while (string[pos])
584218822Sdim    {
585218822Sdim      if (CTRL_CHAR (*string) || *string == RUBOUT)
586218822Sdim	{
587218822Sdim	  width += 2;
588218822Sdim	  pos++;
589218822Sdim	}
590218822Sdim      else
591218822Sdim	{
592218822Sdim#if defined (HANDLE_MULTIBYTE)
593218822Sdim	  clen = mbrtowc (&wc, string + pos, left - pos, &ps);
594218822Sdim	  if (MB_INVALIDCH (clen))
595218822Sdim	    {
596218822Sdim	      width++;
597218822Sdim	      pos++;
598218822Sdim	      memset (&ps, 0, sizeof (mbstate_t));
599218822Sdim	    }
600218822Sdim	  else if (MB_NULLWCH (clen))
601218822Sdim	    break;
602218822Sdim	  else
603218822Sdim	    {
604218822Sdim	      pos += clen;
605218822Sdim	      w = wcwidth (wc);
606218822Sdim	      width += (w >= 0) ? w : 1;
607218822Sdim	    }
608218822Sdim#else
609218822Sdim	  width++;
610218822Sdim	  pos++;
611218822Sdim#endif
612218822Sdim	}
613218822Sdim    }
614218822Sdim
615218822Sdim  return width;
616218822Sdim}
617218822Sdim
618218822Sdimstatic int
619218822Sdimfnprint (to_print)
620218822Sdim     const char *to_print;
621218822Sdim{
622218822Sdim  int printed_len;
623218822Sdim  const char *s;
624218822Sdim#if defined (HANDLE_MULTIBYTE)
625218822Sdim  mbstate_t ps;
626218822Sdim  const char *end;
627218822Sdim  size_t tlen;
628218822Sdim  int width, w;
629218822Sdim  wchar_t wc;
630218822Sdim
631218822Sdim  end = to_print + strlen (to_print) + 1;
632218822Sdim  memset (&ps, 0, sizeof (mbstate_t));
633218822Sdim#endif
634218822Sdim
635218822Sdim  printed_len = 0;
636218822Sdim  s = to_print;
637218822Sdim  while (*s)
638218822Sdim    {
639218822Sdim      if (CTRL_CHAR (*s))
640218822Sdim        {
641218822Sdim          putc ('^', rl_outstream);
642218822Sdim          putc (UNCTRL (*s), rl_outstream);
643218822Sdim          printed_len += 2;
644218822Sdim          s++;
645218822Sdim#if defined (HANDLE_MULTIBYTE)
646218822Sdim	  memset (&ps, 0, sizeof (mbstate_t));
647218822Sdim#endif
648218822Sdim        }
649218822Sdim      else if (*s == RUBOUT)
650218822Sdim	{
651218822Sdim	  putc ('^', rl_outstream);
652218822Sdim	  putc ('?', rl_outstream);
653218822Sdim	  printed_len += 2;
654218822Sdim	  s++;
655218822Sdim#if defined (HANDLE_MULTIBYTE)
656218822Sdim	  memset (&ps, 0, sizeof (mbstate_t));
657218822Sdim#endif
658218822Sdim	}
659218822Sdim      else
660218822Sdim	{
661218822Sdim#if defined (HANDLE_MULTIBYTE)
662218822Sdim	  tlen = mbrtowc (&wc, s, end - s, &ps);
663218822Sdim	  if (MB_INVALIDCH (tlen))
664218822Sdim	    {
665218822Sdim	      tlen = 1;
666218822Sdim	      width = 1;
667218822Sdim	      memset (&ps, 0, sizeof (mbstate_t));
668218822Sdim	    }
669218822Sdim	  else if (MB_NULLWCH (tlen))
670218822Sdim	    break;
671218822Sdim	  else
672218822Sdim	    {
673218822Sdim	      w = wcwidth (wc);
674218822Sdim	      width = (w >= 0) ? w : 1;
675218822Sdim	    }
676218822Sdim	  fwrite (s, 1, tlen, rl_outstream);
677218822Sdim	  s += tlen;
678218822Sdim	  printed_len += width;
679218822Sdim#else
680218822Sdim	  putc (*s, rl_outstream);
681218822Sdim	  s++;
682218822Sdim	  printed_len++;
683218822Sdim#endif
684218822Sdim	}
685218822Sdim    }
686218822Sdim
687218822Sdim  return printed_len;
688218822Sdim}
689218822Sdim
690218822Sdim/* Output TO_PRINT to rl_outstream.  If VISIBLE_STATS is defined and we
691218822Sdim   are using it, check for and output a single character for `special'
692218822Sdim   filenames.  Return the number of characters we output. */
693218822Sdim
694218822Sdimstatic int
695218822Sdimprint_filename (to_print, full_pathname)
696218822Sdim     char *to_print, *full_pathname;
697218822Sdim{
698218822Sdim  int printed_len, extension_char, slen, tlen;
699218822Sdim  char *s, c, *new_full_pathname, *dn;
700218822Sdim
701218822Sdim  extension_char = 0;
702218822Sdim  printed_len = fnprint (to_print);
703218822Sdim
704218822Sdim#if defined (VISIBLE_STATS)
705218822Sdim if (rl_filename_completion_desired && (rl_visible_stats || _rl_complete_mark_directories))
706218822Sdim#else
707218822Sdim if (rl_filename_completion_desired && _rl_complete_mark_directories)
70894536Sobrien#endif
70938889Sjdp    {
71038889Sjdp      /* If to_print != full_pathname, to_print is the basename of the
71138889Sjdp	 path passed.  In this case, we try to expand the directory
712218822Sdim	 name before checking for the stat character. */
71338889Sjdp      if (to_print != full_pathname)
71438889Sjdp	{
71538889Sjdp	  /* Terminate the directory name. */
71638889Sjdp	  c = to_print[-1];
71738889Sjdp	  to_print[-1] = '\0';
71838889Sjdp
719218822Sdim	  /* If setting the last slash in full_pathname to a NUL results in
720218822Sdim	     full_pathname being the empty string, we are trying to complete
72138889Sjdp	     files in the root directory.  If we pass a null string to the
722218822Sdim	     bash directory completion hook, for example, it will expand it
72338889Sjdp	     to the current directory.  We just want the `/'. */
724218822Sdim	  if (full_pathname == 0 || *full_pathname == 0)
725218822Sdim	    dn = "/";
726218822Sdim	  else if (full_pathname[0] != '/')
72738889Sjdp	    dn = full_pathname;
72838889Sjdp	  else if (full_pathname[1] == 0)
72938889Sjdp	    dn = "//";		/* restore trailing slash to `//' */
73038889Sjdp	  else if (full_pathname[1] == '/' && full_pathname[2] == 0)
73138889Sjdp	    dn = "/";		/* don't turn /// into // */
73238889Sjdp	  else
73338889Sjdp	    dn = full_pathname;
73438889Sjdp	  s = tilde_expand (dn);
73538889Sjdp	  if (rl_directory_completion_hook)
736218822Sdim	    (*rl_directory_completion_hook) (&s);
73738889Sjdp
73838889Sjdp	  slen = strlen (s);
73938889Sjdp	  tlen = strlen (to_print);
74038889Sjdp	  new_full_pathname = (char *)xmalloc (slen + tlen + 2);
74138889Sjdp	  strcpy (new_full_pathname, s);
74238889Sjdp	  if (s[slen - 1] == '/')
74338889Sjdp	    slen--;
74438889Sjdp	  else
74538889Sjdp	    new_full_pathname[slen] = '/';
74638889Sjdp	  new_full_pathname[slen] = '/';
747218822Sdim	  strcpy (new_full_pathname + slen + 1, to_print);
748218822Sdim
749218822Sdim#if defined (VISIBLE_STATS)
750218822Sdim	  if (rl_visible_stats)
751218822Sdim	    extension_char = stat_char (new_full_pathname);
752218822Sdim	  else
753218822Sdim#endif
754218822Sdim	  if (path_isdir (new_full_pathname))
755218822Sdim	    extension_char = '/';
756218822Sdim
757218822Sdim	  free (new_full_pathname);
758218822Sdim	  to_print[-1] = c;
759218822Sdim	}
760218822Sdim      else
761218822Sdim	{
762218822Sdim	  s = tilde_expand (full_pathname);
763218822Sdim#if defined (VISIBLE_STATS)
764218822Sdim	  if (rl_visible_stats)
765218822Sdim	    extension_char = stat_char (s);
766218822Sdim	  else
767218822Sdim#endif
768218822Sdim	    if (path_isdir (s))
769218822Sdim	      extension_char = '/';
770218822Sdim	}
77138889Sjdp
772218822Sdim      free (s);
773218822Sdim      if (extension_char)
77438889Sjdp	{
775218822Sdim	  putc (extension_char, rl_outstream);
77638889Sjdp	  printed_len++;
777218822Sdim	}
778218822Sdim    }
779218822Sdim
780218822Sdim  return printed_len;
781218822Sdim}
782218822Sdim
783218822Sdimstatic char *
784218822Sdimrl_quote_filename (s, rtype, qcp)
785218822Sdim     char *s;
786218822Sdim     int rtype;
787218822Sdim     char *qcp;
788218822Sdim{
789218822Sdim  char *r;
790218822Sdim
791218822Sdim  r = (char *)xmalloc (strlen (s) + 2);
792218822Sdim  *r = *rl_completer_quote_characters;
793218822Sdim  strcpy (r + 1, s);
794218822Sdim  if (qcp)
795218822Sdim    *qcp = *rl_completer_quote_characters;
796218822Sdim  return r;
797218822Sdim}
798218822Sdim
799218822Sdim/* Find the bounds of the current word for completion purposes, and leave
800218822Sdim   rl_point set to the end of the word.  This function skips quoted
801218822Sdim   substrings (characters between matched pairs of characters in
802218822Sdim   rl_completer_quote_characters).  First we try to find an unclosed
803218822Sdim   quoted substring on which to do matching.  If one is not found, we use
804218822Sdim   the word break characters to find the boundaries of the current word.
805218822Sdim   We call an application-specific function to decide whether or not a
806218822Sdim   particular word break character is quoted; if that function returns a
807218822Sdim   non-zero result, the character does not break a word.  This function
808218822Sdim   returns the opening quote character if we found an unclosed quoted
809218822Sdim   substring, '\0' otherwise.  FP, if non-null, is set to a value saying
810218822Sdim   which (shell-like) quote characters we found (single quote, double
811218822Sdim   quote, or backslash) anywhere in the string.  DP, if non-null, is set to
812218822Sdim   the value of the delimiter character that caused a word break. */
813218822Sdim
814218822Sdimchar
815218822Sdim_rl_find_completion_word (fp, dp)
816218822Sdim     int *fp, *dp;
817218822Sdim{
818218822Sdim  int scan, end, found_quote, delimiter, pass_next, isbrk;
819218822Sdim  char quote_char, *brkchars;
820218822Sdim
821218822Sdim  end = rl_point;
82238889Sjdp  found_quote = delimiter = 0;
823218822Sdim  quote_char = '\0';
824218822Sdim
825218822Sdim  brkchars = 0;
826218822Sdim  if (rl_completion_word_break_hook)
827218822Sdim    brkchars = (*rl_completion_word_break_hook) ();
828218822Sdim  if (brkchars == 0)
829218822Sdim    brkchars = rl_completer_word_break_characters;
830218822Sdim
831218822Sdim  if (rl_completer_quote_characters)
832218822Sdim    {
833218822Sdim      /* We have a list of characters which can be used in pairs to
834218822Sdim	 quote substrings for the completer.  Try to find the start
835218822Sdim	 of an unclosed quoted substring. */
836218822Sdim      /* FOUND_QUOTE is set so we know what kind of quotes we found. */
837218822Sdim      for (scan = pass_next = 0; scan < end; scan = MB_NEXTCHAR (rl_line_buffer, scan, 1, MB_FIND_ANY))
838218822Sdim	{
839218822Sdim	  if (pass_next)
840218822Sdim	    {
841218822Sdim	      pass_next = 0;
842218822Sdim	      continue;
843218822Sdim	    }
844218822Sdim
845218822Sdim	  /* Shell-like semantics for single quotes -- don't allow backslash
84638889Sjdp	     to quote anything in single quotes, especially not the closing
84738889Sjdp	     quote.  If you don't like this, take out the check on the value
848218822Sdim	     of quote_char. */
849218822Sdim	  if (quote_char != '\'' && rl_line_buffer[scan] == '\\')
850218822Sdim	    {
85138889Sjdp	      pass_next = 1;
852218822Sdim	      found_quote |= RL_QF_BACKSLASH;
853218822Sdim	      continue;
854218822Sdim	    }
855218822Sdim
856218822Sdim	  if (quote_char != '\0')
857218822Sdim	    {
858218822Sdim	      /* Ignore everything until the matching close quote char. */
859218822Sdim	      if (rl_line_buffer[scan] == quote_char)
860218822Sdim		{
861218822Sdim		  /* Found matching close.  Abandon this substring. */
862218822Sdim		  quote_char = '\0';
863218822Sdim		  rl_point = end;
86438889Sjdp		}
865218822Sdim	    }
866218822Sdim	  else if (strchr (rl_completer_quote_characters, rl_line_buffer[scan]))
867218822Sdim	    {
868218822Sdim	      /* Found start of a quoted substring. */
869218822Sdim	      quote_char = rl_line_buffer[scan];
87038889Sjdp	      rl_point = scan + 1;
871218822Sdim	      /* Shell-like quoting conventions. */
872218822Sdim	      if (quote_char == '\'')
873218822Sdim		found_quote |= RL_QF_SINGLE_QUOTE;
874218822Sdim	      else if (quote_char == '"')
875218822Sdim		found_quote |= RL_QF_DOUBLE_QUOTE;
876218822Sdim	      else
877218822Sdim		found_quote |= RL_QF_OTHER_QUOTE;
878218822Sdim	    }
879218822Sdim	}
880218822Sdim    }
881218822Sdim
882218822Sdim  if (rl_point == end && quote_char == '\0')
883218822Sdim    {
884218822Sdim      /* We didn't find an unclosed quoted substring upon which to do
885218822Sdim         completion, so use the word break characters to find the
886         substring on which to complete. */
887      while (rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_ANY))
888	{
889	  scan = rl_line_buffer[rl_point];
890
891	  if (strchr (brkchars, scan) == 0)
892	    continue;
893
894	  /* Call the application-specific function to tell us whether
895	     this word break character is quoted and should be skipped. */
896	  if (rl_char_is_quoted_p && found_quote &&
897	      (*rl_char_is_quoted_p) (rl_line_buffer, rl_point))
898	    continue;
899
900	  /* Convoluted code, but it avoids an n^2 algorithm with calls
901	     to char_is_quoted. */
902	  break;
903	}
904    }
905
906  /* If we are at an unquoted word break, then advance past it. */
907  scan = rl_line_buffer[rl_point];
908
909  /* If there is an application-specific function to say whether or not
910     a character is quoted and we found a quote character, let that
911     function decide whether or not a character is a word break, even
912     if it is found in rl_completer_word_break_characters.  Don't bother
913     if we're at the end of the line, though. */
914  if (scan)
915    {
916      if (rl_char_is_quoted_p)
917	isbrk = (found_quote == 0 ||
918		(*rl_char_is_quoted_p) (rl_line_buffer, rl_point) == 0) &&
919		strchr (brkchars, scan) != 0;
920      else
921	isbrk = strchr (brkchars, scan) != 0;
922
923      if (isbrk)
924	{
925	  /* If the character that caused the word break was a quoting
926	     character, then remember it as the delimiter. */
927	  if (rl_basic_quote_characters &&
928	      strchr (rl_basic_quote_characters, scan) &&
929	      (end - rl_point) > 1)
930	    delimiter = scan;
931
932	  /* If the character isn't needed to determine something special
933	     about what kind of completion to perform, then advance past it. */
934	  if (rl_special_prefixes == 0 || strchr (rl_special_prefixes, scan) == 0)
935	    rl_point++;
936	}
937    }
938
939  if (fp)
940    *fp = found_quote;
941  if (dp)
942    *dp = delimiter;
943
944  return (quote_char);
945}
946
947static char **
948gen_completion_matches (text, start, end, our_func, found_quote, quote_char)
949     char *text;
950     int start, end;
951     rl_compentry_func_t *our_func;
952     int found_quote, quote_char;
953{
954  char **matches, *temp;
955
956  rl_completion_found_quote = found_quote;
957  rl_completion_quote_character = quote_char;
958
959  /* If the user wants to TRY to complete, but then wants to give
960     up and use the default completion function, they set the
961     variable rl_attempted_completion_function. */
962  if (rl_attempted_completion_function)
963    {
964      matches = (*rl_attempted_completion_function) (text, start, end);
965
966      if (matches || rl_attempted_completion_over)
967	{
968	  rl_attempted_completion_over = 0;
969	  return (matches);
970	}
971    }
972
973  /* Beware -- we're stripping the quotes here.  Do this only if we know
974     we are doing filename completion and the application has defined a
975     filename dequoting function. */
976  temp = (char *)NULL;
977
978  if (found_quote && our_func == rl_filename_completion_function &&
979      rl_filename_dequoting_function)
980    {
981      /* delete single and double quotes */
982      temp = (*rl_filename_dequoting_function) (text, quote_char);
983      text = temp;	/* not freeing text is not a memory leak */
984    }
985
986  matches = rl_completion_matches (text, our_func);
987  FREE (temp);
988  return matches;
989}
990
991/* Filter out duplicates in MATCHES.  This frees up the strings in
992   MATCHES. */
993static char **
994remove_duplicate_matches (matches)
995     char **matches;
996{
997  char *lowest_common;
998  int i, j, newlen;
999  char dead_slot;
1000  char **temp_array;
1001
1002  /* Sort the items. */
1003  for (i = 0; matches[i]; i++)
1004    ;
1005
1006  /* Sort the array without matches[0], since we need it to
1007     stay in place no matter what. */
1008  if (i)
1009    qsort (matches+1, i-1, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
1010
1011  /* Remember the lowest common denominator for it may be unique. */
1012  lowest_common = savestring (matches[0]);
1013
1014  for (i = newlen = 0; matches[i + 1]; i++)
1015    {
1016      if (strcmp (matches[i], matches[i + 1]) == 0)
1017	{
1018	  free (matches[i]);
1019	  matches[i] = (char *)&dead_slot;
1020	}
1021      else
1022	newlen++;
1023    }
1024
1025  /* We have marked all the dead slots with (char *)&dead_slot.
1026     Copy all the non-dead entries into a new array. */
1027  temp_array = (char **)xmalloc ((3 + newlen) * sizeof (char *));
1028  for (i = j = 1; matches[i]; i++)
1029    {
1030      if (matches[i] != (char *)&dead_slot)
1031	temp_array[j++] = matches[i];
1032    }
1033  temp_array[j] = (char *)NULL;
1034
1035  if (matches[0] != (char *)&dead_slot)
1036    free (matches[0]);
1037
1038  /* Place the lowest common denominator back in [0]. */
1039  temp_array[0] = lowest_common;
1040
1041  /* If there is one string left, and it is identical to the
1042     lowest common denominator, then the LCD is the string to
1043     insert. */
1044  if (j == 2 && strcmp (temp_array[0], temp_array[1]) == 0)
1045    {
1046      free (temp_array[1]);
1047      temp_array[1] = (char *)NULL;
1048    }
1049  return (temp_array);
1050}
1051
1052/* Find the common prefix of the list of matches, and put it into
1053   matches[0]. */
1054static int
1055compute_lcd_of_matches (match_list, matches, text)
1056     char **match_list;
1057     int matches;
1058     const char *text;
1059{
1060  register int i, c1, c2, si;
1061  int low;		/* Count of max-matched characters. */
1062  char *dtext;		/* dequoted TEXT, if needed */
1063#if defined (HANDLE_MULTIBYTE)
1064  int v;
1065  mbstate_t ps1, ps2;
1066  wchar_t wc1, wc2;
1067#endif
1068
1069  /* If only one match, just use that.  Otherwise, compare each
1070     member of the list with the next, finding out where they
1071     stop matching. */
1072  if (matches == 1)
1073    {
1074      match_list[0] = match_list[1];
1075      match_list[1] = (char *)NULL;
1076      return 1;
1077    }
1078
1079  for (i = 1, low = 100000; i < matches; i++)
1080    {
1081#if defined (HANDLE_MULTIBYTE)
1082      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1083	{
1084	  memset (&ps1, 0, sizeof (mbstate_t));
1085	  memset (&ps2, 0, sizeof (mbstate_t));
1086	}
1087#endif
1088      if (_rl_completion_case_fold)
1089	{
1090	  for (si = 0;
1091	       (c1 = _rl_to_lower(match_list[i][si])) &&
1092	       (c2 = _rl_to_lower(match_list[i + 1][si]));
1093	       si++)
1094#if defined (HANDLE_MULTIBYTE)
1095	    if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1096	      {
1097		v = mbrtowc (&wc1, match_list[i]+si, strlen (match_list[i]+si), &ps1);
1098		mbrtowc (&wc2, match_list[i+1]+si, strlen (match_list[i+1]+si), &ps2);
1099		wc1 = towlower (wc1);
1100		wc2 = towlower (wc2);
1101		if (wc1 != wc2)
1102		  break;
1103		else if (v > 1)
1104		  si += v - 1;
1105	      }
1106	    else
1107#endif
1108	    if (c1 != c2)
1109	      break;
1110	}
1111      else
1112	{
1113	  for (si = 0;
1114	       (c1 = match_list[i][si]) &&
1115	       (c2 = match_list[i + 1][si]);
1116	       si++)
1117#if defined (HANDLE_MULTIBYTE)
1118	    if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1119	      {
1120		mbstate_t ps_back = ps1;
1121		if (!_rl_compare_chars (match_list[i], si, &ps1, match_list[i+1], si, &ps2))
1122		  break;
1123		else if ((v = _rl_get_char_len (&match_list[i][si], &ps_back)) > 1)
1124		  si += v - 1;
1125	      }
1126	    else
1127#endif
1128	    if (c1 != c2)
1129	      break;
1130	}
1131
1132      if (low > si)
1133	low = si;
1134    }
1135
1136  /* If there were multiple matches, but none matched up to even the
1137     first character, and the user typed something, use that as the
1138     value of matches[0]. */
1139  if (low == 0 && text && *text)
1140    {
1141      match_list[0] = (char *)xmalloc (strlen (text) + 1);
1142      strcpy (match_list[0], text);
1143    }
1144  else
1145    {
1146      match_list[0] = (char *)xmalloc (low + 1);
1147
1148      /* XXX - this might need changes in the presence of multibyte chars */
1149
1150      /* If we are ignoring case, try to preserve the case of the string
1151	 the user typed in the face of multiple matches differing in case. */
1152      if (_rl_completion_case_fold)
1153	{
1154	  /* We're making an assumption here:
1155		IF we're completing filenames AND
1156		   the application has defined a filename dequoting function AND
1157		   we found a quote character AND
1158		   the application has requested filename quoting
1159		THEN
1160		   we assume that TEXT was dequoted before checking against
1161		   the file system and needs to be dequoted here before we
1162		   check against the list of matches
1163		FI */
1164	  dtext = (char *)NULL;
1165	  if (rl_filename_completion_desired &&
1166	      rl_filename_dequoting_function &&
1167	      rl_completion_found_quote &&
1168	      rl_filename_quoting_desired)
1169	    {
1170	      dtext = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character);
1171	      text = dtext;
1172	    }
1173
1174	  /* sort the list to get consistent answers. */
1175	  qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare);
1176
1177	  si = strlen (text);
1178	  if (si <= low)
1179	    {
1180	      for (i = 1; i <= matches; i++)
1181		if (strncmp (match_list[i], text, si) == 0)
1182		  {
1183		    strncpy (match_list[0], match_list[i], low);
1184		    break;
1185		  }
1186	      /* no casematch, use first entry */
1187	      if (i > matches)
1188		strncpy (match_list[0], match_list[1], low);
1189	    }
1190	  else
1191	    /* otherwise, just use the text the user typed. */
1192	    strncpy (match_list[0], text, low);
1193
1194	  FREE (dtext);
1195	}
1196      else
1197        strncpy (match_list[0], match_list[1], low);
1198
1199      match_list[0][low] = '\0';
1200    }
1201
1202  return matches;
1203}
1204
1205static int
1206postprocess_matches (matchesp, matching_filenames)
1207     char ***matchesp;
1208     int matching_filenames;
1209{
1210  char *t, **matches, **temp_matches;
1211  int nmatch, i;
1212
1213  matches = *matchesp;
1214
1215  if (matches == 0)
1216    return 0;
1217
1218  /* It seems to me that in all the cases we handle we would like
1219     to ignore duplicate possiblilities.  Scan for the text to
1220     insert being identical to the other completions. */
1221  if (rl_ignore_completion_duplicates)
1222    {
1223      temp_matches = remove_duplicate_matches (matches);
1224      free (matches);
1225      matches = temp_matches;
1226    }
1227
1228  /* If we are matching filenames, then here is our chance to
1229     do clever processing by re-examining the list.  Call the
1230     ignore function with the array as a parameter.  It can
1231     munge the array, deleting matches as it desires. */
1232  if (rl_ignore_some_completions_function && matching_filenames)
1233    {
1234      for (nmatch = 1; matches[nmatch]; nmatch++)
1235	;
1236      (void)(*rl_ignore_some_completions_function) (matches);
1237      if (matches == 0 || matches[0] == 0)
1238	{
1239	  FREE (matches);
1240	  *matchesp = (char **)0;
1241	  return 0;
1242        }
1243      else
1244	{
1245	  /* If we removed some matches, recompute the common prefix. */
1246	  for (i = 1; matches[i]; i++)
1247	    ;
1248	  if (i > 1 && i < nmatch)
1249	    {
1250	      t = matches[0];
1251	      compute_lcd_of_matches (matches, i - 1, t);
1252	      FREE (t);
1253	    }
1254	}
1255    }
1256
1257  *matchesp = matches;
1258  return (1);
1259}
1260
1261/* A convenience function for displaying a list of strings in
1262   columnar format on readline's output stream.  MATCHES is the list
1263   of strings, in argv format, LEN is the number of strings in MATCHES,
1264   and MAX is the length of the longest string in MATCHES. */
1265void
1266rl_display_match_list (matches, len, max)
1267     char **matches;
1268     int len, max;
1269{
1270  int count, limit, printed_len, lines;
1271  int i, j, k, l;
1272  char *temp;
1273
1274  /* How many items of MAX length can we fit in the screen window? */
1275  max += 2;
1276  limit = _rl_screenwidth / max;
1277  if (limit != 1 && (limit * max == _rl_screenwidth))
1278    limit--;
1279
1280  /* Avoid a possible floating exception.  If max > _rl_screenwidth,
1281     limit will be 0 and a divide-by-zero fault will result. */
1282  if (limit == 0)
1283    limit = 1;
1284
1285  /* How many iterations of the printing loop? */
1286  count = (len + (limit - 1)) / limit;
1287
1288  /* Watch out for special case.  If LEN is less than LIMIT, then
1289     just do the inner printing loop.
1290	   0 < len <= limit  implies  count = 1. */
1291
1292  /* Sort the items if they are not already sorted. */
1293  if (rl_ignore_completion_duplicates == 0)
1294    qsort (matches + 1, len, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
1295
1296  rl_crlf ();
1297
1298  lines = 0;
1299  if (_rl_print_completions_horizontally == 0)
1300    {
1301      /* Print the sorted items, up-and-down alphabetically, like ls. */
1302      for (i = 1; i <= count; i++)
1303	{
1304	  for (j = 0, l = i; j < limit; j++)
1305	    {
1306	      if (l > len || matches[l] == 0)
1307		break;
1308	      else
1309		{
1310		  temp = printable_part (matches[l]);
1311		  printed_len = print_filename (temp, matches[l]);
1312
1313		  if (j + 1 < limit)
1314		    for (k = 0; k < max - printed_len; k++)
1315		      putc (' ', rl_outstream);
1316		}
1317	      l += count;
1318	    }
1319	  rl_crlf ();
1320	  lines++;
1321	  if (_rl_page_completions && lines >= (_rl_screenheight - 1) && i < count)
1322	    {
1323	      lines = _rl_internal_pager (lines);
1324	      if (lines < 0)
1325		return;
1326	    }
1327	}
1328    }
1329  else
1330    {
1331      /* Print the sorted items, across alphabetically, like ls -x. */
1332      for (i = 1; matches[i]; i++)
1333	{
1334	  temp = printable_part (matches[i]);
1335	  printed_len = print_filename (temp, matches[i]);
1336	  /* Have we reached the end of this line? */
1337	  if (matches[i+1])
1338	    {
1339	      if (i && (limit > 1) && (i % limit) == 0)
1340		{
1341		  rl_crlf ();
1342		  lines++;
1343		  if (_rl_page_completions && lines >= _rl_screenheight - 1)
1344		    {
1345		      lines = _rl_internal_pager (lines);
1346		      if (lines < 0)
1347			return;
1348		    }
1349		}
1350	      else
1351		for (k = 0; k < max - printed_len; k++)
1352		  putc (' ', rl_outstream);
1353	    }
1354	}
1355      rl_crlf ();
1356    }
1357}
1358
1359/* Display MATCHES, a list of matching filenames in argv format.  This
1360   handles the simple case -- a single match -- first.  If there is more
1361   than one match, we compute the number of strings in the list and the
1362   length of the longest string, which will be needed by the display
1363   function.  If the application wants to handle displaying the list of
1364   matches itself, it sets RL_COMPLETION_DISPLAY_MATCHES_HOOK to the
1365   address of a function, and we just call it.  If we're handling the
1366   display ourselves, we just call rl_display_match_list.  We also check
1367   that the list of matches doesn't exceed the user-settable threshold,
1368   and ask the user if he wants to see the list if there are more matches
1369   than RL_COMPLETION_QUERY_ITEMS. */
1370static void
1371display_matches (matches)
1372     char **matches;
1373{
1374  int len, max, i;
1375  char *temp;
1376
1377  /* Move to the last visible line of a possibly-multiple-line command. */
1378  _rl_move_vert (_rl_vis_botlin);
1379
1380  /* Handle simple case first.  What if there is only one answer? */
1381  if (matches[1] == 0)
1382    {
1383      temp = printable_part (matches[0]);
1384      rl_crlf ();
1385      print_filename (temp, matches[0]);
1386      rl_crlf ();
1387
1388      rl_forced_update_display ();
1389      rl_display_fixed = 1;
1390
1391      return;
1392    }
1393
1394  /* There is more than one answer.  Find out how many there are,
1395     and find the maximum printed length of a single entry. */
1396  for (max = 0, i = 1; matches[i]; i++)
1397    {
1398      temp = printable_part (matches[i]);
1399      len = fnwidth (temp);
1400
1401      if (len > max)
1402	max = len;
1403    }
1404
1405  len = i - 1;
1406
1407  /* If the caller has defined a display hook, then call that now. */
1408  if (rl_completion_display_matches_hook)
1409    {
1410      (*rl_completion_display_matches_hook) (matches, len, max);
1411      return;
1412    }
1413
1414  /* If there are many items, then ask the user if she really wants to
1415     see them all. */
1416  if (rl_completion_query_items > 0 && len >= rl_completion_query_items)
1417    {
1418      rl_crlf ();
1419      fprintf (rl_outstream, "Display all %d possibilities? (y or n)", len);
1420      fflush (rl_outstream);
1421      if (get_y_or_n (0) == 0)
1422	{
1423	  rl_crlf ();
1424
1425	  rl_forced_update_display ();
1426	  rl_display_fixed = 1;
1427
1428	  return;
1429	}
1430    }
1431
1432  rl_display_match_list (matches, len, max);
1433
1434  rl_forced_update_display ();
1435  rl_display_fixed = 1;
1436}
1437
1438static char *
1439make_quoted_replacement (match, mtype, qc)
1440     char *match;
1441     int mtype;
1442     char *qc;	/* Pointer to quoting character, if any */
1443{
1444  int should_quote, do_replace;
1445  char *replacement;
1446
1447  /* If we are doing completion on quoted substrings, and any matches
1448     contain any of the completer_word_break_characters, then auto-
1449     matically prepend the substring with a quote character (just pick
1450     the first one from the list of such) if it does not already begin
1451     with a quote string.  FIXME: Need to remove any such automatically
1452     inserted quote character when it no longer is necessary, such as
1453     if we change the string we are completing on and the new set of
1454     matches don't require a quoted substring. */
1455  replacement = match;
1456
1457  should_quote = match && rl_completer_quote_characters &&
1458			rl_filename_completion_desired &&
1459			rl_filename_quoting_desired;
1460
1461  if (should_quote)
1462    should_quote = should_quote && (!qc || !*qc ||
1463		     (rl_completer_quote_characters && strchr (rl_completer_quote_characters, *qc)));
1464
1465  if (should_quote)
1466    {
1467      /* If there is a single match, see if we need to quote it.
1468         This also checks whether the common prefix of several
1469	 matches needs to be quoted. */
1470      should_quote = rl_filename_quote_characters
1471			? (_rl_strpbrk (match, rl_filename_quote_characters) != 0)
1472			: 0;
1473
1474      do_replace = should_quote ? mtype : NO_MATCH;
1475      /* Quote the replacement, since we found an embedded
1476	 word break character in a potential match. */
1477      if (do_replace != NO_MATCH && rl_filename_quoting_function)
1478	replacement = (*rl_filename_quoting_function) (match, do_replace, qc);
1479    }
1480  return (replacement);
1481}
1482
1483static void
1484insert_match (match, start, mtype, qc)
1485     char *match;
1486     int start, mtype;
1487     char *qc;
1488{
1489  char *replacement;
1490  char oqc;
1491
1492  oqc = qc ? *qc : '\0';
1493  replacement = make_quoted_replacement (match, mtype, qc);
1494
1495  /* Now insert the match. */
1496  if (replacement)
1497    {
1498      /* Don't double an opening quote character. */
1499      if (qc && *qc && start && rl_line_buffer[start - 1] == *qc &&
1500	    replacement[0] == *qc)
1501	start--;
1502      /* If make_quoted_replacement changed the quoting character, remove
1503	 the opening quote and insert the (fully-quoted) replacement. */
1504      else if (qc && (*qc != oqc) && start && rl_line_buffer[start - 1] == oqc &&
1505	    replacement[0] != oqc)
1506	start--;
1507      _rl_replace_text (replacement, start, rl_point - 1);
1508      if (replacement != match)
1509        free (replacement);
1510    }
1511}
1512
1513/* Append any necessary closing quote and a separator character to the
1514   just-inserted match.  If the user has specified that directories
1515   should be marked by a trailing `/', append one of those instead.  The
1516   default trailing character is a space.  Returns the number of characters
1517   appended.  If NONTRIVIAL_MATCH is set, we test for a symlink (if the OS
1518   has them) and don't add a suffix for a symlink to a directory.  A
1519   nontrivial match is one that actually adds to the word being completed.
1520   The variable rl_completion_mark_symlink_dirs controls this behavior
1521   (it's initially set to the what the user has chosen, indicated by the
1522   value of _rl_complete_mark_symlink_dirs, but may be modified by an
1523   application's completion function). */
1524static int
1525append_to_match (text, delimiter, quote_char, nontrivial_match)
1526     char *text;
1527     int delimiter, quote_char, nontrivial_match;
1528{
1529  char temp_string[4], *filename;
1530  int temp_string_index, s;
1531  struct stat finfo;
1532
1533  temp_string_index = 0;
1534  if (quote_char && rl_point && rl_completion_suppress_quote == 0 &&
1535      rl_line_buffer[rl_point - 1] != quote_char)
1536    temp_string[temp_string_index++] = quote_char;
1537
1538  if (delimiter)
1539    temp_string[temp_string_index++] = delimiter;
1540  else if (rl_completion_suppress_append == 0 && rl_completion_append_character)
1541    temp_string[temp_string_index++] = rl_completion_append_character;
1542
1543  temp_string[temp_string_index++] = '\0';
1544
1545  if (rl_filename_completion_desired)
1546    {
1547      filename = tilde_expand (text);
1548      s = (nontrivial_match && rl_completion_mark_symlink_dirs == 0)
1549		? LSTAT (filename, &finfo)
1550		: stat (filename, &finfo);
1551      if (s == 0 && S_ISDIR (finfo.st_mode))
1552	{
1553	  if (_rl_complete_mark_directories /* && rl_completion_suppress_append == 0 */)
1554	    {
1555	      /* This is clumsy.  Avoid putting in a double slash if point
1556		 is at the end of the line and the previous character is a
1557		 slash. */
1558	      if (rl_point && rl_line_buffer[rl_point] == '\0' && rl_line_buffer[rl_point - 1] == '/')
1559		;
1560	      else if (rl_line_buffer[rl_point] != '/')
1561		rl_insert_text ("/");
1562	    }
1563	}
1564#ifdef S_ISLNK
1565      /* Don't add anything if the filename is a symlink and resolves to a
1566	 directory. */
1567      else if (s == 0 && S_ISLNK (finfo.st_mode) &&
1568	       stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode))
1569	;
1570#endif
1571      else
1572	{
1573	  if (rl_point == rl_end && temp_string_index)
1574	    rl_insert_text (temp_string);
1575	}
1576      free (filename);
1577    }
1578  else
1579    {
1580      if (rl_point == rl_end && temp_string_index)
1581	rl_insert_text (temp_string);
1582    }
1583
1584  return (temp_string_index);
1585}
1586
1587static void
1588insert_all_matches (matches, point, qc)
1589     char **matches;
1590     int point;
1591     char *qc;
1592{
1593  int i;
1594  char *rp;
1595
1596  rl_begin_undo_group ();
1597  /* remove any opening quote character; make_quoted_replacement will add
1598     it back. */
1599  if (qc && *qc && point && rl_line_buffer[point - 1] == *qc)
1600    point--;
1601  rl_delete_text (point, rl_point);
1602  rl_point = point;
1603
1604  if (matches[1])
1605    {
1606      for (i = 1; matches[i]; i++)
1607	{
1608	  rp = make_quoted_replacement (matches[i], SINGLE_MATCH, qc);
1609	  rl_insert_text (rp);
1610	  rl_insert_text (" ");
1611	  if (rp != matches[i])
1612	    free (rp);
1613	}
1614    }
1615  else
1616    {
1617      rp = make_quoted_replacement (matches[0], SINGLE_MATCH, qc);
1618      rl_insert_text (rp);
1619      rl_insert_text (" ");
1620      if (rp != matches[0])
1621	free (rp);
1622    }
1623  rl_end_undo_group ();
1624}
1625
1626void
1627_rl_free_match_list (matches)
1628     char **matches;
1629{
1630  register int i;
1631
1632  if (matches == 0)
1633    return;
1634
1635  for (i = 0; matches[i]; i++)
1636    free (matches[i]);
1637  free (matches);
1638}
1639
1640/* Complete the word at or before point.
1641   WHAT_TO_DO says what to do with the completion.
1642   `?' means list the possible completions.
1643   TAB means do standard completion.
1644   `*' means insert all of the possible completions.
1645   `!' means to do standard completion, and list all possible completions if
1646   there is more than one.
1647   `@' means to do standard completion, and list all possible completions if
1648   there is more than one and partial completion is not possible. */
1649int
1650rl_complete_internal (what_to_do)
1651     int what_to_do;
1652{
1653  char **matches;
1654  rl_compentry_func_t *our_func;
1655  int start, end, delimiter, found_quote, i, nontrivial_lcd;
1656  char *text, *saved_line_buffer;
1657  char quote_char;
1658
1659  RL_SETSTATE(RL_STATE_COMPLETING);
1660
1661  set_completion_defaults (what_to_do);
1662
1663  saved_line_buffer = rl_line_buffer ? savestring (rl_line_buffer) : (char *)NULL;
1664  our_func = rl_completion_entry_function
1665		? rl_completion_entry_function
1666		: rl_filename_completion_function;
1667  /* We now look backwards for the start of a filename/variable word. */
1668  end = rl_point;
1669  found_quote = delimiter = 0;
1670  quote_char = '\0';
1671
1672  if (rl_point)
1673    /* This (possibly) changes rl_point.  If it returns a non-zero char,
1674       we know we have an open quote. */
1675    quote_char = _rl_find_completion_word (&found_quote, &delimiter);
1676
1677  start = rl_point;
1678  rl_point = end;
1679
1680  text = rl_copy_text (start, end);
1681  matches = gen_completion_matches (text, start, end, our_func, found_quote, quote_char);
1682  /* nontrivial_lcd is set if the common prefix adds something to the word
1683     being completed. */
1684  nontrivial_lcd = matches && strcmp (text, matches[0]) != 0;
1685  free (text);
1686
1687  if (matches == 0)
1688    {
1689      rl_ding ();
1690      FREE (saved_line_buffer);
1691      completion_changed_buffer = 0;
1692      RL_UNSETSTATE(RL_STATE_COMPLETING);
1693      return (0);
1694    }
1695
1696  /* If we are matching filenames, the attempted completion function will
1697     have set rl_filename_completion_desired to a non-zero value.  The basic
1698     rl_filename_completion_function does this. */
1699  i = rl_filename_completion_desired;
1700
1701  if (postprocess_matches (&matches, i) == 0)
1702    {
1703      rl_ding ();
1704      FREE (saved_line_buffer);
1705      completion_changed_buffer = 0;
1706      RL_UNSETSTATE(RL_STATE_COMPLETING);
1707      return (0);
1708    }
1709
1710  switch (what_to_do)
1711    {
1712    case TAB:
1713    case '!':
1714    case '@':
1715      /* Insert the first match with proper quoting. */
1716      if (*matches[0])
1717	insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
1718
1719      /* If there are more matches, ring the bell to indicate.
1720	 If we are in vi mode, Posix.2 says to not ring the bell.
1721	 If the `show-all-if-ambiguous' variable is set, display
1722	 all the matches immediately.  Otherwise, if this was the
1723	 only match, and we are hacking files, check the file to
1724	 see if it was a directory.  If so, and the `mark-directories'
1725	 variable is set, add a '/' to the name.  If not, and we
1726	 are at the end of the line, then add a space.  */
1727      if (matches[1])
1728	{
1729	  if (what_to_do == '!')
1730	    {
1731	      display_matches (matches);
1732	      break;
1733	    }
1734	  else if (what_to_do == '@')
1735	    {
1736	      if (nontrivial_lcd == 0)
1737		display_matches (matches);
1738	      break;
1739	    }
1740	  else if (rl_editing_mode != vi_mode)
1741	    rl_ding ();	/* There are other matches remaining. */
1742	}
1743      else
1744	append_to_match (matches[0], delimiter, quote_char, nontrivial_lcd);
1745
1746      break;
1747
1748    case '*':
1749      insert_all_matches (matches, start, &quote_char);
1750      break;
1751
1752    case '?':
1753      display_matches (matches);
1754      break;
1755
1756    default:
1757      fprintf (stderr, "\r\nreadline: bad value %d for what_to_do in rl_complete\n", what_to_do);
1758      rl_ding ();
1759      FREE (saved_line_buffer);
1760      RL_UNSETSTATE(RL_STATE_COMPLETING);
1761      return 1;
1762    }
1763
1764  _rl_free_match_list (matches);
1765
1766  /* Check to see if the line has changed through all of this manipulation. */
1767  if (saved_line_buffer)
1768    {
1769      completion_changed_buffer = strcmp (rl_line_buffer, saved_line_buffer) != 0;
1770      free (saved_line_buffer);
1771    }
1772
1773  RL_UNSETSTATE(RL_STATE_COMPLETING);
1774  return 0;
1775}
1776
1777/***************************************************************/
1778/*							       */
1779/*  Application-callable completion match generator functions  */
1780/*							       */
1781/***************************************************************/
1782
1783/* Return an array of (char *) which is a list of completions for TEXT.
1784   If there are no completions, return a NULL pointer.
1785   The first entry in the returned array is the substitution for TEXT.
1786   The remaining entries are the possible completions.
1787   The array is terminated with a NULL pointer.
1788
1789   ENTRY_FUNCTION is a function of two args, and returns a (char *).
1790     The first argument is TEXT.
1791     The second is a state argument; it should be zero on the first call, and
1792     non-zero on subsequent calls.  It returns a NULL pointer to the caller
1793     when there are no more matches.
1794 */
1795char **
1796rl_completion_matches (text, entry_function)
1797     const char *text;
1798     rl_compentry_func_t *entry_function;
1799{
1800  /* Number of slots in match_list. */
1801  int match_list_size;
1802
1803  /* The list of matches. */
1804  char **match_list;
1805
1806  /* Number of matches actually found. */
1807  int matches;
1808
1809  /* Temporary string binder. */
1810  char *string;
1811
1812  matches = 0;
1813  match_list_size = 10;
1814  match_list = (char **)xmalloc ((match_list_size + 1) * sizeof (char *));
1815  match_list[1] = (char *)NULL;
1816
1817  while (string = (*entry_function) (text, matches))
1818    {
1819      if (matches + 1 == match_list_size)
1820	match_list = (char **)xrealloc
1821	  (match_list, ((match_list_size += 10) + 1) * sizeof (char *));
1822
1823      match_list[++matches] = string;
1824      match_list[matches + 1] = (char *)NULL;
1825    }
1826
1827  /* If there were any matches, then look through them finding out the
1828     lowest common denominator.  That then becomes match_list[0]. */
1829  if (matches)
1830    compute_lcd_of_matches (match_list, matches, text);
1831  else				/* There were no matches. */
1832    {
1833      free (match_list);
1834      match_list = (char **)NULL;
1835    }
1836  return (match_list);
1837}
1838
1839/* A completion function for usernames.
1840   TEXT contains a partial username preceded by a random
1841   character (usually `~').  */
1842char *
1843rl_username_completion_function (text, state)
1844     const char *text;
1845     int state;
1846{
1847#if defined (__WIN32__) || defined (__OPENNT)
1848  return (char *)NULL;
1849#else /* !__WIN32__ && !__OPENNT) */
1850  static char *username = (char *)NULL;
1851  static struct passwd *entry;
1852  static int namelen, first_char, first_char_loc;
1853  char *value;
1854
1855  if (state == 0)
1856    {
1857      FREE (username);
1858
1859      first_char = *text;
1860      first_char_loc = first_char == '~';
1861
1862      username = savestring (&text[first_char_loc]);
1863      namelen = strlen (username);
1864      setpwent ();
1865    }
1866
1867#if defined (HAVE_GETPWENT)
1868  while (entry = getpwent ())
1869    {
1870      /* Null usernames should result in all users as possible completions. */
1871      if (namelen == 0 || (STREQN (username, entry->pw_name, namelen)))
1872	break;
1873    }
1874#endif
1875
1876  if (entry == 0)
1877    {
1878#if defined (HAVE_GETPWENT)
1879      endpwent ();
1880#endif
1881      return ((char *)NULL);
1882    }
1883  else
1884    {
1885      value = (char *)xmalloc (2 + strlen (entry->pw_name));
1886
1887      *value = *text;
1888
1889      strcpy (value + first_char_loc, entry->pw_name);
1890
1891      if (first_char == '~')
1892	rl_filename_completion_desired = 1;
1893
1894      return (value);
1895    }
1896#endif /* !__WIN32__ && !__OPENNT */
1897}
1898
1899/* Okay, now we write the entry_function for filename completion.  In the
1900   general case.  Note that completion in the shell is a little different
1901   because of all the pathnames that must be followed when looking up the
1902   completion for a command. */
1903char *
1904rl_filename_completion_function (text, state)
1905     const char *text;
1906     int state;
1907{
1908  static DIR *directory = (DIR *)NULL;
1909  static char *filename = (char *)NULL;
1910  static char *dirname = (char *)NULL;
1911  static char *users_dirname = (char *)NULL;
1912  static int filename_len;
1913  char *temp;
1914  int dirlen;
1915  struct dirent *entry;
1916
1917  /* If we don't have any state, then do some initialization. */
1918  if (state == 0)
1919    {
1920      /* If we were interrupted before closing the directory or reading
1921	 all of its contents, close it. */
1922      if (directory)
1923	{
1924	  closedir (directory);
1925	  directory = (DIR *)NULL;
1926	}
1927      FREE (dirname);
1928      FREE (filename);
1929      FREE (users_dirname);
1930
1931      filename = savestring (text);
1932      if (*text == 0)
1933	text = ".";
1934      dirname = savestring (text);
1935
1936      temp = strrchr (dirname, '/');
1937
1938#if defined (__MSDOS__)
1939      /* special hack for //X/... */
1940      if (dirname[0] == '/' && dirname[1] == '/' && ISALPHA ((unsigned char)dirname[2]) && dirname[3] == '/')
1941        temp = strrchr (dirname + 3, '/');
1942#endif
1943
1944      if (temp)
1945	{
1946	  strcpy (filename, ++temp);
1947	  *temp = '\0';
1948	}
1949#if defined (__MSDOS__)
1950      /* searches from current directory on the drive */
1951      else if (ISALPHA ((unsigned char)dirname[0]) && dirname[1] == ':')
1952        {
1953          strcpy (filename, dirname + 2);
1954          dirname[2] = '\0';
1955        }
1956#endif
1957      else
1958	{
1959	  dirname[0] = '.';
1960	  dirname[1] = '\0';
1961	}
1962
1963      /* We aren't done yet.  We also support the "~user" syntax. */
1964
1965      /* Save the version of the directory that the user typed. */
1966      users_dirname = savestring (dirname);
1967
1968      if (*dirname == '~')
1969	{
1970	  temp = tilde_expand (dirname);
1971	  free (dirname);
1972	  dirname = temp;
1973	}
1974
1975      if (rl_directory_rewrite_hook)
1976	(*rl_directory_rewrite_hook) (&dirname);
1977
1978      if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&dirname))
1979	{
1980	  free (users_dirname);
1981	  users_dirname = savestring (dirname);
1982	}
1983
1984      directory = opendir (dirname);
1985      filename_len = strlen (filename);
1986
1987      rl_filename_completion_desired = 1;
1988    }
1989
1990  /* At this point we should entertain the possibility of hacking wildcarded
1991     filenames, like /usr/man/man<WILD>/te<TAB>.  If the directory name
1992     contains globbing characters, then build an array of directories, and
1993     then map over that list while completing. */
1994  /* *** UNIMPLEMENTED *** */
1995
1996  /* Now that we have some state, we can read the directory. */
1997
1998  entry = (struct dirent *)NULL;
1999  while (directory && (entry = readdir (directory)))
2000    {
2001      /* Special case for no filename.  If the user has disabled the
2002         `match-hidden-files' variable, skip filenames beginning with `.'.
2003	 All other entries except "." and ".." match. */
2004      if (filename_len == 0)
2005	{
2006	  if (_rl_match_hidden_files == 0 && HIDDEN_FILE (entry->d_name))
2007	    continue;
2008
2009	  if (entry->d_name[0] != '.' ||
2010	       (entry->d_name[1] &&
2011		 (entry->d_name[1] != '.' || entry->d_name[2])))
2012	    break;
2013	}
2014      else
2015	{
2016	  /* Otherwise, if these match up to the length of filename, then
2017	     it is a match. */
2018	  if (_rl_completion_case_fold)
2019	    {
2020	      if ((_rl_to_lower (entry->d_name[0]) == _rl_to_lower (filename[0])) &&
2021		  (((int)D_NAMLEN (entry)) >= filename_len) &&
2022		  (_rl_strnicmp (filename, entry->d_name, filename_len) == 0))
2023		break;
2024	    }
2025	  else
2026	    {
2027	      if ((entry->d_name[0] == filename[0]) &&
2028		  (((int)D_NAMLEN (entry)) >= filename_len) &&
2029		  (strncmp (filename, entry->d_name, filename_len) == 0))
2030		break;
2031	    }
2032	}
2033    }
2034
2035  if (entry == 0)
2036    {
2037      if (directory)
2038	{
2039	  closedir (directory);
2040	  directory = (DIR *)NULL;
2041	}
2042      if (dirname)
2043	{
2044	  free (dirname);
2045	  dirname = (char *)NULL;
2046	}
2047      if (filename)
2048	{
2049	  free (filename);
2050	  filename = (char *)NULL;
2051	}
2052      if (users_dirname)
2053	{
2054	  free (users_dirname);
2055	  users_dirname = (char *)NULL;
2056	}
2057
2058      return (char *)NULL;
2059    }
2060  else
2061    {
2062      /* dirname && (strcmp (dirname, ".") != 0) */
2063      if (dirname && (dirname[0] != '.' || dirname[1]))
2064	{
2065	  if (rl_complete_with_tilde_expansion && *users_dirname == '~')
2066	    {
2067	      dirlen = strlen (dirname);
2068	      temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry));
2069	      strcpy (temp, dirname);
2070	      /* Canonicalization cuts off any final slash present.  We
2071		 may need to add it back. */
2072	      if (dirname[dirlen - 1] != '/')
2073	        {
2074	          temp[dirlen++] = '/';
2075	          temp[dirlen] = '\0';
2076	        }
2077	    }
2078	  else
2079	    {
2080	      dirlen = strlen (users_dirname);
2081	      temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry));
2082	      strcpy (temp, users_dirname);
2083	      /* Make sure that temp has a trailing slash here. */
2084	      if (users_dirname[dirlen - 1] != '/')
2085		temp[dirlen++] = '/';
2086	    }
2087
2088	  strcpy (temp + dirlen, entry->d_name);
2089	}
2090      else
2091	temp = savestring (entry->d_name);
2092
2093      return (temp);
2094    }
2095}
2096
2097/* An initial implementation of a menu completion function a la tcsh.  The
2098   first time (if the last readline command was not rl_menu_complete), we
2099   generate the list of matches.  This code is very similar to the code in
2100   rl_complete_internal -- there should be a way to combine the two.  Then,
2101   for each item in the list of matches, we insert the match in an undoable
2102   fashion, with the appropriate character appended (this happens on the
2103   second and subsequent consecutive calls to rl_menu_complete).  When we
2104   hit the end of the match list, we restore the original unmatched text,
2105   ring the bell, and reset the counter to zero. */
2106int
2107rl_menu_complete (count, ignore)
2108     int count, ignore;
2109{
2110  rl_compentry_func_t *our_func;
2111  int matching_filenames, found_quote;
2112
2113  static char *orig_text;
2114  static char **matches = (char **)0;
2115  static int match_list_index = 0;
2116  static int match_list_size = 0;
2117  static int orig_start, orig_end;
2118  static char quote_char;
2119  static int delimiter;
2120
2121  /* The first time through, we generate the list of matches and set things
2122     up to insert them. */
2123  if (rl_last_func != rl_menu_complete)
2124    {
2125      /* Clean up from previous call, if any. */
2126      FREE (orig_text);
2127      if (matches)
2128	_rl_free_match_list (matches);
2129
2130      match_list_index = match_list_size = 0;
2131      matches = (char **)NULL;
2132
2133      /* Only the completion entry function can change these. */
2134      set_completion_defaults ('%');
2135
2136      our_func = rl_completion_entry_function
2137			? rl_completion_entry_function
2138			: rl_filename_completion_function;
2139
2140      /* We now look backwards for the start of a filename/variable word. */
2141      orig_end = rl_point;
2142      found_quote = delimiter = 0;
2143      quote_char = '\0';
2144
2145      if (rl_point)
2146	/* This (possibly) changes rl_point.  If it returns a non-zero char,
2147	   we know we have an open quote. */
2148	quote_char = _rl_find_completion_word (&found_quote, &delimiter);
2149
2150      orig_start = rl_point;
2151      rl_point = orig_end;
2152
2153      orig_text = rl_copy_text (orig_start, orig_end);
2154      matches = gen_completion_matches (orig_text, orig_start, orig_end,
2155					our_func, found_quote, quote_char);
2156
2157      /* If we are matching filenames, the attempted completion function will
2158	 have set rl_filename_completion_desired to a non-zero value.  The basic
2159	 rl_filename_completion_function does this. */
2160      matching_filenames = rl_filename_completion_desired;
2161
2162      if (matches == 0 || postprocess_matches (&matches, matching_filenames) == 0)
2163	{
2164    	  rl_ding ();
2165	  FREE (matches);
2166	  matches = (char **)0;
2167	  FREE (orig_text);
2168	  orig_text = (char *)0;
2169    	  completion_changed_buffer = 0;
2170          return (0);
2171	}
2172
2173      for (match_list_size = 0; matches[match_list_size]; match_list_size++)
2174        ;
2175      /* matches[0] is lcd if match_list_size > 1, but the circular buffer
2176	 code below should take care of it. */
2177    }
2178
2179  /* Now we have the list of matches.  Replace the text between
2180     rl_line_buffer[orig_start] and rl_line_buffer[rl_point] with
2181     matches[match_list_index], and add any necessary closing char. */
2182
2183  if (matches == 0 || match_list_size == 0)
2184    {
2185      rl_ding ();
2186      FREE (matches);
2187      matches = (char **)0;
2188      completion_changed_buffer = 0;
2189      return (0);
2190    }
2191
2192  match_list_index += count;
2193  if (match_list_index < 0)
2194    match_list_index += match_list_size;
2195  else
2196    match_list_index %= match_list_size;
2197
2198  if (match_list_index == 0 && match_list_size > 1)
2199    {
2200      rl_ding ();
2201      insert_match (orig_text, orig_start, MULT_MATCH, &quote_char);
2202    }
2203  else
2204    {
2205      insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, &quote_char);
2206      append_to_match (matches[match_list_index], delimiter, quote_char,
2207		       strcmp (orig_text, matches[match_list_index]));
2208    }
2209
2210  completion_changed_buffer = 1;
2211  return (0);
2212}
2213