[v3,3/3] gdb: Tab-complete registers in expressions

Message ID 20240901214351.3134941-4-nt8r@protonmail.com
State New
Headers
Series Tab complete convenience variables |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Test passed

Commit Message

Antonio Rische Sept. 1, 2024, 9:44 p.m. UTC
  For example, "print $ea<tab>" completes to "print $eax" on x86.

Tested-By: Guinevere Larsen <blarsen@redhat.com>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=7353
---
 gdb/completer.c                       | 18 +++++++++++++++++-
 gdb/testsuite/gdb.base/completion.exp | 26 +++++++++++++++++++++-----
 2 files changed, 38 insertions(+), 6 deletions(-)
  

Patch

diff --git a/gdb/completer.c b/gdb/completer.c
index 0fb085cf8..a495aed19 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -52,6 +52,9 @@  static const char *completion_find_completion_word (completion_tracker &tracker,
 
 static void set_rl_completer_word_break_characters (const char *break_chars);
 
+static void complete_register (completion_tracker &tracker,
+			       const char *text, const char *word);
+
 /* See completer.h.  */
 
 class completion_tracker::completion_hash_entry
@@ -1104,7 +1107,10 @@  complete_expression (completion_tracker &tracker,
 	{
 	  /* We don't support completion of history indices.  */
 	  if (!isdigit (word[0]))
-	    complete_internalvar (tracker, word);
+	    {
+	      complete_internalvar (tracker, word);
+	      complete_register (tracker, text, word);
+	    }
 	  return;
 	}
 
@@ -1870,6 +1876,16 @@  reggroup_completer (struct cmd_list_element *ignore,
 			    complete_reggroup_names);
 }
 
+/* Perform completion on register names.  */
+
+void
+complete_register (completion_tracker &tracker,
+		    const char *text, const char *word)
+{
+  reg_or_group_completer_1 (tracker, text, word,
+			    complete_register_names);
+}
+
 /* The default completer_handle_brkchars implementation.  */
 
 static void
diff --git a/gdb/testsuite/gdb.base/completion.exp b/gdb/testsuite/gdb.base/completion.exp
index 026724dd4..fabb9c8af 100644
--- a/gdb/testsuite/gdb.base/completion.exp
+++ b/gdb/testsuite/gdb.base/completion.exp
@@ -139,17 +139,24 @@  gdb_test "complete set trace-buffer-size unl" "set trace-buffer-size unlimited"
 set regs_output [capture_command_output "mt print registers" \
 		     ".*Name.*Nr.*Rel.*Offset.*Size.*Type.\[^\n\]*\n"]
 append regs_output "\n"
-append regs_output [capture_command_output "mt print reggroups" \
-			".*Group.*Type\[^\n]*\n"]
-append regs_output "\n"
 append regs_output [capture_command_output "mt print user-registers" \
 		     ".*Name.*Nr\[^\n]*\n"]
+set reg_groups_output [capture_command_output "mt print reggroups" \
+			".*Group.*Type\[^\n]*\n"]
+append reg_groups_output "\n"
+
 set all_regs {}
 foreach {- reg} [regexp -all -inline -line {^\s+(\w+)} $regs_output] {
     lappend all_regs $reg
 }
 
-set all_regs [join [lsort -unique $all_regs]]
+set all_reg_groups {}
+foreach {- group} [regexp -all -inline -line {^\s+(\w+)} $reg_groups_output] {
+    lappend all_reg_groups $group
+}
+
+set all_regs_and_groups [concat $all_regs $all_reg_groups]
+set all_regs_and_groups [join [lsort -unique $all_regs_and_groups]]
 
 # ... and then compare them to the completion of "info registers".
 
@@ -159,7 +166,7 @@  foreach {-> reg} [regexp -all -inline -line {^info registers (\w+\S*)} $regs_out
     lappend completed_regs $reg
 }
 set completed_regs [join [lsort $completed_regs]]
-gdb_assert {$all_regs eq $completed_regs} "complete 'info registers '"
+gdb_assert {$all_regs_and_groups eq $completed_regs} "complete 'info registers '"
 
 # Tests below are about tab-completion, which doesn't work if readline
 # library isn't used.  Check it first.
@@ -168,6 +175,15 @@  if { ![readline_is_used] } {
     return -1
 }
 
+# Test "print $<registername>" completion
+set complete_dollar_output [capture_command_output "complete print $" ""]
+
+set found_all_regs true
+foreach {- reg} $all_regs {
+    set found_all_regs [expr $found_all_regs && [string first $reg $complete_dollar_output] != -1]
+}
+gdb_assert $found_all_regs "complete 'print \$' contained all registers"
+
 # The bulk of this test script pre-dates the completion-support
 # library, and should probably (where possible) be converted.
 # However, for now, new tests are being added using this library.