158314Sache/* $FreeBSD$ */
221308Sache/* complete.c -- filename completion for readline. */
321308Sache
4157188Sache/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
521308Sache
621308Sache   This file is part of the GNU Readline Library, a library for
721308Sache   reading lines of text with interactive input and history editing.
821308Sache
921308Sache   The GNU Readline Library is free software; you can redistribute it
1021308Sache   and/or modify it under the terms of the GNU General Public License
1158314Sache   as published by the Free Software Foundation; either version 2, or
1221308Sache   (at your option) any later version.
1321308Sache
1421308Sache   The GNU Readline Library is distributed in the hope that it will be
1521308Sache   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
1621308Sache   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1721308Sache   GNU General Public License for more details.
1821308Sache
1921308Sache   The GNU General Public License is often shipped with GNU software, and
2021308Sache   is generally kept in a file called COPYING or LICENSE.  If you do not
2121308Sache   have a copy of the license, write to the Free Software Foundation,
2258314Sache   59 Temple Place, Suite 330, Boston, MA 02111 USA. */
2321308Sache#define READLINE_LIBRARY
2421308Sache
2521308Sache#if defined (HAVE_CONFIG_H)
2621308Sache#  include <config.h>
2721308Sache#endif
2821308Sache
2921308Sache#include <sys/types.h>
3021308Sache#include <fcntl.h>
3121308Sache#if defined (HAVE_SYS_FILE_H)
32136758Speter#  include <sys/file.h>
3321308Sache#endif
3421308Sache
3521308Sache#if defined (HAVE_UNISTD_H)
3621308Sache#  include <unistd.h>
3721308Sache#endif /* HAVE_UNISTD_H */
3821308Sache
3921308Sache#if defined (HAVE_STDLIB_H)
4021308Sache#  include <stdlib.h>
4121308Sache#else
4221308Sache#  include "ansi_stdlib.h"
4321308Sache#endif /* HAVE_STDLIB_H */
4421308Sache
4526500Sache#include <stdio.h>
4626500Sache
4721308Sache#include <errno.h>
4821308Sache#if !defined (errno)
4921308Sacheextern int errno;
5021308Sache#endif /* !errno */
5121308Sache
52157188Sache#if defined (HAVE_PWD_H)
5321308Sache#include <pwd.h>
54157188Sache#endif
5521308Sache
5621308Sache#include "posixdir.h"
5721308Sache#include "posixstat.h"
5821308Sache
5921308Sache/* System-specific feature definitions and include files. */
6021308Sache#include "rldefs.h"
61119614Sache#include "rlmbutil.h"
6221308Sache
6321308Sache/* Some standard library routines. */
6421308Sache#include "readline.h"
6558314Sache#include "xmalloc.h"
6658314Sache#include "rlprivate.h"
6721308Sache
6858314Sache#ifdef __STDC__
6958314Sachetypedef int QSFUNC (const void *, const void *);
7058314Sache#else
7158314Sachetypedef int QSFUNC ();
7258314Sache#endif
7321308Sache
74119614Sache#ifdef HAVE_LSTAT
75119614Sache#  define LSTAT lstat
76119614Sache#else
77119614Sache#  define LSTAT stat
78119614Sache#endif
79119614Sache
80119614Sache/* Unix version of a hidden file.  Could be different on other systems. */
81119614Sache#define HIDDEN_FILE(fname)	((fname)[0] == '.')
82119614Sache
8375409Sache/* Most systems don't declare getpwent in <pwd.h> if _POSIX_SOURCE is
8475409Sache   defined. */
85157188Sache#if defined (HAVE_GETPWENT) && (!defined (HAVE_GETPW_DECLS) || defined (_POSIX_SOURCE))
86119614Sacheextern struct passwd *getpwent PARAMS((void));
87157188Sache#endif /* HAVE_GETPWENT && (!HAVE_GETPW_DECLS || _POSIX_SOURCE) */
8875409Sache
8947563Sache/* If non-zero, then this is the address of a function to call when
9047563Sache   completing a word would normally display the list of possible matches.
9147563Sache   This function is called instead of actually doing the display.
9247563Sache   It takes three arguments: (char **matches, int num_matches, int max_length)
9347563Sache   where MATCHES is the array of strings that matched, NUM_MATCHES is the
9447563Sache   number of strings in that array, and MAX_LENGTH is the length of the
9547563Sache   longest string in that array. */
9675409Sacherl_compdisp_func_t *rl_completion_display_matches_hook = (rl_compdisp_func_t *)NULL;
9747563Sache
9835489Sache#if defined (VISIBLE_STATS)
9935489Sache#  if !defined (X_OK)
10035489Sache#    define X_OK 1
10135489Sache#  endif
102119614Sachestatic int stat_char PARAMS((char *));
10335489Sache#endif
10435489Sache
105136758Speterstatic int path_isdir PARAMS((const char *));
106136758Speter
107119614Sachestatic char *rl_quote_filename PARAMS((char *, int, char *));
10821308Sache
109119614Sachestatic void set_completion_defaults PARAMS((int));
110119614Sachestatic int get_y_or_n PARAMS((int));
111119614Sachestatic int _rl_internal_pager PARAMS((int));
112119614Sachestatic char *printable_part PARAMS((char *));
113136758Speterstatic int fnwidth PARAMS((const char *));
114136758Speterstatic int fnprint PARAMS((const char *));
115119614Sachestatic int print_filename PARAMS((char *, char *));
11621308Sache
117119614Sachestatic char **gen_completion_matches PARAMS((char *, int, int, rl_compentry_func_t *, int, int));
118119614Sache
119119614Sachestatic char **remove_duplicate_matches PARAMS((char **));
120119614Sachestatic void insert_match PARAMS((char *, int, int, char *));
121119614Sachestatic int append_to_match PARAMS((char *, int, int, int));
122119614Sachestatic void insert_all_matches PARAMS((char **, int, char *));
123119614Sachestatic void display_matches PARAMS((char **));
124119614Sachestatic int compute_lcd_of_matches PARAMS((char **, int, const char *));
125119614Sachestatic int postprocess_matches PARAMS((char ***, int));
126119614Sache
127119614Sachestatic char *make_quoted_replacement PARAMS((char *, int, char *));
128119614Sache
12935489Sache/* **************************************************************** */
13035489Sache/*								    */
13135489Sache/*	Completion matching, from readline's point of view.	    */
13235489Sache/*								    */
13335489Sache/* **************************************************************** */
13421308Sache
13535489Sache/* Variables known only to the readline library. */
13621308Sache
13721308Sache/* If non-zero, non-unique completions always show the list of matches. */
13821308Sacheint _rl_complete_show_all = 0;
13921308Sache
140136758Speter/* If non-zero, non-unique completions show the list of matches, unless it
141136758Speter   is not possible to do partial completion and modify the line. */
142136758Speterint _rl_complete_show_unmodified = 0;
143136758Speter
14421308Sache/* If non-zero, completed directory names have a slash appended. */
14521308Sacheint _rl_complete_mark_directories = 1;
14621308Sache
147119614Sache/* If non-zero, the symlinked directory completion behavior introduced in
148119614Sache   readline-4.2a is disabled, and symlinks that point to directories have
149119614Sache   a slash appended (subject to the value of _rl_complete_mark_directories).
150119614Sache   This is user-settable via the mark-symlinked-directories variable. */
151119614Sacheint _rl_complete_mark_symlink_dirs = 0;
152119614Sache
15335489Sache/* If non-zero, completions are printed horizontally in alphabetical order,
15435489Sache   like `ls -x'. */
15535489Sacheint _rl_print_completions_horizontally;
15621308Sache
15735489Sache/* Non-zero means that case is not significant in filename completion. */
15858314Sache#if defined (__MSDOS__) && !defined (__DJGPP__)
15958314Sacheint _rl_completion_case_fold = 1;
16058314Sache#else
16135489Sacheint _rl_completion_case_fold;
16258314Sache#endif
16321308Sache
164119614Sache/* If non-zero, don't match hidden files (filenames beginning with a `.' on
165119614Sache   Unix) when doing filename completion. */
166119614Sacheint _rl_match_hidden_files = 1;
167119614Sache
16835489Sache/* Global variables available to applications using readline. */
16935489Sache
17035489Sache#if defined (VISIBLE_STATS)
17121308Sache/* Non-zero means add an additional character to each filename displayed
17221308Sache   during listing completion iff rl_filename_completion_desired which helps
17321308Sache   to indicate the type of file being listed. */
17421308Sacheint rl_visible_stats = 0;
17521308Sache#endif /* VISIBLE_STATS */
17621308Sache
17735489Sache/* If non-zero, then this is the address of a function to call when
17835489Sache   completing on a directory name.  The function is called with
17935489Sache   the address of a string (the current directory name) as an arg. */
18075409Sacherl_icppfunc_t *rl_directory_completion_hook = (rl_icppfunc_t *)NULL;
18121308Sache
18275409Sacherl_icppfunc_t *rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL;
18375409Sache
18435489Sache/* Non-zero means readline completion functions perform tilde expansion. */
18535489Sacheint rl_complete_with_tilde_expansion = 0;
18621308Sache
18721308Sache/* Pointer to the generator function for completion_matches ().
18875409Sache   NULL means to use rl_filename_completion_function (), the default filename
18921308Sache   completer. */
19075409Sacherl_compentry_func_t *rl_completion_entry_function = (rl_compentry_func_t *)NULL;
19121308Sache
19221308Sache/* Pointer to alternative function to create matches.
19321308Sache   Function is called with TEXT, START, and END.
19421308Sache   START and END are indices in RL_LINE_BUFFER saying what the boundaries
19521308Sache   of TEXT are.
19621308Sache   If this function exists and returns NULL then call the value of
19721308Sache   rl_completion_entry_function to try to match, otherwise use the
19821308Sache   array of strings returned. */
19975409Sacherl_completion_func_t *rl_attempted_completion_function = (rl_completion_func_t *)NULL;
20021308Sache
20121308Sache/* Non-zero means to suppress normal filename completion after the
20221308Sache   user-specified completion function has been called. */
20321308Sacheint rl_attempted_completion_over = 0;
20421308Sache
20521308Sache/* Set to a character indicating the type of completion being performed
20621308Sache   by rl_complete_internal, available for use by application completion
20721308Sache   functions. */
20821308Sacheint rl_completion_type = 0;
20921308Sache
21021308Sache/* Up to this many items will be displayed in response to a
21121308Sache   possible-completions call.  After that, we ask the user if
212157188Sache   she is sure she wants to see them all.  A negative value means
213157188Sache   don't ask. */
21421308Sacheint rl_completion_query_items = 100;
21521308Sache
216119614Sacheint _rl_page_completions = 1;
217119614Sache
21821308Sache/* The basic list of characters that signal a break between words for the
21921308Sache   completer routine.  The contents of this variable is what breaks words
22021308Sache   in the shell, i.e. " \t\n\"\\'`@$><=" */
221119614Sacheconst char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{("; /* }) */
22221308Sache
22321308Sache/* List of basic quoting characters. */
22475409Sacheconst char *rl_basic_quote_characters = "\"'";
22521308Sache
22621308Sache/* The list of characters that signal a break between words for
22721308Sache   rl_complete_internal.  The default list is the contents of
22821308Sache   rl_basic_word_break_characters.  */
229136758Speter/*const*/ char *rl_completer_word_break_characters = (/*const*/ char *)NULL;
23021308Sache
231136758Speter/* Hook function to allow an application to set the completion word
232136758Speter   break characters before readline breaks up the line.  Allows
233136758Speter   position-dependent word break characters. */
234136758Speterrl_cpvfunc_t *rl_completion_word_break_hook = (rl_cpvfunc_t *)NULL;
235136758Speter
23621308Sache/* List of characters which can be used to quote a substring of the line.
23721308Sache   Completion occurs on the entire substring, and within the substring
23821308Sache   rl_completer_word_break_characters are treated as any other character,
23921308Sache   unless they also appear within this list. */
24075409Sacheconst char *rl_completer_quote_characters = (const char *)NULL;
24121308Sache
24221308Sache/* List of characters that should be quoted in filenames by the completer. */
24375409Sacheconst char *rl_filename_quote_characters = (const char *)NULL;
24421308Sache
24521308Sache/* List of characters that are word break characters, but should be left
24621308Sache   in TEXT when it is passed to the completion function.  The shell uses
24721308Sache   this to help determine what kind of completing to do. */
24875409Sacheconst char *rl_special_prefixes = (const char *)NULL;
24921308Sache
25021308Sache/* If non-zero, then disallow duplicates in the matches. */
25121308Sacheint rl_ignore_completion_duplicates = 1;
25221308Sache
25321308Sache/* Non-zero means that the results of the matches are to be treated
25421308Sache   as filenames.  This is ALWAYS zero on entry, and can only be changed
25521308Sache   within a completion entry finder function. */
25621308Sacheint rl_filename_completion_desired = 0;
25721308Sache
25821308Sache/* Non-zero means that the results of the matches are to be quoted using
25921308Sache   double quotes (or an application-specific quoting mechanism) if the
26021308Sache   filename contains any characters in rl_filename_quote_chars.  This is
26121308Sache   ALWAYS non-zero on entry, and can only be changed within a completion
26221308Sache   entry finder function. */
26321308Sacheint rl_filename_quoting_desired = 1;
26421308Sache
26521308Sache/* This function, if defined, is called by the completer when real
26621308Sache   filename completion is done, after all the matching names have been
26721308Sache   generated. It is passed a (char**) known as matches in the code below.
26821308Sache   It consists of a NULL-terminated array of pointers to potential
26921308Sache   matching strings.  The 1st element (matches[0]) is the maximal
27021308Sache   substring that is common to all matches. This function can re-arrange
27121308Sache   the list of matches as required, but all elements of the array must be
27221308Sache   free()'d if they are deleted. The main intent of this function is
27321308Sache   to implement FIGNORE a la SunOS csh. */
27475409Sacherl_compignore_func_t *rl_ignore_some_completions_function = (rl_compignore_func_t *)NULL;
27521308Sache
27621308Sache/* Set to a function to quote a filename in an application-specific fashion.
27721308Sache   Called with the text to quote, the type of match found (single or multiple)
27821308Sache   and a pointer to the quoting character to be used, which the function can
27921308Sache   reset if desired. */
28075409Sacherl_quote_func_t *rl_filename_quoting_function = rl_quote_filename;
28121308Sache
28221308Sache/* Function to call to remove quoting characters from a filename.  Called
28321308Sache   before completion is attempted, so the embedded quotes do not interfere
28421308Sache   with matching names in the file system.  Readline doesn't do anything
28521308Sache   with this; it's set only by applications. */
28675409Sacherl_dequote_func_t *rl_filename_dequoting_function = (rl_dequote_func_t *)NULL;
28721308Sache
28821308Sache/* Function to call to decide whether or not a word break character is
28921308Sache   quoted.  If a character is quoted, it does not break words for the
29021308Sache   completer. */
29175409Sacherl_linebuf_func_t *rl_char_is_quoted_p = (rl_linebuf_func_t *)NULL;
29221308Sache
293119614Sache/* If non-zero, the completion functions don't append anything except a
294119614Sache   possible closing quote.  This is set to 0 by rl_complete_internal and
295119614Sache   may be changed by an application-specific completion function. */
296119614Sacheint rl_completion_suppress_append = 0;
297119614Sache
29821308Sache/* Character appended to completed words when at the end of the line.  The
29921308Sache   default is a space. */
30021308Sacheint rl_completion_append_character = ' ';
30121308Sache
302136758Speter/* If non-zero, the completion functions don't append any closing quote.
303136758Speter   This is set to 0 by rl_complete_internal and may be changed by an
304136758Speter   application-specific completion function. */
305136758Speterint rl_completion_suppress_quote = 0;
306136758Speter
307136758Speter/* Set to any quote character readline thinks it finds before any application
308136758Speter   completion function is called. */
309136758Speterint rl_completion_quote_character;
310136758Speter
311136758Speter/* Set to a non-zero value if readline found quoting anywhere in the word to
312136758Speter   be completed; set before any application completion function is called. */
313136758Speterint rl_completion_found_quote;
314136758Speter
315119614Sache/* If non-zero, a slash will be appended to completed filenames that are
316119614Sache   symbolic links to directory names, subject to the value of the
317119614Sache   mark-directories variable (which is user-settable).  This exists so
318119614Sache   that application completion functions can override the user's preference
319119614Sache   (set via the mark-symlinked-directories variable) if appropriate.
320119614Sache   It's set to the value of _rl_complete_mark_symlink_dirs in
321119614Sache   rl_complete_internal before any application-specific completion
322119614Sache   function is called, so without that function doing anything, the user's
323119614Sache   preferences are honored. */
324119614Sacheint rl_completion_mark_symlink_dirs;
325119614Sache
32621308Sache/* If non-zero, inhibit completion (temporarily). */
32721308Sacheint rl_inhibit_completion;
32821308Sache
32935489Sache/* Variables local to this file. */
33035489Sache
33135489Sache/* Local variable states what happened during the last completion attempt. */
33235489Sachestatic int completion_changed_buffer;
33335489Sache
33435489Sache/*************************************/
33535489Sache/*				     */
33635489Sache/*    Bindable completion functions  */
33735489Sache/*				     */
33835489Sache/*************************************/
33935489Sache
34021308Sache/* Complete the word at or before point.  You have supplied the function
34121308Sache   that does the initial simple matching selection algorithm (see
34275409Sache   rl_completion_matches ()).  The default is to do filename completion. */
34321308Sacheint
34421308Sacherl_complete (ignore, invoking_key)
34521308Sache     int ignore, invoking_key;
34621308Sache{
34721308Sache  if (rl_inhibit_completion)
348119614Sache    return (_rl_insert_char (ignore, invoking_key));
34921308Sache  else if (rl_last_func == rl_complete && !completion_changed_buffer)
35021308Sache    return (rl_complete_internal ('?'));
35121308Sache  else if (_rl_complete_show_all)
35221308Sache    return (rl_complete_internal ('!'));
353136758Speter  else if (_rl_complete_show_unmodified)
354136758Speter    return (rl_complete_internal ('@'));
35521308Sache  else
35621308Sache    return (rl_complete_internal (TAB));
35721308Sache}
35821308Sache
35921308Sache/* List the possible completions.  See description of rl_complete (). */
36021308Sacheint
36121308Sacherl_possible_completions (ignore, invoking_key)
36221308Sache     int ignore, invoking_key;
36321308Sache{
36421308Sache  return (rl_complete_internal ('?'));
36521308Sache}
36621308Sache
36721308Sacheint
36821308Sacherl_insert_completions (ignore, invoking_key)
36921308Sache     int ignore, invoking_key;
37021308Sache{
37121308Sache  return (rl_complete_internal ('*'));
37221308Sache}
37321308Sache
374119614Sache/* Return the correct value to pass to rl_complete_internal performing
375119614Sache   the same tests as rl_complete.  This allows consecutive calls to an
376119614Sache   application's completion function to list possible completions and for
377119614Sache   an application-specific completion function to honor the
378119614Sache   show-all-if-ambiguous readline variable. */
379119614Sacheint
380119614Sacherl_completion_mode (cfunc)
381119614Sache     rl_command_func_t *cfunc;
382119614Sache{
383119614Sache  if (rl_last_func == cfunc && !completion_changed_buffer)
384119614Sache    return '?';
385119614Sache  else if (_rl_complete_show_all)
386119614Sache    return '!';
387136758Speter  else if (_rl_complete_show_unmodified)
388136758Speter    return '@';
389119614Sache  else
390119614Sache    return TAB;
391119614Sache}
392119614Sache
39335489Sache/************************************/
39435489Sache/*				    */
39535489Sache/*    Completion utility functions  */
39635489Sache/*				    */
39735489Sache/************************************/
39835489Sache
399119614Sache/* Set default values for readline word completion.  These are the variables
400119614Sache   that application completion functions can change or inspect. */
401119614Sachestatic void
402119614Sacheset_completion_defaults (what_to_do)
403119614Sache     int what_to_do;
404119614Sache{
405119614Sache  /* Only the completion entry function can change these. */
406119614Sache  rl_filename_completion_desired = 0;
407119614Sache  rl_filename_quoting_desired = 1;
408119614Sache  rl_completion_type = what_to_do;
409136758Speter  rl_completion_suppress_append = rl_completion_suppress_quote = 0;
410119614Sache
411119614Sache  /* The completion entry function may optionally change this. */
412119614Sache  rl_completion_mark_symlink_dirs = _rl_complete_mark_symlink_dirs;
413119614Sache}
414119614Sache
41521308Sache/* The user must press "y" or "n". Non-zero return means "y" pressed. */
41621308Sachestatic int
417119614Sacheget_y_or_n (for_pager)
418119614Sache     int for_pager;
41921308Sache{
42021308Sache  int c;
42121308Sache
42221308Sache  for (;;)
42321308Sache    {
42475409Sache      RL_SETSTATE(RL_STATE_MOREINPUT);
42521308Sache      c = rl_read_key ();
42675409Sache      RL_UNSETSTATE(RL_STATE_MOREINPUT);
42775409Sache
42821308Sache      if (c == 'y' || c == 'Y' || c == ' ')
42921308Sache	return (1);
43021308Sache      if (c == 'n' || c == 'N' || c == RUBOUT)
43121308Sache	return (0);
432173406Sache      if (c == ABORT_CHAR || c < 0)
43321308Sache	_rl_abort_internal ();
434119614Sache      if (for_pager && (c == NEWLINE || c == RETURN))
435119614Sache	return (2);
436119614Sache      if (for_pager && (c == 'q' || c == 'Q'))
437119614Sache	return (0);
43875409Sache      rl_ding ();
43921308Sache    }
44021308Sache}
44121308Sache
442119614Sachestatic int
443119614Sache_rl_internal_pager (lines)
444119614Sache     int lines;
445119614Sache{
446119614Sache  int i;
447119614Sache
448119614Sache  fprintf (rl_outstream, "--More--");
449119614Sache  fflush (rl_outstream);
450119614Sache  i = get_y_or_n (1);
451119614Sache  _rl_erase_entire_line ();
452119614Sache  if (i == 0)
453119614Sache    return -1;
454119614Sache  else if (i == 2)
455119614Sache    return (lines - 1);
456119614Sache  else
457119614Sache    return 0;
458119614Sache}
459119614Sache
460136758Speterstatic int
461136758Speterpath_isdir (filename)
462136758Speter     const char *filename;
463136758Speter{
464136758Speter  struct stat finfo;
465136758Speter
466136758Speter  return (stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode));
467136758Speter}
468136758Speter
46935489Sache#if defined (VISIBLE_STATS)
47035489Sache/* Return the character which best describes FILENAME.
47135489Sache     `@' for symbolic links
47235489Sache     `/' for directories
47335489Sache     `*' for executables
47435489Sache     `=' for sockets
47535489Sache     `|' for FIFOs
47635489Sache     `%' for character special devices
47735489Sache     `#' for block special devices */
47835489Sachestatic int
47935489Sachestat_char (filename)
48035489Sache     char *filename;
48135489Sache{
48235489Sache  struct stat finfo;
48335489Sache  int character, r;
48435489Sache
48535489Sache#if defined (HAVE_LSTAT) && defined (S_ISLNK)
48635489Sache  r = lstat (filename, &finfo);
48735489Sache#else
48835489Sache  r = stat (filename, &finfo);
48935489Sache#endif
49035489Sache
49135489Sache  if (r == -1)
49235489Sache    return (0);
49335489Sache
49435489Sache  character = 0;
49535489Sache  if (S_ISDIR (finfo.st_mode))
49635489Sache    character = '/';
49735489Sache#if defined (S_ISCHR)
49835489Sache  else if (S_ISCHR (finfo.st_mode))
49935489Sache    character = '%';
50035489Sache#endif /* S_ISCHR */
50135489Sache#if defined (S_ISBLK)
50235489Sache  else if (S_ISBLK (finfo.st_mode))
50335489Sache    character = '#';
50435489Sache#endif /* S_ISBLK */
50535489Sache#if defined (S_ISLNK)
50635489Sache  else if (S_ISLNK (finfo.st_mode))
50735489Sache    character = '@';
50835489Sache#endif /* S_ISLNK */
50935489Sache#if defined (S_ISSOCK)
51035489Sache  else if (S_ISSOCK (finfo.st_mode))
51135489Sache    character = '=';
51235489Sache#endif /* S_ISSOCK */
51335489Sache#if defined (S_ISFIFO)
51435489Sache  else if (S_ISFIFO (finfo.st_mode))
51535489Sache    character = '|';
51635489Sache#endif
51735489Sache  else if (S_ISREG (finfo.st_mode))
51835489Sache    {
51935489Sache      if (access (filename, X_OK) == 0)
52035489Sache	character = '*';
52135489Sache    }
52235489Sache  return (character);
52335489Sache}
52435489Sache#endif /* VISIBLE_STATS */
52535489Sache
52621308Sache/* Return the portion of PATHNAME that should be output when listing
52721308Sache   possible completions.  If we are hacking filename completion, we
52821308Sache   are only interested in the basename, the portion following the
529119614Sache   final slash.  Otherwise, we return what we were passed.  Since
530119614Sache   printing empty strings is not very informative, if we're doing
531119614Sache   filename completion, and the basename is the empty string, we look
532119614Sache   for the previous slash and return the portion following that.  If
533119614Sache   there's no previous slash, we just return what we were passed. */
53421308Sachestatic char *
53521308Sacheprintable_part (pathname)
53621308Sache      char *pathname;
53721308Sache{
538119614Sache  char *temp, *x;
53921308Sache
540119614Sache  if (rl_filename_completion_desired == 0)	/* don't need to do anything */
541119614Sache    return (pathname);
542119614Sache
543119614Sache  temp = strrchr (pathname, '/');
54458314Sache#if defined (__MSDOS__)
545119614Sache  if (temp == 0 && ISALPHA ((unsigned char)pathname[0]) && pathname[1] == ':')
54658314Sache    temp = pathname + 1;
54758314Sache#endif
548119614Sache
549119614Sache  if (temp == 0 || *temp == '\0')
550119614Sache    return (pathname);
551119614Sache  /* If the basename is NULL, we might have a pathname like '/usr/src/'.
552119614Sache     Look for a previous slash and, if one is found, return the portion
553119614Sache     following that slash.  If there's no previous slash, just return the
554119614Sache     pathname we were passed. */
555119614Sache  else if (temp[1] == '\0')
556119614Sache    {
557119614Sache      for (x = temp - 1; x > pathname; x--)
558119614Sache        if (*x == '/')
559119614Sache          break;
560119614Sache      return ((*x == '/') ? x + 1 : pathname);
561119614Sache    }
562119614Sache  else
563119614Sache    return ++temp;
56421308Sache}
56521308Sache
566136758Speter/* Compute width of STRING when displayed on screen by print_filename */
567136758Speterstatic int
568136758Speterfnwidth (string)
569136758Speter     const char *string;
570136758Speter{
571136758Speter  int width, pos;
572136758Speter#if defined (HANDLE_MULTIBYTE)
573136758Speter  mbstate_t ps;
574136758Speter  int left, w;
575136758Speter  size_t clen;
576136758Speter  wchar_t wc;
577136758Speter
578136758Speter  left = strlen (string) + 1;
579136758Speter  memset (&ps, 0, sizeof (mbstate_t));
580136758Speter#endif
581136758Speter
582136758Speter  width = pos = 0;
583136758Speter  while (string[pos])
584136758Speter    {
585136758Speter      if (CTRL_CHAR (*string) || *string == RUBOUT)
586136758Speter	{
587136758Speter	  width += 2;
588136758Speter	  pos++;
589136758Speter	}
590136758Speter      else
591136758Speter	{
592136758Speter#if defined (HANDLE_MULTIBYTE)
593136758Speter	  clen = mbrtowc (&wc, string + pos, left - pos, &ps);
594136758Speter	  if (MB_INVALIDCH (clen))
595136758Speter	    {
596136758Speter	      width++;
597136758Speter	      pos++;
598136758Speter	      memset (&ps, 0, sizeof (mbstate_t));
599136758Speter	    }
600136758Speter	  else if (MB_NULLWCH (clen))
601136758Speter	    break;
602136758Speter	  else
603136758Speter	    {
604136758Speter	      pos += clen;
605136758Speter	      w = wcwidth (wc);
606136758Speter	      width += (w >= 0) ? w : 1;
607136758Speter	    }
608136758Speter#else
609136758Speter	  width++;
610136758Speter	  pos++;
611136758Speter#endif
612136758Speter	}
613136758Speter    }
614136758Speter
615136758Speter  return width;
616136758Speter}
617136758Speter
618136758Speterstatic int
619136758Speterfnprint (to_print)
620136758Speter     const char *to_print;
621136758Speter{
622136758Speter  int printed_len;
623136758Speter  const char *s;
624136758Speter#if defined (HANDLE_MULTIBYTE)
625136758Speter  mbstate_t ps;
626136758Speter  const char *end;
627136758Speter  size_t tlen;
628157188Sache  int width, w;
629157188Sache  wchar_t wc;
630136758Speter
631136758Speter  end = to_print + strlen (to_print) + 1;
632136758Speter  memset (&ps, 0, sizeof (mbstate_t));
633136758Speter#endif
634136758Speter
635136758Speter  printed_len = 0;
636136758Speter  s = to_print;
637136758Speter  while (*s)
638136758Speter    {
639136758Speter      if (CTRL_CHAR (*s))
640136758Speter        {
641136758Speter          putc ('^', rl_outstream);
642136758Speter          putc (UNCTRL (*s), rl_outstream);
643136758Speter          printed_len += 2;
644136758Speter          s++;
645136758Speter#if defined (HANDLE_MULTIBYTE)
646136758Speter	  memset (&ps, 0, sizeof (mbstate_t));
647136758Speter#endif
648136758Speter        }
649136758Speter      else if (*s == RUBOUT)
650136758Speter	{
651136758Speter	  putc ('^', rl_outstream);
652136758Speter	  putc ('?', rl_outstream);
653136758Speter	  printed_len += 2;
654136758Speter	  s++;
655136758Speter#if defined (HANDLE_MULTIBYTE)
656136758Speter	  memset (&ps, 0, sizeof (mbstate_t));
657136758Speter#endif
658136758Speter	}
659136758Speter      else
660136758Speter	{
661136758Speter#if defined (HANDLE_MULTIBYTE)
662157188Sache	  tlen = mbrtowc (&wc, s, end - s, &ps);
663136758Speter	  if (MB_INVALIDCH (tlen))
664136758Speter	    {
665136758Speter	      tlen = 1;
666157188Sache	      width = 1;
667136758Speter	      memset (&ps, 0, sizeof (mbstate_t));
668136758Speter	    }
669136758Speter	  else if (MB_NULLWCH (tlen))
670136758Speter	    break;
671157188Sache	  else
672157188Sache	    {
673157188Sache	      w = wcwidth (wc);
674157188Sache	      width = (w >= 0) ? w : 1;
675157188Sache	    }
676136758Speter	  fwrite (s, 1, tlen, rl_outstream);
677136758Speter	  s += tlen;
678157188Sache	  printed_len += width;
679136758Speter#else
680136758Speter	  putc (*s, rl_outstream);
681136758Speter	  s++;
682157188Sache	  printed_len++;
683136758Speter#endif
684136758Speter	}
685136758Speter    }
686136758Speter
687136758Speter  return printed_len;
688136758Speter}
689136758Speter
69021308Sache/* Output TO_PRINT to rl_outstream.  If VISIBLE_STATS is defined and we
69121308Sache   are using it, check for and output a single character for `special'
69235489Sache   filenames.  Return the number of characters we output. */
69321308Sache
69421308Sachestatic int
69521308Sacheprint_filename (to_print, full_pathname)
69621308Sache     char *to_print, *full_pathname;
69721308Sache{
698136758Speter  int printed_len, extension_char, slen, tlen;
699157188Sache  char *s, c, *new_full_pathname, *dn;
70021308Sache
701136758Speter  extension_char = 0;
702136758Speter  printed_len = fnprint (to_print);
70321308Sache
704136758Speter#if defined (VISIBLE_STATS)
705136758Speter if (rl_filename_completion_desired && (rl_visible_stats || _rl_complete_mark_directories))
706136758Speter#else
707136758Speter if (rl_filename_completion_desired && _rl_complete_mark_directories)
708136758Speter#endif
70921308Sache    {
71021308Sache      /* If to_print != full_pathname, to_print is the basename of the
71121308Sache	 path passed.  In this case, we try to expand the directory
71221308Sache	 name before checking for the stat character. */
71321308Sache      if (to_print != full_pathname)
71421308Sache	{
71521308Sache	  /* Terminate the directory name. */
71621308Sache	  c = to_print[-1];
71721308Sache	  to_print[-1] = '\0';
71821308Sache
71958314Sache	  /* If setting the last slash in full_pathname to a NUL results in
72058314Sache	     full_pathname being the empty string, we are trying to complete
72158314Sache	     files in the root directory.  If we pass a null string to the
72258314Sache	     bash directory completion hook, for example, it will expand it
72358314Sache	     to the current directory.  We just want the `/'. */
724157188Sache	  if (full_pathname == 0 || *full_pathname == 0)
725157188Sache	    dn = "/";
726157188Sache	  else if (full_pathname[0] != '/')
727157188Sache	    dn = full_pathname;
728157188Sache	  else if (full_pathname[1] == 0)
729157188Sache	    dn = "//";		/* restore trailing slash to `//' */
730157188Sache	  else if (full_pathname[1] == '/' && full_pathname[2] == 0)
731157188Sache	    dn = "/";		/* don't turn /// into // */
732157188Sache	  else
733157188Sache	    dn = full_pathname;
734157188Sache	  s = tilde_expand (dn);
73521308Sache	  if (rl_directory_completion_hook)
73621308Sache	    (*rl_directory_completion_hook) (&s);
73721308Sache
73821308Sache	  slen = strlen (s);
73921308Sache	  tlen = strlen (to_print);
740119614Sache	  new_full_pathname = (char *)xmalloc (slen + tlen + 2);
74121308Sache	  strcpy (new_full_pathname, s);
742157188Sache	  if (s[slen - 1] == '/')
743157188Sache	    slen--;
744157188Sache	  else
745157188Sache	    new_full_pathname[slen] = '/';
74621308Sache	  new_full_pathname[slen] = '/';
74721308Sache	  strcpy (new_full_pathname + slen + 1, to_print);
74821308Sache
749136758Speter#if defined (VISIBLE_STATS)
750136758Speter	  if (rl_visible_stats)
751136758Speter	    extension_char = stat_char (new_full_pathname);
752136758Speter	  else
753136758Speter#endif
754136758Speter	  if (path_isdir (new_full_pathname))
755136758Speter	    extension_char = '/';
75621308Sache
75721308Sache	  free (new_full_pathname);
75821308Sache	  to_print[-1] = c;
75921308Sache	}
76021308Sache      else
76121308Sache	{
76221308Sache	  s = tilde_expand (full_pathname);
763136758Speter#if defined (VISIBLE_STATS)
764136758Speter	  if (rl_visible_stats)
765136758Speter	    extension_char = stat_char (s);
766136758Speter	  else
767136758Speter#endif
768136758Speter	    if (path_isdir (s))
769136758Speter	      extension_char = '/';
77021308Sache	}
77121308Sache
77221308Sache      free (s);
77321308Sache      if (extension_char)
77435489Sache	{
77535489Sache	  putc (extension_char, rl_outstream);
77635489Sache	  printed_len++;
77735489Sache	}
77821308Sache    }
779136758Speter
78035489Sache  return printed_len;
78121308Sache}
78221308Sache
78321308Sachestatic char *
78421308Sacherl_quote_filename (s, rtype, qcp)
78521308Sache     char *s;
78621308Sache     int rtype;
78721308Sache     char *qcp;
78821308Sache{
78921308Sache  char *r;
79021308Sache
791119614Sache  r = (char *)xmalloc (strlen (s) + 2);
79221308Sache  *r = *rl_completer_quote_characters;
79321308Sache  strcpy (r + 1, s);
79421308Sache  if (qcp)
79521308Sache    *qcp = *rl_completer_quote_characters;
79621308Sache  return r;
79721308Sache}
79821308Sache
79921308Sache/* Find the bounds of the current word for completion purposes, and leave
80021308Sache   rl_point set to the end of the word.  This function skips quoted
80121308Sache   substrings (characters between matched pairs of characters in
802119614Sache   rl_completer_quote_characters).  First we try to find an unclosed
80321308Sache   quoted substring on which to do matching.  If one is not found, we use
80421308Sache   the word break characters to find the boundaries of the current word.
80521308Sache   We call an application-specific function to decide whether or not a
80621308Sache   particular word break character is quoted; if that function returns a
80721308Sache   non-zero result, the character does not break a word.  This function
80821308Sache   returns the opening quote character if we found an unclosed quoted
80921308Sache   substring, '\0' otherwise.  FP, if non-null, is set to a value saying
81021308Sache   which (shell-like) quote characters we found (single quote, double
81121308Sache   quote, or backslash) anywhere in the string.  DP, if non-null, is set to
81221308Sache   the value of the delimiter character that caused a word break. */
81321308Sache
814119614Sachechar
815119614Sache_rl_find_completion_word (fp, dp)
81621308Sache     int *fp, *dp;
81721308Sache{
81821308Sache  int scan, end, found_quote, delimiter, pass_next, isbrk;
819136758Speter  char quote_char, *brkchars;
82021308Sache
82121308Sache  end = rl_point;
82221308Sache  found_quote = delimiter = 0;
82321308Sache  quote_char = '\0';
82421308Sache
825136758Speter  brkchars = 0;
826136758Speter  if (rl_completion_word_break_hook)
827136758Speter    brkchars = (*rl_completion_word_break_hook) ();
828136758Speter  if (brkchars == 0)
829136758Speter    brkchars = rl_completer_word_break_characters;
830136758Speter
83121308Sache  if (rl_completer_quote_characters)
83221308Sache    {
83321308Sache      /* We have a list of characters which can be used in pairs to
83421308Sache	 quote substrings for the completer.  Try to find the start
83521308Sache	 of an unclosed quoted substring. */
83621308Sache      /* FOUND_QUOTE is set so we know what kind of quotes we found. */
837157188Sache      for (scan = pass_next = 0; scan < end; scan = MB_NEXTCHAR (rl_line_buffer, scan, 1, MB_FIND_ANY))
83821308Sache	{
83921308Sache	  if (pass_next)
84021308Sache	    {
84121308Sache	      pass_next = 0;
84221308Sache	      continue;
84321308Sache	    }
84421308Sache
84575409Sache	  /* Shell-like semantics for single quotes -- don't allow backslash
84675409Sache	     to quote anything in single quotes, especially not the closing
84775409Sache	     quote.  If you don't like this, take out the check on the value
84875409Sache	     of quote_char. */
84975409Sache	  if (quote_char != '\'' && rl_line_buffer[scan] == '\\')
85021308Sache	    {
85121308Sache	      pass_next = 1;
85221308Sache	      found_quote |= RL_QF_BACKSLASH;
85321308Sache	      continue;
85421308Sache	    }
85521308Sache
85621308Sache	  if (quote_char != '\0')
85721308Sache	    {
85821308Sache	      /* Ignore everything until the matching close quote char. */
85921308Sache	      if (rl_line_buffer[scan] == quote_char)
86021308Sache		{
86121308Sache		  /* Found matching close.  Abandon this substring. */
86221308Sache		  quote_char = '\0';
86321308Sache		  rl_point = end;
86421308Sache		}
86521308Sache	    }
86621308Sache	  else if (strchr (rl_completer_quote_characters, rl_line_buffer[scan]))
86721308Sache	    {
86821308Sache	      /* Found start of a quoted substring. */
86921308Sache	      quote_char = rl_line_buffer[scan];
87021308Sache	      rl_point = scan + 1;
87121308Sache	      /* Shell-like quoting conventions. */
87221308Sache	      if (quote_char == '\'')
87321308Sache		found_quote |= RL_QF_SINGLE_QUOTE;
87421308Sache	      else if (quote_char == '"')
87521308Sache		found_quote |= RL_QF_DOUBLE_QUOTE;
876119614Sache	      else
877119614Sache		found_quote |= RL_QF_OTHER_QUOTE;
87821308Sache	    }
87921308Sache	}
88021308Sache    }
88121308Sache
88221308Sache  if (rl_point == end && quote_char == '\0')
88321308Sache    {
88421308Sache      /* We didn't find an unclosed quoted substring upon which to do
88521308Sache         completion, so use the word break characters to find the
88621308Sache         substring on which to complete. */
887157188Sache      while (rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_ANY))
88821308Sache	{
88921308Sache	  scan = rl_line_buffer[rl_point];
89021308Sache
891136758Speter	  if (strchr (brkchars, scan) == 0)
89221308Sache	    continue;
89321308Sache
89421308Sache	  /* Call the application-specific function to tell us whether
89521308Sache	     this word break character is quoted and should be skipped. */
89621308Sache	  if (rl_char_is_quoted_p && found_quote &&
89721308Sache	      (*rl_char_is_quoted_p) (rl_line_buffer, rl_point))
89821308Sache	    continue;
89921308Sache
90021308Sache	  /* Convoluted code, but it avoids an n^2 algorithm with calls
90121308Sache	     to char_is_quoted. */
90221308Sache	  break;
90321308Sache	}
90421308Sache    }
90521308Sache
90621308Sache  /* If we are at an unquoted word break, then advance past it. */
90721308Sache  scan = rl_line_buffer[rl_point];
90821308Sache
90921308Sache  /* If there is an application-specific function to say whether or not
91021308Sache     a character is quoted and we found a quote character, let that
91121308Sache     function decide whether or not a character is a word break, even
91258314Sache     if it is found in rl_completer_word_break_characters.  Don't bother
91358314Sache     if we're at the end of the line, though. */
91458314Sache  if (scan)
91521308Sache    {
91658314Sache      if (rl_char_is_quoted_p)
91758314Sache	isbrk = (found_quote == 0 ||
91858314Sache		(*rl_char_is_quoted_p) (rl_line_buffer, rl_point) == 0) &&
919136758Speter		strchr (brkchars, scan) != 0;
92058314Sache      else
921136758Speter	isbrk = strchr (brkchars, scan) != 0;
92221308Sache
92358314Sache      if (isbrk)
92458314Sache	{
92558314Sache	  /* If the character that caused the word break was a quoting
92658314Sache	     character, then remember it as the delimiter. */
92758314Sache	  if (rl_basic_quote_characters &&
92858314Sache	      strchr (rl_basic_quote_characters, scan) &&
92958314Sache	      (end - rl_point) > 1)
93058314Sache	    delimiter = scan;
93158314Sache
93258314Sache	  /* If the character isn't needed to determine something special
93358314Sache	     about what kind of completion to perform, then advance past it. */
93458314Sache	  if (rl_special_prefixes == 0 || strchr (rl_special_prefixes, scan) == 0)
93558314Sache	    rl_point++;
93658314Sache	}
93721308Sache    }
93821308Sache
93921308Sache  if (fp)
94021308Sache    *fp = found_quote;
94121308Sache  if (dp)
94221308Sache    *dp = delimiter;
94321308Sache
94421308Sache  return (quote_char);
94521308Sache}
94621308Sache
94721308Sachestatic char **
94821308Sachegen_completion_matches (text, start, end, our_func, found_quote, quote_char)
94921308Sache     char *text;
95021308Sache     int start, end;
95175409Sache     rl_compentry_func_t *our_func;
95221308Sache     int found_quote, quote_char;
95321308Sache{
954165675Sache  char **matches;
95521308Sache
956136758Speter  rl_completion_found_quote = found_quote;
957136758Speter  rl_completion_quote_character = quote_char;
958136758Speter
95921308Sache  /* If the user wants to TRY to complete, but then wants to give
96021308Sache     up and use the default completion function, they set the
96121308Sache     variable rl_attempted_completion_function. */
96221308Sache  if (rl_attempted_completion_function)
96321308Sache    {
96421308Sache      matches = (*rl_attempted_completion_function) (text, start, end);
96521308Sache
96621308Sache      if (matches || rl_attempted_completion_over)
96721308Sache	{
96821308Sache	  rl_attempted_completion_over = 0;
96921308Sache	  return (matches);
97021308Sache	}
97121308Sache    }
97221308Sache
973165675Sache  /* XXX -- filename dequoting moved into rl_filename_completion_function */
97447563Sache
97575409Sache  matches = rl_completion_matches (text, our_func);
97621308Sache  return matches;
97721308Sache}
97821308Sache
97921308Sache/* Filter out duplicates in MATCHES.  This frees up the strings in
98021308Sache   MATCHES. */
98121308Sachestatic char **
98221308Sacheremove_duplicate_matches (matches)
98321308Sache     char **matches;
98421308Sache{
98521308Sache  char *lowest_common;
98621308Sache  int i, j, newlen;
98721308Sache  char dead_slot;
98821308Sache  char **temp_array;
98921308Sache
99021308Sache  /* Sort the items. */
99121308Sache  for (i = 0; matches[i]; i++)
99221308Sache    ;
99321308Sache
99421308Sache  /* Sort the array without matches[0], since we need it to
99521308Sache     stay in place no matter what. */
99621308Sache  if (i)
99758314Sache    qsort (matches+1, i-1, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
99821308Sache
99921308Sache  /* Remember the lowest common denominator for it may be unique. */
100021308Sache  lowest_common = savestring (matches[0]);
100121308Sache
100221308Sache  for (i = newlen = 0; matches[i + 1]; i++)
100321308Sache    {
100421308Sache      if (strcmp (matches[i], matches[i + 1]) == 0)
100521308Sache	{
100621308Sache	  free (matches[i]);
100721308Sache	  matches[i] = (char *)&dead_slot;
100821308Sache	}
100921308Sache      else
101021308Sache	newlen++;
101121308Sache    }
101221308Sache
101321308Sache  /* We have marked all the dead slots with (char *)&dead_slot.
101421308Sache     Copy all the non-dead entries into a new array. */
101521308Sache  temp_array = (char **)xmalloc ((3 + newlen) * sizeof (char *));
101621308Sache  for (i = j = 1; matches[i]; i++)
101721308Sache    {
101821308Sache      if (matches[i] != (char *)&dead_slot)
101921308Sache	temp_array[j++] = matches[i];
102021308Sache    }
102121308Sache  temp_array[j] = (char *)NULL;
102221308Sache
102321308Sache  if (matches[0] != (char *)&dead_slot)
102421308Sache    free (matches[0]);
102521308Sache
102621308Sache  /* Place the lowest common denominator back in [0]. */
102721308Sache  temp_array[0] = lowest_common;
102821308Sache
102921308Sache  /* If there is one string left, and it is identical to the
103021308Sache     lowest common denominator, then the LCD is the string to
103121308Sache     insert. */
103221308Sache  if (j == 2 && strcmp (temp_array[0], temp_array[1]) == 0)
103321308Sache    {
103421308Sache      free (temp_array[1]);
103521308Sache      temp_array[1] = (char *)NULL;
103621308Sache    }
103721308Sache  return (temp_array);
103821308Sache}
103921308Sache
104035489Sache/* Find the common prefix of the list of matches, and put it into
104135489Sache   matches[0]. */
104235489Sachestatic int
104335489Sachecompute_lcd_of_matches (match_list, matches, text)
104435489Sache     char **match_list;
104535489Sache     int matches;
104675409Sache     const char *text;
104735489Sache{
104835489Sache  register int i, c1, c2, si;
104935489Sache  int low;		/* Count of max-matched characters. */
1050136758Speter  char *dtext;		/* dequoted TEXT, if needed */
1051119614Sache#if defined (HANDLE_MULTIBYTE)
1052119614Sache  int v;
1053119614Sache  mbstate_t ps1, ps2;
1054119614Sache  wchar_t wc1, wc2;
1055119614Sache#endif
105635489Sache
105735489Sache  /* If only one match, just use that.  Otherwise, compare each
105835489Sache     member of the list with the next, finding out where they
105935489Sache     stop matching. */
106035489Sache  if (matches == 1)
106135489Sache    {
106235489Sache      match_list[0] = match_list[1];
106335489Sache      match_list[1] = (char *)NULL;
106435489Sache      return 1;
106535489Sache    }
106635489Sache
106735489Sache  for (i = 1, low = 100000; i < matches; i++)
106835489Sache    {
1069119614Sache#if defined (HANDLE_MULTIBYTE)
1070119614Sache      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1071119614Sache	{
1072119614Sache	  memset (&ps1, 0, sizeof (mbstate_t));
1073119614Sache	  memset (&ps2, 0, sizeof (mbstate_t));
1074119614Sache	}
1075119614Sache#endif
107635489Sache      if (_rl_completion_case_fold)
107735489Sache	{
107835489Sache	  for (si = 0;
107935489Sache	       (c1 = _rl_to_lower(match_list[i][si])) &&
108035489Sache	       (c2 = _rl_to_lower(match_list[i + 1][si]));
108135489Sache	       si++)
1082119614Sache#if defined (HANDLE_MULTIBYTE)
1083119614Sache	    if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1084119614Sache	      {
1085119614Sache		v = mbrtowc (&wc1, match_list[i]+si, strlen (match_list[i]+si), &ps1);
1086119614Sache		mbrtowc (&wc2, match_list[i+1]+si, strlen (match_list[i+1]+si), &ps2);
1087119614Sache		wc1 = towlower (wc1);
1088119614Sache		wc2 = towlower (wc2);
1089119614Sache		if (wc1 != wc2)
1090119614Sache		  break;
1091119614Sache		else if (v > 1)
1092119614Sache		  si += v - 1;
1093119614Sache	      }
1094119614Sache	    else
1095119614Sache#endif
109635489Sache	    if (c1 != c2)
109735489Sache	      break;
109835489Sache	}
109935489Sache      else
110035489Sache	{
110135489Sache	  for (si = 0;
110235489Sache	       (c1 = match_list[i][si]) &&
110335489Sache	       (c2 = match_list[i + 1][si]);
110435489Sache	       si++)
1105119614Sache#if defined (HANDLE_MULTIBYTE)
1106119614Sache	    if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1107119614Sache	      {
1108165675Sache		mbstate_t ps_back;
1109165675Sache		ps_back = ps1;
1110119614Sache		if (!_rl_compare_chars (match_list[i], si, &ps1, match_list[i+1], si, &ps2))
1111119614Sache		  break;
1112119614Sache		else if ((v = _rl_get_char_len (&match_list[i][si], &ps_back)) > 1)
1113119614Sache		  si += v - 1;
1114119614Sache	      }
1115119614Sache	    else
1116119614Sache#endif
111735489Sache	    if (c1 != c2)
111835489Sache	      break;
111935489Sache	}
112035489Sache
112135489Sache      if (low > si)
112235489Sache	low = si;
112335489Sache    }
112435489Sache
112535489Sache  /* If there were multiple matches, but none matched up to even the
112635489Sache     first character, and the user typed something, use that as the
112735489Sache     value of matches[0]. */
112835489Sache  if (low == 0 && text && *text)
112935489Sache    {
1130119614Sache      match_list[0] = (char *)xmalloc (strlen (text) + 1);
113135489Sache      strcpy (match_list[0], text);
113235489Sache    }
113335489Sache  else
113435489Sache    {
1135119614Sache      match_list[0] = (char *)xmalloc (low + 1);
1136119614Sache
1137119614Sache      /* XXX - this might need changes in the presence of multibyte chars */
1138119614Sache
1139119614Sache      /* If we are ignoring case, try to preserve the case of the string
1140119614Sache	 the user typed in the face of multiple matches differing in case. */
1141119614Sache      if (_rl_completion_case_fold)
1142119614Sache	{
1143136758Speter	  /* We're making an assumption here:
1144136758Speter		IF we're completing filenames AND
1145136758Speter		   the application has defined a filename dequoting function AND
1146136758Speter		   we found a quote character AND
1147136758Speter		   the application has requested filename quoting
1148136758Speter		THEN
1149136758Speter		   we assume that TEXT was dequoted before checking against
1150136758Speter		   the file system and needs to be dequoted here before we
1151136758Speter		   check against the list of matches
1152136758Speter		FI */
1153136758Speter	  dtext = (char *)NULL;
1154136758Speter	  if (rl_filename_completion_desired &&
1155136758Speter	      rl_filename_dequoting_function &&
1156136758Speter	      rl_completion_found_quote &&
1157136758Speter	      rl_filename_quoting_desired)
1158136758Speter	    {
1159157188Sache	      dtext = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character);
1160136758Speter	      text = dtext;
1161136758Speter	    }
1162136758Speter
1163119614Sache	  /* sort the list to get consistent answers. */
1164119614Sache	  qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare);
1165119614Sache
1166119614Sache	  si = strlen (text);
1167119614Sache	  if (si <= low)
1168119614Sache	    {
1169119614Sache	      for (i = 1; i <= matches; i++)
1170119614Sache		if (strncmp (match_list[i], text, si) == 0)
1171119614Sache		  {
1172119614Sache		    strncpy (match_list[0], match_list[i], low);
1173119614Sache		    break;
1174119614Sache		  }
1175119614Sache	      /* no casematch, use first entry */
1176119614Sache	      if (i > matches)
1177119614Sache		strncpy (match_list[0], match_list[1], low);
1178119614Sache	    }
1179119614Sache	  else
1180119614Sache	    /* otherwise, just use the text the user typed. */
1181119614Sache	    strncpy (match_list[0], text, low);
1182136758Speter
1183136758Speter	  FREE (dtext);
1184119614Sache	}
1185119614Sache      else
1186119614Sache        strncpy (match_list[0], match_list[1], low);
1187119614Sache
118835489Sache      match_list[0][low] = '\0';
118935489Sache    }
119035489Sache
119135489Sache  return matches;
119235489Sache}
119335489Sache
119435489Sachestatic int
119547563Sachepostprocess_matches (matchesp, matching_filenames)
119635489Sache     char ***matchesp;
119735489Sache     int matching_filenames;
119835489Sache{
119935489Sache  char *t, **matches, **temp_matches;
120035489Sache  int nmatch, i;
120135489Sache
120235489Sache  matches = *matchesp;
120335489Sache
1204119614Sache  if (matches == 0)
1205119614Sache    return 0;
1206119614Sache
120735489Sache  /* It seems to me that in all the cases we handle we would like
120835489Sache     to ignore duplicate possiblilities.  Scan for the text to
120935489Sache     insert being identical to the other completions. */
121035489Sache  if (rl_ignore_completion_duplicates)
121135489Sache    {
121235489Sache      temp_matches = remove_duplicate_matches (matches);
121335489Sache      free (matches);
121435489Sache      matches = temp_matches;
121535489Sache    }
121635489Sache
121735489Sache  /* If we are matching filenames, then here is our chance to
121835489Sache     do clever processing by re-examining the list.  Call the
121935489Sache     ignore function with the array as a parameter.  It can
122035489Sache     munge the array, deleting matches as it desires. */
122135489Sache  if (rl_ignore_some_completions_function && matching_filenames)
122235489Sache    {
122335489Sache      for (nmatch = 1; matches[nmatch]; nmatch++)
122435489Sache	;
122535489Sache      (void)(*rl_ignore_some_completions_function) (matches);
122635489Sache      if (matches == 0 || matches[0] == 0)
122735489Sache	{
122835489Sache	  FREE (matches);
122935489Sache	  *matchesp = (char **)0;
123035489Sache	  return 0;
123135489Sache        }
123235489Sache      else
123335489Sache	{
123435489Sache	  /* If we removed some matches, recompute the common prefix. */
123535489Sache	  for (i = 1; matches[i]; i++)
123635489Sache	    ;
123735489Sache	  if (i > 1 && i < nmatch)
123835489Sache	    {
123935489Sache	      t = matches[0];
124047563Sache	      compute_lcd_of_matches (matches, i - 1, t);
124135489Sache	      FREE (t);
124235489Sache	    }
124335489Sache	}
124435489Sache    }
124535489Sache
124635489Sache  *matchesp = matches;
124735489Sache  return (1);
124835489Sache}
124935489Sache
125047563Sache/* A convenience function for displaying a list of strings in
125147563Sache   columnar format on readline's output stream.  MATCHES is the list
125247563Sache   of strings, in argv format, LEN is the number of strings in MATCHES,
125347563Sache   and MAX is the length of the longest string in MATCHES. */
125447563Sachevoid
125547563Sacherl_display_match_list (matches, len, max)
125621308Sache     char **matches;
125747563Sache     int len, max;
125821308Sache{
1259119614Sache  int count, limit, printed_len, lines;
126021308Sache  int i, j, k, l;
126121308Sache  char *temp;
126221308Sache
126321308Sache  /* How many items of MAX length can we fit in the screen window? */
126421308Sache  max += 2;
126575409Sache  limit = _rl_screenwidth / max;
126675409Sache  if (limit != 1 && (limit * max == _rl_screenwidth))
126721308Sache    limit--;
126821308Sache
126975409Sache  /* Avoid a possible floating exception.  If max > _rl_screenwidth,
127021308Sache     limit will be 0 and a divide-by-zero fault will result. */
127121308Sache  if (limit == 0)
127221308Sache    limit = 1;
127321308Sache
127421308Sache  /* How many iterations of the printing loop? */
127521308Sache  count = (len + (limit - 1)) / limit;
127621308Sache
127721308Sache  /* Watch out for special case.  If LEN is less than LIMIT, then
127821308Sache     just do the inner printing loop.
127921308Sache	   0 < len <= limit  implies  count = 1. */
128021308Sache
128121308Sache  /* Sort the items if they are not already sorted. */
128221308Sache  if (rl_ignore_completion_duplicates == 0)
128358314Sache    qsort (matches + 1, len, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
128421308Sache
128575409Sache  rl_crlf ();
128621308Sache
1287119614Sache  lines = 0;
128835489Sache  if (_rl_print_completions_horizontally == 0)
128921308Sache    {
129035489Sache      /* Print the sorted items, up-and-down alphabetically, like ls. */
129135489Sache      for (i = 1; i <= count; i++)
129221308Sache	{
129335489Sache	  for (j = 0, l = i; j < limit; j++)
129421308Sache	    {
129535489Sache	      if (l > len || matches[l] == 0)
129635489Sache		break;
129735489Sache	      else
129835489Sache		{
129935489Sache		  temp = printable_part (matches[l]);
130035489Sache		  printed_len = print_filename (temp, matches[l]);
130121308Sache
130235489Sache		  if (j + 1 < limit)
130335489Sache		    for (k = 0; k < max - printed_len; k++)
130435489Sache		      putc (' ', rl_outstream);
130535489Sache		}
130635489Sache	      l += count;
130735489Sache	    }
130875409Sache	  rl_crlf ();
1309119614Sache	  lines++;
1310119614Sache	  if (_rl_page_completions && lines >= (_rl_screenheight - 1) && i < count)
1311119614Sache	    {
1312119614Sache	      lines = _rl_internal_pager (lines);
1313119614Sache	      if (lines < 0)
1314119614Sache		return;
1315119614Sache	    }
131635489Sache	}
131735489Sache    }
131835489Sache  else
131935489Sache    {
132035489Sache      /* Print the sorted items, across alphabetically, like ls -x. */
132135489Sache      for (i = 1; matches[i]; i++)
132235489Sache	{
132335489Sache	  temp = printable_part (matches[i]);
132435489Sache	  printed_len = print_filename (temp, matches[i]);
132535489Sache	  /* Have we reached the end of this line? */
132635489Sache	  if (matches[i+1])
132735489Sache	    {
132835489Sache	      if (i && (limit > 1) && (i % limit) == 0)
1329119614Sache		{
1330119614Sache		  rl_crlf ();
1331119614Sache		  lines++;
1332119614Sache		  if (_rl_page_completions && lines >= _rl_screenheight - 1)
1333119614Sache		    {
1334119614Sache		      lines = _rl_internal_pager (lines);
1335119614Sache		      if (lines < 0)
1336119614Sache			return;
1337119614Sache		    }
1338119614Sache		}
133935489Sache	      else
134021308Sache		for (k = 0; k < max - printed_len; k++)
134121308Sache		  putc (' ', rl_outstream);
134221308Sache	    }
134321308Sache	}
134475409Sache      rl_crlf ();
134521308Sache    }
134647563Sache}
134721308Sache
134847563Sache/* Display MATCHES, a list of matching filenames in argv format.  This
134947563Sache   handles the simple case -- a single match -- first.  If there is more
135047563Sache   than one match, we compute the number of strings in the list and the
135147563Sache   length of the longest string, which will be needed by the display
135247563Sache   function.  If the application wants to handle displaying the list of
135347563Sache   matches itself, it sets RL_COMPLETION_DISPLAY_MATCHES_HOOK to the
135447563Sache   address of a function, and we just call it.  If we're handling the
135547563Sache   display ourselves, we just call rl_display_match_list.  We also check
135647563Sache   that the list of matches doesn't exceed the user-settable threshold,
135747563Sache   and ask the user if he wants to see the list if there are more matches
135847563Sache   than RL_COMPLETION_QUERY_ITEMS. */
135947563Sachestatic void
136047563Sachedisplay_matches (matches)
136147563Sache     char **matches;
136247563Sache{
136347563Sache  int len, max, i;
136447563Sache  char *temp;
136547563Sache
136647563Sache  /* Move to the last visible line of a possibly-multiple-line command. */
136747563Sache  _rl_move_vert (_rl_vis_botlin);
136847563Sache
136947563Sache  /* Handle simple case first.  What if there is only one answer? */
137047563Sache  if (matches[1] == 0)
137147563Sache    {
137247563Sache      temp = printable_part (matches[0]);
137375409Sache      rl_crlf ();
137447563Sache      print_filename (temp, matches[0]);
137575409Sache      rl_crlf ();
137647563Sache
137747563Sache      rl_forced_update_display ();
137847563Sache      rl_display_fixed = 1;
137947563Sache
138047563Sache      return;
138147563Sache    }
138247563Sache
138347563Sache  /* There is more than one answer.  Find out how many there are,
138447563Sache     and find the maximum printed length of a single entry. */
138547563Sache  for (max = 0, i = 1; matches[i]; i++)
138647563Sache    {
138747563Sache      temp = printable_part (matches[i]);
1388136758Speter      len = fnwidth (temp);
138947563Sache
139047563Sache      if (len > max)
139147563Sache	max = len;
139247563Sache    }
139347563Sache
139447563Sache  len = i - 1;
139547563Sache
139647563Sache  /* If the caller has defined a display hook, then call that now. */
139747563Sache  if (rl_completion_display_matches_hook)
139847563Sache    {
139947563Sache      (*rl_completion_display_matches_hook) (matches, len, max);
140047563Sache      return;
140147563Sache    }
140247563Sache
140347563Sache  /* If there are many items, then ask the user if she really wants to
140447563Sache     see them all. */
1405157188Sache  if (rl_completion_query_items > 0 && len >= rl_completion_query_items)
140647563Sache    {
140775409Sache      rl_crlf ();
140847563Sache      fprintf (rl_outstream, "Display all %d possibilities? (y or n)", len);
140947563Sache      fflush (rl_outstream);
1410119614Sache      if (get_y_or_n (0) == 0)
141147563Sache	{
141275409Sache	  rl_crlf ();
141347563Sache
141447563Sache	  rl_forced_update_display ();
141547563Sache	  rl_display_fixed = 1;
141647563Sache
141747563Sache	  return;
141847563Sache	}
141947563Sache    }
142047563Sache
142147563Sache  rl_display_match_list (matches, len, max);
142247563Sache
142321308Sache  rl_forced_update_display ();
142421308Sache  rl_display_fixed = 1;
142521308Sache}
142621308Sache
142721308Sachestatic char *
142826500Sachemake_quoted_replacement (match, mtype, qc)
142921308Sache     char *match;
143026500Sache     int mtype;
143126500Sache     char *qc;	/* Pointer to quoting character, if any */
143221308Sache{
143321308Sache  int should_quote, do_replace;
143426500Sache  char *replacement;
143521308Sache
143621308Sache  /* If we are doing completion on quoted substrings, and any matches
143721308Sache     contain any of the completer_word_break_characters, then auto-
143821308Sache     matically prepend the substring with a quote character (just pick
143921308Sache     the first one from the list of such) if it does not already begin
144021308Sache     with a quote string.  FIXME: Need to remove any such automatically
144121308Sache     inserted quote character when it no longer is necessary, such as
144221308Sache     if we change the string we are completing on and the new set of
144321308Sache     matches don't require a quoted substring. */
144421308Sache  replacement = match;
144521308Sache
144621308Sache  should_quote = match && rl_completer_quote_characters &&
144721308Sache			rl_filename_completion_desired &&
144821308Sache			rl_filename_quoting_desired;
144921308Sache
145021308Sache  if (should_quote)
145147563Sache    should_quote = should_quote && (!qc || !*qc ||
145247563Sache		     (rl_completer_quote_characters && strchr (rl_completer_quote_characters, *qc)));
145321308Sache
145421308Sache  if (should_quote)
145521308Sache    {
145621308Sache      /* If there is a single match, see if we need to quote it.
145721308Sache         This also checks whether the common prefix of several
145821308Sache	 matches needs to be quoted. */
145930974Sache      should_quote = rl_filename_quote_characters
146075409Sache			? (_rl_strpbrk (match, rl_filename_quote_characters) != 0)
146130974Sache			: 0;
146221308Sache
146321308Sache      do_replace = should_quote ? mtype : NO_MATCH;
146426500Sache      /* Quote the replacement, since we found an embedded
146526500Sache	 word break character in a potential match. */
146626500Sache      if (do_replace != NO_MATCH && rl_filename_quoting_function)
146726500Sache	replacement = (*rl_filename_quoting_function) (match, do_replace, qc);
146821308Sache    }
146921308Sache  return (replacement);
147021308Sache}
147121308Sache
147221308Sachestatic void
147326500Sacheinsert_match (match, start, mtype, qc)
147421308Sache     char *match;
147526500Sache     int start, mtype;
147626500Sache     char *qc;
147721308Sache{
147821308Sache  char *replacement;
147926500Sache  char oqc;
148021308Sache
148126500Sache  oqc = qc ? *qc : '\0';
148226500Sache  replacement = make_quoted_replacement (match, mtype, qc);
148321308Sache
148421308Sache  /* Now insert the match. */
148521308Sache  if (replacement)
148621308Sache    {
148721308Sache      /* Don't double an opening quote character. */
148826500Sache      if (qc && *qc && start && rl_line_buffer[start - 1] == *qc &&
148926500Sache	    replacement[0] == *qc)
149021308Sache	start--;
149126500Sache      /* If make_quoted_replacement changed the quoting character, remove
149226500Sache	 the opening quote and insert the (fully-quoted) replacement. */
149326500Sache      else if (qc && (*qc != oqc) && start && rl_line_buffer[start - 1] == oqc &&
149426500Sache	    replacement[0] != oqc)
149526500Sache	start--;
149635489Sache      _rl_replace_text (replacement, start, rl_point - 1);
149721308Sache      if (replacement != match)
149821308Sache        free (replacement);
149921308Sache    }
150021308Sache}
150121308Sache
150221308Sache/* Append any necessary closing quote and a separator character to the
150321308Sache   just-inserted match.  If the user has specified that directories
150421308Sache   should be marked by a trailing `/', append one of those instead.  The
150535489Sache   default trailing character is a space.  Returns the number of characters
1506119614Sache   appended.  If NONTRIVIAL_MATCH is set, we test for a symlink (if the OS
1507119614Sache   has them) and don't add a suffix for a symlink to a directory.  A
1508119614Sache   nontrivial match is one that actually adds to the word being completed.
1509119614Sache   The variable rl_completion_mark_symlink_dirs controls this behavior
1510119614Sache   (it's initially set to the what the user has chosen, indicated by the
1511119614Sache   value of _rl_complete_mark_symlink_dirs, but may be modified by an
1512119614Sache   application's completion function). */
151335489Sachestatic int
1514119614Sacheappend_to_match (text, delimiter, quote_char, nontrivial_match)
151521308Sache     char *text;
1516119614Sache     int delimiter, quote_char, nontrivial_match;
151721308Sache{
151821308Sache  char temp_string[4], *filename;
1519119614Sache  int temp_string_index, s;
152021308Sache  struct stat finfo;
152121308Sache
152221308Sache  temp_string_index = 0;
1523136758Speter  if (quote_char && rl_point && rl_completion_suppress_quote == 0 &&
1524136758Speter      rl_line_buffer[rl_point - 1] != quote_char)
152521308Sache    temp_string[temp_string_index++] = quote_char;
152621308Sache
152721308Sache  if (delimiter)
152821308Sache    temp_string[temp_string_index++] = delimiter;
1529119614Sache  else if (rl_completion_suppress_append == 0 && rl_completion_append_character)
153021308Sache    temp_string[temp_string_index++] = rl_completion_append_character;
153121308Sache
153221308Sache  temp_string[temp_string_index++] = '\0';
153321308Sache
153421308Sache  if (rl_filename_completion_desired)
153521308Sache    {
153621308Sache      filename = tilde_expand (text);
1537119614Sache      s = (nontrivial_match && rl_completion_mark_symlink_dirs == 0)
1538119614Sache		? LSTAT (filename, &finfo)
1539119614Sache		: stat (filename, &finfo);
1540119614Sache      if (s == 0 && S_ISDIR (finfo.st_mode))
154121308Sache	{
1542157188Sache	  if (_rl_complete_mark_directories /* && rl_completion_suppress_append == 0 */)
1543119614Sache	    {
1544119614Sache	      /* This is clumsy.  Avoid putting in a double slash if point
1545119614Sache		 is at the end of the line and the previous character is a
1546119614Sache		 slash. */
1547119614Sache	      if (rl_point && rl_line_buffer[rl_point] == '\0' && rl_line_buffer[rl_point - 1] == '/')
1548119614Sache		;
1549119614Sache	      else if (rl_line_buffer[rl_point] != '/')
1550119614Sache		rl_insert_text ("/");
1551119614Sache	    }
155221308Sache	}
1553119614Sache#ifdef S_ISLNK
1554119614Sache      /* Don't add anything if the filename is a symlink and resolves to a
1555119614Sache	 directory. */
1556119614Sache      else if (s == 0 && S_ISLNK (finfo.st_mode) &&
1557119614Sache	       stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode))
1558119614Sache	;
1559119614Sache#endif
156021308Sache      else
156121308Sache	{
1562119614Sache	  if (rl_point == rl_end && temp_string_index)
156321308Sache	    rl_insert_text (temp_string);
156421308Sache	}
156521308Sache      free (filename);
156621308Sache    }
156721308Sache  else
156821308Sache    {
1569119614Sache      if (rl_point == rl_end && temp_string_index)
157021308Sache	rl_insert_text (temp_string);
157121308Sache    }
157235489Sache
157335489Sache  return (temp_string_index);
157421308Sache}
157521308Sache
157621308Sachestatic void
157726500Sacheinsert_all_matches (matches, point, qc)
157821308Sache     char **matches;
157926500Sache     int point;
158026500Sache     char *qc;
158121308Sache{
158221308Sache  int i;
158321308Sache  char *rp;
158421308Sache
158521308Sache  rl_begin_undo_group ();
158621308Sache  /* remove any opening quote character; make_quoted_replacement will add
158721308Sache     it back. */
158826500Sache  if (qc && *qc && point && rl_line_buffer[point - 1] == *qc)
158921308Sache    point--;
159021308Sache  rl_delete_text (point, rl_point);
159121308Sache  rl_point = point;
159221308Sache
159321308Sache  if (matches[1])
159421308Sache    {
159521308Sache      for (i = 1; matches[i]; i++)
159621308Sache	{
159726500Sache	  rp = make_quoted_replacement (matches[i], SINGLE_MATCH, qc);
159821308Sache	  rl_insert_text (rp);
159921308Sache	  rl_insert_text (" ");
160021308Sache	  if (rp != matches[i])
160121308Sache	    free (rp);
160221308Sache	}
160321308Sache    }
160421308Sache  else
160521308Sache    {
160626500Sache      rp = make_quoted_replacement (matches[0], SINGLE_MATCH, qc);
160721308Sache      rl_insert_text (rp);
160821308Sache      rl_insert_text (" ");
160921308Sache      if (rp != matches[0])
161021308Sache	free (rp);
161121308Sache    }
161221308Sache  rl_end_undo_group ();
161321308Sache}
161421308Sache
1615119614Sachevoid
1616119614Sache_rl_free_match_list (matches)
161747563Sache     char **matches;
161847563Sache{
161947563Sache  register int i;
162047563Sache
1621119614Sache  if (matches == 0)
1622119614Sache    return;
1623119614Sache
162447563Sache  for (i = 0; matches[i]; i++)
162547563Sache    free (matches[i]);
162647563Sache  free (matches);
162747563Sache}
162847563Sache
162921308Sache/* Complete the word at or before point.
163021308Sache   WHAT_TO_DO says what to do with the completion.
163121308Sache   `?' means list the possible completions.
163221308Sache   TAB means do standard completion.
163321308Sache   `*' means insert all of the possible completions.
163421308Sache   `!' means to do standard completion, and list all possible completions if
1635136758Speter   there is more than one.
1636136758Speter   `@' means to do standard completion, and list all possible completions if
1637136758Speter   there is more than one and partial completion is not possible. */
163821308Sacheint
163921308Sacherl_complete_internal (what_to_do)
164021308Sache     int what_to_do;
164121308Sache{
164235489Sache  char **matches;
164375409Sache  rl_compentry_func_t *our_func;
1644119614Sache  int start, end, delimiter, found_quote, i, nontrivial_lcd;
164535489Sache  char *text, *saved_line_buffer;
164621308Sache  char quote_char;
164721308Sache
164875409Sache  RL_SETSTATE(RL_STATE_COMPLETING);
164935489Sache
1650119614Sache  set_completion_defaults (what_to_do);
1651119614Sache
165221308Sache  saved_line_buffer = rl_line_buffer ? savestring (rl_line_buffer) : (char *)NULL;
165321308Sache  our_func = rl_completion_entry_function
165421308Sache		? rl_completion_entry_function
165575409Sache		: rl_filename_completion_function;
165621308Sache  /* We now look backwards for the start of a filename/variable word. */
165721308Sache  end = rl_point;
165821308Sache  found_quote = delimiter = 0;
165921308Sache  quote_char = '\0';
166021308Sache
166121308Sache  if (rl_point)
166221308Sache    /* This (possibly) changes rl_point.  If it returns a non-zero char,
166321308Sache       we know we have an open quote. */
1664119614Sache    quote_char = _rl_find_completion_word (&found_quote, &delimiter);
166521308Sache
166621308Sache  start = rl_point;
166721308Sache  rl_point = end;
166821308Sache
166921308Sache  text = rl_copy_text (start, end);
167021308Sache  matches = gen_completion_matches (text, start, end, our_func, found_quote, quote_char);
1671119614Sache  /* nontrivial_lcd is set if the common prefix adds something to the word
1672119614Sache     being completed. */
1673119614Sache  nontrivial_lcd = matches && strcmp (text, matches[0]) != 0;
167447563Sache  free (text);
167521308Sache
167621308Sache  if (matches == 0)
167721308Sache    {
167875409Sache      rl_ding ();
167921308Sache      FREE (saved_line_buffer);
1680119614Sache      completion_changed_buffer = 0;
168175409Sache      RL_UNSETSTATE(RL_STATE_COMPLETING);
168235489Sache      return (0);
168321308Sache    }
168435489Sache
168547563Sache  /* If we are matching filenames, the attempted completion function will
168647563Sache     have set rl_filename_completion_desired to a non-zero value.  The basic
168775409Sache     rl_filename_completion_function does this. */
168847563Sache  i = rl_filename_completion_desired;
168947563Sache
169047563Sache  if (postprocess_matches (&matches, i) == 0)
169121308Sache    {
169275409Sache      rl_ding ();
169335489Sache      FREE (saved_line_buffer);
169447563Sache      completion_changed_buffer = 0;
169575409Sache      RL_UNSETSTATE(RL_STATE_COMPLETING);
169635489Sache      return (0);
169721308Sache    }
169821308Sache
169921308Sache  switch (what_to_do)
170021308Sache    {
170121308Sache    case TAB:
170221308Sache    case '!':
1703136758Speter    case '@':
170421308Sache      /* Insert the first match with proper quoting. */
170521308Sache      if (*matches[0])
170626500Sache	insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
170721308Sache
170821308Sache      /* If there are more matches, ring the bell to indicate.
170921308Sache	 If we are in vi mode, Posix.2 says to not ring the bell.
171021308Sache	 If the `show-all-if-ambiguous' variable is set, display
171121308Sache	 all the matches immediately.  Otherwise, if this was the
171221308Sache	 only match, and we are hacking files, check the file to
171321308Sache	 see if it was a directory.  If so, and the `mark-directories'
171421308Sache	 variable is set, add a '/' to the name.  If not, and we
171521308Sache	 are at the end of the line, then add a space.  */
171621308Sache      if (matches[1])
171721308Sache	{
171821308Sache	  if (what_to_do == '!')
171921308Sache	    {
172021308Sache	      display_matches (matches);
172121308Sache	      break;
172221308Sache	    }
1723136758Speter	  else if (what_to_do == '@')
1724136758Speter	    {
1725136758Speter	      if (nontrivial_lcd == 0)
1726136758Speter		display_matches (matches);
1727136758Speter	      break;
1728136758Speter	    }
172921308Sache	  else if (rl_editing_mode != vi_mode)
173075409Sache	    rl_ding ();	/* There are other matches remaining. */
173121308Sache	}
173221308Sache      else
1733119614Sache	append_to_match (matches[0], delimiter, quote_char, nontrivial_lcd);
173421308Sache
173521308Sache      break;
173621308Sache
173721308Sache    case '*':
173826500Sache      insert_all_matches (matches, start, &quote_char);
173921308Sache      break;
174021308Sache
174121308Sache    case '?':
174221308Sache      display_matches (matches);
174321308Sache      break;
174421308Sache
174521308Sache    default:
174621308Sache      fprintf (stderr, "\r\nreadline: bad value %d for what_to_do in rl_complete\n", what_to_do);
174775409Sache      rl_ding ();
174821308Sache      FREE (saved_line_buffer);
174975409Sache      RL_UNSETSTATE(RL_STATE_COMPLETING);
175021308Sache      return 1;
175121308Sache    }
175221308Sache
1753119614Sache  _rl_free_match_list (matches);
175421308Sache
175521308Sache  /* Check to see if the line has changed through all of this manipulation. */
175621308Sache  if (saved_line_buffer)
175721308Sache    {
175821308Sache      completion_changed_buffer = strcmp (rl_line_buffer, saved_line_buffer) != 0;
175921308Sache      free (saved_line_buffer);
176021308Sache    }
176121308Sache
176275409Sache  RL_UNSETSTATE(RL_STATE_COMPLETING);
176321308Sache  return 0;
176421308Sache}
176521308Sache
176635489Sache/***************************************************************/
176735489Sache/*							       */
176835489Sache/*  Application-callable completion match generator functions  */
176935489Sache/*							       */
177035489Sache/***************************************************************/
177135489Sache
177235489Sache/* Return an array of (char *) which is a list of completions for TEXT.
177335489Sache   If there are no completions, return a NULL pointer.
177435489Sache   The first entry in the returned array is the substitution for TEXT.
177535489Sache   The remaining entries are the possible completions.
177635489Sache   The array is terminated with a NULL pointer.
177735489Sache
177835489Sache   ENTRY_FUNCTION is a function of two args, and returns a (char *).
177935489Sache     The first argument is TEXT.
178035489Sache     The second is a state argument; it should be zero on the first call, and
178135489Sache     non-zero on subsequent calls.  It returns a NULL pointer to the caller
178235489Sache     when there are no more matches.
178335489Sache */
178435489Sachechar **
178575409Sacherl_completion_matches (text, entry_function)
178675409Sache     const char *text;
178775409Sache     rl_compentry_func_t *entry_function;
178821308Sache{
178935489Sache  /* Number of slots in match_list. */
179035489Sache  int match_list_size;
179121308Sache
179235489Sache  /* The list of matches. */
179335489Sache  char **match_list;
179421308Sache
179535489Sache  /* Number of matches actually found. */
179635489Sache  int matches;
179721308Sache
179835489Sache  /* Temporary string binder. */
179935489Sache  char *string;
180035489Sache
180135489Sache  matches = 0;
180235489Sache  match_list_size = 10;
180335489Sache  match_list = (char **)xmalloc ((match_list_size + 1) * sizeof (char *));
180435489Sache  match_list[1] = (char *)NULL;
180535489Sache
180635489Sache  while (string = (*entry_function) (text, matches))
180721308Sache    {
180835489Sache      if (matches + 1 == match_list_size)
180935489Sache	match_list = (char **)xrealloc
181035489Sache	  (match_list, ((match_list_size += 10) + 1) * sizeof (char *));
181135489Sache
181235489Sache      match_list[++matches] = string;
181335489Sache      match_list[matches + 1] = (char *)NULL;
181421308Sache    }
181535489Sache
181635489Sache  /* If there were any matches, then look through them finding out the
181735489Sache     lowest common denominator.  That then becomes match_list[0]. */
181835489Sache  if (matches)
181935489Sache    compute_lcd_of_matches (match_list, matches, text);
182035489Sache  else				/* There were no matches. */
182135489Sache    {
182235489Sache      free (match_list);
182335489Sache      match_list = (char **)NULL;
182435489Sache    }
182535489Sache  return (match_list);
182621308Sache}
182721308Sache
182821308Sache/* A completion function for usernames.
182921308Sache   TEXT contains a partial username preceded by a random
183021308Sache   character (usually `~').  */
183121308Sachechar *
183275409Sacherl_username_completion_function (text, state)
183375409Sache     const char *text;
183421308Sache     int state;
183521308Sache{
183658314Sache#if defined (__WIN32__) || defined (__OPENNT)
183721308Sache  return (char *)NULL;
183858314Sache#else /* !__WIN32__ && !__OPENNT) */
183921308Sache  static char *username = (char *)NULL;
184021308Sache  static struct passwd *entry;
184121308Sache  static int namelen, first_char, first_char_loc;
184221308Sache  char *value;
184321308Sache
184421308Sache  if (state == 0)
184521308Sache    {
184621308Sache      FREE (username);
184721308Sache
184821308Sache      first_char = *text;
184921308Sache      first_char_loc = first_char == '~';
185021308Sache
185121308Sache      username = savestring (&text[first_char_loc]);
185221308Sache      namelen = strlen (username);
185321308Sache      setpwent ();
185421308Sache    }
185521308Sache
1856157188Sache#if defined (HAVE_GETPWENT)
185721308Sache  while (entry = getpwent ())
185821308Sache    {
185921308Sache      /* Null usernames should result in all users as possible completions. */
186021308Sache      if (namelen == 0 || (STREQN (username, entry->pw_name, namelen)))
186121308Sache	break;
186221308Sache    }
1863157188Sache#endif
186421308Sache
186521308Sache  if (entry == 0)
186621308Sache    {
1867157188Sache#if defined (HAVE_GETPWENT)
186821308Sache      endpwent ();
1869157188Sache#endif
187021308Sache      return ((char *)NULL);
187121308Sache    }
187221308Sache  else
187321308Sache    {
1874119614Sache      value = (char *)xmalloc (2 + strlen (entry->pw_name));
187521308Sache
187621308Sache      *value = *text;
187721308Sache
187821308Sache      strcpy (value + first_char_loc, entry->pw_name);
187921308Sache
188021308Sache      if (first_char == '~')
188121308Sache	rl_filename_completion_desired = 1;
188221308Sache
188321308Sache      return (value);
188421308Sache    }
188558314Sache#endif /* !__WIN32__ && !__OPENNT */
188621308Sache}
188721308Sache
188821308Sache/* Okay, now we write the entry_function for filename completion.  In the
188921308Sache   general case.  Note that completion in the shell is a little different
189021308Sache   because of all the pathnames that must be followed when looking up the
189121308Sache   completion for a command. */
189221308Sachechar *
189375409Sacherl_filename_completion_function (text, state)
189475409Sache     const char *text;
189521308Sache     int state;
189621308Sache{
189726500Sache  static DIR *directory = (DIR *)NULL;
189821308Sache  static char *filename = (char *)NULL;
189921308Sache  static char *dirname = (char *)NULL;
190021308Sache  static char *users_dirname = (char *)NULL;
190121308Sache  static int filename_len;
190221308Sache  char *temp;
190321308Sache  int dirlen;
190421308Sache  struct dirent *entry;
190521308Sache
190621308Sache  /* If we don't have any state, then do some initialization. */
190721308Sache  if (state == 0)
190821308Sache    {
190926500Sache      /* If we were interrupted before closing the directory or reading
191026500Sache	 all of its contents, close it. */
191126500Sache      if (directory)
191226500Sache	{
191326500Sache	  closedir (directory);
191426500Sache	  directory = (DIR *)NULL;
191526500Sache	}
191621308Sache      FREE (dirname);
191721308Sache      FREE (filename);
191821308Sache      FREE (users_dirname);
191921308Sache
192021308Sache      filename = savestring (text);
192121308Sache      if (*text == 0)
192221308Sache	text = ".";
192321308Sache      dirname = savestring (text);
192421308Sache
192521308Sache      temp = strrchr (dirname, '/');
192621308Sache
192758314Sache#if defined (__MSDOS__)
192858314Sache      /* special hack for //X/... */
1929119614Sache      if (dirname[0] == '/' && dirname[1] == '/' && ISALPHA ((unsigned char)dirname[2]) && dirname[3] == '/')
193058314Sache        temp = strrchr (dirname + 3, '/');
193158314Sache#endif
193258314Sache
193321308Sache      if (temp)
193421308Sache	{
193521308Sache	  strcpy (filename, ++temp);
193621308Sache	  *temp = '\0';
193721308Sache	}
193858314Sache#if defined (__MSDOS__)
193958314Sache      /* searches from current directory on the drive */
1940119614Sache      else if (ISALPHA ((unsigned char)dirname[0]) && dirname[1] == ':')
194158314Sache        {
194258314Sache          strcpy (filename, dirname + 2);
194358314Sache          dirname[2] = '\0';
194458314Sache        }
194558314Sache#endif
194621308Sache      else
194721308Sache	{
194821308Sache	  dirname[0] = '.';
194921308Sache	  dirname[1] = '\0';
195021308Sache	}
195121308Sache
195221308Sache      /* We aren't done yet.  We also support the "~user" syntax. */
195321308Sache
195421308Sache      /* Save the version of the directory that the user typed. */
195521308Sache      users_dirname = savestring (dirname);
195621308Sache
195721308Sache      if (*dirname == '~')
195821308Sache	{
195921308Sache	  temp = tilde_expand (dirname);
196021308Sache	  free (dirname);
196121308Sache	  dirname = temp;
196221308Sache	}
196321308Sache
196475409Sache      if (rl_directory_rewrite_hook)
196575409Sache	(*rl_directory_rewrite_hook) (&dirname);
196675409Sache
1967165675Sache      /* The directory completion hook should perform any necessary
1968165675Sache	 dequoting. */
196921308Sache      if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&dirname))
197021308Sache	{
197121308Sache	  free (users_dirname);
197221308Sache	  users_dirname = savestring (dirname);
197321308Sache	}
1974165675Sache      else if (rl_completion_found_quote && rl_filename_dequoting_function)
1975165675Sache	{
1976165675Sache	  /* delete single and double quotes */
1977165675Sache	  temp = (*rl_filename_dequoting_function) (users_dirname, rl_completion_quote_character);
1978165675Sache	  free (users_dirname);
1979165675Sache	  users_dirname = temp;
1980165675Sache	}
1981165675Sache      directory = opendir (dirname);
198221308Sache
1983165675Sache      /* Now dequote a non-null filename. */
1984165675Sache      if (filename && *filename && rl_completion_found_quote && rl_filename_dequoting_function)
1985165675Sache	{
1986165675Sache	  /* delete single and double quotes */
1987165675Sache	  temp = (*rl_filename_dequoting_function) (filename, rl_completion_quote_character);
1988165675Sache	  free (filename);
1989165675Sache	  filename = temp;
1990165675Sache	}
199121308Sache      filename_len = strlen (filename);
199221308Sache
199321308Sache      rl_filename_completion_desired = 1;
199421308Sache    }
199521308Sache
199621308Sache  /* At this point we should entertain the possibility of hacking wildcarded
199721308Sache     filenames, like /usr/man/man<WILD>/te<TAB>.  If the directory name
199821308Sache     contains globbing characters, then build an array of directories, and
199921308Sache     then map over that list while completing. */
200021308Sache  /* *** UNIMPLEMENTED *** */
200121308Sache
200221308Sache  /* Now that we have some state, we can read the directory. */
200321308Sache
200421308Sache  entry = (struct dirent *)NULL;
200521308Sache  while (directory && (entry = readdir (directory)))
200621308Sache    {
2007119614Sache      /* Special case for no filename.  If the user has disabled the
2008119614Sache         `match-hidden-files' variable, skip filenames beginning with `.'.
2009119614Sache	 All other entries except "." and ".." match. */
201021308Sache      if (filename_len == 0)
201121308Sache	{
2012119614Sache	  if (_rl_match_hidden_files == 0 && HIDDEN_FILE (entry->d_name))
2013119614Sache	    continue;
2014119614Sache
201521308Sache	  if (entry->d_name[0] != '.' ||
201621308Sache	       (entry->d_name[1] &&
201721308Sache		 (entry->d_name[1] != '.' || entry->d_name[2])))
201821308Sache	    break;
201921308Sache	}
202021308Sache      else
202121308Sache	{
202221308Sache	  /* Otherwise, if these match up to the length of filename, then
202321308Sache	     it is a match. */
202435489Sache	  if (_rl_completion_case_fold)
202535489Sache	    {
202635489Sache	      if ((_rl_to_lower (entry->d_name[0]) == _rl_to_lower (filename[0])) &&
202735489Sache		  (((int)D_NAMLEN (entry)) >= filename_len) &&
202835489Sache		  (_rl_strnicmp (filename, entry->d_name, filename_len) == 0))
202935489Sache		break;
203035489Sache	    }
203135489Sache	  else
203235489Sache	    {
203335489Sache	      if ((entry->d_name[0] == filename[0]) &&
203435489Sache		  (((int)D_NAMLEN (entry)) >= filename_len) &&
203535489Sache		  (strncmp (filename, entry->d_name, filename_len) == 0))
203635489Sache		break;
203735489Sache	    }
203821308Sache	}
203921308Sache    }
204021308Sache
204121308Sache  if (entry == 0)
204221308Sache    {
204321308Sache      if (directory)
204421308Sache	{
204521308Sache	  closedir (directory);
204621308Sache	  directory = (DIR *)NULL;
204721308Sache	}
204821308Sache      if (dirname)
204921308Sache	{
205021308Sache	  free (dirname);
205121308Sache	  dirname = (char *)NULL;
205221308Sache	}
205321308Sache      if (filename)
205421308Sache	{
205521308Sache	  free (filename);
205621308Sache	  filename = (char *)NULL;
205721308Sache	}
205821308Sache      if (users_dirname)
205921308Sache	{
206021308Sache	  free (users_dirname);
206121308Sache	  users_dirname = (char *)NULL;
206221308Sache	}
206321308Sache
206421308Sache      return (char *)NULL;
206521308Sache    }
206621308Sache  else
206721308Sache    {
206821308Sache      /* dirname && (strcmp (dirname, ".") != 0) */
206921308Sache      if (dirname && (dirname[0] != '.' || dirname[1]))
207021308Sache	{
207121308Sache	  if (rl_complete_with_tilde_expansion && *users_dirname == '~')
207221308Sache	    {
207321308Sache	      dirlen = strlen (dirname);
2074119614Sache	      temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry));
207521308Sache	      strcpy (temp, dirname);
207621308Sache	      /* Canonicalization cuts off any final slash present.  We
207721308Sache		 may need to add it back. */
207821308Sache	      if (dirname[dirlen - 1] != '/')
207921308Sache	        {
208021308Sache	          temp[dirlen++] = '/';
208121308Sache	          temp[dirlen] = '\0';
208221308Sache	        }
208321308Sache	    }
208421308Sache	  else
208521308Sache	    {
208621308Sache	      dirlen = strlen (users_dirname);
2087119614Sache	      temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry));
208821308Sache	      strcpy (temp, users_dirname);
208975409Sache	      /* Make sure that temp has a trailing slash here. */
209075409Sache	      if (users_dirname[dirlen - 1] != '/')
209175409Sache		temp[dirlen++] = '/';
209221308Sache	    }
209321308Sache
209447563Sache	  strcpy (temp + dirlen, entry->d_name);
209521308Sache	}
209621308Sache      else
209721308Sache	temp = savestring (entry->d_name);
209821308Sache
209921308Sache      return (temp);
210021308Sache    }
210121308Sache}
210221308Sache
210335489Sache/* An initial implementation of a menu completion function a la tcsh.  The
210435489Sache   first time (if the last readline command was not rl_menu_complete), we
210535489Sache   generate the list of matches.  This code is very similar to the code in
210635489Sache   rl_complete_internal -- there should be a way to combine the two.  Then,
210735489Sache   for each item in the list of matches, we insert the match in an undoable
210835489Sache   fashion, with the appropriate character appended (this happens on the
210935489Sache   second and subsequent consecutive calls to rl_menu_complete).  When we
211035489Sache   hit the end of the match list, we restore the original unmatched text,
211135489Sache   ring the bell, and reset the counter to zero. */
211221308Sacheint
211335489Sacherl_menu_complete (count, ignore)
211435489Sache     int count, ignore;
211521308Sache{
211675409Sache  rl_compentry_func_t *our_func;
211735489Sache  int matching_filenames, found_quote;
211821308Sache
211935489Sache  static char *orig_text;
212035489Sache  static char **matches = (char **)0;
212135489Sache  static int match_list_index = 0;
212235489Sache  static int match_list_size = 0;
212335489Sache  static int orig_start, orig_end;
212435489Sache  static char quote_char;
212535489Sache  static int delimiter;
212621308Sache
212735489Sache  /* The first time through, we generate the list of matches and set things
212835489Sache     up to insert them. */
212935489Sache  if (rl_last_func != rl_menu_complete)
213021308Sache    {
213135489Sache      /* Clean up from previous call, if any. */
213235489Sache      FREE (orig_text);
213335489Sache      if (matches)
2134119614Sache	_rl_free_match_list (matches);
213521308Sache
213635489Sache      match_list_index = match_list_size = 0;
213735489Sache      matches = (char **)NULL;
213821308Sache
213935489Sache      /* Only the completion entry function can change these. */
2140119614Sache      set_completion_defaults ('%');
214121308Sache
214235489Sache      our_func = rl_completion_entry_function
214335489Sache			? rl_completion_entry_function
214475409Sache			: rl_filename_completion_function;
214521308Sache
214635489Sache      /* We now look backwards for the start of a filename/variable word. */
214735489Sache      orig_end = rl_point;
214835489Sache      found_quote = delimiter = 0;
214935489Sache      quote_char = '\0';
215021308Sache
215135489Sache      if (rl_point)
215235489Sache	/* This (possibly) changes rl_point.  If it returns a non-zero char,
215335489Sache	   we know we have an open quote. */
2154119614Sache	quote_char = _rl_find_completion_word (&found_quote, &delimiter);
215521308Sache
215635489Sache      orig_start = rl_point;
215735489Sache      rl_point = orig_end;
215821308Sache
215935489Sache      orig_text = rl_copy_text (orig_start, orig_end);
216035489Sache      matches = gen_completion_matches (orig_text, orig_start, orig_end,
216135489Sache					our_func, found_quote, quote_char);
216235489Sache
216347563Sache      /* If we are matching filenames, the attempted completion function will
216447563Sache	 have set rl_filename_completion_desired to a non-zero value.  The basic
216575409Sache	 rl_filename_completion_function does this. */
216647563Sache      matching_filenames = rl_filename_completion_desired;
216775409Sache
216847563Sache      if (matches == 0 || postprocess_matches (&matches, matching_filenames) == 0)
216921308Sache	{
217075409Sache    	  rl_ding ();
217135489Sache	  FREE (matches);
217235489Sache	  matches = (char **)0;
217335489Sache	  FREE (orig_text);
217435489Sache	  orig_text = (char *)0;
217535489Sache    	  completion_changed_buffer = 0;
217635489Sache          return (0);
217721308Sache	}
217835489Sache
217935489Sache      for (match_list_size = 0; matches[match_list_size]; match_list_size++)
218035489Sache        ;
218135489Sache      /* matches[0] is lcd if match_list_size > 1, but the circular buffer
218235489Sache	 code below should take care of it. */
218321308Sache    }
218435489Sache
218535489Sache  /* Now we have the list of matches.  Replace the text between
218635489Sache     rl_line_buffer[orig_start] and rl_line_buffer[rl_point] with
218735489Sache     matches[match_list_index], and add any necessary closing char. */
218835489Sache
218935489Sache  if (matches == 0 || match_list_size == 0)
219035489Sache    {
219175409Sache      rl_ding ();
219235489Sache      FREE (matches);
219335489Sache      matches = (char **)0;
219435489Sache      completion_changed_buffer = 0;
219535489Sache      return (0);
219635489Sache    }
219735489Sache
2198157188Sache  match_list_index += count;
219935489Sache  if (match_list_index < 0)
220035489Sache    match_list_index += match_list_size;
2201157188Sache  else
2202157188Sache    match_list_index %= match_list_size;
220335489Sache
220447563Sache  if (match_list_index == 0 && match_list_size > 1)
220535489Sache    {
220675409Sache      rl_ding ();
220735489Sache      insert_match (orig_text, orig_start, MULT_MATCH, &quote_char);
220835489Sache    }
220935489Sache  else
221035489Sache    {
221135489Sache      insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, &quote_char);
2212119614Sache      append_to_match (matches[match_list_index], delimiter, quote_char,
2213119614Sache		       strcmp (orig_text, matches[match_list_index]));
221435489Sache    }
221535489Sache
221635489Sache  completion_changed_buffer = 1;
221735489Sache  return (0);
221821308Sache}
2219