]> git.ipfire.org Git - thirdparty/bash.git/blobdiff - bashline.c
fix quoting for positional parameters if not word splitting; retry open for startup...
[thirdparty/bash.git] / bashline.c
index c11484ecfe4469d37c34aea447e7b8db37a45ae7..353e8b1e68aab2578cbcb2db8e003e14a8aa6dd3 100644 (file)
@@ -1,6 +1,6 @@
 /* bashline.c -- Bash's interface to the readline library. */
 
-/* Copyright (C) 1987-2023 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2024 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -606,6 +606,7 @@ initialize_readline (void)
   rl_bind_key_if_unbound_in_map ('@', posix_edit_macros, vi_movement_keymap);
 #  endif
 
+  rl_add_defun ("bash-vi-complete", bash_vi_complete, -1);
   rl_bind_key_in_map ('\\', bash_vi_complete, vi_movement_keymap);
   rl_bind_key_in_map ('*', bash_vi_complete, vi_movement_keymap);
   rl_bind_key_in_map ('=', bash_vi_complete, vi_movement_keymap);
@@ -797,7 +798,11 @@ snarf_hosts_from_file (const char *filename)
   char *temp, buffer[256], name[256];
   register int i, start;
 
+#ifdef __MSYS__
+  file = fopen (filename, "rt");
+#else
   file = fopen (filename, "r");
+#endif
   if (file == 0)
     return;
 
@@ -948,8 +953,11 @@ edit_and_execute_command (int count, int c, int editing_mode, const char *edit_c
 
   if (rl_explicit_arg)
     {
-      command = (char *)xmalloc (strlen (edit_command) + 8);
-      sprintf (command, "%s %d", edit_command, count);
+      size_t clen;
+      /* 32 exceeds strlen (itos (INTMAX_MAX)) (19) */
+      clen = strlen (edit_command) + 32;
+      command = (char *)xmalloc (clen);
+      snprintf (command, clen, "%s %d", edit_command, count);
     }
   else
     {
@@ -3125,6 +3133,19 @@ test_for_directory (const char *name)
   int r;
 
   fn = bash_tilde_expand (name, 0);
+
+#if __CYGWIN
+  /* stat("//server") can only be successful as a directory, but can take
+     seconds to time out on failure.  It is much faster to assume that
+     "//server" is a valid name than it is to wait for a stat, even if it
+     gives false positives on bad names.  */
+  if (fn[0] == '/' && fn[1] == '/' && ! strchr (&fn[2], '/'))
+    {
+      free (fn);
+      return 1;
+    }
+#endif
+
   r = file_isdir (fn);
   free (fn);
 
@@ -4012,10 +4033,38 @@ bash_specific_completion (int what_to_do, rl_compentry_func_t *generator)
 #endif /* SPECIFIC_COMPLETION_FUNCTIONS */
 
 #if defined (VI_MODE)
+/* This does pretty much what _rl_vi_advance_point does. */
+static inline int
+vi_advance_point (void)
+{
+  int point;
+  DECLARE_MBSTATE;
+
+  point = rl_point;
+  if (rl_point < rl_end)
+#if defined (HANDLE_MULTIBYTE)
+    {
+      if (locale_mb_cur_max == 1)
+       rl_point++;
+      else
+       {
+         point = rl_point;
+         ADVANCE_CHAR (rl_line_buffer, rl_end, rl_point);
+         if (point == rl_point || rl_point > rl_end)
+           rl_point = rl_end;
+       }
+    }
+#else
+    rl_point++:
+#endif
+  return point;
+}
+
 /* Completion, from vi mode's point of view.  This is a modified version of
    rl_vi_complete which uses the bash globbing code to implement what POSIX
-   specifies, which is to append a `*' and attempt filename generation (which
-   has the side effect of expanding any globbing characters in the word). */
+   specifies, which is to optinally append a `*' and attempt filename
+   generation (which has the side effect of expanding any globbing characters
+   in the word). */
 static int
 bash_vi_complete (int count, int key)
 {
@@ -4027,7 +4076,7 @@ bash_vi_complete (int count, int key)
     {
       if (!whitespace (rl_line_buffer[rl_point + 1]))
        rl_vi_end_word (1, 'E');
-      rl_point++;
+      vi_advance_point ();
     }
 
   /* Find boundaries of current word, according to vi definition of a