public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Andrew Burgess <aburgess@redhat.com>
To: gdb-patches@sourceware.org
Cc: Andrew Burgess <aburgess@redhat.com>,
	Lancelot SIX <lsix@lancelotsix.com>, Eli Zaretskii <eliz@gnu.org>
Subject: [PATCHv2 5/8] gdb: simplify completion_result::print_matches
Date: Sat, 20 Apr 2024 10:10:05 +0100	[thread overview]
Message-ID: <7a132f2949bb05f00d0ffb6be8e0863417a7e0fc.1713603416.git.aburgess@redhat.com> (raw)
In-Reply-To: <cover.1713603415.git.aburgess@redhat.com>

Simplify completion_result::print_matches by removing one of the code
paths.  Now, every time we call ::print_matches we always add the
trailing quote.

Previously, when using the 'complete' command, if there was only one
result then trailing quote was added in ::build_completion_result, but
when we had multiple results the trailing quote was added in
::print_matches.  As a consequence, ::print_matches had to understand
not to add the trailing quote for the single result case.

After this commit we don't add the trailing quote in
::build_completion_result, instead ::print_matches always adds the
trailing quote, which makes ::print_matches simpler.

However, there is a slight problem.  When completion is being driven
by readline, and not by the 'complete' command, we still need to
manually add the trailing quote in the single result case, and as the
printing is done by readline we can't add the quote at the time of
printing, and so, in ::build_completion_result, we still add the
trailing quote, but only when completion is being done for readline.

And this does cause a small problem.  When completing a filename, if
the completion results in a directory name then, when using the
'complete' command, GDB should not be adding a trailing quote.  For
example, if we have the file /tmp/xxx/foo.c, then what we should see
is this:

  (gdb) complete file '/tmp/xx
  file 'tmp/xxx/

But what we actually see after this commit is this:

  (gdb) complete file '/tmp/xx
  file 'tmp/xxx/'

Previously we didn't get the trailing quote in this case, as when
there is only a single result, the quote was added in
::build_completion_result, and for filename completion, GDB didn't
know what the quote character was in ::build_completion_result, so no
quote was added.  Now that the trailing quote is always added in
::print_matches, and GDB does know the quote character at this point,
so we are now getting the trailing quote, which is not correct.

This is a regression, but really, GDB is now broken in a consistent
way, if we create the file /tmp/xxa/bar.c, then previously if we did
this:

  (gdb) complete file '/tmp/xx
  file '/tmp/xxa/'
  file '/tmp/xxx/'

Notice how we get the trailing quote in this case, this is the before
patch behaviour, and is also wrong.

A later commit will fix things so that the trailing quote is not added
in this filename completion case, but for now I'm going to accept this
small regression.

This change in behaviour caused some failures in one of the completion
tests, I've tweaked the test case to expect the trailing quote as part
of this commit, but will revert this in a later commit in this series.

I've also added an extra test for when the 'complete' command does
complete to a single complete filename, in which case the trailing
quote is expected.
---
 gdb/completer.c                               | 62 +++++++++----------
 .../gdb.base/filename-completion.exp          | 21 ++++++-
 2 files changed, 50 insertions(+), 33 deletions(-)

diff --git a/gdb/completer.c b/gdb/completer.c
index af1c09b45b1..4ba45a35f8f 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -2327,23 +2327,30 @@ completion_tracker::build_completion_result (const char *text,
 
   if (m_lowest_common_denominator_unique)
     {
-      /* We don't rely on readline appending the quote char as
-	 delimiter as then readline wouldn't append the ' ' after the
-	 completion.  */
-      char buf[2] = { (char) quote_char () };
-
-      match_list[0] = reconcat (match_list[0], match_list[0],
-				buf, (char *) NULL);
-      match_list[1] = NULL;
-
-      /* If the tracker wants to, or we already have a space at the
-	 end of the match, tell readline to skip appending
-	 another.  */
-      char *match = match_list[0];
-      bool completion_suppress_append
-	= (suppress_append_ws ()
-	   || (match[0] != '\0'
-	       && match[strlen (match) - 1] == ' '));
+      bool completion_suppress_append;
+
+      if (from_readline ())
+	{
+	  /* We don't rely on readline appending the quote char as
+	     delimiter as then readline wouldn't append the ' ' after the
+	     completion.  */
+	  char buf[2] = { (char) quote_char (), '\0' };
+
+	  match_list[0] = reconcat (match_list[0], match_list[0], buf,
+				    (char *) nullptr);
+
+	  /* If the tracker wants to, or we already have a space at the end
+	     of the match, tell readline to skip appending another.  */
+	  char *match = match_list[0];
+	  completion_suppress_append
+	    = (suppress_append_ws ()
+	       || (match[0] != '\0'
+		   && match[strlen (match) - 1] == ' '));
+	}
+      else
+	completion_suppress_append = false;
+
+      match_list[1] = nullptr;
 
       return completion_result (match_list, 1, completion_suppress_append);
     }
@@ -2465,21 +2472,14 @@ void
 completion_result::print_matches (const std::string &prefix,
 				  const char *word, int quote_char)
 {
-  if (this->number_matches == 1)
-    printf_unfiltered ("%s%s\n", prefix.c_str (), this->match_list[0]);
-  else
-    {
-      this->sort_match_list ();
+  this->sort_match_list ();
 
-      for (size_t i = 0; i < this->number_matches; i++)
-	{
-	  printf_unfiltered ("%s%s", prefix.c_str (),
-			     this->match_list[i + 1]);
-	  if (quote_char)
-	    printf_unfiltered ("%c", quote_char);
-	  printf_unfiltered ("\n");
-	}
-    }
+  char buf[2] = { (char) quote_char, '\0' };
+  size_t off = this->number_matches == 1 ? 0 : 1;
+
+  for (size_t i = 0; i < this->number_matches; i++)
+    printf_unfiltered ("%s%s%s\n", prefix.c_str (),
+		       this->match_list[i + off], buf);
 
   if (this->number_matches == max_completions)
     {
diff --git a/gdb/testsuite/gdb.base/filename-completion.exp b/gdb/testsuite/gdb.base/filename-completion.exp
index 275140ffd9d..3e3b9b29ba4 100644
--- a/gdb/testsuite/gdb.base/filename-completion.exp
+++ b/gdb/testsuite/gdb.base/filename-completion.exp
@@ -82,8 +82,25 @@ proc run_quoting_and_escaping_tests { root } {
 	    test_gdb_complete_none "$cmd ${qc}${root}/xx" \
 		"expand a non-existent filename"
 
-	    test_gdb_complete_unique "$cmd ${qc}${root}/a" \
-		"$cmd ${qc}${root}/aaa/" "" false \
+	    # The following test is split into separate cmd and tab calls
+	    # so we can xfail the cmd version.  The cmd version will add a
+	    # closing quote, it shouldn't be doing this.  This will be
+	    # fixed in a later commit.
+	    if { $qc ne "" } {
+		setup_xfail "*-*-*"
+	    }
+	    test_gdb_complete_cmd_unique "file ${qc}${root}/a" \
+		"file ${qc}${root}/aaa/" \
+		"expand a unique directory name"
+
+	    if { [readline_is_used] } {
+		test_gdb_complete_tab_unique "file ${qc}${root}/a" \
+		    "file ${qc}${root}/aaa/" "" \
+		    "expand a unique directory name"
+	    }
+
+	    test_gdb_complete_unique "file ${qc}${root}/cc2" \
+		"file ${qc}${root}/cc2${qc}" " " false \
 		"expand a unique filename"
 
 	    test_gdb_complete_multiple "$cmd ${qc}${root}/" \
-- 
2.25.4


  parent reply	other threads:[~2024-04-20  9:10 UTC|newest]

Thread overview: 38+ 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   ` Andrew Burgess [this message]
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

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=7a132f2949bb05f00d0ffb6be8e0863417a7e0fc.1713603416.git.aburgess@redhat.com \
    --to=aburgess@redhat.com \
    --cc=eliz@gnu.org \
    --cc=gdb-patches@sourceware.org \
    --cc=lsix@lancelotsix.com \
    /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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).