RFC: add completion for "set gnutarget"

Tom Tromey
2013-01-03T16:25:34Z

While working on another patch, I got annoyed that "set gnutarget"
doesn't have completion. So, I wrote the appended.

I think it is basically straightforward.

I had to change one of the CLI constructors to return the new
command... to me the proliferation of such constructors and their
various oddities is evidence that this area is factored wrongly, but at
the same time it has never risen near the top of my heap to try to clean
up.

Built and regtested on x86-64 Fedora 16.

Tom

2013-01-02 Tom Tromey <tromey@redhat.com>

* cli/cli-decode.c (add_setshow_string_noescape_cmd): Return the
set command.
* command.h (add_setshow_string_noescape_cmd): Update.
* corefile.c (set_gnutarget_command): Remove trailing whitespace.
(complete_set_gnutarget): New function.
(_initialize_core): Set the "set gnutarget" completer.

2013-01-02 Tom Tromey <tromey@redhat.com>

* gdb.base/completion.exp: Add "set gnutarget" test.

diff --git a/gdb/cli/cli-decode.c b/gdb/cli/cli-decode.c
index 758b0ff..27d94bb 100644
--- a/gdb/cli/cli-decode.c
+++ b/gdb/cli/cli-decode.c
@@ -597,7 +597,7 @@ add_setshow_string_cmd (char *name, enum command_class class,

/* Add element named NAME to both the set and show command LISTs (the
list for set/show or some sublist thereof). */
-void
+struct cmd_list_element *
add_setshow_string_noescape_cmd (char *name, enum command_class class,
char **var,
const char *set_doc, const char *show_doc,
@@ -607,11 +607,14 @@ add_setshow_string_noescape_cmd (char *name, enum command_class class,
struct cmd_list_element **set_list,
struct cmd_list_element **show_list)
{
+ struct cmd_list_element *set_cmd;
+
add_setshow_cmd_full (name, class, var_string_noescape, var,
set_doc, show_doc, help_doc,
set_func, show_func,
set_list, show_list,
- NULL, NULL);
+ &set_cmd, NULL);
+ return set_cmd;
}

/* Add element named NAME to both the set and show command LISTs (the
diff --git a/gdb/command.h b/gdb/command.h
index 6809a62..17662b4 100644
--- a/gdb/command.h
+++ b/gdb/command.h
@@ -291,16 +291,17 @@ extern void add_setshow_string_cmd (char *name,
struct cmd_list_element **set_list,
struct cmd_list_element **show_list);

-extern void add_setshow_string_noescape_cmd (char *name,
- enum command_class class,
- char **var,
- const char *set_doc,
- const char *show_doc,
- const char *help_doc,
- cmd_sfunc_ftype *set_func,
- show_value_ftype *show_func,
- struct cmd_list_element **set_list,
- struct cmd_list_element **show_list);
+extern struct cmd_list_element *add_setshow_string_noescape_cmd
+ (char *name,
+ enum command_class class,
+ char **var,
+ const char *set_doc,
+ const char *show_doc,
+ const char *help_doc,
+ cmd_sfunc_ftype *set_func,
+ show_value_ftype *show_func,
+ struct cmd_list_element **set_list,
+ struct cmd_list_element **show_list);

extern void add_setshow_optional_filename_cmd (char *name,
enum command_class class,
diff --git a/gdb/corefile.c b/gdb/corefile.c
index e940e3c..87b29ee 100644
--- a/gdb/corefile.c
+++ b/gdb/corefile.c
@@ -34,6 +34,7 @@
#include "completer.h"
#include "exceptions.h"
#include "observer.h"
+#include "cli/cli-utils.h"

/* Local function declarations. */

@@ -419,12 +420,40 @@ static void
set_gnutarget_command (char *ignore, int from_tty,
struct cmd_list_element *c)
{
+ char *gend = gnutarget_string + strlen (gnutarget_string);
+
+ gend = remove_trailing_whitespace (gnutarget_string, gend);
+ *gend = '\0';
+
if (strcmp (gnutarget_string, "auto") == 0)
gnutarget = NULL;
else
gnutarget = gnutarget_string;
}

+/* A completion function for "set gnutarget". */
+
+static VEC (char_ptr) *
+complete_set_gnutarget (struct cmd_list_element *cmd, char *text, char *word)
+{
+ const char **bfd_targets = bfd_target_list ();
+ struct cleanup *cleanup = make_cleanup (free_current_contents, &bfd_targets);
+ int last;
+ VEC (char_ptr) *result;
+
+ for (last = 0; bfd_targets[last] != NULL; ++last)
+ ;
+
+ bfd_targets = xrealloc (bfd_targets, (last + 2) * sizeof (const char **));
+ bfd_targets[last] = "auto";
+ bfd_targets[last + 1] = NULL;
+
+ result = complete_on_enum (bfd_targets, text, word);
+ do_cleanups (cleanup);
+
+ return result;
+}
+
/* Set the gnutarget. */
void
set_gnutarget (char *newtarget)
@@ -447,14 +476,16 @@ No arg means have no core file. This command has been superseded by the\n\
set_cmd_completer (c, filename_completer);

- add_setshow_string_noescape_cmd ("gnutarget", class_files,
- &gnutarget_string, _("\
+ c = add_setshow_string_noescape_cmd ("gnutarget", class_files,
+ &gnutarget_string, _("\
Set the current BFD target."), _("\
Show the current BFD target."), _("\
Use `set gnutarget auto' to specify automatic detection."),
- set_gnutarget_command,
- show_gnutarget_string,
- &setlist, &showlist);
+ set_gnutarget_command,
+ show_gnutarget_string,
+ &setlist, &showlist);
+ set_cmd_completer (c, complete_set_gnutarget);
+
add_alias_cmd ("g", "gnutarget", class_files, 1, &setlist);

if (getenv ("GNUTARGET"))
diff --git a/gdb/testsuite/gdb.base/completion.exp b/gdb/testsuite/gdb.base/completion.exp
index 566f5e0..8163a86 100644
--- a/gdb/testsuite/gdb.base/completion.exp
+++ b/gdb/testsuite/gdb.base/completion.exp
@@ -707,6 +707,9 @@ gdb_test "complete ptype struct some_" "ptype struct some_struct"
gdb_test "complete ptype enum some_" "ptype enum some_enum"
gdb_test "complete ptype union some_" "ptype union some_union"

+
+gdb_test "complete set gnutarget aut" "set gnutarget auto"
+
# Restore globals modified in this test...
set timeout $oldtimeout1