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, "e_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, "e_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, "e_char); 220835489Sache } 220935489Sache else 221035489Sache { 221135489Sache insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, "e_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