aboutsummaryrefslogtreecommitdiff
path: root/gdb/remote-sim.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2017-07-18 11:38:17 +0100
committerPedro Alves <palves@redhat.com>2017-07-18 11:38:17 +0100
commit386535dd91432b784f6a46f8a92c6a599ba30174 (patch)
treedde4a840f347150c793c61eae71cb1769ceae0b7 /gdb/remote-sim.c
parent0a79bef4f206d89214c48454a4302d6b6f8f68c0 (diff)
downloadgdb-386535dd91432b784f6a46f8a92c6a599ba30174.zip
gdb-386535dd91432b784f6a46f8a92c6a599ba30174.tar.gz
gdb-386535dd91432b784f6a46f8a92c6a599ba30174.tar.bz2
Fix GDB builds that include the simulator
The completer rewrite series missed adjusting target sim to the new completion_tracker interface. src/gdb/remote-sim.c: In function ‘void _initialize_remote_sim()’: src/gdb/remote-sim.c:1350:46: error: invalid conversion from ‘VEC_char_ptr* (*)(cmd_list_element*, const char*, const char*)’ to ‘void (*)(cmd_list_element*, completion_tracker&, const char*, const char*)’ [-fpermissive] set_cmd_completer (c, sim_command_completer); ^ This commit fixes it, and also takes care to be exception safe (the previous code would leak if growing the VEC throws). Tested manually with a --target=arm-none-eabi build. gdb/ChangeLog: 2017-07-18 Pedro Alves <palves@redhat.com> * remote-sim.c (sim_command_completer): Adjust to work with a completion_tracker instead of a VEC.
Diffstat (limited to 'gdb/remote-sim.c')
-rw-r--r--gdb/remote-sim.c48
1 files changed, 33 insertions, 15 deletions
diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c
index 13137ab..508e2c2 100644
--- a/gdb/remote-sim.c
+++ b/gdb/remote-sim.c
@@ -1220,30 +1220,48 @@ simulator_command (char *args, int from_tty)
registers_changed ();
}
-static VEC (char_ptr) *
-sim_command_completer (struct cmd_list_element *ignore, const char *text,
- const char *word)
+static void
+sim_command_completer (struct cmd_list_element *ignore,
+ completion_tracker &tracker,
+ const char *text, const char *word)
{
struct sim_inferior_data *sim_data;
- char **tmp;
- int i;
- VEC (char_ptr) *result = NULL;
sim_data = ((struct sim_inferior_data *)
inferior_data (current_inferior (), sim_inferior_data_key));
if (sim_data == NULL || sim_data->gdbsim_desc == NULL)
- return NULL;
+ return;
- tmp = sim_complete_command (sim_data->gdbsim_desc, text, word);
- if (tmp == NULL)
- return NULL;
+ /* sim_complete_command returns a NULL-terminated malloc'ed array of
+ malloc'ed strings. */
+ struct sim_completions_deleter
+ {
+ void operator() (char **ptr) const
+ {
+ for (size_t i = 0; ptr[i] != NULL; i++)
+ xfree (ptr[i]);
+ xfree (ptr);
+ }
+ };
+
+ std::unique_ptr<char *[], sim_completions_deleter> sim_completions
+ (sim_complete_command (sim_data->gdbsim_desc, text, word));
+ if (sim_completions == NULL)
+ return;
- /* Transform the array into a VEC, and then free the array. */
- for (i = 0; tmp[i] != NULL; i++)
- VEC_safe_push (char_ptr, result, tmp[i]);
- xfree (tmp);
+ /* Count the elements and add completions from tail to head because
+ below we'll swap elements out of the array in case add_completion
+ throws and the deleter deletes until it finds a NULL element. */
+ size_t count = 0;
+ while (sim_completions[count] != NULL)
+ count++;
- return result;
+ for (size_t i = count; i > 0; i--)
+ {
+ gdb::unique_xmalloc_ptr<char> match (sim_completions[i - 1]);
+ sim_completions[i - 1] = NULL;
+ tracker.add_completion (std::move (match));
+ }
}
/* Check to see if a thread is still alive. */