* elf.c (bfd_section_from_shdr): Make "name" const.
[deliverable/binutils-gdb.git] / readline / complete.c
index 985e8981eee66fc9a5d3222af0e91fc9ae77a224..fb48712a4e0684be4e59dd9fe3b13a1fcf1de605 100644 (file)
@@ -7,7 +7,7 @@
 
    The GNU Readline Library is free software; you can redistribute it
    and/or modify it under the terms of the GNU General Public License
-   as published by the Free Software Foundation; either version 1, or
+   as published by the Free Software Foundation; either version 2, or
    (at your option) any later version.
 
    The GNU Readline Library is distributed in the hope that it will be
@@ -18,7 +18,7 @@
    The GNU General Public License is often shipped with GNU software, and
    is generally kept in a file called COPYING or LICENSE.  If you do not
    have a copy of the license, write to the Free Software Foundation,
-   675 Mass Ave, Cambridge, MA 02139, USA. */
+   59 Temple Place, Suite 330, Boston, MA 02111 USA. */
 #define READLINE_LIBRARY
 
 #if defined (HAVE_CONFIG_H)
@@ -70,43 +70,44 @@ extern struct passwd *getpwent ();
 
 /* Some standard library routines. */
 #include "readline.h"
+#include "xmalloc.h"
+#include "rlprivate.h"
 
-extern char *tilde_expand ();
-extern char *rl_copy_text ();
-extern void _rl_abort_internal ();
-extern int _rl_qsort_string_compare ();
-extern void _rl_replace_text ();
-
-extern Function *rl_last_func;
-extern int rl_editing_mode;
-extern int screenwidth;
+#ifdef __STDC__
+typedef int QSFUNC (const void *, const void *);
+#else
+typedef int QSFUNC ();
+#endif
 
-extern void _rl_move_vert ();
-extern int _rl_vis_botlin;
-extern int rl_display_fixed;
+/* If non-zero, then this is the address of a function to call when
+   completing a word would normally display the list of possible matches.
+   This function is called instead of actually doing the display.
+   It takes three arguments: (char **matches, int num_matches, int max_length)
+   where MATCHES is the array of strings that matched, NUM_MATCHES is the
+   number of strings in that array, and MAX_LENGTH is the length of the
+   longest string in that array. */
+VFunction *rl_completion_display_matches_hook = (VFunction *)NULL;
 
 /* Forward declarations for functions defined and used in this file. */
-char *filename_completion_function ();
-char **completion_matches ();
+char *filename_completion_function __P((char *, int));
+char **completion_matches __P((char *, CPFunction *));
 
 #if defined (VISIBLE_STATS)
 #  if !defined (X_OK)
 #    define X_OK 1
 #  endif
-static int stat_char ();
+static int stat_char __P((char *));
 #endif
 
-static char *rl_quote_filename ();
-static char *rl_strpbrk ();
-
-static char **remove_duplicate_matches ();
-static void insert_match ();
-static int append_to_match ();
-static void insert_all_matches ();
-static void display_matches ();
-static int compute_lcd_of_matches ();
+static char *rl_quote_filename __P((char *, int, char *));
+static char *rl_strpbrk __P((char *, char *));
 
-extern char *xmalloc (), *xrealloc ();
+static char **remove_duplicate_matches __P((char **));
+static void insert_match __P((char *, int, int, char *));
+static int append_to_match __P((char *, int, int));
+static void insert_all_matches __P((char **, int, char *));
+static void display_matches __P((char **));
+static int compute_lcd_of_matches __P((char **, int, char *));
 
 /* **************************************************************** */
 /*                                                                 */
@@ -127,7 +128,11 @@ int _rl_complete_mark_directories = 1;
 int _rl_print_completions_horizontally;
 
 /* Non-zero means that case is not significant in filename completion. */
+#if defined (__MSDOS__) && !defined (__DJGPP__)
+int _rl_completion_case_fold = 1;
+#else
 int _rl_completion_case_fold;
+#endif
 
 /* Global variables available to applications using readline. */
 
@@ -408,6 +413,10 @@ printable_part (pathname)
   char *temp;
 
   temp = rl_filename_completion_desired ? strrchr (pathname, '/') : (char *)NULL;
+#if defined (__MSDOS__)
+  if (rl_filename_completion_desired && temp == 0 && isalpha (pathname[0]) && pathname[1] == ':')
+    temp = pathname + 1;
+#endif
   return (temp ? ++temp : pathname);
 }
 
@@ -468,7 +477,12 @@ print_filename (to_print, full_pathname)
          c = to_print[-1];
          to_print[-1] = '\0';
 
-         s = tilde_expand (full_pathname);
+         /* If setting the last slash in full_pathname to a NUL results in
+            full_pathname being the empty string, we are trying to complete
+            files in the root directory.  If we pass a null string to the
+            bash directory completion hook, for example, it will expand it
+            to the current directory.  We just want the `/'. */
+         s = tilde_expand (full_pathname && *full_pathname ? full_pathname : "/");
          if (rl_directory_completion_hook)
            (*rl_directory_completion_hook) (&s);
 
@@ -618,25 +632,31 @@ find_completion_word (fp, dp)
   /* If there is an application-specific function to say whether or not
      a character is quoted and we found a quote character, let that
      function decide whether or not a character is a word break, even
-     if it is found in rl_completer_word_break_characters. */
-  if (rl_char_is_quoted_p)
-    isbrk = (found_quote == 0 ||
-               (*rl_char_is_quoted_p) (rl_line_buffer, rl_point) == 0) &&
-             strchr (rl_completer_word_break_characters, scan) != 0;
-  else
-    isbrk = strchr (rl_completer_word_break_characters, scan) != 0;
-
-  if (isbrk)
+     if it is found in rl_completer_word_break_characters.  Don't bother
+     if we're at the end of the line, though. */
+  if (scan)
     {
-      /* If the character that caused the word break was a quoting
-        character, then remember it as the delimiter. */
-      if (rl_basic_quote_characters && strchr (rl_basic_quote_characters, scan) && (end - rl_point) > 1)
-       delimiter = scan;
-
-      /* If the character isn't needed to determine something special
-        about what kind of completion to perform, then advance past it. */
-      if (rl_special_prefixes == 0 || strchr (rl_special_prefixes, scan) == 0)
-       rl_point++;
+      if (rl_char_is_quoted_p)
+       isbrk = (found_quote == 0 ||
+               (*rl_char_is_quoted_p) (rl_line_buffer, rl_point) == 0) &&
+               strchr (rl_completer_word_break_characters, scan) != 0;
+      else
+       isbrk = strchr (rl_completer_word_break_characters, scan) != 0;
+
+      if (isbrk)
+       {
+         /* If the character that caused the word break was a quoting
+            character, then remember it as the delimiter. */
+         if (rl_basic_quote_characters &&
+             strchr (rl_basic_quote_characters, scan) &&
+             (end - rl_point) > 1)
+           delimiter = scan;
+
+         /* If the character isn't needed to determine something special
+            about what kind of completion to perform, then advance past it. */
+         if (rl_special_prefixes == 0 || strchr (rl_special_prefixes, scan) == 0)
+           rl_point++;
+       }
     }
 
   if (fp)
@@ -674,6 +694,7 @@ gen_completion_matches (text, start, end, our_func, found_quote, quote_char)
      we are doing filename completion and the application has defined a
      filename dequoting function. */
   temp = (char *)NULL;
+
   if (found_quote && our_func == (Function *)filename_completion_function &&
       rl_filename_dequoting_function)
     {
@@ -682,7 +703,7 @@ gen_completion_matches (text, start, end, our_func, found_quote, quote_char)
       text = temp;     /* not freeing text is not a memory leak */
     }
 
-  matches = completion_matches (text, our_func);
+  matches = completion_matches (text, (CPFunction *)our_func);
   FREE (temp);
   return matches;  
 }
@@ -705,7 +726,7 @@ remove_duplicate_matches (matches)
   /* Sort the array without matches[0], since we need it to
      stay in place no matter what. */
   if (i)
-    qsort (matches+1, i-1, sizeof (char *), _rl_qsort_string_compare);
+    qsort (matches+1, i-1, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
 
   /* Remember the lowest common denominator for it may be unique. */
   lowest_common = savestring (matches[0]);
@@ -813,8 +834,7 @@ compute_lcd_of_matches (match_list, matches, text)
 }
 
 static int
-postprocess_matches (text, matchesp, matching_filenames)
-     char *text;
+postprocess_matches (matchesp, matching_filenames)
      char ***matchesp;
      int matching_filenames;
 {
@@ -845,7 +865,6 @@ postprocess_matches (text, matchesp, matching_filenames)
       if (matches == 0 || matches[0] == 0)
        {
          FREE (matches);
-         ding ();
          *matchesp = (char **)0;
          return 0;
         }
@@ -857,7 +876,7 @@ postprocess_matches (text, matchesp, matching_filenames)
          if (i > 1 && i < nmatch)
            {
              t = matches[0];
-             compute_lcd_of_matches (matches, i - 1, text);
+             compute_lcd_of_matches (matches, i - 1, t);
              FREE (t);
            }
        }
@@ -867,66 +886,19 @@ postprocess_matches (text, matchesp, matching_filenames)
   return (1);
 }
 
-static void
-display_matches (matches)
+/* A convenience function for displaying a list of strings in
+   columnar format on readline's output stream.  MATCHES is the list
+   of strings, in argv format, LEN is the number of strings in MATCHES,
+   and MAX is the length of the longest string in MATCHES. */
+void
+rl_display_match_list (matches, len, max)
      char **matches;
+     int len, max;
 {
-  int len, count, limit, max, printed_len;
+  int count, limit, printed_len;
   int i, j, k, l;
   char *temp;
 
-  /* Move to the last visible line of a possibly-multiple-line command. */
-  _rl_move_vert (_rl_vis_botlin);
-
-  /* Handle simple case first.  What if there is only one answer? */
-  if (matches[1] == 0)
-    {
-      temp = printable_part (matches[0]);
-      crlf ();
-      print_filename (temp, matches[0]);
-      crlf ();
-#if 0
-      rl_on_new_line ();
-#else
-      rl_forced_update_display ();
-      rl_display_fixed = 1;
-#endif
-      return;
-    }
-
-  /* There is more than one answer.  Find out how many there are,
-     and find the maximum printed length of a single entry. */
-  for (max = 0, i = 1; matches[i]; i++)
-    {
-      temp = printable_part (matches[i]);
-      len = strlen (temp);
-
-      if (len > max)
-       max = len;
-    }
-
-  len = i - 1;
-
-  /* If there are many items, then ask the user if she really wants to
-     see them all. */
-  if (len >= rl_completion_query_items)
-    {
-      crlf ();
-      fprintf (rl_outstream, "Display all %d possibilities? (y or n)", len);
-      fflush (rl_outstream);
-      if (get_y_or_n () == 0)
-       {
-         crlf ();
-#if 0
-         rl_on_new_line ();
-#else
-         rl_forced_update_display ();
-         rl_display_fixed = 1;
-#endif
-         return;
-       }
-    }
-
   /* How many items of MAX length can we fit in the screen window? */
   max += 2;
   limit = screenwidth / max;
@@ -947,7 +919,7 @@ display_matches (matches)
 
   /* Sort the items if they are not already sorted. */
   if (rl_ignore_completion_duplicates == 0)
-    qsort (matches + 1, len, sizeof (char *), _rl_qsort_string_compare);
+    qsort (matches + 1, len, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
 
   crlf ();
 
@@ -993,13 +965,85 @@ display_matches (matches)
        }
       crlf ();
     }
+}
+
+/* Display MATCHES, a list of matching filenames in argv format.  This
+   handles the simple case -- a single match -- first.  If there is more
+   than one match, we compute the number of strings in the list and the
+   length of the longest string, which will be needed by the display
+   function.  If the application wants to handle displaying the list of
+   matches itself, it sets RL_COMPLETION_DISPLAY_MATCHES_HOOK to the
+   address of a function, and we just call it.  If we're handling the
+   display ourselves, we just call rl_display_match_list.  We also check
+   that the list of matches doesn't exceed the user-settable threshold,
+   and ask the user if he wants to see the list if there are more matches
+   than RL_COMPLETION_QUERY_ITEMS. */
+static void
+display_matches (matches)
+     char **matches;
+{
+  int len, max, i;
+  char *temp;
+
+  /* Move to the last visible line of a possibly-multiple-line command. */
+  _rl_move_vert (_rl_vis_botlin);
+
+  /* Handle simple case first.  What if there is only one answer? */
+  if (matches[1] == 0)
+    {
+      temp = printable_part (matches[0]);
+      crlf ();
+      print_filename (temp, matches[0]);
+      crlf ();
+
+      rl_forced_update_display ();
+      rl_display_fixed = 1;
+
+      return;
+    }
+
+  /* There is more than one answer.  Find out how many there are,
+     and find the maximum printed length of a single entry. */
+  for (max = 0, i = 1; matches[i]; i++)
+    {
+      temp = printable_part (matches[i]);
+      len = strlen (temp);
+
+      if (len > max)
+       max = len;
+    }
+
+  len = i - 1;
+
+  /* If the caller has defined a display hook, then call that now. */
+  if (rl_completion_display_matches_hook)
+    {
+      (*rl_completion_display_matches_hook) (matches, len, max);
+      return;
+    }
+       
+  /* If there are many items, then ask the user if she really wants to
+     see them all. */
+  if (len >= rl_completion_query_items)
+    {
+      crlf ();
+      fprintf (rl_outstream, "Display all %d possibilities? (y or n)", len);
+      fflush (rl_outstream);
+      if (get_y_or_n () == 0)
+       {
+         crlf ();
+
+         rl_forced_update_display ();
+         rl_display_fixed = 1;
+
+         return;
+       }
+    }
+
+  rl_display_match_list (matches, len, max);
 
-#if 0
-  rl_on_new_line ();
-#else
   rl_forced_update_display ();
   rl_display_fixed = 1;
-#endif
 }
 
 static char *
@@ -1026,11 +1070,8 @@ make_quoted_replacement (match, mtype, qc)
                        rl_filename_quoting_desired;
 
   if (should_quote)
-#if defined (SHELL)
-    should_quote = should_quote && (!qc || !*qc || *qc == '"' || *qc == '\'');
-#else /* !SHELL */
-    should_quote = should_quote && (!qc || !*qc);
-#endif /* !SHELL */
+    should_quote = should_quote && (!qc || !*qc ||
+                    (rl_completer_quote_characters && strchr (rl_completer_quote_characters, *qc)));
 
   if (should_quote)
     {
@@ -1168,6 +1209,17 @@ insert_all_matches (matches, point, qc)
   rl_end_undo_group ();
 }
 
+static void
+free_match_list (matches)
+     char **matches;
+{
+  register int i;
+
+  for (i = 0; matches[i]; i++)
+    free (matches[i]);
+  free (matches);
+}
+
 /* Complete the word at or before point.
    WHAT_TO_DO says what to do with the completion.
    `?' means list the possible completions.
@@ -1210,27 +1262,34 @@ rl_complete_internal (what_to_do)
 
   text = rl_copy_text (start, end);
   matches = gen_completion_matches (text, start, end, our_func, found_quote, quote_char);
+  free (text);
 
   if (matches == 0)
     {
       ding ();
       FREE (saved_line_buffer);
-      free (text);
       return (0);
     }
 
+#if 0
   /* If we are matching filenames, our_func will have been set to
      filename_completion_function */
   i = our_func == (Function *)filename_completion_function;
-  if (postprocess_matches (text, &matches, i) == 0)
+#else
+  /* If we are matching filenames, the attempted completion function will
+     have set rl_filename_completion_desired to a non-zero value.  The basic
+     filename_completion_function does this. */
+  i = rl_filename_completion_desired;
+#endif
+
+  if (postprocess_matches (&matches, i) == 0)
     {
+      ding ();
       FREE (saved_line_buffer);
-      free (text);
+      completion_changed_buffer = 0;
       return (0);
     }
 
-  free (text);
-
   switch (what_to_do)
     {
     case TAB:
@@ -1277,9 +1336,7 @@ rl_complete_internal (what_to_do)
       return 1;
     }
 
-  for (i = 0; matches[i]; i++)
-    free (matches[i]);
-  free (matches);
+  free_match_list (matches);
 
   /* Check to see if the line has changed through all of this manipulation. */
   if (saved_line_buffer)
@@ -1358,12 +1415,12 @@ completion_matches (text, entry_function)
    character (usually `~').  */
 char *
 username_completion_function (text, state)
-     int state;
      char *text;
+     int state;
 {
-#if defined (__GO32__) || defined (__WIN32__)
+#if defined (__WIN32__) || defined (__OPENNT)
   return (char *)NULL;
-#else /* !__GO32__ */
+#else /* !__WIN32__ && !__OPENNT) */
   static char *username = (char *)NULL;
   static struct passwd *entry;
   static int namelen, first_char, first_char_loc;
@@ -1406,7 +1463,7 @@ username_completion_function (text, state)
 
       return (value);
     }
-#endif /* !__GO32__ */
+#endif /* !__WIN32__ && !__OPENNT */
 }
 
 /* Okay, now we write the entry_function for filename completion.  In the
@@ -1415,8 +1472,8 @@ username_completion_function (text, state)
    completion for a command. */
 char *
 filename_completion_function (text, state)
-     int state;
      char *text;
+     int state;
 {
   static DIR *directory = (DIR *)NULL;
   static char *filename = (char *)NULL;
@@ -1448,11 +1505,25 @@ filename_completion_function (text, state)
 
       temp = strrchr (dirname, '/');
 
+#if defined (__MSDOS__)
+      /* special hack for //X/... */
+      if (dirname[0] == '/' && dirname[1] == '/' && isalpha (dirname[2]) && dirname[3] == '/')
+        temp = strrchr (dirname + 3, '/');
+#endif
+
       if (temp)
        {
          strcpy (filename, ++temp);
          *temp = '\0';
        }
+#if defined (__MSDOS__)
+      /* searches from current directory on the drive */
+      else if (isalpha (dirname[0]) && dirname[1] == ':')
+        {
+          strcpy (filename, dirname + 2);
+          dirname[2] = '\0';
+        }
+#endif
       else
        {
          dirname[0] = '.';
@@ -1574,7 +1645,7 @@ filename_completion_function (text, state)
              strcpy (temp, users_dirname);
            }
 
-         strcpy (temp + dirlen, entry->d_name); /* strcat (temp, entry->d_name); */
+         strcpy (temp + dirlen, entry->d_name);
        }
       else
        temp = savestring (entry->d_name);
@@ -1614,11 +1685,7 @@ rl_menu_complete (count, ignore)
       /* Clean up from previous call, if any. */
       FREE (orig_text);
       if (matches)
-       {
-         for (match_list_index = 0; matches[match_list_index]; match_list_index++)
-           free (matches[match_list_index]);
-         free (matches);
-       }
+       free_match_list (matches);
 
       match_list_index = match_list_size = 0;
       matches = (char **)NULL;
@@ -1649,10 +1716,17 @@ rl_menu_complete (count, ignore)
       matches = gen_completion_matches (orig_text, orig_start, orig_end,
                                        our_func, found_quote, quote_char);
 
+#if 0
       /* If we are matching filenames, our_func will have been set to
         filename_completion_function */
       matching_filenames = our_func == (Function *)filename_completion_function;
-      if (matches == 0 || postprocess_matches (orig_text, &matches, matching_filenames) == 0)
+#else
+      /* If we are matching filenames, the attempted completion function will
+        have set rl_filename_completion_desired to a non-zero value.  The basic
+        filename_completion_function does this. */
+      matching_filenames = rl_filename_completion_desired;
+#endif
+      if (matches == 0 || postprocess_matches (&matches, matching_filenames) == 0)
        {
          ding ();
          FREE (matches);
@@ -1686,7 +1760,7 @@ rl_menu_complete (count, ignore)
   if (match_list_index < 0)
     match_list_index += match_list_size;
 
-  if (match_list_index == 0)
+  if (match_list_index == 0 && match_list_size > 1)
     {
       ding ();
       insert_match (orig_text, orig_start, MULT_MATCH, &quote_char);
This page took 0.030514 seconds and 4 git commands to generate.