Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Andrew Burgess <aburgess@redhat.com>
To: gdb-patches@sourceware.org
Cc: Andrew Burgess <aburgess@redhat.com>
Subject: [PATCHv5 11/14] gdb: extend completion of quoted filenames to work in brkchars phase
Date: Tue, 20 Aug 2024 18:10:41 +0100	[thread overview]
Message-ID: <c6b78a15a901a34d211040311d7ea5f503c4a166.1724173728.git.aburgess@redhat.com> (raw)
In-Reply-To: <cover.1724173728.git.aburgess@redhat.com>

Up to this point filename completion for possibly quoted filenames has
always been handled during the second (non-brkchars) phase of
completion.  This works fine for commands that only want to complete
on a single filename argument.

In a later commit though I need to perform completion of a quoted
filename argument during the first (brkchars) phase of completion.
This will allow me to add a custom completer that completes both
command options and arguments for a command (remove-symbol-file) that
takes a possibly quoted filename argument.

This commit doesn't add the remove-symbol-file completer, this commit
is just about putting support for that in place.

To achieve this I've added the new function
advance_to_filename_maybe_quoted_complete_word_point, which is unused
in this commit.  I've then had to extend some other functions in order
to extract the quoting state during the brkchars phase.

As this commit doesn't use the new functionality, the important thing
at this point is that I've not regressed the existing filename
completion (or any of the other completion).  The next commit in this
series will make use of the new functionality, and will include
tests.

There should be no user visible changes after this commit.
---
 gdb/completer.c | 98 +++++++++++++++++++++++++++++++++++++++++--------
 gdb/completer.h |  8 ++++
 2 files changed, 91 insertions(+), 15 deletions(-)

diff --git a/gdb/completer.c b/gdb/completer.c
index b80649c5260..e8f5e7bb577 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -730,13 +730,23 @@ gdb_rl_find_completion_word (struct gdb_rl_completion_word_info *info,
 
 /* Find the completion word point for TEXT, emulating the algorithm
    readline uses to find the word point, using WORD_BREAK_CHARACTERS
-   as word break characters.  */
+   as word break characters.
+
+   The output argument *FOUND_ANY_QUOTING is set to true if the completion
+   word found either has an opening quote, or contains backslash escaping
+   within it.  Otherwise *FOUND_ANY_QUOTING is set to false.
+
+   The output argument *QC is set to the opening quote character for the
+   completion word that is found, or to the null character if there is no
+   opening quote.  */
 
 static const char *
 advance_to_completion_word (completion_tracker &tracker,
 			    const char *word_break_characters,
 			    const char *quote_characters,
-			    const char *text)
+			    const char *text,
+			    bool *found_any_quoting,
+			    int *qc)
 {
   gdb_rl_completion_word_info info;
 
@@ -746,7 +756,8 @@ advance_to_completion_word (completion_tracker &tracker,
 
   int delimiter;
   const char *start
-    = gdb_rl_find_completion_word (&info, nullptr, &delimiter, nullptr, text);
+    = gdb_rl_find_completion_word (&info, qc, &delimiter, found_any_quoting,
+				   text);
 
   tracker.advance_custom_word_point_by (start - text);
 
@@ -767,18 +778,54 @@ advance_to_expression_complete_word_point (completion_tracker &tracker,
 {
   const char *brk_chars = current_language->word_break_characters ();
   const char *quote_chars = gdb_completer_expression_quote_characters;
-  return advance_to_completion_word (tracker, brk_chars, quote_chars, text);
+  return advance_to_completion_word (tracker, brk_chars, quote_chars,
+				     text, nullptr, nullptr);
 }
 
 /* See completer.h.  */
 
 const char *
-advance_to_deprecated_filename_complete_word_point
+advance_to_filename_maybe_quoted_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;
+  rl_char_is_quoted_p = gdb_completer_file_name_char_is_quoted;
+  bool found_any_quoting = false;
+  int qc;
+  const char *result
+    = advance_to_completion_word (tracker, brk_chars, quote_chars,
+				  text, &found_any_quoting, &qc);
+  rl_completion_found_quote = found_any_quoting ? 1 : 0;
+  if (qc != '\0')
+    {
+      tracker.set_quote_char (qc);
+      /* If we're completing for readline (not the 'complete' command) then
+	 we want readline to correctly detect the opening quote.  The set
+	 of quote characters will have been set during the brkchars phase,
+	 so now we move the word point back by one (so it's pointing at
+	 the quote character) and now readline will correctly spot the
+	 opening quote.  For the 'complete' command setting the quote
+	 character in the tracker is enough, so there's no need to move
+	 the word point back here.  */
+      if (tracker.from_readline ())
+	tracker.advance_custom_word_point_by (-1);
+    }
+  return result;
+}
+
+/* See completer.h.  */
+
+const char *
+advance_to_deprecated_filename_complete_word_point (completion_tracker &tracker,
+						    const char *text)
 {
   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);
+  rl_filename_quoting_desired = 0;
+
+  return advance_to_completion_word (tracker, brk_chars, quote_chars,
+				     text, nullptr, nullptr);
 }
 
 /* See completer.h.  */
@@ -2283,7 +2330,21 @@ gdb_completion_word_break_characters_throw ()
 
       gdb_custom_word_point_brkchars[0] = rl_line_buffer[rl_point];
       rl_completer_word_break_characters = gdb_custom_word_point_brkchars;
-      rl_completer_quote_characters = NULL;
+
+      /* When performing filename completion we have two options, unquoted
+	 filename completion, in which case the quote characters will have
+	 already been set to nullptr, or quoted filename completion in
+	 which case the quote characters will be set to a string of
+	 characters.  In this second case we need readline to perform the
+	 check for a quoted string so that it sets its internal notion of
+	 the quote character correctly, this allows readline to correctly
+	 add the trailing quote (if necessary) after completing a
+	 filename.
+
+	 For non-filename completion we manually add a trailing quote if
+	 needed, so we clear the quote characters set here.  */
+      if (!rl_filename_completion_desired)
+	rl_completer_quote_characters = NULL;
 
       /* Clear this too, so that if we're completing a quoted string,
 	 readline doesn't consider the quote character a delimiter.
@@ -2330,7 +2391,12 @@ gdb_completion_word_break_characters () noexcept
    handle_brkchars phase (using TRACKER) to figure out the right work break
    characters for the command in TEXT.  QUOTE_CHAR, if non-null, is set to
    the opening quote character if we found an unclosed quoted substring,
-   '\0' otherwise.  */
+   '\0' otherwise.
+
+   The argument *FOUND_ANY_QUOTING is set to true if the completion word is
+   either surrounded by quotes, or contains any backslash escapes, but is
+   only set if TRACKER.use_custom_word_point() is false, otherwise
+   *FOUND_ANY_QUOTING is just set to false.  */
 
 static const char *
 completion_find_completion_word (completion_tracker &tracker, const char *text,
@@ -2344,13 +2410,12 @@ completion_find_completion_word (completion_tracker &tracker, const char *text,
     {
       gdb_assert (tracker.custom_word_point () > 0);
       *quote_char = tracker.quote_char ();
-      /* This isn't really correct, we're ignoring the case where we found
-	 a backslash escaping a character.  However, this isn't an issue
-	 right now as we only rely on *FOUND_ANY_QUOTING being set when
-	 performing filename completion, which doesn't go through this
-	 path.  */
+      /* If use_custom_word_point is set then the completions have already
+	 been calculated, in which case we don't need to have this flag
+	 set correctly, which is lucky as we don't currently have any way
+	 to know if the completion word included any backslash escapes.  */
       if (found_any_quoting != nullptr)
-	*found_any_quoting = *quote_char != '\0';
+	*found_any_quoting = false;
       return text + tracker.custom_word_point ();
     }
 
@@ -2527,7 +2592,10 @@ completion_tracker::build_completion_result (const char *text,
     {
       bool completion_suppress_append;
 
-      if (from_readline ())
+      /* For filename completion we rely on readline to append the closing
+	 quote.  While for other types of completion we append the closing
+	 quote here.  */
+      if (from_readline () && !rl_filename_completion_desired)
 	{
 	  /* We don't rely on readline appending the quote char as
 	     delimiter as then readline wouldn't append the ' ' after the
diff --git a/gdb/completer.h b/gdb/completer.h
index c18bd16ad26..44eafc487f7 100644
--- a/gdb/completer.h
+++ b/gdb/completer.h
@@ -618,6 +618,14 @@ const char *advance_to_expression_complete_word_point
 extern const char *advance_to_deprecated_filename_complete_word_point
   (completion_tracker &tracker, const char *text);
 
+/* Assuming TEXT is a filename, find the completion word point for TEXT,
+   emulating the algorithm readline uses to find the word point.  The
+   filenames that are located by this function assume that filenames
+   can be quoted, this function should be paired with
+   filename_maybe_quoted_completer.  */
+extern const char *advance_to_filename_maybe_quoted_complete_word_point
+  (completion_tracker &tracker, const char *text);
+
 extern void noop_completer (struct cmd_list_element *,
 			    completion_tracker &tracker,
 			    const char *, const char *);
-- 
2.25.4


  parent reply	other threads:[~2024-08-20 17:13 UTC|newest]

Thread overview: 104+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-29 11:42 [PATCH 0/6] Further filename completion improvements Andrew Burgess
2024-03-29 11:42 ` [PATCH 1/6] gdb: improve escaping when completing filenames Andrew Burgess
2024-03-30 23:48   ` Lancelot SIX
2024-03-29 11:42 ` [PATCH 2/6] gdb: move display of completion results into completion_result class Andrew Burgess
2024-03-29 12:14   ` Eli Zaretskii
2024-03-30 23:30     ` Lancelot SIX
2024-03-31  5:49       ` Eli Zaretskii
2024-04-12 17:24         ` Andrew Burgess
2024-04-12 18:42           ` Eli Zaretskii
2024-04-12 22:20             ` Andrew Burgess
2024-04-13  6:36               ` Eli Zaretskii
2024-04-13  9:09                 ` Andrew Burgess
2024-04-13  9:46                   ` Eli Zaretskii
2024-04-12 17:31       ` Andrew Burgess
2024-03-29 11:42 ` [PATCH 3/6] gdb: simplify completion_result::print_matches Andrew Burgess
2024-03-30 23:48   ` Lancelot SIX
2024-03-29 11:42 ` [PATCH 4/6] gdb: add match formatter mechanism for 'complete' command output Andrew Burgess
2024-03-30 23:49   ` Lancelot SIX
2024-03-31  5:55     ` Eli Zaretskii
2024-04-12 17:42       ` Andrew Burgess
2024-04-12 18:44         ` Eli Zaretskii
2024-04-12 22:29           ` Andrew Burgess
2024-04-13  6:39             ` Eli Zaretskii
2024-03-29 11:42 ` [PATCH 5/6] gdb: apply escaping to filenames in 'complete' results Andrew Burgess
2024-03-29 11:42 ` [PATCH 6/6] gdb: improve gdb_rl_find_completion_word for quoted words Andrew Burgess
2024-04-20  9:10 ` [PATCHv2 0/8] Further filename completion improvements Andrew Burgess
2024-04-20  9:10   ` [PATCHv2 1/8] gdb/doc: document how filename arguments are formatted Andrew Burgess
2024-04-20  9:44     ` Eli Zaretskii
2024-04-27 10:01       ` Andrew Burgess
2024-04-27 10:06         ` Eli Zaretskii
2024-04-29  9:10           ` Andrew Burgess
2024-04-20  9:10   ` [PATCHv2 2/8] gdb: split apart two different types of filename completion Andrew Burgess
2024-04-20  9:10   ` [PATCHv2 3/8] gdb: improve escaping when completing filenames Andrew Burgess
2024-04-20  9:10   ` [PATCHv2 4/8] gdb: move display of completion results into completion_result class Andrew Burgess
2024-04-20  9:10   ` [PATCHv2 5/8] gdb: simplify completion_result::print_matches Andrew Burgess
2024-04-20  9:10   ` [PATCHv2 6/8] gdb: add match formatter mechanism for 'complete' command output Andrew Burgess
2024-04-20  9:10   ` [PATCHv2 7/8] gdb: apply escaping to filenames in 'complete' results Andrew Burgess
2024-04-20  9:10   ` [PATCHv2 8/8] gdb: improve gdb_rl_find_completion_word for quoted words Andrew Burgess
2024-06-05 13:36   ` [PATCHv3 0/7] Further filename completion improvements Andrew Burgess
2024-06-05 13:36     ` [PATCHv3 1/7] gdb: split apart two different types of filename completion Andrew Burgess
2024-06-06 16:18       ` Tom Tromey
2024-06-17 13:05         ` Andrew Burgess
2024-06-05 13:36     ` [PATCHv3 2/7] gdb: improve escaping when completing filenames Andrew Burgess
2024-06-05 13:36     ` [PATCHv3 3/7] gdb: move display of completion results into completion_result class Andrew Burgess
2024-06-06 16:19       ` Tom Tromey
2024-06-05 13:36     ` [PATCHv3 4/7] gdb: simplify completion_result::print_matches Andrew Burgess
2024-06-05 13:36     ` [PATCHv3 5/7] gdb: add match formatter mechanism for 'complete' command output Andrew Burgess
2024-06-06 16:14       ` Tom Tromey
2024-06-17 13:29         ` Andrew Burgess
2024-06-05 13:36     ` [PATCHv3 6/7] gdb: apply escaping to filenames in 'complete' results Andrew Burgess
2024-06-05 13:36     ` [PATCHv3 7/7] gdb: improve gdb_rl_find_completion_word for quoted words Andrew Burgess
2024-06-06 16:24     ` [PATCHv3 0/7] Further filename completion improvements Tom Tromey
2024-07-04 14:20     ` [PATCHv4 00/14] " Andrew Burgess
2024-07-04 14:20       ` [PATCHv4 01/14] gdb: split apart two different types of filename completion Andrew Burgess
2024-07-04 14:20       ` [PATCHv4 02/14] gdb: deprecated filename_completer and associated functions Andrew Burgess
2024-07-04 14:20       ` [PATCHv4 03/14] gdb: improve escaping when completing filenames Andrew Burgess
2024-07-04 14:20       ` [PATCHv4 04/14] gdb: move display of completion results into completion_result class Andrew Burgess
2024-07-04 14:21       ` [PATCHv4 05/14] gdb: simplify completion_result::print_matches Andrew Burgess
2024-07-04 14:21       ` [PATCHv4 06/14] gdb: add match formatter mechanism for 'complete' command output Andrew Burgess
2024-07-04 14:21       ` [PATCHv4 07/14] gdb: apply escaping to filenames in 'complete' results Andrew Burgess
2024-07-04 14:21       ` [PATCHv4 08/14] gdb: improve gdb_rl_find_completion_word for quoted words Andrew Burgess
2024-07-04 14:21       ` [PATCHv4 09/14] gdb: implement readline rl_directory_rewrite_hook callback Andrew Burgess
2024-07-04 14:21       ` [PATCHv4 10/14] gdb: new extract_single_filename_arg helper function Andrew Burgess
2024-07-04 14:21       ` [PATCHv4 11/14] gdb: extend completion of quoted filenames to work in brkchars phase Andrew Burgess
2024-07-04 14:21       ` [PATCHv4 12/14] gdb: add remove-symbol-file command completion Andrew Burgess
2024-07-04 15:38         ` Eli Zaretskii
2024-07-04 14:21       ` [PATCHv4 13/14] gdb: allow quoted filenames for commands that have custom completion Andrew Burgess
2024-07-04 15:42         ` Eli Zaretskii
2024-08-20 17:18           ` Andrew Burgess
2024-07-04 14:21       ` [PATCHv4 14/14] gdb: 'target ...' commands now expect quoted/escaped filenames Andrew Burgess
2024-07-04 15:34         ` Eli Zaretskii
2024-08-20 17:10       ` [PATCHv5 00/14] Further filename completion improvements Andrew Burgess
2024-08-20 17:10         ` [PATCHv5 01/14] gdb: split apart two different types of filename completion Andrew Burgess
2024-08-20 17:10         ` [PATCHv5 02/14] gdb: deprecated filename_completer and associated functions Andrew Burgess
2024-08-20 17:10         ` [PATCHv5 03/14] gdb: improve escaping when completing filenames Andrew Burgess
2024-08-20 17:10         ` [PATCHv5 04/14] gdb: move display of completion results into completion_result class Andrew Burgess
2024-08-20 17:10         ` [PATCHv5 05/14] gdb: simplify completion_result::print_matches Andrew Burgess
2024-08-20 17:10         ` [PATCHv5 06/14] gdb: add match formatter mechanism for 'complete' command output Andrew Burgess
2024-08-20 17:10         ` [PATCHv5 07/14] gdb: apply escaping to filenames in 'complete' results Andrew Burgess
2024-08-20 17:10         ` [PATCHv5 08/14] gdb: improve gdb_rl_find_completion_word for quoted words Andrew Burgess
2024-08-20 17:10         ` [PATCHv5 09/14] gdb: implement readline rl_directory_rewrite_hook callback Andrew Burgess
2024-08-20 17:10         ` [PATCHv5 10/14] gdb: new extract_single_filename_arg helper function Andrew Burgess
2024-08-20 17:10         ` Andrew Burgess [this message]
2024-08-20 17:10         ` [PATCHv5 12/14] gdb: add remove-symbol-file command completion Andrew Burgess
2024-08-20 18:46           ` Eli Zaretskii
2024-08-20 17:10         ` [PATCHv5 13/14] gdb: allow quoted filenames for commands that have custom completion Andrew Burgess
2024-08-20 18:47           ` Eli Zaretskii
2024-08-20 17:10         ` [PATCHv5 14/14] gdb: 'target ...' commands now expect quoted/escaped filenames Andrew Burgess
2024-08-30 11:33         ` [PATCHv6 00/14] Further filename completion improvements Andrew Burgess
2024-08-30 11:33           ` [PATCHv6 01/14] gdb: split apart two different types of filename completion Andrew Burgess
2024-08-30 11:33           ` [PATCHv6 02/14] gdb: deprecated filename_completer and associated functions Andrew Burgess
2024-08-30 11:33           ` [PATCHv6 03/14] gdb: improve escaping when completing filenames Andrew Burgess
2024-08-30 11:33           ` [PATCHv6 04/14] gdb: move display of completion results into completion_result class Andrew Burgess
2024-08-30 11:33           ` [PATCHv6 05/14] gdb: simplify completion_result::print_matches Andrew Burgess
2024-08-30 11:33           ` [PATCHv6 06/14] gdb: add match formatter mechanism for 'complete' command output Andrew Burgess
2024-08-30 11:33           ` [PATCHv6 07/14] gdb: apply escaping to filenames in 'complete' results Andrew Burgess
2024-08-30 11:33           ` [PATCHv6 08/14] gdb: improve gdb_rl_find_completion_word for quoted words Andrew Burgess
2024-08-30 11:33           ` [PATCHv6 09/14] gdb: implement readline rl_directory_rewrite_hook callback Andrew Burgess
2024-08-30 11:33           ` [PATCHv6 10/14] gdb: new extract_single_filename_arg helper function Andrew Burgess
2024-08-30 11:33           ` [PATCHv6 11/14] gdb: extend completion of quoted filenames to work in brkchars phase Andrew Burgess
2024-08-30 11:33           ` [PATCHv6 12/14] gdb: add remove-symbol-file command completion Andrew Burgess
2024-08-30 11:33           ` [PATCHv6 13/14] gdb: allow quoted filenames for commands that have custom completion Andrew Burgess
2024-08-30 11:33           ` [PATCHv6 14/14] gdb: 'target ...' commands now expect quoted/escaped filenames Andrew Burgess
2024-09-07 19:57           ` [PATCHv6 00/14] Further filename completion improvements Andrew Burgess

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c6b78a15a901a34d211040311d7ea5f503c4a166.1724173728.git.aburgess@redhat.com \
    --to=aburgess@redhat.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox