Annotation of embedaddon/readline/complete.c, revision 1.1.1.2

1.1       misho       1: /* complete.c -- filename completion for readline. */
                      2: 
1.1.1.2 ! misho       3: /* Copyright (C) 1987-2020 Free Software Foundation, Inc.
1.1       misho       4: 
                      5:    This file is part of the GNU Readline Library (Readline), a library
                      6:    for reading lines of text with interactive input and history editing.
                      7: 
                      8:    Readline is free software: you can redistribute it and/or modify
                      9:    it under the terms of the GNU General Public License as published by
                     10:    the Free Software Foundation, either version 3 of the License, or
                     11:    (at your option) any later version.
                     12: 
                     13:    Readline is distributed in the hope that it will be useful,
                     14:    but WITHOUT ANY WARRANTY; without even the implied warranty of
                     15:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     16:    GNU General Public License for more details.
                     17: 
                     18:    You should have received a copy of the GNU General Public License
                     19:    along with Readline.  If not, see <http://www.gnu.org/licenses/>.
                     20: */
                     21: 
                     22: #define READLINE_LIBRARY
                     23: 
1.1.1.2 ! misho      24: #if defined (__TANDEM)
        !            25: #  define _XOPEN_SOURCE_EXTENDED 1
        !            26: #endif
        !            27: 
1.1       misho      28: #if defined (HAVE_CONFIG_H)
                     29: #  include <config.h>
                     30: #endif
                     31: 
                     32: #include <sys/types.h>
1.1.1.2 ! misho      33: #if defined (__TANDEM)
        !            34: #  include <sys/stat.h>
        !            35: #endif
1.1       misho      36: #include <fcntl.h>
                     37: #if defined (HAVE_SYS_FILE_H)
                     38: #  include <sys/file.h>
                     39: #endif
                     40: 
                     41: #include <signal.h>
                     42: 
                     43: #if defined (HAVE_UNISTD_H)
                     44: #  include <unistd.h>
                     45: #endif /* HAVE_UNISTD_H */
                     46: 
                     47: #if defined (HAVE_STDLIB_H)
                     48: #  include <stdlib.h>
                     49: #else
                     50: #  include "ansi_stdlib.h"
                     51: #endif /* HAVE_STDLIB_H */
                     52: 
                     53: #include <stdio.h>
                     54: 
                     55: #include <errno.h>
                     56: #if !defined (errno)
                     57: extern int errno;
                     58: #endif /* !errno */
                     59: 
                     60: #if defined (HAVE_PWD_H)
                     61: #include <pwd.h>
                     62: #endif
                     63: 
                     64: #include "posixdir.h"
                     65: #include "posixstat.h"
                     66: 
                     67: /* System-specific feature definitions and include files. */
                     68: #include "rldefs.h"
                     69: #include "rlmbutil.h"
                     70: 
                     71: /* Some standard library routines. */
                     72: #include "readline.h"
                     73: #include "xmalloc.h"
                     74: #include "rlprivate.h"
                     75: 
                     76: #if defined (COLOR_SUPPORT)
                     77: #  include "colors.h"
                     78: #endif
                     79: 
                     80: #ifdef __STDC__
                     81: typedef int QSFUNC (const void *, const void *);
                     82: #else
                     83: typedef int QSFUNC ();
                     84: #endif
                     85: 
                     86: #ifdef HAVE_LSTAT
                     87: #  define LSTAT lstat
                     88: #else
                     89: #  define LSTAT stat
                     90: #endif
                     91: 
                     92: /* Unix version of a hidden file.  Could be different on other systems. */
                     93: #define HIDDEN_FILE(fname)     ((fname)[0] == '.')
                     94: 
                     95: /* Most systems don't declare getpwent in <pwd.h> if _POSIX_SOURCE is
                     96:    defined. */
                     97: #if defined (HAVE_GETPWENT) && (!defined (HAVE_GETPW_DECLS) || defined (_POSIX_SOURCE))
                     98: extern struct passwd *getpwent PARAMS((void));
                     99: #endif /* HAVE_GETPWENT && (!HAVE_GETPW_DECLS || _POSIX_SOURCE) */
                    100: 
                    101: /* If non-zero, then this is the address of a function to call when
                    102:    completing a word would normally display the list of possible matches.
                    103:    This function is called instead of actually doing the display.
                    104:    It takes three arguments: (char **matches, int num_matches, int max_length)
                    105:    where MATCHES is the array of strings that matched, NUM_MATCHES is the
                    106:    number of strings in that array, and MAX_LENGTH is the length of the
                    107:    longest string in that array. */
                    108: rl_compdisp_func_t *rl_completion_display_matches_hook = (rl_compdisp_func_t *)NULL;
                    109: 
                    110: #if defined (VISIBLE_STATS) || defined (COLOR_SUPPORT)
                    111: #  if !defined (X_OK)
                    112: #    define X_OK 1
                    113: #  endif
                    114: #endif
                    115: 
                    116: #if defined (VISIBLE_STATS)
                    117: static int stat_char PARAMS((char *));
                    118: #endif
                    119: 
                    120: #if defined (COLOR_SUPPORT)
1.1.1.2 ! misho     121: static int colored_stat_start PARAMS((const char *));
1.1       misho     122: static void colored_stat_end PARAMS((void));
1.1.1.2 ! misho     123: static int colored_prefix_start PARAMS((void));
        !           124: static void colored_prefix_end PARAMS((void));
1.1       misho     125: #endif
                    126: 
                    127: static int path_isdir PARAMS((const char *));
                    128: 
                    129: static char *rl_quote_filename PARAMS((char *, int, char *));
                    130: 
                    131: static void _rl_complete_sigcleanup PARAMS((int, void *));
                    132: 
                    133: static void set_completion_defaults PARAMS((int));
                    134: static int get_y_or_n PARAMS((int));
                    135: static int _rl_internal_pager PARAMS((int));
                    136: static char *printable_part PARAMS((char *));
                    137: static int fnwidth PARAMS((const char *));
1.1.1.2 ! misho     138: static int fnprint PARAMS((const char *, int, const char *));
1.1       misho     139: static int print_filename PARAMS((char *, char *, int));
                    140: 
                    141: static char **gen_completion_matches PARAMS((char *, int, int, rl_compentry_func_t *, int, int));
                    142: 
                    143: static char **remove_duplicate_matches PARAMS((char **));
                    144: static void insert_match PARAMS((char *, int, int, char *));
                    145: static int append_to_match PARAMS((char *, int, int, int));
                    146: static void insert_all_matches PARAMS((char **, int, char *));
                    147: static int complete_fncmp PARAMS((const char *, int, const char *, int));
                    148: static void display_matches PARAMS((char **));
                    149: static int compute_lcd_of_matches PARAMS((char **, int, const char *));
                    150: static int postprocess_matches PARAMS((char ***, int));
1.1.1.2 ! misho     151: static int compare_match PARAMS((char *, const char *));
1.1       misho     152: static int complete_get_screenwidth PARAMS((void));
                    153: 
                    154: static char *make_quoted_replacement PARAMS((char *, int, char *));
                    155: 
                    156: /* **************************************************************** */
                    157: /*                                                                 */
                    158: /*     Completion matching, from readline's point of view.         */
                    159: /*                                                                 */
                    160: /* **************************************************************** */
                    161: 
                    162: /* Variables known only to the readline library. */
                    163: 
                    164: /* If non-zero, non-unique completions always show the list of matches. */
                    165: int _rl_complete_show_all = 0;
                    166: 
                    167: /* If non-zero, non-unique completions show the list of matches, unless it
                    168:    is not possible to do partial completion and modify the line. */
                    169: int _rl_complete_show_unmodified = 0;
                    170: 
                    171: /* If non-zero, completed directory names have a slash appended. */
                    172: int _rl_complete_mark_directories = 1;
                    173: 
                    174: /* If non-zero, the symlinked directory completion behavior introduced in
                    175:    readline-4.2a is disabled, and symlinks that point to directories have
                    176:    a slash appended (subject to the value of _rl_complete_mark_directories).
                    177:    This is user-settable via the mark-symlinked-directories variable. */
                    178: int _rl_complete_mark_symlink_dirs = 0;
                    179: 
                    180: /* If non-zero, completions are printed horizontally in alphabetical order,
                    181:    like `ls -x'. */
                    182: int _rl_print_completions_horizontally;
                    183: 
                    184: /* Non-zero means that case is not significant in filename completion. */
1.1.1.2 ! misho     185: #if (defined (__MSDOS__) && !defined (__DJGPP__)) || (defined (_WIN32) && !defined (__CYGWIN__))
1.1       misho     186: int _rl_completion_case_fold = 1;
                    187: #else
                    188: int _rl_completion_case_fold = 0;
                    189: #endif
                    190: 
                    191: /* Non-zero means that `-' and `_' are equivalent when comparing filenames
                    192:   for completion. */
                    193: int _rl_completion_case_map = 0;
                    194: 
                    195: /* If zero, don't match hidden files (filenames beginning with a `.' on
                    196:    Unix) when doing filename completion. */
                    197: int _rl_match_hidden_files = 1;
                    198: 
                    199: /* Length in characters of a common prefix replaced with an ellipsis (`...')
                    200:    when displaying completion matches.  Matches whose printable portion has
                    201:    more than this number of displaying characters in common will have the common
                    202:    display prefix replaced with an ellipsis. */
                    203: int _rl_completion_prefix_display_length = 0;
                    204: 
                    205: /* The readline-private number of screen columns to use when displaying
                    206:    matches.  If < 0 or > _rl_screenwidth, it is ignored. */
                    207: int _rl_completion_columns = -1;
                    208: 
                    209: #if defined (COLOR_SUPPORT)
                    210: /* Non-zero means to use colors to indicate file type when listing possible
                    211:    completions.  The colors used are taken from $LS_COLORS, if set. */
                    212: int _rl_colored_stats = 0;
1.1.1.2 ! misho     213: 
        !           214: /* Non-zero means to use a color (currently magenta) to indicate the common
        !           215:    prefix of a set of possible word completions. */
        !           216: int _rl_colored_completion_prefix = 0;
1.1       misho     217: #endif
                    218: 
                    219: /* If non-zero, when completing in the middle of a word, don't insert
                    220:    characters from the match that match characters following point in
                    221:    the word.  This means, for instance, completing when the cursor is
                    222:    after the `e' in `Makefile' won't result in `Makefilefile'. */
                    223: int _rl_skip_completed_text = 0;
                    224: 
                    225: /* If non-zero, menu completion displays the common prefix first in the
                    226:    cycle of possible completions instead of the last. */
                    227: int _rl_menu_complete_prefix_first = 0;
                    228: 
1.1.1.2 ! misho     229: /* Global variables available to applications using readline. */
        !           230: 
        !           231: #if defined (VISIBLE_STATS)
        !           232: /* Non-zero means add an additional character to each filename displayed
        !           233:    during listing completion iff rl_filename_completion_desired which helps
        !           234:    to indicate the type of file being listed. */
        !           235: int rl_visible_stats = 0;
        !           236: #endif /* VISIBLE_STATS */
        !           237: 
1.1       misho     238: /* If non-zero, then this is the address of a function to call when
                    239:    completing on a directory name.  The function is called with
                    240:    the address of a string (the current directory name) as an arg. */
                    241: rl_icppfunc_t *rl_directory_completion_hook = (rl_icppfunc_t *)NULL;
                    242: 
                    243: rl_icppfunc_t *rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL;
                    244: 
                    245: rl_icppfunc_t *rl_filename_stat_hook = (rl_icppfunc_t *)NULL;
                    246: 
                    247: /* If non-zero, this is the address of a function to call when reading
                    248:    directory entries from the filesystem for completion and comparing
                    249:    them to the partial word to be completed.  The function should
                    250:    either return its first argument (if no conversion takes place) or
                    251:    newly-allocated memory.  This can, for instance, convert filenames
                    252:    between character sets for comparison against what's typed at the
                    253:    keyboard.  The returned value is what is added to the list of
                    254:    matches.  The second argument is the length of the filename to be
                    255:    converted. */
                    256: rl_dequote_func_t *rl_filename_rewrite_hook = (rl_dequote_func_t *)NULL;
                    257: 
                    258: /* Non-zero means readline completion functions perform tilde expansion. */
                    259: int rl_complete_with_tilde_expansion = 0;
                    260: 
                    261: /* Pointer to the generator function for completion_matches ().
                    262:    NULL means to use rl_filename_completion_function (), the default filename
                    263:    completer. */
                    264: rl_compentry_func_t *rl_completion_entry_function = (rl_compentry_func_t *)NULL;
                    265: 
                    266: /* Pointer to generator function for rl_menu_complete ().  NULL means to use
                    267:    *rl_completion_entry_function (see above). */
                    268: rl_compentry_func_t *rl_menu_completion_entry_function = (rl_compentry_func_t *)NULL;
                    269: 
                    270: /* Pointer to alternative function to create matches.
                    271:    Function is called with TEXT, START, and END.
                    272:    START and END are indices in RL_LINE_BUFFER saying what the boundaries
                    273:    of TEXT are.
                    274:    If this function exists and returns NULL then call the value of
                    275:    rl_completion_entry_function to try to match, otherwise use the
                    276:    array of strings returned. */
                    277: rl_completion_func_t *rl_attempted_completion_function = (rl_completion_func_t *)NULL;
                    278: 
                    279: /* Non-zero means to suppress normal filename completion after the
                    280:    user-specified completion function has been called. */
                    281: int rl_attempted_completion_over = 0;
                    282: 
                    283: /* Set to a character indicating the type of completion being performed
                    284:    by rl_complete_internal, available for use by application completion
                    285:    functions. */
                    286: int rl_completion_type = 0;
                    287: 
                    288: /* Up to this many items will be displayed in response to a
                    289:    possible-completions call.  After that, we ask the user if
                    290:    she is sure she wants to see them all.  A negative value means
                    291:    don't ask. */
                    292: int rl_completion_query_items = 100;
                    293: 
                    294: int _rl_page_completions = 1;
                    295: 
                    296: /* The basic list of characters that signal a break between words for the
                    297:    completer routine.  The contents of this variable is what breaks words
                    298:    in the shell, i.e. " \t\n\"\\'`@$><=" */
                    299: const char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{("; /* }) */
                    300: 
                    301: /* List of basic quoting characters. */
                    302: const char *rl_basic_quote_characters = "\"'";
                    303: 
                    304: /* The list of characters that signal a break between words for
                    305:    rl_complete_internal.  The default list is the contents of
                    306:    rl_basic_word_break_characters.  */
                    307: /*const*/ char *rl_completer_word_break_characters = (/*const*/ char *)NULL;
                    308: 
                    309: /* Hook function to allow an application to set the completion word
                    310:    break characters before readline breaks up the line.  Allows
                    311:    position-dependent word break characters. */
                    312: rl_cpvfunc_t *rl_completion_word_break_hook = (rl_cpvfunc_t *)NULL;
                    313: 
                    314: /* List of characters which can be used to quote a substring of the line.
                    315:    Completion occurs on the entire substring, and within the substring
                    316:    rl_completer_word_break_characters are treated as any other character,
                    317:    unless they also appear within this list. */
                    318: const char *rl_completer_quote_characters = (const char *)NULL;
                    319: 
                    320: /* List of characters that should be quoted in filenames by the completer. */
                    321: const char *rl_filename_quote_characters = (const char *)NULL;
                    322: 
                    323: /* List of characters that are word break characters, but should be left
                    324:    in TEXT when it is passed to the completion function.  The shell uses
                    325:    this to help determine what kind of completing to do. */
                    326: const char *rl_special_prefixes = (const char *)NULL;
                    327: 
                    328: /* If non-zero, then disallow duplicates in the matches. */
                    329: int rl_ignore_completion_duplicates = 1;
                    330: 
                    331: /* Non-zero means that the results of the matches are to be treated
                    332:    as filenames.  This is ALWAYS zero on entry, and can only be changed
                    333:    within a completion entry finder function. */
                    334: int rl_filename_completion_desired = 0;
                    335: 
                    336: /* Non-zero means that the results of the matches are to be quoted using
                    337:    double quotes (or an application-specific quoting mechanism) if the
                    338:    filename contains any characters in rl_filename_quote_chars.  This is
                    339:    ALWAYS non-zero on entry, and can only be changed within a completion
                    340:    entry finder function. */
                    341: int rl_filename_quoting_desired = 1;
                    342: 
                    343: /* This function, if defined, is called by the completer when real
                    344:    filename completion is done, after all the matching names have been
                    345:    generated. It is passed a (char**) known as matches in the code below.
                    346:    It consists of a NULL-terminated array of pointers to potential
                    347:    matching strings.  The 1st element (matches[0]) is the maximal
                    348:    substring that is common to all matches. This function can re-arrange
                    349:    the list of matches as required, but all elements of the array must be
                    350:    free()'d if they are deleted. The main intent of this function is
                    351:    to implement FIGNORE a la SunOS csh. */
                    352: rl_compignore_func_t *rl_ignore_some_completions_function = (rl_compignore_func_t *)NULL;
                    353: 
                    354: /* Set to a function to quote a filename in an application-specific fashion.
                    355:    Called with the text to quote, the type of match found (single or multiple)
                    356:    and a pointer to the quoting character to be used, which the function can
                    357:    reset if desired. */
                    358: rl_quote_func_t *rl_filename_quoting_function = rl_quote_filename;
                    359:          
                    360: /* Function to call to remove quoting characters from a filename.  Called
                    361:    before completion is attempted, so the embedded quotes do not interfere
                    362:    with matching names in the file system.  Readline doesn't do anything
                    363:    with this; it's set only by applications. */
                    364: rl_dequote_func_t *rl_filename_dequoting_function = (rl_dequote_func_t *)NULL;
                    365: 
                    366: /* Function to call to decide whether or not a word break character is
                    367:    quoted.  If a character is quoted, it does not break words for the
                    368:    completer. */
                    369: rl_linebuf_func_t *rl_char_is_quoted_p = (rl_linebuf_func_t *)NULL;
                    370: 
                    371: /* If non-zero, the completion functions don't append anything except a
                    372:    possible closing quote.  This is set to 0 by rl_complete_internal and
                    373:    may be changed by an application-specific completion function. */
                    374: int rl_completion_suppress_append = 0;
                    375: 
                    376: /* Character appended to completed words when at the end of the line.  The
                    377:    default is a space. */
                    378: int rl_completion_append_character = ' ';
                    379: 
                    380: /* If non-zero, the completion functions don't append any closing quote.
                    381:    This is set to 0 by rl_complete_internal and may be changed by an
                    382:    application-specific completion function. */
                    383: int rl_completion_suppress_quote = 0;
                    384: 
                    385: /* Set to any quote character readline thinks it finds before any application
                    386:    completion function is called. */
                    387: int rl_completion_quote_character;
                    388: 
                    389: /* Set to a non-zero value if readline found quoting anywhere in the word to
                    390:    be completed; set before any application completion function is called. */
                    391: int rl_completion_found_quote;
                    392: 
                    393: /* If non-zero, a slash will be appended to completed filenames that are
                    394:    symbolic links to directory names, subject to the value of the
                    395:    mark-directories variable (which is user-settable).  This exists so
                    396:    that application completion functions can override the user's preference
                    397:    (set via the mark-symlinked-directories variable) if appropriate.
                    398:    It's set to the value of _rl_complete_mark_symlink_dirs in
                    399:    rl_complete_internal before any application-specific completion
                    400:    function is called, so without that function doing anything, the user's
                    401:    preferences are honored. */
                    402: int rl_completion_mark_symlink_dirs;
                    403: 
                    404: /* If non-zero, inhibit completion (temporarily). */
                    405: int rl_inhibit_completion;
                    406: 
                    407: /* Set to the last key used to invoke one of the completion functions */
                    408: int rl_completion_invoking_key;
                    409: 
                    410: /* If non-zero, sort the completion matches.  On by default. */
                    411: int rl_sort_completion_matches = 1;
                    412: 
                    413: /* Variables local to this file. */
                    414: 
                    415: /* Local variable states what happened during the last completion attempt. */
                    416: static int completion_changed_buffer;
1.1.1.2 ! misho     417: static int last_completion_failed = 0;
1.1       misho     418: 
                    419: /* The result of the query to the user about displaying completion matches */
                    420: static int completion_y_or_n;
                    421: 
1.1.1.2 ! misho     422: static int _rl_complete_display_matches_interrupt = 0;
        !           423: 
1.1       misho     424: /*************************************/
                    425: /*                                  */
                    426: /*    Bindable completion functions  */
                    427: /*                                  */
                    428: /*************************************/
                    429: 
                    430: /* Complete the word at or before point.  You have supplied the function
                    431:    that does the initial simple matching selection algorithm (see
                    432:    rl_completion_matches ()).  The default is to do filename completion. */
                    433: int
1.1.1.2 ! misho     434: rl_complete (int ignore, int invoking_key)
1.1       misho     435: {
                    436:   rl_completion_invoking_key = invoking_key;
                    437: 
                    438:   if (rl_inhibit_completion)
                    439:     return (_rl_insert_char (ignore, invoking_key));
1.1.1.2 ! misho     440: #if 0
        !           441:   else if (rl_last_func == rl_complete && completion_changed_buffer == 0 && last_completion_failed == 0)
        !           442: #else
        !           443:   else if (rl_last_func == rl_complete && completion_changed_buffer == 0)
        !           444: #endif
1.1       misho     445:     return (rl_complete_internal ('?'));
                    446:   else if (_rl_complete_show_all)
                    447:     return (rl_complete_internal ('!'));
                    448:   else if (_rl_complete_show_unmodified)
                    449:     return (rl_complete_internal ('@'));
                    450:   else
                    451:     return (rl_complete_internal (TAB));
                    452: }
                    453: 
                    454: /* List the possible completions.  See description of rl_complete (). */
                    455: int
1.1.1.2 ! misho     456: rl_possible_completions (int ignore, int invoking_key)
1.1       misho     457: {
                    458:   rl_completion_invoking_key = invoking_key;
                    459:   return (rl_complete_internal ('?'));
                    460: }
                    461: 
                    462: int
1.1.1.2 ! misho     463: rl_insert_completions (int ignore, int invoking_key)
1.1       misho     464: {
                    465:   rl_completion_invoking_key = invoking_key;
                    466:   return (rl_complete_internal ('*'));
                    467: }
                    468: 
                    469: /* Return the correct value to pass to rl_complete_internal performing
                    470:    the same tests as rl_complete.  This allows consecutive calls to an
                    471:    application's completion function to list possible completions and for
                    472:    an application-specific completion function to honor the
                    473:    show-all-if-ambiguous readline variable. */
                    474: int
1.1.1.2 ! misho     475: rl_completion_mode (rl_command_func_t *cfunc)
1.1       misho     476: {
                    477:   if (rl_last_func == cfunc && !completion_changed_buffer)
                    478:     return '?';
                    479:   else if (_rl_complete_show_all)
                    480:     return '!';
                    481:   else if (_rl_complete_show_unmodified)
                    482:     return '@';
                    483:   else
                    484:     return TAB;
                    485: }
                    486: 
                    487: /************************************/
                    488: /*                                 */
                    489: /*    Completion utility functions  */
                    490: /*                                 */
                    491: /************************************/
                    492: 
1.1.1.2 ! misho     493: /* Reset public readline state on a signal or other event. */
1.1       misho     494: void
1.1.1.2 ! misho     495: _rl_reset_completion_state (void)
1.1       misho     496: {
                    497:   rl_completion_found_quote = 0;
                    498:   rl_completion_quote_character = 0;
                    499: }
                    500: 
                    501: static void
1.1.1.2 ! misho     502: _rl_complete_sigcleanup (int sig, void *ptr)
1.1       misho     503: {
                    504:   if (sig == SIGINT)   /* XXX - for now */
1.1.1.2 ! misho     505:     {
        !           506:       _rl_free_match_list ((char **)ptr);
        !           507:       _rl_complete_display_matches_interrupt = 1;
        !           508:     }
1.1       misho     509: }
                    510: 
                    511: /* Set default values for readline word completion.  These are the variables
                    512:    that application completion functions can change or inspect. */
                    513: static void
1.1.1.2 ! misho     514: set_completion_defaults (int what_to_do)
1.1       misho     515: {
                    516:   /* Only the completion entry function can change these. */
                    517:   rl_filename_completion_desired = 0;
                    518:   rl_filename_quoting_desired = 1;
                    519:   rl_completion_type = what_to_do;
                    520:   rl_completion_suppress_append = rl_completion_suppress_quote = 0;
                    521:   rl_completion_append_character = ' ';
                    522: 
                    523:   /* The completion entry function may optionally change this. */
                    524:   rl_completion_mark_symlink_dirs = _rl_complete_mark_symlink_dirs;
1.1.1.2 ! misho     525: 
        !           526:   /* Reset private state. */
        !           527:   _rl_complete_display_matches_interrupt = 0;
1.1       misho     528: }
                    529: 
                    530: /* The user must press "y" or "n". Non-zero return means "y" pressed. */
                    531: static int
1.1.1.2 ! misho     532: get_y_or_n (int for_pager)
1.1       misho     533: {
                    534:   int c;
                    535: 
                    536:   /* For now, disable pager in callback mode, until we later convert to state
                    537:      driven functions.  Have to wait until next major version to add new
                    538:      state definition, since it will change value of RL_STATE_DONE. */
                    539: #if defined (READLINE_CALLBACKS)
                    540:   if (RL_ISSTATE (RL_STATE_CALLBACK))
                    541:     return 1;
                    542: #endif
                    543: 
                    544:   for (;;)
                    545:     {
                    546:       RL_SETSTATE(RL_STATE_MOREINPUT);
                    547:       c = rl_read_key ();
                    548:       RL_UNSETSTATE(RL_STATE_MOREINPUT);
                    549: 
                    550:       if (c == 'y' || c == 'Y' || c == ' ')
                    551:        return (1);
                    552:       if (c == 'n' || c == 'N' || c == RUBOUT)
                    553:        return (0);
                    554:       if (c == ABORT_CHAR || c < 0)
                    555:        _rl_abort_internal ();
                    556:       if (for_pager && (c == NEWLINE || c == RETURN))
                    557:        return (2);
                    558:       if (for_pager && (c == 'q' || c == 'Q'))
                    559:        return (0);
                    560:       rl_ding ();
                    561:     }
                    562: }
                    563: 
                    564: static int
1.1.1.2 ! misho     565: _rl_internal_pager (int lines)
1.1       misho     566: {
                    567:   int i;
                    568: 
                    569:   fprintf (rl_outstream, "--More--");
                    570:   fflush (rl_outstream);
                    571:   i = get_y_or_n (1);
                    572:   _rl_erase_entire_line ();
                    573:   if (i == 0)
                    574:     return -1;
                    575:   else if (i == 2)
                    576:     return (lines - 1);
                    577:   else
                    578:     return 0;
                    579: }
                    580: 
                    581: static int
1.1.1.2 ! misho     582: path_isdir (const char *filename)
1.1       misho     583: {
                    584:   struct stat finfo;
                    585: 
                    586:   return (stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode));
                    587: }
                    588: 
                    589: #if defined (VISIBLE_STATS)
                    590: /* Return the character which best describes FILENAME.
                    591:      `@' for symbolic links
                    592:      `/' for directories
                    593:      `*' for executables
                    594:      `=' for sockets
                    595:      `|' for FIFOs
                    596:      `%' for character special devices
                    597:      `#' for block special devices */
                    598: static int
1.1.1.2 ! misho     599: stat_char (char *filename)
1.1       misho     600: {
                    601:   struct stat finfo;
                    602:   int character, r;
                    603:   char *f;
                    604:   const char *fn;
                    605: 
                    606:   /* Short-circuit a //server on cygwin, since that will always behave as
                    607:      a directory. */
                    608: #if __CYGWIN__
                    609:   if (filename[0] == '/' && filename[1] == '/' && strchr (filename+2, '/') == 0)
                    610:     return '/';
                    611: #endif
                    612: 
                    613:   f = 0;
                    614:   if (rl_filename_stat_hook)
                    615:     {
                    616:       f = savestring (filename);
                    617:       (*rl_filename_stat_hook) (&f);
                    618:       fn = f;
                    619:     }
                    620:   else
                    621:     fn = filename;
                    622:     
                    623: #if defined (HAVE_LSTAT) && defined (S_ISLNK)
                    624:   r = lstat (fn, &finfo);
                    625: #else
                    626:   r = stat (fn, &finfo);
                    627: #endif
                    628: 
                    629:   if (r == -1)
1.1.1.2 ! misho     630:     {
        !           631:       xfree (f);
        !           632:       return (0);
        !           633:     }
1.1       misho     634: 
                    635:   character = 0;
                    636:   if (S_ISDIR (finfo.st_mode))
                    637:     character = '/';
                    638: #if defined (S_ISCHR)
                    639:   else if (S_ISCHR (finfo.st_mode))
                    640:     character = '%';
                    641: #endif /* S_ISCHR */
                    642: #if defined (S_ISBLK)
                    643:   else if (S_ISBLK (finfo.st_mode))
                    644:     character = '#';
                    645: #endif /* S_ISBLK */
                    646: #if defined (S_ISLNK)
                    647:   else if (S_ISLNK (finfo.st_mode))
                    648:     character = '@';
                    649: #endif /* S_ISLNK */
                    650: #if defined (S_ISSOCK)
                    651:   else if (S_ISSOCK (finfo.st_mode))
                    652:     character = '=';
                    653: #endif /* S_ISSOCK */
                    654: #if defined (S_ISFIFO)
                    655:   else if (S_ISFIFO (finfo.st_mode))
                    656:     character = '|';
                    657: #endif
                    658:   else if (S_ISREG (finfo.st_mode))
                    659:     {
1.1.1.2 ! misho     660: #if defined (_WIN32) && !defined (__CYGWIN__)
        !           661:       char *ext;
        !           662: 
        !           663:       /* Windows doesn't do access and X_OK; check file extension instead */
        !           664:       ext = strrchr (fn, '.');
        !           665:       if (ext && (_rl_stricmp (ext, ".exe") == 0 ||
        !           666:                  _rl_stricmp (ext, ".cmd") == 0 ||
        !           667:                  _rl_stricmp (ext, ".bat") == 0 ||
        !           668:                  _rl_stricmp (ext, ".com") == 0))
        !           669:        character = '*';
        !           670: #else
1.1       misho     671:       if (access (filename, X_OK) == 0)
                    672:        character = '*';
1.1.1.2 ! misho     673: #endif
1.1       misho     674:     }
                    675: 
1.1.1.2 ! misho     676:   xfree (f);
1.1       misho     677:   return (character);
                    678: }
                    679: #endif /* VISIBLE_STATS */
                    680: 
                    681: #if defined (COLOR_SUPPORT)
                    682: static int
1.1.1.2 ! misho     683: colored_stat_start (const char *filename)
1.1       misho     684: {
                    685:   _rl_set_normal_color ();
                    686:   return (_rl_print_color_indicator (filename));
                    687: }
                    688: 
                    689: static void
1.1.1.2 ! misho     690: colored_stat_end (void)
1.1       misho     691: {
                    692:   _rl_prep_non_filename_text ();
                    693:   _rl_put_indicator (&_rl_color_indicator[C_CLR_TO_EOL]);
                    694: }
1.1.1.2 ! misho     695: 
        !           696: static int
        !           697: colored_prefix_start (void)
        !           698: {
        !           699:   _rl_set_normal_color ();
        !           700:   return (_rl_print_prefix_color ());
        !           701: }
        !           702: 
        !           703: static void
        !           704: colored_prefix_end (void)
        !           705: {
        !           706:   colored_stat_end ();         /* for now */
        !           707: }
1.1       misho     708: #endif
                    709: 
                    710: /* Return the portion of PATHNAME that should be output when listing
                    711:    possible completions.  If we are hacking filename completion, we
                    712:    are only interested in the basename, the portion following the
                    713:    final slash.  Otherwise, we return what we were passed.  Since
                    714:    printing empty strings is not very informative, if we're doing
                    715:    filename completion, and the basename is the empty string, we look
                    716:    for the previous slash and return the portion following that.  If
                    717:    there's no previous slash, we just return what we were passed. */
                    718: static char *
1.1.1.2 ! misho     719: printable_part (char *pathname)
1.1       misho     720: {
                    721:   char *temp, *x;
                    722: 
                    723:   if (rl_filename_completion_desired == 0)     /* don't need to do anything */
                    724:     return (pathname);
                    725: 
                    726:   temp = strrchr (pathname, '/');
1.1.1.2 ! misho     727: #if defined (__MSDOS__) || defined (_WIN32)
1.1       misho     728:   if (temp == 0 && ISALPHA ((unsigned char)pathname[0]) && pathname[1] == ':')
                    729:     temp = pathname + 1;
                    730: #endif
                    731: 
                    732:   if (temp == 0 || *temp == '\0')
                    733:     return (pathname);
1.1.1.2 ! misho     734:   else if (temp[1] == 0 && temp == pathname)
        !           735:     return (pathname);
1.1       misho     736:   /* If the basename is NULL, we might have a pathname like '/usr/src/'.
                    737:      Look for a previous slash and, if one is found, return the portion
                    738:      following that slash.  If there's no previous slash, just return the
                    739:      pathname we were passed. */
                    740:   else if (temp[1] == '\0')
                    741:     {
                    742:       for (x = temp - 1; x > pathname; x--)
                    743:         if (*x == '/')
                    744:           break;
                    745:       return ((*x == '/') ? x + 1 : pathname);
                    746:     }
                    747:   else
                    748:     return ++temp;
                    749: }
                    750: 
                    751: /* Compute width of STRING when displayed on screen by print_filename */
                    752: static int
1.1.1.2 ! misho     753: fnwidth (const char *string)
1.1       misho     754: {
                    755:   int width, pos;
                    756: #if defined (HANDLE_MULTIBYTE)
                    757:   mbstate_t ps;
                    758:   int left, w;
                    759:   size_t clen;
                    760:   wchar_t wc;
                    761: 
                    762:   left = strlen (string) + 1;
                    763:   memset (&ps, 0, sizeof (mbstate_t));
                    764: #endif
                    765: 
                    766:   width = pos = 0;
                    767:   while (string[pos])
                    768:     {
                    769:       if (CTRL_CHAR (string[pos]) || string[pos] == RUBOUT)
                    770:        {
                    771:          width += 2;
                    772:          pos++;
                    773:        }
                    774:       else
                    775:        {
                    776: #if defined (HANDLE_MULTIBYTE)
                    777:          clen = mbrtowc (&wc, string + pos, left - pos, &ps);
                    778:          if (MB_INVALIDCH (clen))
                    779:            {
                    780:              width++;
                    781:              pos++;
                    782:              memset (&ps, 0, sizeof (mbstate_t));
                    783:            }
                    784:          else if (MB_NULLWCH (clen))
                    785:            break;
                    786:          else
                    787:            {
                    788:              pos += clen;
                    789:              w = WCWIDTH (wc);
                    790:              width += (w >= 0) ? w : 1;
                    791:            }
                    792: #else
                    793:          width++;
                    794:          pos++;
                    795: #endif
                    796:        }
                    797:     }
                    798: 
                    799:   return width;
                    800: }
                    801: 
                    802: #define ELLIPSIS_LEN   3
                    803: 
                    804: static int
1.1.1.2 ! misho     805: fnprint (const char *to_print, int prefix_bytes, const char *real_pathname)
1.1       misho     806: {
                    807:   int printed_len, w;
                    808:   const char *s;
1.1.1.2 ! misho     809:   int common_prefix_len, print_len;
1.1       misho     810: #if defined (HANDLE_MULTIBYTE)
                    811:   mbstate_t ps;
                    812:   const char *end;
                    813:   size_t tlen;
                    814:   int width;
                    815:   wchar_t wc;
                    816: 
1.1.1.2 ! misho     817:   print_len = strlen (to_print);
        !           818:   end = to_print + print_len + 1;
1.1       misho     819:   memset (&ps, 0, sizeof (mbstate_t));
1.1.1.2 ! misho     820: #else
        !           821:   print_len = strlen (to_print);
1.1       misho     822: #endif
                    823: 
1.1.1.2 ! misho     824:   printed_len = common_prefix_len = 0;
1.1       misho     825: 
                    826:   /* Don't print only the ellipsis if the common prefix is one of the
1.1.1.2 ! misho     827:      possible completions.  Only cut off prefix_bytes if we're going to be
        !           828:      printing the ellipsis, which takes precedence over coloring the
        !           829:      completion prefix (see print_filename() below). */
        !           830:   if (_rl_completion_prefix_display_length > 0 && prefix_bytes >= print_len)
1.1       misho     831:     prefix_bytes = 0;
                    832: 
1.1.1.2 ! misho     833: #if defined (COLOR_SUPPORT)
        !           834:   if (_rl_colored_stats && (prefix_bytes == 0 || _rl_colored_completion_prefix <= 0))
        !           835:     colored_stat_start (real_pathname);
        !           836: #endif
        !           837: 
        !           838:   if (prefix_bytes && _rl_completion_prefix_display_length > 0)
1.1       misho     839:     {
                    840:       char ellipsis;
                    841: 
                    842:       ellipsis = (to_print[prefix_bytes] == '.') ? '_' : '.';
                    843:       for (w = 0; w < ELLIPSIS_LEN; w++)
                    844:        putc (ellipsis, rl_outstream);
                    845:       printed_len = ELLIPSIS_LEN;
                    846:     }
1.1.1.2 ! misho     847: #if defined (COLOR_SUPPORT)
        !           848:   else if (prefix_bytes && _rl_colored_completion_prefix > 0)
        !           849:     {
        !           850:       common_prefix_len = prefix_bytes;
        !           851:       prefix_bytes = 0;
        !           852:       /* XXX - print color indicator start here */
        !           853:       colored_prefix_start ();
        !           854:     }
        !           855: #endif
1.1       misho     856: 
                    857:   s = to_print + prefix_bytes;
                    858:   while (*s)
                    859:     {
                    860:       if (CTRL_CHAR (*s))
                    861:         {
                    862:           putc ('^', rl_outstream);
                    863:           putc (UNCTRL (*s), rl_outstream);
                    864:           printed_len += 2;
                    865:           s++;
                    866: #if defined (HANDLE_MULTIBYTE)
                    867:          memset (&ps, 0, sizeof (mbstate_t));
                    868: #endif
                    869:         }
                    870:       else if (*s == RUBOUT)
                    871:        {
                    872:          putc ('^', rl_outstream);
                    873:          putc ('?', rl_outstream);
                    874:          printed_len += 2;
                    875:          s++;
                    876: #if defined (HANDLE_MULTIBYTE)
                    877:          memset (&ps, 0, sizeof (mbstate_t));
                    878: #endif
                    879:        }
                    880:       else
                    881:        {
                    882: #if defined (HANDLE_MULTIBYTE)
                    883:          tlen = mbrtowc (&wc, s, end - s, &ps);
                    884:          if (MB_INVALIDCH (tlen))
                    885:            {
                    886:              tlen = 1;
                    887:              width = 1;
                    888:              memset (&ps, 0, sizeof (mbstate_t));
                    889:            }
                    890:          else if (MB_NULLWCH (tlen))
                    891:            break;
                    892:          else
                    893:            {
                    894:              w = WCWIDTH (wc);
                    895:              width = (w >= 0) ? w : 1;
                    896:            }
                    897:          fwrite (s, 1, tlen, rl_outstream);
                    898:          s += tlen;
                    899:          printed_len += width;
                    900: #else
                    901:          putc (*s, rl_outstream);
                    902:          s++;
                    903:          printed_len++;
                    904: #endif
                    905:        }
1.1.1.2 ! misho     906:       if (common_prefix_len > 0 && (s - to_print) >= common_prefix_len)
        !           907:        {
        !           908: #if defined (COLOR_SUPPORT)
        !           909:          /* printed bytes = s - to_print */
        !           910:          /* printed bytes should never be > but check for paranoia's sake */
        !           911:          colored_prefix_end ();
        !           912:          if (_rl_colored_stats)
        !           913:            colored_stat_start (real_pathname);         /* XXX - experiment */
        !           914: #endif
        !           915:          common_prefix_len = 0;
        !           916:        }
1.1       misho     917:     }
                    918: 
1.1.1.2 ! misho     919: #if defined (COLOR_SUPPORT)
        !           920:   /* XXX - unconditional for now */
        !           921:   if (_rl_colored_stats)
        !           922:     colored_stat_end ();
        !           923: #endif
        !           924: 
1.1       misho     925:   return printed_len;
                    926: }
                    927: 
                    928: /* Output TO_PRINT to rl_outstream.  If VISIBLE_STATS is defined and we
                    929:    are using it, check for and output a single character for `special'
                    930:    filenames.  Return the number of characters we output. */
                    931: 
                    932: static int
1.1.1.2 ! misho     933: print_filename (char *to_print, char *full_pathname, int prefix_bytes)
1.1       misho     934: {
                    935:   int printed_len, extension_char, slen, tlen;
                    936:   char *s, c, *new_full_pathname, *dn;
                    937: 
                    938:   extension_char = 0;
                    939: #if defined (COLOR_SUPPORT)
                    940:   /* Defer printing if we want to prefix with a color indicator */
                    941:   if (_rl_colored_stats == 0 || rl_filename_completion_desired == 0)
                    942: #endif
1.1.1.2 ! misho     943:     printed_len = fnprint (to_print, prefix_bytes, to_print);
1.1       misho     944: 
                    945:   if (rl_filename_completion_desired && (
                    946: #if defined (VISIBLE_STATS)
                    947:      rl_visible_stats ||
                    948: #endif
                    949: #if defined (COLOR_SUPPORT)
                    950:      _rl_colored_stats ||
                    951: #endif
                    952:      _rl_complete_mark_directories))
                    953:     {
                    954:       /* If to_print != full_pathname, to_print is the basename of the
                    955:         path passed.  In this case, we try to expand the directory
                    956:         name before checking for the stat character. */
                    957:       if (to_print != full_pathname)
                    958:        {
                    959:          /* Terminate the directory name. */
                    960:          c = to_print[-1];
                    961:          to_print[-1] = '\0';
                    962: 
                    963:          /* If setting the last slash in full_pathname to a NUL results in
                    964:             full_pathname being the empty string, we are trying to complete
                    965:             files in the root directory.  If we pass a null string to the
                    966:             bash directory completion hook, for example, it will expand it
                    967:             to the current directory.  We just want the `/'. */
                    968:          if (full_pathname == 0 || *full_pathname == 0)
                    969:            dn = "/";
                    970:          else if (full_pathname[0] != '/')
                    971:            dn = full_pathname;
                    972:          else if (full_pathname[1] == 0)
                    973:            dn = "//";          /* restore trailing slash to `//' */
                    974:          else if (full_pathname[1] == '/' && full_pathname[2] == 0)
                    975:            dn = "/";           /* don't turn /// into // */
                    976:          else
                    977:            dn = full_pathname;
                    978:          s = tilde_expand (dn);
                    979:          if (rl_directory_completion_hook)
                    980:            (*rl_directory_completion_hook) (&s);
                    981: 
                    982:          slen = strlen (s);
                    983:          tlen = strlen (to_print);
                    984:          new_full_pathname = (char *)xmalloc (slen + tlen + 2);
                    985:          strcpy (new_full_pathname, s);
                    986:          if (s[slen - 1] == '/')
                    987:            slen--;
                    988:          else
                    989:            new_full_pathname[slen] = '/';
                    990:          strcpy (new_full_pathname + slen + 1, to_print);
                    991: 
                    992: #if defined (VISIBLE_STATS)
                    993:          if (rl_visible_stats)
                    994:            extension_char = stat_char (new_full_pathname);
                    995:          else
                    996: #endif
                    997:          if (_rl_complete_mark_directories)
                    998:            {
                    999:              dn = 0;
                   1000:              if (rl_directory_completion_hook == 0 && rl_filename_stat_hook)
                   1001:                {
                   1002:                  dn = savestring (new_full_pathname);
                   1003:                  (*rl_filename_stat_hook) (&dn);
1.1.1.2 ! misho    1004:                  xfree (new_full_pathname);
1.1       misho    1005:                  new_full_pathname = dn;
                   1006:                }
                   1007:              if (path_isdir (new_full_pathname))
                   1008:                extension_char = '/';
                   1009:            }
                   1010: 
1.1.1.2 ! misho    1011:          /* Move colored-stats code inside fnprint() */
1.1       misho    1012: #if defined (COLOR_SUPPORT)
                   1013:          if (_rl_colored_stats)
1.1.1.2 ! misho    1014:            printed_len = fnprint (to_print, prefix_bytes, new_full_pathname);
1.1       misho    1015: #endif
                   1016: 
                   1017:          xfree (new_full_pathname);
                   1018:          to_print[-1] = c;
                   1019:        }
                   1020:       else
                   1021:        {
                   1022:          s = tilde_expand (full_pathname);
                   1023: #if defined (VISIBLE_STATS)
                   1024:          if (rl_visible_stats)
                   1025:            extension_char = stat_char (s);
                   1026:          else
                   1027: #endif
                   1028:            if (_rl_complete_mark_directories && path_isdir (s))
                   1029:              extension_char = '/';
                   1030: 
1.1.1.2 ! misho    1031:          /* Move colored-stats code inside fnprint() */
1.1       misho    1032: #if defined (COLOR_SUPPORT)
                   1033:          if (_rl_colored_stats)
1.1.1.2 ! misho    1034:            printed_len = fnprint (to_print, prefix_bytes, s);
1.1       misho    1035: #endif
                   1036:        }
                   1037: 
                   1038:       xfree (s);
                   1039:       if (extension_char)
                   1040:        {
                   1041:          putc (extension_char, rl_outstream);
                   1042:          printed_len++;
                   1043:        }
                   1044:     }
                   1045: 
                   1046:   return printed_len;
                   1047: }
                   1048: 
                   1049: static char *
1.1.1.2 ! misho    1050: rl_quote_filename (char *s, int rtype, char *qcp)
1.1       misho    1051: {
                   1052:   char *r;
                   1053: 
                   1054:   r = (char *)xmalloc (strlen (s) + 2);
                   1055:   *r = *rl_completer_quote_characters;
                   1056:   strcpy (r + 1, s);
                   1057:   if (qcp)
                   1058:     *qcp = *rl_completer_quote_characters;
                   1059:   return r;
                   1060: }
                   1061: 
                   1062: /* Find the bounds of the current word for completion purposes, and leave
                   1063:    rl_point set to the end of the word.  This function skips quoted
                   1064:    substrings (characters between matched pairs of characters in
                   1065:    rl_completer_quote_characters).  First we try to find an unclosed
                   1066:    quoted substring on which to do matching.  If one is not found, we use
                   1067:    the word break characters to find the boundaries of the current word.
                   1068:    We call an application-specific function to decide whether or not a
                   1069:    particular word break character is quoted; if that function returns a
                   1070:    non-zero result, the character does not break a word.  This function
                   1071:    returns the opening quote character if we found an unclosed quoted
                   1072:    substring, '\0' otherwise.  FP, if non-null, is set to a value saying
                   1073:    which (shell-like) quote characters we found (single quote, double
                   1074:    quote, or backslash) anywhere in the string.  DP, if non-null, is set to
                   1075:    the value of the delimiter character that caused a word break. */
                   1076: 
                   1077: char
1.1.1.2 ! misho    1078: _rl_find_completion_word (int *fp, int *dp)
1.1       misho    1079: {
                   1080:   int scan, end, found_quote, delimiter, pass_next, isbrk;
                   1081:   char quote_char, *brkchars;
                   1082: 
                   1083:   end = rl_point;
                   1084:   found_quote = delimiter = 0;
                   1085:   quote_char = '\0';
                   1086: 
                   1087:   brkchars = 0;
                   1088:   if (rl_completion_word_break_hook)
                   1089:     brkchars = (*rl_completion_word_break_hook) ();
                   1090:   if (brkchars == 0)
                   1091:     brkchars = rl_completer_word_break_characters;
                   1092: 
                   1093:   if (rl_completer_quote_characters)
                   1094:     {
                   1095:       /* We have a list of characters which can be used in pairs to
                   1096:         quote substrings for the completer.  Try to find the start
                   1097:         of an unclosed quoted substring. */
                   1098:       /* FOUND_QUOTE is set so we know what kind of quotes we found. */
                   1099:       for (scan = pass_next = 0; scan < end; scan = MB_NEXTCHAR (rl_line_buffer, scan, 1, MB_FIND_ANY))
                   1100:        {
                   1101:          if (pass_next)
                   1102:            {
                   1103:              pass_next = 0;
                   1104:              continue;
                   1105:            }
                   1106: 
                   1107:          /* Shell-like semantics for single quotes -- don't allow backslash
                   1108:             to quote anything in single quotes, especially not the closing
                   1109:             quote.  If you don't like this, take out the check on the value
                   1110:             of quote_char. */
                   1111:          if (quote_char != '\'' && rl_line_buffer[scan] == '\\')
                   1112:            {
                   1113:              pass_next = 1;
                   1114:              found_quote |= RL_QF_BACKSLASH;
                   1115:              continue;
                   1116:            }
                   1117: 
                   1118:          if (quote_char != '\0')
                   1119:            {
                   1120:              /* Ignore everything until the matching close quote char. */
                   1121:              if (rl_line_buffer[scan] == quote_char)
                   1122:                {
                   1123:                  /* Found matching close.  Abandon this substring. */
                   1124:                  quote_char = '\0';
                   1125:                  rl_point = end;
                   1126:                }
                   1127:            }
                   1128:          else if (strchr (rl_completer_quote_characters, rl_line_buffer[scan]))
                   1129:            {
                   1130:              /* Found start of a quoted substring. */
                   1131:              quote_char = rl_line_buffer[scan];
                   1132:              rl_point = scan + 1;
                   1133:              /* Shell-like quoting conventions. */
                   1134:              if (quote_char == '\'')
                   1135:                found_quote |= RL_QF_SINGLE_QUOTE;
                   1136:              else if (quote_char == '"')
                   1137:                found_quote |= RL_QF_DOUBLE_QUOTE;
                   1138:              else
                   1139:                found_quote |= RL_QF_OTHER_QUOTE;      
                   1140:            }
                   1141:        }
                   1142:     }
                   1143: 
                   1144:   if (rl_point == end && quote_char == '\0')
                   1145:     {
                   1146:       /* We didn't find an unclosed quoted substring upon which to do
                   1147:          completion, so use the word break characters to find the
                   1148:          substring on which to complete. */
                   1149:       while (rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_ANY))
                   1150:        {
                   1151:          scan = rl_line_buffer[rl_point];
                   1152: 
                   1153:          if (strchr (brkchars, scan) == 0)
                   1154:            continue;
                   1155: 
                   1156:          /* Call the application-specific function to tell us whether
                   1157:             this word break character is quoted and should be skipped. */
                   1158:          if (rl_char_is_quoted_p && found_quote &&
                   1159:              (*rl_char_is_quoted_p) (rl_line_buffer, rl_point))
                   1160:            continue;
                   1161: 
                   1162:          /* Convoluted code, but it avoids an n^2 algorithm with calls
                   1163:             to char_is_quoted. */
                   1164:          break;
                   1165:        }
                   1166:     }
                   1167: 
                   1168:   /* If we are at an unquoted word break, then advance past it. */
                   1169:   scan = rl_line_buffer[rl_point];
                   1170: 
                   1171:   /* If there is an application-specific function to say whether or not
                   1172:      a character is quoted and we found a quote character, let that
                   1173:      function decide whether or not a character is a word break, even
                   1174:      if it is found in rl_completer_word_break_characters.  Don't bother
                   1175:      if we're at the end of the line, though. */
                   1176:   if (scan)
                   1177:     {
                   1178:       if (rl_char_is_quoted_p)
                   1179:        isbrk = (found_quote == 0 ||
                   1180:                (*rl_char_is_quoted_p) (rl_line_buffer, rl_point) == 0) &&
                   1181:                strchr (brkchars, scan) != 0;
                   1182:       else
                   1183:        isbrk = strchr (brkchars, scan) != 0;
                   1184: 
                   1185:       if (isbrk)
                   1186:        {
                   1187:          /* If the character that caused the word break was a quoting
                   1188:             character, then remember it as the delimiter. */
                   1189:          if (rl_basic_quote_characters &&
                   1190:              strchr (rl_basic_quote_characters, scan) &&
                   1191:              (end - rl_point) > 1)
                   1192:            delimiter = scan;
                   1193: 
                   1194:          /* If the character isn't needed to determine something special
                   1195:             about what kind of completion to perform, then advance past it. */
                   1196:          if (rl_special_prefixes == 0 || strchr (rl_special_prefixes, scan) == 0)
                   1197:            rl_point++;
                   1198:        }
                   1199:     }
                   1200: 
                   1201:   if (fp)
                   1202:     *fp = found_quote;
                   1203:   if (dp)
                   1204:     *dp = delimiter;
                   1205: 
                   1206:   return (quote_char);
                   1207: }
                   1208: 
                   1209: static char **
1.1.1.2 ! misho    1210: gen_completion_matches (char *text, int start, int end, rl_compentry_func_t *our_func, int found_quote, int quote_char)
1.1       misho    1211: {
                   1212:   char **matches;
                   1213: 
                   1214:   rl_completion_found_quote = found_quote;
                   1215:   rl_completion_quote_character = quote_char;
                   1216: 
                   1217:   /* If the user wants to TRY to complete, but then wants to give
                   1218:      up and use the default completion function, they set the
                   1219:      variable rl_attempted_completion_function. */
                   1220:   if (rl_attempted_completion_function)
                   1221:     {
                   1222:       matches = (*rl_attempted_completion_function) (text, start, end);
                   1223:       if (RL_SIG_RECEIVED())
                   1224:        {
                   1225:          _rl_free_match_list (matches);
                   1226:          matches = 0;
                   1227:          RL_CHECK_SIGNALS ();
                   1228:        }
                   1229: 
                   1230:       if (matches || rl_attempted_completion_over)
                   1231:        {
                   1232:          rl_attempted_completion_over = 0;
                   1233:          return (matches);
                   1234:        }
                   1235:     }
                   1236: 
                   1237:   /* XXX -- filename dequoting moved into rl_filename_completion_function */
                   1238: 
                   1239:   /* rl_completion_matches will check for signals as well to avoid a long
                   1240:      delay while reading a directory. */
                   1241:   matches = rl_completion_matches (text, our_func);
                   1242:   if (RL_SIG_RECEIVED())
                   1243:     {
                   1244:       _rl_free_match_list (matches);
                   1245:       matches = 0;
                   1246:       RL_CHECK_SIGNALS ();
                   1247:     }
                   1248:   return matches;  
                   1249: }
                   1250: 
                   1251: /* Filter out duplicates in MATCHES.  This frees up the strings in
                   1252:    MATCHES. */
                   1253: static char **
1.1.1.2 ! misho    1254: remove_duplicate_matches (char **matches)
1.1       misho    1255: {
                   1256:   char *lowest_common;
                   1257:   int i, j, newlen;
                   1258:   char dead_slot;
                   1259:   char **temp_array;
                   1260: 
                   1261:   /* Sort the items. */
                   1262:   for (i = 0; matches[i]; i++)
                   1263:     ;
                   1264: 
                   1265:   /* Sort the array without matches[0], since we need it to
                   1266:      stay in place no matter what. */
                   1267:   if (i && rl_sort_completion_matches)
                   1268:     qsort (matches+1, i-1, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
                   1269: 
                   1270:   /* Remember the lowest common denominator for it may be unique. */
                   1271:   lowest_common = savestring (matches[0]);
                   1272: 
                   1273:   for (i = newlen = 0; matches[i + 1]; i++)
                   1274:     {
                   1275:       if (strcmp (matches[i], matches[i + 1]) == 0)
                   1276:        {
                   1277:          xfree (matches[i]);
                   1278:          matches[i] = (char *)&dead_slot;
                   1279:        }
                   1280:       else
                   1281:        newlen++;
                   1282:     }
                   1283: 
                   1284:   /* We have marked all the dead slots with (char *)&dead_slot.
                   1285:      Copy all the non-dead entries into a new array. */
                   1286:   temp_array = (char **)xmalloc ((3 + newlen) * sizeof (char *));
                   1287:   for (i = j = 1; matches[i]; i++)
                   1288:     {
                   1289:       if (matches[i] != (char *)&dead_slot)
                   1290:        temp_array[j++] = matches[i];
                   1291:     }
                   1292:   temp_array[j] = (char *)NULL;
                   1293: 
                   1294:   if (matches[0] != (char *)&dead_slot)
                   1295:     xfree (matches[0]);
                   1296: 
                   1297:   /* Place the lowest common denominator back in [0]. */
                   1298:   temp_array[0] = lowest_common;
                   1299: 
                   1300:   /* If there is one string left, and it is identical to the
                   1301:      lowest common denominator, then the LCD is the string to
                   1302:      insert. */
                   1303:   if (j == 2 && strcmp (temp_array[0], temp_array[1]) == 0)
                   1304:     {
                   1305:       xfree (temp_array[1]);
                   1306:       temp_array[1] = (char *)NULL;
                   1307:     }
                   1308:   return (temp_array);
                   1309: }
                   1310: 
                   1311: /* Find the common prefix of the list of matches, and put it into
                   1312:    matches[0]. */
                   1313: static int
1.1.1.2 ! misho    1314: compute_lcd_of_matches (char **match_list, int matches, const char *text)
1.1       misho    1315: {
                   1316:   register int i, c1, c2, si;
                   1317:   int low;             /* Count of max-matched characters. */
                   1318:   int lx;
                   1319:   char *dtext;         /* dequoted TEXT, if needed */
                   1320: #if defined (HANDLE_MULTIBYTE)
                   1321:   int v;
                   1322:   size_t v1, v2;
                   1323:   mbstate_t ps1, ps2;
                   1324:   wchar_t wc1, wc2;
                   1325: #endif
                   1326: 
                   1327:   /* If only one match, just use that.  Otherwise, compare each
                   1328:      member of the list with the next, finding out where they
                   1329:      stop matching. */
                   1330:   if (matches == 1)
                   1331:     {
                   1332:       match_list[0] = match_list[1];
                   1333:       match_list[1] = (char *)NULL;
                   1334:       return 1;
                   1335:     }
                   1336: 
                   1337:   for (i = 1, low = 100000; i < matches; i++)
                   1338:     {
                   1339: #if defined (HANDLE_MULTIBYTE)
                   1340:       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
                   1341:        {
                   1342:          memset (&ps1, 0, sizeof (mbstate_t));
                   1343:          memset (&ps2, 0, sizeof (mbstate_t));
                   1344:        }
                   1345: #endif
1.1.1.2 ! misho    1346:       for (si = 0; (c1 = match_list[i][si]) && (c2 = match_list[i + 1][si]); si++)
1.1       misho    1347:        {
1.1.1.2 ! misho    1348:            if (_rl_completion_case_fold)
        !          1349:              {
        !          1350:                c1 = _rl_to_lower (c1);
        !          1351:                c2 = _rl_to_lower (c2);
        !          1352:              }
1.1       misho    1353: #if defined (HANDLE_MULTIBYTE)
                   1354:            if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
                   1355:              {
                   1356:                v1 = mbrtowc(&wc1, match_list[i]+si, strlen (match_list[i]+si), &ps1);
                   1357:                v2 = mbrtowc (&wc2, match_list[i+1]+si, strlen (match_list[i+1]+si), &ps2);
                   1358:                if (MB_INVALIDCH (v1) || MB_INVALIDCH (v2))
                   1359:                  {
                   1360:                    if (c1 != c2)       /* do byte comparison */
                   1361:                      break;
                   1362:                    continue;
                   1363:                  }
1.1.1.2 ! misho    1364:                if (_rl_completion_case_fold)
        !          1365:                  {
        !          1366:                    wc1 = towlower (wc1);
        !          1367:                   wc2 = towlower (wc2);
        !          1368:                  }
1.1       misho    1369:                if (wc1 != wc2)
                   1370:                  break;
                   1371:                else if (v1 > 1)
                   1372:                  si += v1 - 1;
                   1373:              }
                   1374:            else
                   1375: #endif
                   1376:            if (c1 != c2)
                   1377:              break;
                   1378:        }
                   1379: 
                   1380:       if (low > si)
                   1381:        low = si;
                   1382:     }
                   1383: 
                   1384:   /* If there were multiple matches, but none matched up to even the
                   1385:      first character, and the user typed something, use that as the
                   1386:      value of matches[0]. */
                   1387:   if (low == 0 && text && *text)
                   1388:     {
                   1389:       match_list[0] = (char *)xmalloc (strlen (text) + 1);
                   1390:       strcpy (match_list[0], text);
                   1391:     }
                   1392:   else
                   1393:     {
                   1394:       match_list[0] = (char *)xmalloc (low + 1);
                   1395: 
                   1396:       /* XXX - this might need changes in the presence of multibyte chars */
                   1397: 
                   1398:       /* If we are ignoring case, try to preserve the case of the string
                   1399:         the user typed in the face of multiple matches differing in case. */
                   1400:       if (_rl_completion_case_fold)
                   1401:        {
                   1402:          /* We're making an assumption here:
                   1403:                IF we're completing filenames AND
                   1404:                   the application has defined a filename dequoting function AND
                   1405:                   we found a quote character AND
                   1406:                   the application has requested filename quoting
                   1407:                THEN
                   1408:                   we assume that TEXT was dequoted before checking against
                   1409:                   the file system and needs to be dequoted here before we
                   1410:                   check against the list of matches
                   1411:                FI */
                   1412:          dtext = (char *)NULL;
                   1413:          if (rl_filename_completion_desired &&
                   1414:              rl_filename_dequoting_function &&
                   1415:              rl_completion_found_quote &&
                   1416:              rl_filename_quoting_desired)
                   1417:            {
                   1418:              dtext = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character);
                   1419:              text = dtext;
                   1420:            }
                   1421: 
                   1422:          /* sort the list to get consistent answers. */
1.1.1.2 ! misho    1423:          if (rl_sort_completion_matches)
        !          1424:            qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare);
1.1       misho    1425: 
                   1426:          si = strlen (text);
                   1427:          lx = (si <= low) ? si : low;  /* check shorter of text and matches */
                   1428:          /* Try to preserve the case of what the user typed in the presence of
                   1429:             multiple matches: check each match for something that matches
                   1430:             what the user typed taking case into account; use it up to common
                   1431:             length of matches if one is found.  If not, just use first match. */
                   1432:          for (i = 1; i <= matches; i++)
                   1433:            if (strncmp (match_list[i], text, lx) == 0)
                   1434:              {
                   1435:                strncpy (match_list[0], match_list[i], low);
                   1436:                break;
                   1437:              }
                   1438:          /* no casematch, use first entry */
                   1439:          if (i > matches)
                   1440:            strncpy (match_list[0], match_list[1], low);
                   1441: 
                   1442:          FREE (dtext);
                   1443:        }
                   1444:       else
                   1445:         strncpy (match_list[0], match_list[1], low);
                   1446: 
                   1447:       match_list[0][low] = '\0';
                   1448:     }
                   1449: 
                   1450:   return matches;
                   1451: }
                   1452: 
                   1453: static int
1.1.1.2 ! misho    1454: postprocess_matches (char ***matchesp, int matching_filenames)
1.1       misho    1455: {
                   1456:   char *t, **matches, **temp_matches;
                   1457:   int nmatch, i;
                   1458: 
                   1459:   matches = *matchesp;
                   1460: 
                   1461:   if (matches == 0)
                   1462:     return 0;
                   1463: 
                   1464:   /* It seems to me that in all the cases we handle we would like
                   1465:      to ignore duplicate possibilities.  Scan for the text to
                   1466:      insert being identical to the other completions. */
                   1467:   if (rl_ignore_completion_duplicates)
                   1468:     {
                   1469:       temp_matches = remove_duplicate_matches (matches);
                   1470:       xfree (matches);
                   1471:       matches = temp_matches;
                   1472:     }
                   1473: 
                   1474:   /* If we are matching filenames, then here is our chance to
                   1475:      do clever processing by re-examining the list.  Call the
                   1476:      ignore function with the array as a parameter.  It can
                   1477:      munge the array, deleting matches as it desires. */
                   1478:   if (rl_ignore_some_completions_function && matching_filenames)
                   1479:     {
                   1480:       for (nmatch = 1; matches[nmatch]; nmatch++)
                   1481:        ;
                   1482:       (void)(*rl_ignore_some_completions_function) (matches);
                   1483:       if (matches == 0 || matches[0] == 0)
                   1484:        {
                   1485:          FREE (matches);
                   1486:          *matchesp = (char **)0;
                   1487:          return 0;
                   1488:         }
                   1489:       else
                   1490:        {
                   1491:          /* If we removed some matches, recompute the common prefix. */
                   1492:          for (i = 1; matches[i]; i++)
                   1493:            ;
                   1494:          if (i > 1 && i < nmatch)
                   1495:            {
                   1496:              t = matches[0];
                   1497:              compute_lcd_of_matches (matches, i - 1, t);
                   1498:              FREE (t);
                   1499:            }
                   1500:        }
                   1501:     }
                   1502: 
                   1503:   *matchesp = matches;
                   1504:   return (1);
                   1505: }
                   1506: 
                   1507: static int
1.1.1.2 ! misho    1508: complete_get_screenwidth (void)
1.1       misho    1509: {
                   1510:   int cols;
                   1511:   char *envcols;
                   1512: 
                   1513:   cols = _rl_completion_columns;
                   1514:   if (cols >= 0 && cols <= _rl_screenwidth)
                   1515:     return cols;
                   1516:   envcols = getenv ("COLUMNS");
                   1517:   if (envcols && *envcols)
                   1518:     cols = atoi (envcols);
                   1519:   if (cols >= 0 && cols <= _rl_screenwidth)
                   1520:     return cols;
                   1521:   return _rl_screenwidth;
                   1522: }
                   1523: 
                   1524: /* A convenience function for displaying a list of strings in
                   1525:    columnar format on readline's output stream.  MATCHES is the list
                   1526:    of strings, in argv format, LEN is the number of strings in MATCHES,
                   1527:    and MAX is the length of the longest string in MATCHES. */
                   1528: void
1.1.1.2 ! misho    1529: rl_display_match_list (char **matches, int len, int max)
1.1       misho    1530: {
                   1531:   int count, limit, printed_len, lines, cols;
                   1532:   int i, j, k, l, common_length, sind;
                   1533:   char *temp, *t;
                   1534: 
                   1535:   /* Find the length of the prefix common to all items: length as displayed
                   1536:      characters (common_length) and as a byte index into the matches (sind) */
                   1537:   common_length = sind = 0;
                   1538:   if (_rl_completion_prefix_display_length > 0)
                   1539:     {
                   1540:       t = printable_part (matches[0]);
1.1.1.2 ! misho    1541:       /* check again in case of /usr/src/ */
        !          1542:       temp = rl_filename_completion_desired ? strrchr (t, '/') : 0;
1.1       misho    1543:       common_length = temp ? fnwidth (temp) : fnwidth (t);
                   1544:       sind = temp ? strlen (temp) : strlen (t);
1.1.1.2 ! misho    1545:       if (common_length > max || sind > max)
        !          1546:        common_length = sind = 0;
1.1       misho    1547: 
                   1548:       if (common_length > _rl_completion_prefix_display_length && common_length > ELLIPSIS_LEN)
                   1549:        max -= common_length - ELLIPSIS_LEN;
                   1550:       else
                   1551:        common_length = sind = 0;
                   1552:     }
1.1.1.2 ! misho    1553: #if defined (COLOR_SUPPORT)
        !          1554:   else if (_rl_colored_completion_prefix > 0)
        !          1555:     {
        !          1556:       t = printable_part (matches[0]);
        !          1557:       temp = rl_filename_completion_desired ? strrchr (t, '/') : 0;
        !          1558:       common_length = temp ? fnwidth (temp) : fnwidth (t);
        !          1559:       sind = temp ? RL_STRLEN (temp+1) : RL_STRLEN (t);                /* want portion after final slash */
        !          1560:       if (common_length > max || sind > max)
        !          1561:        common_length = sind = 0;
        !          1562:     }
        !          1563: #endif
1.1       misho    1564: 
                   1565:   /* How many items of MAX length can we fit in the screen window? */
                   1566:   cols = complete_get_screenwidth ();
                   1567:   max += 2;
                   1568:   limit = cols / max;
                   1569:   if (limit != 1 && (limit * max == cols))
                   1570:     limit--;
                   1571: 
                   1572:   /* If cols == 0, limit will end up -1 */
                   1573:   if (cols < _rl_screenwidth && limit < 0)
                   1574:     limit = 1;
                   1575: 
                   1576:   /* Avoid a possible floating exception.  If max > cols,
                   1577:      limit will be 0 and a divide-by-zero fault will result. */
                   1578:   if (limit == 0)
                   1579:     limit = 1;
                   1580: 
                   1581:   /* How many iterations of the printing loop? */
                   1582:   count = (len + (limit - 1)) / limit;
                   1583: 
                   1584:   /* Watch out for special case.  If LEN is less than LIMIT, then
                   1585:      just do the inner printing loop.
                   1586:           0 < len <= limit  implies  count = 1. */
                   1587: 
                   1588:   /* Sort the items if they are not already sorted. */
                   1589:   if (rl_ignore_completion_duplicates == 0 && rl_sort_completion_matches)
                   1590:     qsort (matches + 1, len, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
                   1591: 
                   1592:   rl_crlf ();
                   1593: 
                   1594:   lines = 0;
                   1595:   if (_rl_print_completions_horizontally == 0)
                   1596:     {
                   1597:       /* Print the sorted items, up-and-down alphabetically, like ls. */
                   1598:       for (i = 1; i <= count; i++)
                   1599:        {
                   1600:          for (j = 0, l = i; j < limit; j++)
                   1601:            {
                   1602:              if (l > len || matches[l] == 0)
                   1603:                break;
                   1604:              else
                   1605:                {
                   1606:                  temp = printable_part (matches[l]);
                   1607:                  printed_len = print_filename (temp, matches[l], sind);
                   1608: 
                   1609:                  if (j + 1 < limit)
1.1.1.2 ! misho    1610:                    {
        !          1611:                      if (max <= printed_len)
        !          1612:                        putc (' ', rl_outstream);
        !          1613:                      else
        !          1614:                        for (k = 0; k < max - printed_len; k++)
        !          1615:                          putc (' ', rl_outstream);
        !          1616:                    }
1.1       misho    1617:                }
                   1618:              l += count;
                   1619:            }
                   1620:          rl_crlf ();
1.1.1.2 ! misho    1621: #if defined (SIGWINCH)
        !          1622:          if (RL_SIG_RECEIVED () && RL_SIGWINCH_RECEIVED() == 0)
        !          1623: #else
        !          1624:          if (RL_SIG_RECEIVED ())
        !          1625: #endif
        !          1626:            return;
1.1       misho    1627:          lines++;
                   1628:          if (_rl_page_completions && lines >= (_rl_screenheight - 1) && i < count)
                   1629:            {
                   1630:              lines = _rl_internal_pager (lines);
                   1631:              if (lines < 0)
                   1632:                return;
                   1633:            }
                   1634:        }
                   1635:     }
                   1636:   else
                   1637:     {
                   1638:       /* Print the sorted items, across alphabetically, like ls -x. */
                   1639:       for (i = 1; matches[i]; i++)
                   1640:        {
                   1641:          temp = printable_part (matches[i]);
                   1642:          printed_len = print_filename (temp, matches[i], sind);
                   1643:          /* Have we reached the end of this line? */
1.1.1.2 ! misho    1644: #if defined (SIGWINCH)
        !          1645:          if (RL_SIG_RECEIVED () && RL_SIGWINCH_RECEIVED() == 0)
        !          1646: #else
        !          1647:          if (RL_SIG_RECEIVED ())
        !          1648: #endif
        !          1649:            return;
1.1       misho    1650:          if (matches[i+1])
                   1651:            {
                   1652:              if (limit == 1 || (i && (limit > 1) && (i % limit) == 0))
                   1653:                {
                   1654:                  rl_crlf ();
                   1655:                  lines++;
                   1656:                  if (_rl_page_completions && lines >= _rl_screenheight - 1)
                   1657:                    {
                   1658:                      lines = _rl_internal_pager (lines);
                   1659:                      if (lines < 0)
                   1660:                        return;
                   1661:                    }
                   1662:                }
1.1.1.2 ! misho    1663:              else if (max <= printed_len)
        !          1664:                putc (' ', rl_outstream);
1.1       misho    1665:              else
                   1666:                for (k = 0; k < max - printed_len; k++)
                   1667:                  putc (' ', rl_outstream);
                   1668:            }
                   1669:        }
                   1670:       rl_crlf ();
                   1671:     }
                   1672: }
                   1673: 
                   1674: /* Display MATCHES, a list of matching filenames in argv format.  This
                   1675:    handles the simple case -- a single match -- first.  If there is more
                   1676:    than one match, we compute the number of strings in the list and the
                   1677:    length of the longest string, which will be needed by the display
                   1678:    function.  If the application wants to handle displaying the list of
                   1679:    matches itself, it sets RL_COMPLETION_DISPLAY_MATCHES_HOOK to the
                   1680:    address of a function, and we just call it.  If we're handling the
                   1681:    display ourselves, we just call rl_display_match_list.  We also check
                   1682:    that the list of matches doesn't exceed the user-settable threshold,
                   1683:    and ask the user if he wants to see the list if there are more matches
                   1684:    than RL_COMPLETION_QUERY_ITEMS. */
                   1685: static void
1.1.1.2 ! misho    1686: display_matches (char **matches)
1.1       misho    1687: {
                   1688:   int len, max, i;
                   1689:   char *temp;
                   1690: 
                   1691:   /* Move to the last visible line of a possibly-multiple-line command. */
                   1692:   _rl_move_vert (_rl_vis_botlin);
                   1693: 
                   1694:   /* Handle simple case first.  What if there is only one answer? */
                   1695:   if (matches[1] == 0)
                   1696:     {
                   1697:       temp = printable_part (matches[0]);
                   1698:       rl_crlf ();
                   1699:       print_filename (temp, matches[0], 0);
                   1700:       rl_crlf ();
                   1701: 
                   1702:       rl_forced_update_display ();
                   1703:       rl_display_fixed = 1;
                   1704: 
                   1705:       return;
                   1706:     }
                   1707: 
                   1708:   /* There is more than one answer.  Find out how many there are,
                   1709:      and find the maximum printed length of a single entry. */
                   1710:   for (max = 0, i = 1; matches[i]; i++)
                   1711:     {
                   1712:       temp = printable_part (matches[i]);
                   1713:       len = fnwidth (temp);
                   1714: 
                   1715:       if (len > max)
                   1716:        max = len;
                   1717:     }
                   1718: 
                   1719:   len = i - 1;
                   1720: 
                   1721:   /* If the caller has defined a display hook, then call that now. */
                   1722:   if (rl_completion_display_matches_hook)
                   1723:     {
                   1724:       (*rl_completion_display_matches_hook) (matches, len, max);
                   1725:       return;
                   1726:     }
                   1727:        
                   1728:   /* If there are many items, then ask the user if she really wants to
                   1729:      see them all. */
                   1730:   if (rl_completion_query_items > 0 && len >= rl_completion_query_items)
                   1731:     {
                   1732:       rl_crlf ();
                   1733:       fprintf (rl_outstream, "Display all %d possibilities? (y or n)", len);
                   1734:       fflush (rl_outstream);
                   1735:       if ((completion_y_or_n = get_y_or_n (0)) == 0)
                   1736:        {
                   1737:          rl_crlf ();
                   1738: 
                   1739:          rl_forced_update_display ();
                   1740:          rl_display_fixed = 1;
                   1741: 
                   1742:          return;
                   1743:        }
                   1744:     }
                   1745: 
                   1746:   rl_display_match_list (matches, len, max);
                   1747: 
                   1748:   rl_forced_update_display ();
                   1749:   rl_display_fixed = 1;
                   1750: }
                   1751: 
1.1.1.2 ! misho    1752: /* qc == pointer to quoting character, if any */
1.1       misho    1753: static char *
1.1.1.2 ! misho    1754: make_quoted_replacement (char *match, int mtype, char *qc)
1.1       misho    1755: {
                   1756:   int should_quote, do_replace;
                   1757:   char *replacement;
                   1758: 
                   1759:   /* If we are doing completion on quoted substrings, and any matches
                   1760:      contain any of the completer_word_break_characters, then auto-
                   1761:      matically prepend the substring with a quote character (just pick
                   1762:      the first one from the list of such) if it does not already begin
                   1763:      with a quote string.  FIXME: Need to remove any such automatically
                   1764:      inserted quote character when it no longer is necessary, such as
                   1765:      if we change the string we are completing on and the new set of
                   1766:      matches don't require a quoted substring. */
                   1767:   replacement = match;
                   1768: 
                   1769:   should_quote = match && rl_completer_quote_characters &&
                   1770:                        rl_filename_completion_desired &&
                   1771:                        rl_filename_quoting_desired;
                   1772: 
                   1773:   if (should_quote)
                   1774:     should_quote = should_quote && (!qc || !*qc ||
                   1775:                     (rl_completer_quote_characters && strchr (rl_completer_quote_characters, *qc)));
                   1776: 
                   1777:   if (should_quote)
                   1778:     {
                   1779:       /* If there is a single match, see if we need to quote it.
                   1780:          This also checks whether the common prefix of several
                   1781:         matches needs to be quoted. */
                   1782:       should_quote = rl_filename_quote_characters
                   1783:                        ? (_rl_strpbrk (match, rl_filename_quote_characters) != 0)
                   1784:                        : 0;
                   1785: 
                   1786:       do_replace = should_quote ? mtype : NO_MATCH;
                   1787:       /* Quote the replacement, since we found an embedded
                   1788:         word break character in a potential match. */
                   1789:       if (do_replace != NO_MATCH && rl_filename_quoting_function)
                   1790:        replacement = (*rl_filename_quoting_function) (match, do_replace, qc);
                   1791:     }
                   1792:   return (replacement);
                   1793: }
                   1794: 
                   1795: static void
1.1.1.2 ! misho    1796: insert_match (char *match, int start, int mtype, char *qc)
1.1       misho    1797: {
                   1798:   char *replacement, *r;
                   1799:   char oqc;
                   1800:   int end, rlen;
                   1801: 
                   1802:   oqc = qc ? *qc : '\0';
                   1803:   replacement = make_quoted_replacement (match, mtype, qc);
                   1804: 
                   1805:   /* Now insert the match. */
                   1806:   if (replacement)
                   1807:     {
                   1808:       rlen = strlen (replacement);
                   1809:       /* Don't double an opening quote character. */
                   1810:       if (qc && *qc && start && rl_line_buffer[start - 1] == *qc &&
                   1811:            replacement[0] == *qc)
                   1812:        start--;
                   1813:       /* If make_quoted_replacement changed the quoting character, remove
                   1814:         the opening quote and insert the (fully-quoted) replacement. */
                   1815:       else if (qc && (*qc != oqc) && start && rl_line_buffer[start - 1] == oqc &&
                   1816:            replacement[0] != oqc)
                   1817:        start--;
                   1818:       end = rl_point - 1;
                   1819:       /* Don't double a closing quote character */
                   1820:       if (qc && *qc && end && rl_line_buffer[rl_point] == *qc && replacement[rlen - 1] == *qc)
                   1821:         end++;
                   1822:       if (_rl_skip_completed_text)
                   1823:        {
                   1824:          r = replacement;
                   1825:          while (start < rl_end && *r && rl_line_buffer[start] == *r)
                   1826:            {
                   1827:              start++;
                   1828:              r++;
                   1829:            }
                   1830:          if (start <= end || *r)
                   1831:            _rl_replace_text (r, start, end);
                   1832:          rl_point = start + strlen (r);
                   1833:        }
                   1834:       else
                   1835:        _rl_replace_text (replacement, start, end);
                   1836:       if (replacement != match)
                   1837:         xfree (replacement);
                   1838:     }
                   1839: }
                   1840: 
                   1841: /* Append any necessary closing quote and a separator character to the
                   1842:    just-inserted match.  If the user has specified that directories
                   1843:    should be marked by a trailing `/', append one of those instead.  The
                   1844:    default trailing character is a space.  Returns the number of characters
                   1845:    appended.  If NONTRIVIAL_MATCH is set, we test for a symlink (if the OS
                   1846:    has them) and don't add a suffix for a symlink to a directory.  A
                   1847:    nontrivial match is one that actually adds to the word being completed.
                   1848:    The variable rl_completion_mark_symlink_dirs controls this behavior
                   1849:    (it's initially set to the what the user has chosen, indicated by the
                   1850:    value of _rl_complete_mark_symlink_dirs, but may be modified by an
                   1851:    application's completion function). */
                   1852: static int
1.1.1.2 ! misho    1853: append_to_match (char *text, int delimiter, int quote_char, int nontrivial_match)
1.1       misho    1854: {
                   1855:   char temp_string[4], *filename, *fn;
                   1856:   int temp_string_index, s;
                   1857:   struct stat finfo;
                   1858: 
                   1859:   temp_string_index = 0;
                   1860:   if (quote_char && rl_point && rl_completion_suppress_quote == 0 &&
                   1861:       rl_line_buffer[rl_point - 1] != quote_char)
                   1862:     temp_string[temp_string_index++] = quote_char;
                   1863: 
                   1864:   if (delimiter)
                   1865:     temp_string[temp_string_index++] = delimiter;
                   1866:   else if (rl_completion_suppress_append == 0 && rl_completion_append_character)
                   1867:     temp_string[temp_string_index++] = rl_completion_append_character;
                   1868: 
                   1869:   temp_string[temp_string_index++] = '\0';
                   1870: 
                   1871:   if (rl_filename_completion_desired)
                   1872:     {
                   1873:       filename = tilde_expand (text);
                   1874:       if (rl_filename_stat_hook)
                   1875:         {
                   1876:           fn = savestring (filename);
                   1877:          (*rl_filename_stat_hook) (&fn);
                   1878:          xfree (filename);
                   1879:          filename = fn;
                   1880:         }
                   1881:       s = (nontrivial_match && rl_completion_mark_symlink_dirs == 0)
                   1882:                ? LSTAT (filename, &finfo)
                   1883:                : stat (filename, &finfo);
                   1884:       if (s == 0 && S_ISDIR (finfo.st_mode))
                   1885:        {
                   1886:          if (_rl_complete_mark_directories /* && rl_completion_suppress_append == 0 */)
                   1887:            {
                   1888:              /* This is clumsy.  Avoid putting in a double slash if point
                   1889:                 is at the end of the line and the previous character is a
                   1890:                 slash. */
                   1891:              if (rl_point && rl_line_buffer[rl_point] == '\0' && rl_line_buffer[rl_point - 1] == '/')
                   1892:                ;
                   1893:              else if (rl_line_buffer[rl_point] != '/')
                   1894:                rl_insert_text ("/");
                   1895:            }
                   1896:        }
                   1897: #ifdef S_ISLNK
                   1898:       /* Don't add anything if the filename is a symlink and resolves to a
                   1899:         directory. */
                   1900:       else if (s == 0 && S_ISLNK (finfo.st_mode) && path_isdir (filename))
                   1901:        ;
                   1902: #endif
                   1903:       else
                   1904:        {
                   1905:          if (rl_point == rl_end && temp_string_index)
                   1906:            rl_insert_text (temp_string);
                   1907:        }
                   1908:       xfree (filename);
                   1909:     }
                   1910:   else
                   1911:     {
                   1912:       if (rl_point == rl_end && temp_string_index)
                   1913:        rl_insert_text (temp_string);
                   1914:     }
                   1915: 
                   1916:   return (temp_string_index);
                   1917: }
                   1918: 
                   1919: static void
1.1.1.2 ! misho    1920: insert_all_matches (char **matches, int point, char *qc)
1.1       misho    1921: {
                   1922:   int i;
                   1923:   char *rp;
                   1924: 
                   1925:   rl_begin_undo_group ();
                   1926:   /* remove any opening quote character; make_quoted_replacement will add
                   1927:      it back. */
                   1928:   if (qc && *qc && point && rl_line_buffer[point - 1] == *qc)
                   1929:     point--;
                   1930:   rl_delete_text (point, rl_point);
                   1931:   rl_point = point;
                   1932: 
                   1933:   if (matches[1])
                   1934:     {
                   1935:       for (i = 1; matches[i]; i++)
                   1936:        {
                   1937:          rp = make_quoted_replacement (matches[i], SINGLE_MATCH, qc);
                   1938:          rl_insert_text (rp);
                   1939:          rl_insert_text (" ");
                   1940:          if (rp != matches[i])
                   1941:            xfree (rp);
                   1942:        }
                   1943:     }
                   1944:   else
                   1945:     {
                   1946:       rp = make_quoted_replacement (matches[0], SINGLE_MATCH, qc);
                   1947:       rl_insert_text (rp);
                   1948:       rl_insert_text (" ");
                   1949:       if (rp != matches[0])
                   1950:        xfree (rp);
                   1951:     }
                   1952:   rl_end_undo_group ();
                   1953: }
                   1954: 
                   1955: void
1.1.1.2 ! misho    1956: _rl_free_match_list (char **matches)
1.1       misho    1957: {
                   1958:   register int i;
                   1959: 
                   1960:   if (matches == 0)
                   1961:     return;
                   1962: 
                   1963:   for (i = 0; matches[i]; i++)
                   1964:     xfree (matches[i]);
                   1965:   xfree (matches);
                   1966: }
                   1967: 
1.1.1.2 ! misho    1968: /* Compare a possibly-quoted filename TEXT from the line buffer and a possible
        !          1969:    MATCH that is the product of filename completion, which acts on the dequoted
        !          1970:    text. */
        !          1971: static int
        !          1972: compare_match (char *text, const char *match)
        !          1973: {
        !          1974:   char *temp;
        !          1975:   int r;
        !          1976: 
        !          1977:   if (rl_filename_completion_desired && rl_filename_quoting_desired && 
        !          1978:       rl_completion_found_quote && rl_filename_dequoting_function)
        !          1979:     {
        !          1980:       temp = (*rl_filename_dequoting_function) (text, rl_completion_quote_character);
        !          1981:       r = strcmp (temp, match);
        !          1982:       free (temp);
        !          1983:       return r;
        !          1984:     }      
        !          1985:   return (strcmp (text, match));
        !          1986: }
        !          1987: 
1.1       misho    1988: /* Complete the word at or before point.
                   1989:    WHAT_TO_DO says what to do with the completion.
                   1990:    `?' means list the possible completions.
                   1991:    TAB means do standard completion.
                   1992:    `*' means insert all of the possible completions.
                   1993:    `!' means to do standard completion, and list all possible completions if
                   1994:    there is more than one.
                   1995:    `@' means to do standard completion, and list all possible completions if
                   1996:    there is more than one and partial completion is not possible. */
                   1997: int
1.1.1.2 ! misho    1998: rl_complete_internal (int what_to_do)
1.1       misho    1999: {
                   2000:   char **matches;
                   2001:   rl_compentry_func_t *our_func;
                   2002:   int start, end, delimiter, found_quote, i, nontrivial_lcd;
                   2003:   char *text, *saved_line_buffer;
                   2004:   char quote_char;
1.1.1.2 ! misho    2005:   int tlen, mlen, saved_last_completion_failed;
1.1       misho    2006: 
                   2007:   RL_SETSTATE(RL_STATE_COMPLETING);
                   2008: 
1.1.1.2 ! misho    2009:   saved_last_completion_failed = last_completion_failed;
        !          2010: 
1.1       misho    2011:   set_completion_defaults (what_to_do);
                   2012: 
                   2013:   saved_line_buffer = rl_line_buffer ? savestring (rl_line_buffer) : (char *)NULL;
                   2014:   our_func = rl_completion_entry_function
                   2015:                ? rl_completion_entry_function
                   2016:                : rl_filename_completion_function;
                   2017:   /* We now look backwards for the start of a filename/variable word. */
                   2018:   end = rl_point;
                   2019:   found_quote = delimiter = 0;
                   2020:   quote_char = '\0';
                   2021: 
                   2022:   if (rl_point)
                   2023:     /* This (possibly) changes rl_point.  If it returns a non-zero char,
                   2024:        we know we have an open quote. */
                   2025:     quote_char = _rl_find_completion_word (&found_quote, &delimiter);
                   2026: 
                   2027:   start = rl_point;
                   2028:   rl_point = end;
                   2029: 
                   2030:   text = rl_copy_text (start, end);
                   2031:   matches = gen_completion_matches (text, start, end, our_func, found_quote, quote_char);
                   2032:   /* nontrivial_lcd is set if the common prefix adds something to the word
                   2033:      being completed. */
1.1.1.2 ! misho    2034:   nontrivial_lcd = matches && compare_match (text, matches[0]) != 0;
1.1       misho    2035:   if (what_to_do == '!' || what_to_do == '@')
                   2036:     tlen = strlen (text);
                   2037:   xfree (text);
                   2038: 
                   2039:   if (matches == 0)
                   2040:     {
                   2041:       rl_ding ();
                   2042:       FREE (saved_line_buffer);
                   2043:       completion_changed_buffer = 0;
1.1.1.2 ! misho    2044:       last_completion_failed = 1;
1.1       misho    2045:       RL_UNSETSTATE(RL_STATE_COMPLETING);
                   2046:       _rl_reset_completion_state ();
                   2047:       return (0);
                   2048:     }
                   2049: 
                   2050:   /* If we are matching filenames, the attempted completion function will
                   2051:      have set rl_filename_completion_desired to a non-zero value.  The basic
                   2052:      rl_filename_completion_function does this. */
                   2053:   i = rl_filename_completion_desired;
                   2054: 
                   2055:   if (postprocess_matches (&matches, i) == 0)
                   2056:     {
                   2057:       rl_ding ();
                   2058:       FREE (saved_line_buffer);
                   2059:       completion_changed_buffer = 0;
1.1.1.2 ! misho    2060:       last_completion_failed = 1;
1.1       misho    2061:       RL_UNSETSTATE(RL_STATE_COMPLETING);
                   2062:       _rl_reset_completion_state ();
                   2063:       return (0);
                   2064:     }
                   2065: 
1.1.1.2 ! misho    2066:   if (matches && matches[0] && *matches[0])
        !          2067:     last_completion_failed = 0;
        !          2068: 
1.1       misho    2069:   switch (what_to_do)
                   2070:     {
                   2071:     case TAB:
                   2072:     case '!':
                   2073:     case '@':
                   2074:       /* Insert the first match with proper quoting. */
                   2075:       if (what_to_do == TAB)
                   2076:         {
                   2077:           if (*matches[0])
                   2078:            insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
                   2079:         }
                   2080:       else if (*matches[0] && matches[1] == 0)
                   2081:        /* should we perform the check only if there are multiple matches? */
                   2082:        insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
                   2083:       else if (*matches[0])    /* what_to_do != TAB && multiple matches */
                   2084:        {
                   2085:          mlen = *matches[0] ? strlen (matches[0]) : 0;
                   2086:          if (mlen >= tlen)
                   2087:            insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
                   2088:        }
                   2089: 
                   2090:       /* If there are more matches, ring the bell to indicate.
                   2091:         If we are in vi mode, Posix.2 says to not ring the bell.
                   2092:         If the `show-all-if-ambiguous' variable is set, display
                   2093:         all the matches immediately.  Otherwise, if this was the
                   2094:         only match, and we are hacking files, check the file to
                   2095:         see if it was a directory.  If so, and the `mark-directories'
                   2096:         variable is set, add a '/' to the name.  If not, and we
                   2097:         are at the end of the line, then add a space.  */
                   2098:       if (matches[1])
                   2099:        {
                   2100:          if (what_to_do == '!')
                   2101:            {
                   2102:              display_matches (matches);
                   2103:              break;
                   2104:            }
                   2105:          else if (what_to_do == '@')
                   2106:            {
                   2107:              if (nontrivial_lcd == 0)
                   2108:                display_matches (matches);
                   2109:              break;
                   2110:            }
                   2111:          else if (rl_editing_mode != vi_mode)
                   2112:            rl_ding (); /* There are other matches remaining. */
                   2113:        }
                   2114:       else
                   2115:        append_to_match (matches[0], delimiter, quote_char, nontrivial_lcd);
                   2116: 
                   2117:       break;
                   2118: 
                   2119:     case '*':
                   2120:       insert_all_matches (matches, start, &quote_char);
                   2121:       break;
                   2122: 
                   2123:     case '?':
1.1.1.2 ! misho    2124:       /* Let's try to insert a single match here if the last completion failed
        !          2125:         but this attempt returned a single match. */
        !          2126:       if (saved_last_completion_failed && matches[0] && *matches[0] && matches[1] == 0)
        !          2127:        {
        !          2128:          insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
        !          2129:          append_to_match (matches[0], delimiter, quote_char, nontrivial_lcd);
        !          2130:          break;
        !          2131:        }
        !          2132:       
1.1       misho    2133:       if (rl_completion_display_matches_hook == 0)
                   2134:        {
                   2135:          _rl_sigcleanup = _rl_complete_sigcleanup;
                   2136:          _rl_sigcleanarg = matches;
1.1.1.2 ! misho    2137:          _rl_complete_display_matches_interrupt = 0;
1.1       misho    2138:        }
                   2139:       display_matches (matches);
1.1.1.2 ! misho    2140:       if (_rl_complete_display_matches_interrupt)
        !          2141:         {
        !          2142:           matches = 0;         /* already freed by rl_complete_sigcleanup */
        !          2143:           _rl_complete_display_matches_interrupt = 0;
        !          2144:          if (rl_signal_event_hook)
        !          2145:            (*rl_signal_event_hook) ();         /* XXX */
        !          2146:         }
1.1       misho    2147:       _rl_sigcleanup = 0;
                   2148:       _rl_sigcleanarg = 0;
                   2149:       break;
                   2150: 
                   2151:     default:
                   2152:       _rl_ttymsg ("bad value %d for what_to_do in rl_complete", what_to_do);
                   2153:       rl_ding ();
                   2154:       FREE (saved_line_buffer);
                   2155:       RL_UNSETSTATE(RL_STATE_COMPLETING);
                   2156:       _rl_free_match_list (matches);
                   2157:       _rl_reset_completion_state ();
                   2158:       return 1;
                   2159:     }
                   2160: 
                   2161:   _rl_free_match_list (matches);
                   2162: 
                   2163:   /* Check to see if the line has changed through all of this manipulation. */
                   2164:   if (saved_line_buffer)
                   2165:     {
                   2166:       completion_changed_buffer = strcmp (rl_line_buffer, saved_line_buffer) != 0;
                   2167:       xfree (saved_line_buffer);
                   2168:     }
                   2169: 
                   2170:   RL_UNSETSTATE(RL_STATE_COMPLETING);
                   2171:   _rl_reset_completion_state ();
1.1.1.2 ! misho    2172: 
        !          2173:   RL_CHECK_SIGNALS ();
1.1       misho    2174:   return 0;
                   2175: }
                   2176: 
                   2177: /***************************************************************/
                   2178: /*                                                            */
                   2179: /*  Application-callable completion match generator functions  */
                   2180: /*                                                            */
                   2181: /***************************************************************/
                   2182: 
                   2183: /* Return an array of (char *) which is a list of completions for TEXT.
                   2184:    If there are no completions, return a NULL pointer.
                   2185:    The first entry in the returned array is the substitution for TEXT.
                   2186:    The remaining entries are the possible completions.
                   2187:    The array is terminated with a NULL pointer.
                   2188: 
                   2189:    ENTRY_FUNCTION is a function of two args, and returns a (char *).
                   2190:      The first argument is TEXT.
                   2191:      The second is a state argument; it should be zero on the first call, and
                   2192:      non-zero on subsequent calls.  It returns a NULL pointer to the caller
                   2193:      when there are no more matches.
                   2194:  */
                   2195: char **
1.1.1.2 ! misho    2196: rl_completion_matches (const char *text, rl_compentry_func_t *entry_function)
1.1       misho    2197: {
                   2198:   register int i;
                   2199: 
                   2200:   /* Number of slots in match_list. */
                   2201:   int match_list_size;
                   2202: 
                   2203:   /* The list of matches. */
                   2204:   char **match_list;
                   2205: 
                   2206:   /* Number of matches actually found. */
                   2207:   int matches;
                   2208: 
                   2209:   /* Temporary string binder. */
                   2210:   char *string;
                   2211: 
                   2212:   matches = 0;
                   2213:   match_list_size = 10;
                   2214:   match_list = (char **)xmalloc ((match_list_size + 1) * sizeof (char *));
                   2215:   match_list[1] = (char *)NULL;
                   2216: 
                   2217:   while (string = (*entry_function) (text, matches))
                   2218:     {
                   2219:       if (RL_SIG_RECEIVED ())
                   2220:        {
                   2221:          /* Start at 1 because we don't set matches[0] in this function.
                   2222:             Only free the list members if we're building match list from
                   2223:             rl_filename_completion_function, since we know that doesn't
                   2224:             free the strings it returns. */
                   2225:          if (entry_function == rl_filename_completion_function)
                   2226:            {
                   2227:              for (i = 1; match_list[i]; i++)
                   2228:                xfree (match_list[i]);
                   2229:            }
                   2230:          xfree (match_list);
                   2231:          match_list = 0;
                   2232:          match_list_size = 0;
                   2233:          matches = 0;
                   2234:          RL_CHECK_SIGNALS ();
                   2235:        }
                   2236: 
                   2237:       if (matches + 1 >= match_list_size)
                   2238:        match_list = (char **)xrealloc
                   2239:          (match_list, ((match_list_size += 10) + 1) * sizeof (char *));
                   2240: 
                   2241:       if (match_list == 0)
                   2242:        return (match_list);
                   2243: 
                   2244:       match_list[++matches] = string;
                   2245:       match_list[matches + 1] = (char *)NULL;
                   2246:     }
                   2247: 
                   2248:   /* If there were any matches, then look through them finding out the
                   2249:      lowest common denominator.  That then becomes match_list[0]. */
                   2250:   if (matches)
                   2251:     compute_lcd_of_matches (match_list, matches, text);
                   2252:   else                         /* There were no matches. */
                   2253:     {
                   2254:       xfree (match_list);
                   2255:       match_list = (char **)NULL;
                   2256:     }
                   2257:   return (match_list);
                   2258: }
                   2259: 
                   2260: /* A completion function for usernames.
                   2261:    TEXT contains a partial username preceded by a random
                   2262:    character (usually `~').  */
                   2263: char *
1.1.1.2 ! misho    2264: rl_username_completion_function (const char *text, int state)
1.1       misho    2265: {
                   2266: #if defined (__WIN32__) || defined (__OPENNT)
                   2267:   return (char *)NULL;
                   2268: #else /* !__WIN32__ && !__OPENNT) */
                   2269:   static char *username = (char *)NULL;
                   2270:   static struct passwd *entry;
                   2271:   static int namelen, first_char, first_char_loc;
                   2272:   char *value;
                   2273: 
                   2274:   if (state == 0)
                   2275:     {
                   2276:       FREE (username);
                   2277: 
                   2278:       first_char = *text;
                   2279:       first_char_loc = first_char == '~';
                   2280: 
                   2281:       username = savestring (&text[first_char_loc]);
                   2282:       namelen = strlen (username);
                   2283: #if defined (HAVE_GETPWENT)
                   2284:       setpwent ();
                   2285: #endif
                   2286:     }
                   2287: 
                   2288: #if defined (HAVE_GETPWENT)
                   2289:   while (entry = getpwent ())
                   2290:     {
                   2291:       /* Null usernames should result in all users as possible completions. */
                   2292:       if (namelen == 0 || (STREQN (username, entry->pw_name, namelen)))
                   2293:        break;
                   2294:     }
                   2295: #endif
                   2296: 
                   2297:   if (entry == 0)
                   2298:     {
                   2299: #if defined (HAVE_GETPWENT)
                   2300:       endpwent ();
                   2301: #endif
                   2302:       return ((char *)NULL);
                   2303:     }
                   2304:   else
                   2305:     {
                   2306:       value = (char *)xmalloc (2 + strlen (entry->pw_name));
                   2307: 
                   2308:       *value = *text;
                   2309: 
                   2310:       strcpy (value + first_char_loc, entry->pw_name);
                   2311: 
                   2312:       if (first_char == '~')
                   2313:        rl_filename_completion_desired = 1;
                   2314: 
                   2315:       return (value);
                   2316:     }
                   2317: #endif /* !__WIN32__ && !__OPENNT */
                   2318: }
                   2319: 
                   2320: /* Return non-zero if CONVFN matches FILENAME up to the length of FILENAME
                   2321:    (FILENAME_LEN).  If _rl_completion_case_fold is set, compare without
                   2322:    regard to the alphabetic case of characters.  If
                   2323:    _rl_completion_case_map is set, make `-' and `_' equivalent.  CONVFN is
                   2324:    the possibly-converted directory entry; FILENAME is what the user typed. */
                   2325: static int
1.1.1.2 ! misho    2326: complete_fncmp (const char *convfn, int convlen, const char *filename, int filename_len)
1.1       misho    2327: {
                   2328:   register char *s1, *s2;
                   2329:   int d, len;
                   2330: #if defined (HANDLE_MULTIBYTE)
                   2331:   size_t v1, v2;
                   2332:   mbstate_t ps1, ps2;
                   2333:   wchar_t wc1, wc2;
                   2334: #endif
                   2335: 
                   2336: #if defined (HANDLE_MULTIBYTE)
                   2337:   memset (&ps1, 0, sizeof (mbstate_t));
                   2338:   memset (&ps2, 0, sizeof (mbstate_t));
                   2339: #endif
                   2340: 
                   2341:   if (filename_len == 0)
                   2342:     return 1;
                   2343:   if (convlen < filename_len)
                   2344:     return 0;
                   2345: 
                   2346:   len = filename_len;
                   2347:   s1 = (char *)convfn;
                   2348:   s2 = (char *)filename;
                   2349: 
                   2350:   /* Otherwise, if these match up to the length of filename, then
                   2351:      it is a match. */
                   2352:   if (_rl_completion_case_fold && _rl_completion_case_map)
                   2353:     {
                   2354:       /* Case-insensitive comparison treating _ and - as equivalent */
                   2355: #if defined (HANDLE_MULTIBYTE)
                   2356:       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
                   2357:        {
                   2358:          do
                   2359:            {
                   2360:              v1 = mbrtowc (&wc1, s1, convlen, &ps1);
                   2361:              v2 = mbrtowc (&wc2, s2, filename_len, &ps2);
                   2362:              if (v1 == 0 && v2 == 0)
                   2363:                return 1;
                   2364:              else if (MB_INVALIDCH (v1) || MB_INVALIDCH (v2))
                   2365:                {
                   2366:                  if (*s1 != *s2)               /* do byte comparison */
                   2367:                    return 0;
                   2368:                  else if ((*s1 == '-' || *s1 == '_') && (*s2 == '-' || *s2 == '_'))
                   2369:                    return 0;
                   2370:                  s1++; s2++; len--;
                   2371:                  continue;
                   2372:                }
                   2373:              wc1 = towlower (wc1);
                   2374:              wc2 = towlower (wc2);
                   2375:              s1 += v1;
                   2376:              s2 += v1;
                   2377:              len -= v1;
                   2378:              if ((wc1 == L'-' || wc1 == L'_') && (wc2 == L'-' || wc2 == L'_'))
                   2379:                continue;
                   2380:              if (wc1 != wc2)
                   2381:                return 0;
                   2382:            }
                   2383:          while (len != 0);
                   2384:        }
                   2385:       else
                   2386: #endif
                   2387:        {
                   2388:        do
                   2389:          {
                   2390:            d = _rl_to_lower (*s1) - _rl_to_lower (*s2);
                   2391:            /* *s1 == [-_] && *s2 == [-_] */
                   2392:            if ((*s1 == '-' || *s1 == '_') && (*s2 == '-' || *s2 == '_'))
                   2393:              d = 0;
                   2394:            if (d != 0)
                   2395:              return 0;
                   2396:            s1++; s2++; /* already checked convlen >= filename_len */
                   2397:          }
                   2398:        while (--len != 0);
                   2399:        }
                   2400: 
                   2401:       return 1;
                   2402:     }
                   2403:   else if (_rl_completion_case_fold)
                   2404:     {
                   2405: #if defined (HANDLE_MULTIBYTE)
                   2406:       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
                   2407:        {
                   2408:          do
                   2409:            {
                   2410:              v1 = mbrtowc (&wc1, s1, convlen, &ps1);
                   2411:              v2 = mbrtowc (&wc2, s2, filename_len, &ps2);
                   2412:              if (v1 == 0 && v2 == 0)
                   2413:                return 1;
                   2414:              else if (MB_INVALIDCH (v1) || MB_INVALIDCH (v2))
                   2415:                {
                   2416:                  if (*s1 != *s2)               /* do byte comparison */
                   2417:                    return 0;
                   2418:                  s1++; s2++; len--;
                   2419:                  continue;
                   2420:                }
                   2421:              wc1 = towlower (wc1);
                   2422:              wc2 = towlower (wc2);
                   2423:              if (wc1 != wc2)
                   2424:                return 0;
                   2425:              s1 += v1;
                   2426:              s2 += v1;
                   2427:              len -= v1;
                   2428:            }
                   2429:          while (len != 0);
                   2430:          return 1;
                   2431:        }
                   2432:       else
                   2433: #endif
                   2434:       if ((_rl_to_lower (convfn[0]) == _rl_to_lower (filename[0])) &&
                   2435:          (convlen >= filename_len) &&
                   2436:          (_rl_strnicmp (filename, convfn, filename_len) == 0))
                   2437:        return 1;
                   2438:     }
                   2439:   else
                   2440:     {
                   2441:       if ((convfn[0] == filename[0]) &&
                   2442:          (convlen >= filename_len) &&
                   2443:          (strncmp (filename, convfn, filename_len) == 0))
                   2444:        return 1;
                   2445:     }
                   2446:   return 0;
                   2447: }
                   2448: 
                   2449: /* Okay, now we write the entry_function for filename completion.  In the
                   2450:    general case.  Note that completion in the shell is a little different
                   2451:    because of all the pathnames that must be followed when looking up the
                   2452:    completion for a command. */
                   2453: char *
1.1.1.2 ! misho    2454: rl_filename_completion_function (const char *text, int state)
1.1       misho    2455: {
                   2456:   static DIR *directory = (DIR *)NULL;
                   2457:   static char *filename = (char *)NULL;
                   2458:   static char *dirname = (char *)NULL;
                   2459:   static char *users_dirname = (char *)NULL;
                   2460:   static int filename_len;
                   2461:   char *temp, *dentry, *convfn;
                   2462:   int dirlen, dentlen, convlen;
1.1.1.2 ! misho    2463:   int tilde_dirname;
1.1       misho    2464:   struct dirent *entry;
                   2465: 
                   2466:   /* If we don't have any state, then do some initialization. */
                   2467:   if (state == 0)
                   2468:     {
                   2469:       /* If we were interrupted before closing the directory or reading
                   2470:         all of its contents, close it. */
                   2471:       if (directory)
                   2472:        {
                   2473:          closedir (directory);
                   2474:          directory = (DIR *)NULL;
                   2475:        }
                   2476:       FREE (dirname);
                   2477:       FREE (filename);
                   2478:       FREE (users_dirname);
                   2479: 
                   2480:       filename = savestring (text);
                   2481:       if (*text == 0)
                   2482:        text = ".";
                   2483:       dirname = savestring (text);
                   2484: 
                   2485:       temp = strrchr (dirname, '/');
                   2486: 
1.1.1.2 ! misho    2487: #if defined (__MSDOS__) || defined (_WIN32)
1.1       misho    2488:       /* special hack for //X/... */
                   2489:       if (dirname[0] == '/' && dirname[1] == '/' && ISALPHA ((unsigned char)dirname[2]) && dirname[3] == '/')
                   2490:         temp = strrchr (dirname + 3, '/');
                   2491: #endif
                   2492: 
                   2493:       if (temp)
                   2494:        {
                   2495:          strcpy (filename, ++temp);
                   2496:          *temp = '\0';
                   2497:        }
1.1.1.2 ! misho    2498: #if defined (__MSDOS__) || (defined (_WIN32) && !defined (__CYGWIN__))
1.1       misho    2499:       /* searches from current directory on the drive */
                   2500:       else if (ISALPHA ((unsigned char)dirname[0]) && dirname[1] == ':')
                   2501:         {
                   2502:           strcpy (filename, dirname + 2);
                   2503:           dirname[2] = '\0';
                   2504:         }
                   2505: #endif
                   2506:       else
                   2507:        {
                   2508:          dirname[0] = '.';
                   2509:          dirname[1] = '\0';
                   2510:        }
                   2511: 
                   2512:       /* We aren't done yet.  We also support the "~user" syntax. */
                   2513: 
                   2514:       /* Save the version of the directory that the user typed, dequoting
                   2515:         it if necessary. */
                   2516:       if (rl_completion_found_quote && rl_filename_dequoting_function)
                   2517:        users_dirname = (*rl_filename_dequoting_function) (dirname, rl_completion_quote_character);
                   2518:       else
                   2519:        users_dirname = savestring (dirname);
                   2520: 
1.1.1.2 ! misho    2521:       tilde_dirname = 0;
1.1       misho    2522:       if (*dirname == '~')
                   2523:        {
                   2524:          temp = tilde_expand (dirname);
                   2525:          xfree (dirname);
                   2526:          dirname = temp;
1.1.1.2 ! misho    2527:          tilde_dirname = 1;
1.1       misho    2528:        }
                   2529: 
                   2530:       /* We have saved the possibly-dequoted version of the directory name
                   2531:         the user typed.  Now transform the directory name we're going to
                   2532:         pass to opendir(2).  The directory rewrite hook modifies only the
                   2533:         directory name; the directory completion hook modifies both the
                   2534:         directory name passed to opendir(2) and the version the user
                   2535:         typed.  Both the directory completion and rewrite hooks should perform
                   2536:         any necessary dequoting.  The hook functions return 1 if they modify
                   2537:         the directory name argument.  If either hook returns 0, it should
                   2538:         not modify the directory name pointer passed as an argument. */
                   2539:       if (rl_directory_rewrite_hook)
                   2540:        (*rl_directory_rewrite_hook) (&dirname);
                   2541:       else if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&dirname))
                   2542:        {
                   2543:          xfree (users_dirname);
                   2544:          users_dirname = savestring (dirname);
                   2545:        }
1.1.1.2 ! misho    2546:       else if (tilde_dirname == 0 && rl_completion_found_quote && rl_filename_dequoting_function)
1.1       misho    2547:        {
                   2548:          /* delete single and double quotes */
                   2549:          xfree (dirname);
                   2550:          dirname = savestring (users_dirname);
                   2551:        }
                   2552:       directory = opendir (dirname);
                   2553: 
                   2554:       /* Now dequote a non-null filename.  FILENAME will not be NULL, but may
                   2555:         be empty. */
                   2556:       if (*filename && rl_completion_found_quote && rl_filename_dequoting_function)
                   2557:        {
                   2558:          /* delete single and double quotes */
                   2559:          temp = (*rl_filename_dequoting_function) (filename, rl_completion_quote_character);
                   2560:          xfree (filename);
                   2561:          filename = temp;
                   2562:        }
                   2563:       filename_len = strlen (filename);
                   2564: 
                   2565:       rl_filename_completion_desired = 1;
                   2566:     }
                   2567: 
                   2568:   /* At this point we should entertain the possibility of hacking wildcarded
                   2569:      filenames, like /usr/man/man<WILD>/te<TAB>.  If the directory name
                   2570:      contains globbing characters, then build an array of directories, and
                   2571:      then map over that list while completing. */
                   2572:   /* *** UNIMPLEMENTED *** */
                   2573: 
                   2574:   /* Now that we have some state, we can read the directory. */
                   2575: 
                   2576:   entry = (struct dirent *)NULL;
                   2577:   while (directory && (entry = readdir (directory)))
                   2578:     {
                   2579:       convfn = dentry = entry->d_name;
                   2580:       convlen = dentlen = D_NAMLEN (entry);
                   2581: 
                   2582:       if (rl_filename_rewrite_hook)
                   2583:        {
                   2584:          convfn = (*rl_filename_rewrite_hook) (dentry, dentlen);
                   2585:          convlen = (convfn == dentry) ? dentlen : strlen (convfn);
                   2586:        }
                   2587: 
                   2588:       /* Special case for no filename.  If the user has disabled the
                   2589:          `match-hidden-files' variable, skip filenames beginning with `.'.
                   2590:         All other entries except "." and ".." match. */
                   2591:       if (filename_len == 0)
                   2592:        {
                   2593:          if (_rl_match_hidden_files == 0 && HIDDEN_FILE (convfn))
                   2594:            continue;
                   2595: 
                   2596:          if (convfn[0] != '.' ||
                   2597:               (convfn[1] && (convfn[1] != '.' || convfn[2])))
                   2598:            break;
                   2599:        }
                   2600:       else
                   2601:        {
                   2602:          if (complete_fncmp (convfn, convlen, filename, filename_len))
                   2603:            break;
                   2604:        }
                   2605:     }
                   2606: 
                   2607:   if (entry == 0)
                   2608:     {
                   2609:       if (directory)
                   2610:        {
                   2611:          closedir (directory);
                   2612:          directory = (DIR *)NULL;
                   2613:        }
                   2614:       if (dirname)
                   2615:        {
                   2616:          xfree (dirname);
                   2617:          dirname = (char *)NULL;
                   2618:        }
                   2619:       if (filename)
                   2620:        {
                   2621:          xfree (filename);
                   2622:          filename = (char *)NULL;
                   2623:        }
                   2624:       if (users_dirname)
                   2625:        {
                   2626:          xfree (users_dirname);
                   2627:          users_dirname = (char *)NULL;
                   2628:        }
                   2629: 
                   2630:       return (char *)NULL;
                   2631:     }
                   2632:   else
                   2633:     {
                   2634:       /* dirname && (strcmp (dirname, ".") != 0) */
                   2635:       if (dirname && (dirname[0] != '.' || dirname[1]))
                   2636:        {
                   2637:          if (rl_complete_with_tilde_expansion && *users_dirname == '~')
                   2638:            {
                   2639:              dirlen = strlen (dirname);
                   2640:              temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry));
                   2641:              strcpy (temp, dirname);
                   2642:              /* Canonicalization cuts off any final slash present.  We
                   2643:                 may need to add it back. */
                   2644:              if (dirname[dirlen - 1] != '/')
                   2645:                {
                   2646:                  temp[dirlen++] = '/';
                   2647:                  temp[dirlen] = '\0';
                   2648:                }
                   2649:            }
                   2650:          else
                   2651:            {
                   2652:              dirlen = strlen (users_dirname);
                   2653:              temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry));
                   2654:              strcpy (temp, users_dirname);
                   2655:              /* Make sure that temp has a trailing slash here. */
                   2656:              if (users_dirname[dirlen - 1] != '/')
                   2657:                temp[dirlen++] = '/';
                   2658:            }
                   2659: 
                   2660:          strcpy (temp + dirlen, convfn);
                   2661:        }
                   2662:       else
                   2663:        temp = savestring (convfn);
                   2664: 
                   2665:       if (convfn != dentry)
                   2666:        xfree (convfn);
                   2667: 
                   2668:       return (temp);
                   2669:     }
                   2670: }
                   2671: 
                   2672: /* An initial implementation of a menu completion function a la tcsh.  The
                   2673:    first time (if the last readline command was not rl_old_menu_complete), we
                   2674:    generate the list of matches.  This code is very similar to the code in
                   2675:    rl_complete_internal -- there should be a way to combine the two.  Then,
                   2676:    for each item in the list of matches, we insert the match in an undoable
                   2677:    fashion, with the appropriate character appended (this happens on the
                   2678:    second and subsequent consecutive calls to rl_old_menu_complete).  When we
                   2679:    hit the end of the match list, we restore the original unmatched text,
                   2680:    ring the bell, and reset the counter to zero. */
                   2681: int
1.1.1.2 ! misho    2682: rl_old_menu_complete (int count, int invoking_key)
1.1       misho    2683: {
                   2684:   rl_compentry_func_t *our_func;
                   2685:   int matching_filenames, found_quote;
                   2686: 
                   2687:   static char *orig_text;
                   2688:   static char **matches = (char **)0;
                   2689:   static int match_list_index = 0;
                   2690:   static int match_list_size = 0;
                   2691:   static int orig_start, orig_end;
                   2692:   static char quote_char;
                   2693:   static int delimiter;
                   2694: 
                   2695:   /* The first time through, we generate the list of matches and set things
                   2696:      up to insert them. */
                   2697:   if (rl_last_func != rl_old_menu_complete)
                   2698:     {
                   2699:       /* Clean up from previous call, if any. */
                   2700:       FREE (orig_text);
                   2701:       if (matches)
                   2702:        _rl_free_match_list (matches);
                   2703: 
                   2704:       match_list_index = match_list_size = 0;
                   2705:       matches = (char **)NULL;
                   2706: 
                   2707:       rl_completion_invoking_key = invoking_key;
                   2708: 
                   2709:       RL_SETSTATE(RL_STATE_COMPLETING);
                   2710: 
                   2711:       /* Only the completion entry function can change these. */
                   2712:       set_completion_defaults ('%');
                   2713: 
                   2714:       our_func = rl_menu_completion_entry_function;
                   2715:       if (our_func == 0)
                   2716:        our_func = rl_completion_entry_function
                   2717:                        ? rl_completion_entry_function
                   2718:                        : rl_filename_completion_function;
                   2719: 
                   2720:       /* We now look backwards for the start of a filename/variable word. */
                   2721:       orig_end = rl_point;
                   2722:       found_quote = delimiter = 0;
                   2723:       quote_char = '\0';
                   2724: 
                   2725:       if (rl_point)
                   2726:        /* This (possibly) changes rl_point.  If it returns a non-zero char,
                   2727:           we know we have an open quote. */
                   2728:        quote_char = _rl_find_completion_word (&found_quote, &delimiter);
                   2729: 
                   2730:       orig_start = rl_point;
                   2731:       rl_point = orig_end;
                   2732: 
                   2733:       orig_text = rl_copy_text (orig_start, orig_end);
                   2734:       matches = gen_completion_matches (orig_text, orig_start, orig_end,
                   2735:                                        our_func, found_quote, quote_char);
                   2736: 
                   2737:       /* If we are matching filenames, the attempted completion function will
                   2738:         have set rl_filename_completion_desired to a non-zero value.  The basic
                   2739:         rl_filename_completion_function does this. */
                   2740:       matching_filenames = rl_filename_completion_desired;
                   2741: 
                   2742:       if (matches == 0 || postprocess_matches (&matches, matching_filenames) == 0)
                   2743:        {
                   2744:          rl_ding ();
                   2745:          FREE (matches);
                   2746:          matches = (char **)0;
                   2747:          FREE (orig_text);
                   2748:          orig_text = (char *)0;
                   2749:          completion_changed_buffer = 0;
                   2750:          RL_UNSETSTATE(RL_STATE_COMPLETING);
                   2751:          return (0);
                   2752:        }
                   2753: 
                   2754:       RL_UNSETSTATE(RL_STATE_COMPLETING);
                   2755: 
                   2756:       for (match_list_size = 0; matches[match_list_size]; match_list_size++)
                   2757:         ;
                   2758:       /* matches[0] is lcd if match_list_size > 1, but the circular buffer
                   2759:         code below should take care of it. */
                   2760: 
                   2761:       if (match_list_size > 1 && _rl_complete_show_all)
                   2762:        display_matches (matches);
                   2763:     }
                   2764: 
                   2765:   /* Now we have the list of matches.  Replace the text between
                   2766:      rl_line_buffer[orig_start] and rl_line_buffer[rl_point] with
                   2767:      matches[match_list_index], and add any necessary closing char. */
                   2768: 
                   2769:   if (matches == 0 || match_list_size == 0) 
                   2770:     {
                   2771:       rl_ding ();
                   2772:       FREE (matches);
                   2773:       matches = (char **)0;
                   2774:       completion_changed_buffer = 0;
                   2775:       return (0);
                   2776:     }
                   2777: 
                   2778:   match_list_index += count;
                   2779:   if (match_list_index < 0)
                   2780:     {
                   2781:       while (match_list_index < 0)
                   2782:        match_list_index += match_list_size;
                   2783:     }
                   2784:   else
                   2785:     match_list_index %= match_list_size;
                   2786: 
                   2787:   if (match_list_index == 0 && match_list_size > 1)
                   2788:     {
                   2789:       rl_ding ();
                   2790:       insert_match (orig_text, orig_start, MULT_MATCH, &quote_char);
                   2791:     }
                   2792:   else
                   2793:     {
                   2794:       insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, &quote_char);
                   2795:       append_to_match (matches[match_list_index], delimiter, quote_char,
1.1.1.2 ! misho    2796:                       compare_match (orig_text, matches[match_list_index]));
1.1       misho    2797:     }
                   2798: 
                   2799:   completion_changed_buffer = 1;
                   2800:   return (0);
                   2801: }
                   2802: 
1.1.1.2 ! misho    2803: /* The current version of menu completion.
        !          2804:    The differences between this function and the original are:
        !          2805: 
        !          2806: 1. It honors the maximum number of completions variable (completion-query-items)
        !          2807: 2. It appends to the word as usual if there is only one match
        !          2808: 3. It displays the common prefix if there is one, and makes it the first menu
        !          2809:    choice if the menu-complete-display-prefix option is enabled
        !          2810: */
        !          2811:  
1.1       misho    2812: int
1.1.1.2 ! misho    2813: rl_menu_complete (int count, int ignore)
1.1       misho    2814: {
                   2815:   rl_compentry_func_t *our_func;
                   2816:   int matching_filenames, found_quote;
                   2817: 
                   2818:   static char *orig_text;
                   2819:   static char **matches = (char **)0;
                   2820:   static int match_list_index = 0;
                   2821:   static int match_list_size = 0;
                   2822:   static int nontrivial_lcd = 0;
                   2823:   static int full_completion = 0;      /* set to 1 if menu completion should reinitialize on next call */
                   2824:   static int orig_start, orig_end;
                   2825:   static char quote_char;
                   2826:   static int delimiter, cstate;
                   2827: 
                   2828:   /* The first time through, we generate the list of matches and set things
                   2829:      up to insert them. */
                   2830:   if ((rl_last_func != rl_menu_complete && rl_last_func != rl_backward_menu_complete) || full_completion)
                   2831:     {
                   2832:       /* Clean up from previous call, if any. */
                   2833:       FREE (orig_text);
                   2834:       if (matches)
                   2835:        _rl_free_match_list (matches);
                   2836: 
                   2837:       match_list_index = match_list_size = 0;
                   2838:       matches = (char **)NULL;
                   2839: 
                   2840:       full_completion = 0;
                   2841: 
                   2842:       RL_SETSTATE(RL_STATE_COMPLETING);
                   2843: 
                   2844:       /* Only the completion entry function can change these. */
                   2845:       set_completion_defaults ('%');
                   2846: 
                   2847:       our_func = rl_menu_completion_entry_function;
                   2848:       if (our_func == 0)
                   2849:        our_func = rl_completion_entry_function
                   2850:                        ? rl_completion_entry_function
                   2851:                        : rl_filename_completion_function;
                   2852: 
                   2853:       /* We now look backwards for the start of a filename/variable word. */
                   2854:       orig_end = rl_point;
                   2855:       found_quote = delimiter = 0;
                   2856:       quote_char = '\0';
                   2857: 
                   2858:       if (rl_point)
                   2859:        /* This (possibly) changes rl_point.  If it returns a non-zero char,
                   2860:           we know we have an open quote. */
                   2861:        quote_char = _rl_find_completion_word (&found_quote, &delimiter);
                   2862: 
                   2863:       orig_start = rl_point;
                   2864:       rl_point = orig_end;
                   2865: 
                   2866:       orig_text = rl_copy_text (orig_start, orig_end);
                   2867:       matches = gen_completion_matches (orig_text, orig_start, orig_end,
                   2868:                                        our_func, found_quote, quote_char);
                   2869: 
1.1.1.2 ! misho    2870:       nontrivial_lcd = matches && compare_match (orig_text, matches[0]) != 0;
1.1       misho    2871: 
                   2872:       /* If we are matching filenames, the attempted completion function will
                   2873:         have set rl_filename_completion_desired to a non-zero value.  The basic
                   2874:         rl_filename_completion_function does this. */
                   2875:       matching_filenames = rl_filename_completion_desired;
                   2876: 
                   2877:       if (matches == 0 || postprocess_matches (&matches, matching_filenames) == 0)
                   2878:        {
                   2879:          rl_ding ();
                   2880:          FREE (matches);
                   2881:          matches = (char **)0;
                   2882:          FREE (orig_text);
                   2883:          orig_text = (char *)0;
                   2884:          completion_changed_buffer = 0;
                   2885:          RL_UNSETSTATE(RL_STATE_COMPLETING);
                   2886:          return (0);
                   2887:        }
                   2888: 
                   2889:       RL_UNSETSTATE(RL_STATE_COMPLETING);
                   2890: 
                   2891:       for (match_list_size = 0; matches[match_list_size]; match_list_size++)
                   2892:         ;
                   2893: 
                   2894:       if (match_list_size == 0) 
                   2895:        {
                   2896:          rl_ding ();
                   2897:          FREE (matches);
                   2898:          matches = (char **)0;
                   2899:          match_list_index = 0;
                   2900:          completion_changed_buffer = 0;
                   2901:          return (0);
                   2902:         }
                   2903: 
                   2904:       /* matches[0] is lcd if match_list_size > 1, but the circular buffer
                   2905:         code below should take care of it. */
                   2906:       if (*matches[0])
                   2907:        {
                   2908:          insert_match (matches[0], orig_start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
                   2909:          orig_end = orig_start + strlen (matches[0]);
                   2910:          completion_changed_buffer = STREQ (orig_text, matches[0]) == 0;
                   2911:        }
                   2912: 
                   2913:       if (match_list_size > 1 && _rl_complete_show_all)
                   2914:        {
                   2915:          display_matches (matches);
                   2916:          /* If there are so many matches that the user has to be asked
                   2917:             whether or not he wants to see the matches, menu completion
                   2918:             is unwieldy. */
                   2919:          if (rl_completion_query_items > 0 && match_list_size >= rl_completion_query_items)
                   2920:            {
                   2921:              rl_ding ();
                   2922:              FREE (matches);
                   2923:              matches = (char **)0;
                   2924:              full_completion = 1;
                   2925:              return (0);
                   2926:            }
                   2927:          else if (_rl_menu_complete_prefix_first)
                   2928:            {
                   2929:              rl_ding ();
                   2930:              return (0);
                   2931:            }
                   2932:        }
                   2933:       else if (match_list_size <= 1)
                   2934:        {
                   2935:          append_to_match (matches[0], delimiter, quote_char, nontrivial_lcd);
                   2936:          full_completion = 1;
                   2937:          return (0);
                   2938:        }
                   2939:       else if (_rl_menu_complete_prefix_first && match_list_size > 1)
                   2940:        {
                   2941:          rl_ding ();
                   2942:          return (0);
                   2943:        }
                   2944:     }
                   2945: 
                   2946:   /* Now we have the list of matches.  Replace the text between
                   2947:      rl_line_buffer[orig_start] and rl_line_buffer[rl_point] with
                   2948:      matches[match_list_index], and add any necessary closing char. */
                   2949: 
                   2950:   if (matches == 0 || match_list_size == 0) 
                   2951:     {
                   2952:       rl_ding ();
                   2953:       FREE (matches);
                   2954:       matches = (char **)0;
                   2955:       completion_changed_buffer = 0;
                   2956:       return (0);
                   2957:     }
                   2958: 
                   2959:   match_list_index += count;
                   2960:   if (match_list_index < 0)
                   2961:     {
                   2962:       while (match_list_index < 0)
                   2963:        match_list_index += match_list_size;
                   2964:     }
                   2965:   else
                   2966:     match_list_index %= match_list_size;
                   2967: 
                   2968:   if (match_list_index == 0 && match_list_size > 1)
                   2969:     {
                   2970:       rl_ding ();
                   2971:       insert_match (matches[0], orig_start, MULT_MATCH, &quote_char);
                   2972:     }
                   2973:   else
                   2974:     {
                   2975:       insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, &quote_char);
                   2976:       append_to_match (matches[match_list_index], delimiter, quote_char,
1.1.1.2 ! misho    2977:                       compare_match (orig_text, matches[match_list_index]));
1.1       misho    2978:     }
                   2979: 
                   2980:   completion_changed_buffer = 1;
                   2981:   return (0);
                   2982: }
                   2983: 
                   2984: int
1.1.1.2 ! misho    2985: rl_backward_menu_complete (int count, int key)
1.1       misho    2986: {
                   2987:   /* Positive arguments to backward-menu-complete translate into negative
                   2988:      arguments for menu-complete, and vice versa. */
                   2989:   return (rl_menu_complete (-count, key));
                   2990: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>