1/* $FreeBSD: head/contrib/libreadline/complete.c 157188 2006-03-27 23:11:32Z ache $ */ |
2/* complete.c -- filename completion for readline. */ 3 |
4/* Copyright (C) 1987-2005 Free Software Foundation, Inc. |
5 6 This file is part of the GNU Readline Library, a library for 7 reading lines of text with interactive input and history editing. 8 9 The GNU Readline Library is free software; you can redistribute it 10 and/or modify it under the terms of the GNU General Public License 11 as published by the Free Software Foundation; either version 2, or 12 (at your option) any later version. --- 31 unchanged lines hidden (view full) --- 44 45#include <stdio.h> 46 47#include <errno.h> 48#if !defined (errno) 49extern int errno; 50#endif /* !errno */ 51 |
52#if defined (HAVE_PWD_H) |
53#include <pwd.h> |
54#endif |
55 56#include "posixdir.h" 57#include "posixstat.h" 58 59/* System-specific feature definitions and include files. */ 60#include "rldefs.h" 61#include "rlmbutil.h" 62 --- 14 unchanged lines hidden (view full) --- 77# define LSTAT stat 78#endif 79 80/* Unix version of a hidden file. Could be different on other systems. */ 81#define HIDDEN_FILE(fname) ((fname)[0] == '.') 82 83/* Most systems don't declare getpwent in <pwd.h> if _POSIX_SOURCE is 84 defined. */ |
85#if defined (HAVE_GETPWENT) && (!defined (HAVE_GETPW_DECLS) || defined (_POSIX_SOURCE)) |
86extern struct passwd *getpwent PARAMS((void)); |
87#endif /* HAVE_GETPWENT && (!HAVE_GETPW_DECLS || _POSIX_SOURCE) */ |
88 89/* If non-zero, then this is the address of a function to call when 90 completing a word would normally display the list of possible matches. 91 This function is called instead of actually doing the display. 92 It takes three arguments: (char **matches, int num_matches, int max_length) 93 where MATCHES is the array of strings that matched, NUM_MATCHES is the 94 number of strings in that array, and MAX_LENGTH is the length of the 95 longest string in that array. */ --- 108 unchanged lines hidden (view full) --- 204 205/* Set to a character indicating the type of completion being performed 206 by rl_complete_internal, available for use by application completion 207 functions. */ 208int rl_completion_type = 0; 209 210/* Up to this many items will be displayed in response to a 211 possible-completions call. After that, we ask the user if |
212 she is sure she wants to see them all. A negative value means 213 don't ask. */ |
214int rl_completion_query_items = 100; 215 216int _rl_page_completions = 1; 217 218/* The basic list of characters that signal a break between words for the 219 completer routine. The contents of this variable is what breaks words 220 in the shell, i.e. " \t\n\"\\'`@$><=" */ 221const char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{("; /* }) */ --- 398 unchanged lines hidden (view full) --- 620 const char *to_print; 621{ 622 int printed_len; 623 const char *s; 624#if defined (HANDLE_MULTIBYTE) 625 mbstate_t ps; 626 const char *end; 627 size_t tlen; |
628 int width, w; 629 wchar_t wc; |
630 631 end = to_print + strlen (to_print) + 1; 632 memset (&ps, 0, sizeof (mbstate_t)); 633#endif 634 635 printed_len = 0; 636 s = to_print; 637 while (*s) --- 16 unchanged lines hidden (view full) --- 654 s++; 655#if defined (HANDLE_MULTIBYTE) 656 memset (&ps, 0, sizeof (mbstate_t)); 657#endif 658 } 659 else 660 { 661#if defined (HANDLE_MULTIBYTE) |
662 tlen = mbrtowc (&wc, s, end - s, &ps); |
663 if (MB_INVALIDCH (tlen)) 664 { 665 tlen = 1; |
666 width = 1; |
667 memset (&ps, 0, sizeof (mbstate_t)); 668 } 669 else if (MB_NULLWCH (tlen)) 670 break; |
671 else 672 { 673 w = wcwidth (wc); 674 width = (w >= 0) ? w : 1; 675 } |
676 fwrite (s, 1, tlen, rl_outstream); 677 s += tlen; |
678 printed_len += width; |
679#else 680 putc (*s, rl_outstream); 681 s++; |
682 printed_len++; |
683#endif |
684 } 685 } 686 687 return printed_len; 688} 689 690/* Output TO_PRINT to rl_outstream. If VISIBLE_STATS is defined and we 691 are using it, check for and output a single character for `special' 692 filenames. Return the number of characters we output. */ 693 694static int 695print_filename (to_print, full_pathname) 696 char *to_print, *full_pathname; 697{ 698 int printed_len, extension_char, slen, tlen; |
699 char *s, c, *new_full_pathname, *dn; |
700 701 extension_char = 0; 702 printed_len = fnprint (to_print); 703 704#if defined (VISIBLE_STATS) 705 if (rl_filename_completion_desired && (rl_visible_stats || _rl_complete_mark_directories)) 706#else 707 if (rl_filename_completion_desired && _rl_complete_mark_directories) --- 8 unchanged lines hidden (view full) --- 716 c = to_print[-1]; 717 to_print[-1] = '\0'; 718 719 /* If setting the last slash in full_pathname to a NUL results in 720 full_pathname being the empty string, we are trying to complete 721 files in the root directory. If we pass a null string to the 722 bash directory completion hook, for example, it will expand it 723 to the current directory. We just want the `/'. */ |
724 if (full_pathname == 0 || *full_pathname == 0) 725 dn = "/"; 726 else if (full_pathname[0] != '/') 727 dn = full_pathname; 728 else if (full_pathname[1] == 0) 729 dn = "//"; /* restore trailing slash to `//' */ 730 else if (full_pathname[1] == '/' && full_pathname[2] == 0) 731 dn = "/"; /* don't turn /// into // */ 732 else 733 dn = full_pathname; 734 s = tilde_expand (dn); |
735 if (rl_directory_completion_hook) 736 (*rl_directory_completion_hook) (&s); 737 738 slen = strlen (s); 739 tlen = strlen (to_print); 740 new_full_pathname = (char *)xmalloc (slen + tlen + 2); 741 strcpy (new_full_pathname, s); |
742 if (s[slen - 1] == '/') 743 slen--; 744 else 745 new_full_pathname[slen] = '/'; |
746 new_full_pathname[slen] = '/'; 747 strcpy (new_full_pathname + slen + 1, to_print); 748 749#if defined (VISIBLE_STATS) 750 if (rl_visible_stats) 751 extension_char = stat_char (new_full_pathname); 752 else 753#endif --- 75 unchanged lines hidden (view full) --- 829 brkchars = rl_completer_word_break_characters; 830 831 if (rl_completer_quote_characters) 832 { 833 /* We have a list of characters which can be used in pairs to 834 quote substrings for the completer. Try to find the start 835 of an unclosed quoted substring. */ 836 /* FOUND_QUOTE is set so we know what kind of quotes we found. */ |
837 for (scan = pass_next = 0; scan < end; scan = MB_NEXTCHAR (rl_line_buffer, scan, 1, MB_FIND_ANY)) |
838 { 839 if (pass_next) 840 { 841 pass_next = 0; 842 continue; 843 } 844 845 /* Shell-like semantics for single quotes -- don't allow backslash --- 33 unchanged lines hidden (view full) --- 879 } 880 } 881 882 if (rl_point == end && quote_char == '\0') 883 { 884 /* We didn't find an unclosed quoted substring upon which to do 885 completion, so use the word break characters to find the 886 substring on which to complete. */ |
887 while (rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_ANY)) |
888 { 889 scan = rl_line_buffer[rl_point]; 890 891 if (strchr (brkchars, scan) == 0) 892 continue; 893 894 /* Call the application-specific function to tell us whether 895 this word break character is quoted and should be skipped. */ --- 266 unchanged lines hidden (view full) --- 1162 check against the list of matches 1163 FI */ 1164 dtext = (char *)NULL; 1165 if (rl_filename_completion_desired && 1166 rl_filename_dequoting_function && 1167 rl_completion_found_quote && 1168 rl_filename_quoting_desired) 1169 { |
1170 dtext = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character); |
1171 text = dtext; 1172 } 1173 1174 /* sort the list to get consistent answers. */ 1175 qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare); 1176 1177 si = strlen (text); 1178 if (si <= low) --- 229 unchanged lines hidden (view full) --- 1408 if (rl_completion_display_matches_hook) 1409 { 1410 (*rl_completion_display_matches_hook) (matches, len, max); 1411 return; 1412 } 1413 1414 /* If there are many items, then ask the user if she really wants to 1415 see them all. */ |
1416 if (rl_completion_query_items > 0 && len >= rl_completion_query_items) |
1417 { 1418 rl_crlf (); 1419 fprintf (rl_outstream, "Display all %d possibilities? (y or n)", len); 1420 fflush (rl_outstream); 1421 if (get_y_or_n (0) == 0) 1422 { 1423 rl_crlf (); 1424 --- 120 unchanged lines hidden (view full) --- 1545 if (rl_filename_completion_desired) 1546 { 1547 filename = tilde_expand (text); 1548 s = (nontrivial_match && rl_completion_mark_symlink_dirs == 0) 1549 ? LSTAT (filename, &finfo) 1550 : stat (filename, &finfo); 1551 if (s == 0 && S_ISDIR (finfo.st_mode)) 1552 { |
1553 if (_rl_complete_mark_directories /* && rl_completion_suppress_append == 0 */) |
1554 { 1555 /* This is clumsy. Avoid putting in a double slash if point 1556 is at the end of the line and the previous character is a 1557 slash. */ 1558 if (rl_point && rl_line_buffer[rl_point] == '\0' && rl_line_buffer[rl_point - 1] == '/') 1559 ; 1560 else if (rl_line_buffer[rl_point] != '/') 1561 rl_insert_text ("/"); --- 297 unchanged lines hidden (view full) --- 1859 first_char = *text; 1860 first_char_loc = first_char == '~'; 1861 1862 username = savestring (&text[first_char_loc]); 1863 namelen = strlen (username); 1864 setpwent (); 1865 } 1866 |
1867#if defined (HAVE_GETPWENT) |
1868 while (entry = getpwent ()) 1869 { 1870 /* Null usernames should result in all users as possible completions. */ 1871 if (namelen == 0 || (STREQN (username, entry->pw_name, namelen))) 1872 break; 1873 } |
1874#endif |
1875 1876 if (entry == 0) 1877 { |
1878#if defined (HAVE_GETPWENT) |
1879 endpwent (); |
1880#endif |
1881 return ((char *)NULL); 1882 } 1883 else 1884 { 1885 value = (char *)xmalloc (2 + strlen (entry->pw_name)); 1886 1887 *value = *text; 1888 --- 295 unchanged lines hidden (view full) --- 2184 { 2185 rl_ding (); 2186 FREE (matches); 2187 matches = (char **)0; 2188 completion_changed_buffer = 0; 2189 return (0); 2190 } 2191 |
2192 match_list_index += count; |
2193 if (match_list_index < 0) 2194 match_list_index += match_list_size; |
2195 else 2196 match_list_index %= match_list_size; |
2197 2198 if (match_list_index == 0 && match_list_size > 1) 2199 { 2200 rl_ding (); 2201 insert_match (orig_text, orig_start, MULT_MATCH, "e_char); 2202 } 2203 else 2204 { 2205 insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, "e_char); 2206 append_to_match (matches[match_list_index], delimiter, quote_char, 2207 strcmp (orig_text, matches[match_list_index])); 2208 } 2209 2210 completion_changed_buffer = 1; 2211 return (0); 2212} |