]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb: implement readline rl_directory_rewrite_hook callback
authorAndrew Burgess <aburgess@redhat.com>
Mon, 24 Jun 2024 14:53:34 +0000 (15:53 +0100)
committerAndrew Burgess <aburgess@redhat.com>
Sat, 7 Sep 2024 19:28:58 +0000 (20:28 +0100)
Implement the readline rl_directory_rewrite_hook callback function,
this is used when readline needs to offer completions from within a
directory.  The important thing is that this function should remove
any escaping, this allows GDB to correctly offer completions in
situations like this:

  (gdb) file /tmp/directory\ with\ spaces/<TAB><TAB>

Note the escaping in 'directory\ with\ spaces'.  Without the
rl_directory_rewrite_hook callback readline will try to open a
directory literally called '/tmp/directory\ with\ spaces' which
obviously doesn't exist.

There are tests added to cover this new functionality.

gdb/completer.c
gdb/testsuite/gdb.base/filename-completion.exp

index b0e999ef514b0560b0a1cf71554cd3b94d8c5d33..b80649c5260a81cee5e2a1b04fb051459e22f4e3 100644 (file)
@@ -321,6 +321,26 @@ gdb_completer_file_name_dequote (char *filename, int quote_char)
   return strdup (tmp.c_str ());
 }
 
+/* Implement readline's rl_directory_rewrite_hook.  Remove any quoting from
+   the string *DIRNAME,update *DIRNAME, and return non-zero.  If *DIRNAME
+   doesn't need updating then return zero.  See readline docs for more
+   information.  */
+
+static int
+gdb_completer_directory_rewrite (char **dirname)
+{
+  if (!rl_completion_found_quote)
+    return 0;
+
+  int quote_char = rl_completion_quote_character;
+  char *new_dirname
+    = gdb_completer_file_name_dequote (*dirname, quote_char);
+  free (*dirname);
+  *dirname = new_dirname;
+
+  return 1;
+}
+
 /* Apply character escaping to the filename in TEXT and return a newly
    allocated buffer containing the possibly updated filename.
 
@@ -3416,6 +3436,7 @@ _initialize_completer ()
   rl_filename_quote_characters = " \t\n\\\"'";
   rl_filename_dequoting_function = gdb_completer_file_name_dequote;
   rl_filename_quoting_function = gdb_completer_file_name_quote;
+  rl_directory_rewrite_hook = gdb_completer_directory_rewrite;
 
   add_setshow_zuinteger_unlimited_cmd ("max-completions", no_class,
                                       &max_completions, _("\
index a4b411c1c6766eefbb953e9dffa763b39f160921..cf00d007ca7efdb1abd597dd5444f26207fa0725 100644 (file)
@@ -170,6 +170,11 @@ proc run_quoting_and_escaping_tests { root } {
                set dq "\\\""
            }
 
+           test_gdb_complete_unique "${cmd} ${qc}${root}/bb2/dir${sp}1/" \
+               "${cmd} ${qc}${root}/bb2/dir${sp}1/unique${sp}file${qc}" " " \
+               false \
+               "expand a unique file name in a directory containing a space"
+
            test_gdb_complete_filename_multiple "$cmd ${qc}${root}/bb2/" \
                "d" "ir${sp}" {
                    "dir 1/"
@@ -177,6 +182,13 @@ proc run_quoting_and_escaping_tests { root } {
                } "" "${qc}" false \
                "expand multiple directory names containing spaces"
 
+           test_gdb_complete_filename_multiple "${cmd} ${qc}${root}/bb2/dir${sp}2/" \
+               "f" "ile${sp}" {
+                   "file 1"
+                   "file 2"
+               } "" "${qc}" false \
+               "expand contents of a directory containing a space"
+
            test_gdb_complete_filename_multiple "$cmd ${qc}${root}/aaa/" \
                "a" "a${sp}" {
                    "aa bb"