aboutsummaryrefslogtreecommitdiff
path: root/gdb/completer.c
diff options
context:
space:
mode:
authorAndrew Burgess <aburgess@redhat.com>2024-06-22 10:10:29 +0100
committerAndrew Burgess <aburgess@redhat.com>2024-09-07 20:28:57 +0100
commit4076f962e8cd73219dfd48a6f682df1ab391c48c (patch)
tree23256cf22815022235da3d5c660ecbdfadffc4ba /gdb/completer.c
parent8358d39b4f0c5c9d29714676bcccb1d59014997f (diff)
downloadbinutils-4076f962e8cd73219dfd48a6f682df1ab391c48c.zip
binutils-4076f962e8cd73219dfd48a6f682df1ab391c48c.tar.gz
binutils-4076f962e8cd73219dfd48a6f682df1ab391c48c.tar.bz2
gdb: split apart two different types of filename completion
Unfortunately we have two different types of filename completion in GDB. The majority of commands have what I call unquoted filename completion, this is for commands like 'set logging file ...', 'target core ...', and 'add-auto-load-safe-path ...'. For these commands everything after the command name (that is not a command option) is treated as a single filename. If the filename contains white space then this does not need to be escaped, nor does the filename need to be quoted. In fact, the filename argument is not de-quoted, and does not have any escaping removed, so if a user does try to add such things, they will be treated as part of the filename. As an example: (gdb) target core "/path/that contains/some white space" Will look for a directory calls '"' (double quotes) in the local directory. A small number of commands do de-quote and remove escapes from filename arguments. These command accept what I call quoted and escaped filenames. Right now these are the commands that specify the file for GDB to debug, so: file exec-file symbol-file add-symbol-file remove-symbol-file As an example of this in action: (gdb) file "/path/that contains/some white space" In this case GDB would load the file: /path/that contains/some white space Current filename completion always assumes that filenames can be quoted, though escaping doesn't work in completion right now. But the assumption that quoting is allowed is clearly wrong. This commit splits filename completion into two. The existing filename_completer is retained, and is used for unquoted filenames. A second filename_maybe_quoted_completer is added which can be used for completing quoted filenames. The filename completion test has been extended to cover more cases. As part of the extended testing I need to know the character that should be used to separate filenames within a path. For this TCL 8.6+ has $::tcl_platform(pathSeparator). To support older versions of TCL I've added some code to testsuite/lib/gdb.exp. You might notice that after this commit the completion for unquoted files is all done in the brkchars phase, that is the function filename_completer_handle_brkchars calculates the completions and marks the completion_tracker as using a custom word point. The reason for this is that we don't want to break on white space for this completion, but if we rely on readline to find the completion word, readline will consider the entire command line, and with no white space in the word break character set, readline will end up using the entire command line as the word to complete. For now at least, the completer for quoted filenames does generate its completions during the completion phase, though this is going to change in a later commit.
Diffstat (limited to 'gdb/completer.c')
-rw-r--r--gdb/completer.c86
1 files changed, 72 insertions, 14 deletions
diff --git a/gdb/completer.c b/gdb/completer.c
index 1008ec2..93eb8db 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -182,6 +182,17 @@ static const char gdb_completer_file_name_break_characters[] =
" \t\n*|\"';:?><";
#endif
+/* When completing on file names, for commands that don't accept quoted
+ file names, the only character that can be used as a word separator is
+ the path separator. Every other character is treated as a literal
+ character within the filename. */
+static const char gdb_completer_path_break_characters[] =
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ ";";
+#else
+ ":";
+#endif
+
/* Characters that can be used to quote expressions. Note that we can't
include '"' (double quote) because the gdb C parser treats such quoted
sequences as strings. */
@@ -203,15 +214,15 @@ noop_completer (struct cmd_list_element *ignore,
{
}
-/* Complete on filenames. */
+/* Generate filename completions of WORD, storing the completions into
+ TRACKER. This is used for generating completions for commands that
+ only accept unquoted filenames as well as for commands that accept
+ quoted and escaped filenames. */
-void
-filename_completer (struct cmd_list_element *ignore,
- completion_tracker &tracker,
- const char *text, const char *word)
+static void
+filename_completer_generate_completions (completion_tracker &tracker,
+ const char *word)
{
- rl_completer_quote_characters = gdb_completer_file_name_quote_characters;
-
int subsequent_name = 0;
while (1)
{
@@ -249,13 +260,13 @@ filename_completer (struct cmd_list_element *ignore,
}
}
-/* The corresponding completer_handle_brkchars
- implementation. */
+/* The brkchars callback used when completing filenames that can be
+ quoted. */
static void
-filename_completer_handle_brkchars (struct cmd_list_element *ignore,
- completion_tracker &tracker,
- const char *text, const char *word)
+filename_maybe_quoted_completer_handle_brkchars
+ (struct cmd_list_element *ignore, completion_tracker &tracker,
+ const char *text, const char *word)
{
set_rl_completer_word_break_characters
(gdb_completer_file_name_break_characters);
@@ -263,6 +274,50 @@ filename_completer_handle_brkchars (struct cmd_list_element *ignore,
rl_completer_quote_characters = gdb_completer_file_name_quote_characters;
}
+/* Complete on filenames. This is for commands that accepts possibly
+ quoted filenames. */
+
+void
+filename_maybe_quoted_completer (struct cmd_list_element *ignore,
+ completion_tracker &tracker,
+ const char *text, const char *word)
+{
+ filename_maybe_quoted_completer_handle_brkchars (ignore, tracker,
+ text, word);
+ filename_completer_generate_completions (tracker, word);
+}
+
+/* The brkchars callback used by commands that don't accept quoted
+ filenames. */
+
+static void
+filename_completer_handle_brkchars
+ (struct cmd_list_element *ignore, completion_tracker &tracker,
+ const char *text, const char *word)
+{
+ gdb_assert (word == nullptr);
+
+ set_rl_completer_word_break_characters (gdb_completer_path_break_characters);
+ rl_completer_quote_characters = nullptr;
+ rl_filename_quoting_desired = 0;
+
+ tracker.set_use_custom_word_point (true);
+ word = advance_to_filename_complete_word_point (tracker, text);
+ filename_completer (ignore, tracker, text, word);
+}
+
+/* See completer.h. */
+
+void
+filename_completer
+ (struct cmd_list_element *ignore, completion_tracker &tracker,
+ const char *text, const char *word)
+{
+ gdb_assert (tracker.use_custom_word_point ());
+ gdb_assert (word != nullptr);
+ filename_completer_generate_completions (tracker, word);
+}
+
/* Find the bounds of the current word for completion purposes, and
return a pointer to the end of the word. This mimics (and is a
modified version of) readline's _rl_find_completion_word internal
@@ -447,8 +502,8 @@ const char *
advance_to_filename_complete_word_point (completion_tracker &tracker,
const char *text)
{
- const char *brk_chars = gdb_completer_file_name_break_characters;
- const char *quote_chars = gdb_completer_file_name_quote_characters;
+ const char *brk_chars = gdb_completer_path_break_characters;
+ const char *quote_chars = nullptr;
return advance_to_completion_word (tracker, brk_chars, quote_chars, text);
}
@@ -1880,6 +1935,9 @@ completer_handle_brkchars_func_for_completer (completer_ftype *fn)
if (fn == filename_completer)
return filename_completer_handle_brkchars;
+ if (fn == filename_maybe_quoted_completer)
+ return filename_maybe_quoted_completer_handle_brkchars;
+
if (fn == location_completer)
return location_completer_handle_brkchars;