[PATCHv2 2/5] gdb/mi: use std::map for MI commands in mi-cmds.c
Simon Marchi
simark@simark.ca
Mon Dec 13 15:51:02 GMT 2021
On 2021-12-03 11:29 a.m., Andrew Burgess via Gdb-patches wrote:
> From: Jan Vrany <jan.vrany@labware.com>
>
> This changes the hashmap used in mi-cmds.c from a custom structure to
> std::map. Not only is replacing a custom container with a standard
> one an improvement, but using std::map will make it easier to
> dynamically add commands; which is something that is planned for a
> later series, where we will allow MI commands to be implemented in
> Python.
>
> There should be no user visible changes after this commit.
LGTM with some minor comments, no need to repost just for that.
> ---
> gdb/mi/mi-cmds.c | 478 +++++++++++++++++++++++------------------------
> 1 file changed, 230 insertions(+), 248 deletions(-)
>
> diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
> index 8899fdd3a1e..4999c9f81b3 100644
> --- a/gdb/mi/mi-cmds.c
> +++ b/gdb/mi/mi-cmds.c
> @@ -22,283 +22,265 @@
> #include "top.h"
> #include "mi-cmds.h"
> #include "mi-main.h"
> +#include <map>
> +#include <string>
>
> -struct mi_cmd;
> -static struct mi_cmd **lookup_table (const char *command);
> -static void build_table (struct mi_cmd *commands);
> +/* A command held in the MI_CMD_TABLE. */
>
> -static struct mi_cmd mi_cmds[] =
> -{
> -/* Define a MI command of NAME, and its corresponding CLI command is
> - CLI_NAME. */
> -#define DEF_MI_CMD_CLI_1(NAME, CLI_NAME, ARGS_P, CALLED) \
> - { NAME, { CLI_NAME, ARGS_P}, NULL, CALLED }
> -#define DEF_MI_CMD_CLI(NAME, CLI_NAME, ARGS_P) \
> - DEF_MI_CMD_CLI_1(NAME, CLI_NAME, ARGS_P, NULL)
> +typedef std::unique_ptr<struct mi_cmd> mi_cmd_up;
Really a nit: since we're using C++11, I prefer the notation `using =
..`, I find it easier to read (since it looks like a standard
assignment, with the name on the left).
> +/* Create an mi_cmd structure with name NAME. */
> +
> +static mi_cmd_up
> +create_mi_cmd (const char *name)
> {
> - return *lookup_table (command);
> + mi_cmd_up cmd (new mi_cmd ());
> + cmd->name = name;
> + return cmd;
> }
It looks like this could be a constructor of mi_cmd quite easily,
instead of being a free function.
>
> -/* Used for collecting hash hit/miss statistics. */
> +/* Create and register a new MI command with an MI specific implementation.
> + NAME must name an MI command that does not already exist, otherwise an
> + assertion will trigger. */
>
> -static struct
> +static void
> +add_mi_cmd_mi (const char *name, mi_cmd_argv_ftype function,
> + int *suppress_notification = nullptr)
> {
> - int hit;
> - int miss;
> - int rehash;
> -} stats;
> + mi_cmd_up cmd_up = create_mi_cmd (name);
> +
> + cmd_up->cli.cmd = nullptr;
> + cmd_up->cli.args_p = 0;
> + cmd_up->argv_func = function;
> + cmd_up->suppress_notification = suppress_notification;
... and these could also be initialized in the mi_cmd constructor. Up
to you to see if you want to make that change, it can also be changed
later.
>
> -/* Look up a command. */
> + bool success = insert_mi_cmd_entry (std::move (cmd_up));
> + gdb_assert (success);
> +}
> +
> +/* Create and register a new MI command implemented on top of a CLI
> + command. NAME must name an MI command that does not already exist,
> + otherwise an assertion will trigger. */
>
> -static struct mi_cmd **
> -lookup_table (const char *command)
> +static void
> +add_mi_cmd_cli (const char *name, const char *cli_name, int args_p,
> + int *suppress_notification = nullptr)
> {
> - const char *chp;
> - unsigned int index = 0;
> + mi_cmd_up cmd_up = create_mi_cmd (name);
>
> - /* Compute our hash. */
> - for (chp = command; *chp; chp++)
> - {
> - /* We use a somewhat arbitrary formula. */
> - index = ((index << 6) + (unsigned int) *chp) % MI_TABLE_SIZE;
> - }
> + cmd_up->cli.cmd = cli_name;
> + cmd_up->cli.args_p = args_p;
> + cmd_up->argv_func = nullptr;
> + cmd_up->suppress_notification = suppress_notification;
>
> - while (1)
> - {
> - struct mi_cmd **entry = &mi_table[index];
> - if ((*entry) == 0)
> - {
> - /* not found, return pointer to next free. */
> - stats.miss++;
> - return entry;
> - }
> - if (strcmp (command, (*entry)->name) == 0)
> - {
> - stats.hit++;
> - return entry; /* found */
> - }
> - index = (index + 1) % MI_TABLE_SIZE;
> - stats.rehash++;
> - }
> + bool success = insert_mi_cmd_entry (std::move (cmd_up));
> + gdb_assert (success);
> }
>
> +/* Initialize MI_CMD_TABLE, the global map of MI commands. */
> +
> static void
> -build_table (struct mi_cmd *commands)
> +build_table ()
Suggest renaming this to something like "add_builtin_mi_cmds", it would
be more descriptive.
Simon
More information about the Gdb-patches
mailing list