From: Tom Tromey Date: Mon, 20 Mar 2023 17:38:00 +0000 (-0600) Subject: Add second mi_parse constructor X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e7a2797eb00dbbceb6796f1baa120055d174a229;p=binutils-gdb.git Add second mi_parse constructor This adds a second mi_parse constructor. This constructor takes a command name and vector of arguments, and does not do any escape processing. This also changes mi_parse::args to handle parse objects created this new way. --- diff --git a/gdb/mi/mi-parse.c b/gdb/mi/mi-parse.c index 09207164291..a113d4d48da 100644 --- a/gdb/mi/mi-parse.c +++ b/gdb/mi/mi-parse.c @@ -109,6 +109,11 @@ mi_parse_escape (const char **string_ptr) void mi_parse::parse_argv () { + /* If arguments were already computed (or were supplied at + construction), then there's no need to re-compute them. */ + if (argv != nullptr) + return; + const char *chp = m_args.c_str (); int argc = 0; char **argv = XNEWVEC (char *, argc + 1); @@ -217,6 +222,27 @@ mi_parse::~mi_parse () /* See mi-parse.h. */ +const char * +mi_parse::args () +{ + /* If args were already computed, or if there is no pre-computed + argv, just return the args. */ + if (!m_args.empty () || argv == nullptr) + return m_args.c_str (); + + /* Compute args from argv. */ + for (int i = 0; i < argc; ++i) + { + if (!m_args.empty ()) + m_args += " "; + m_args += argv[i]; + } + + return m_args.c_str (); +} + +/* See mi-parse.h. */ + void mi_parse::set_thread_group (const char *arg, char **endp) { @@ -387,6 +413,77 @@ mi_parse::make (const char *cmd, char **token) return parse; } +/* See mi-parse.h. */ + +std::unique_ptr +mi_parse::make (gdb::unique_xmalloc_ptr command, + std::vector> args) +{ + std::unique_ptr parse (new struct mi_parse); + + parse->command = command.release (); + parse->token = xstrdup (""); + + if (parse->command[0] != '-') + throw_error (UNDEFINED_COMMAND_ERROR, + _("MI command '%s' does not start with '-'"), + parse->command); + + /* Find the command in the MI table. */ + parse->cmd = mi_cmd_lookup (parse->command + 1); + if (parse->cmd == NULL) + throw_error (UNDEFINED_COMMAND_ERROR, + _("Undefined MI command: %s"), parse->command); + + /* This over-allocates slightly, but it seems unimportant. */ + parse->argv = XCNEWVEC (char *, args.size () + 1); + + for (size_t i = 0; i < args.size (); ++i) + { + const char *chp = args[i].get (); + + /* See if --all is the last token in the input. */ + if (strcmp (chp, "--all") == 0) + { + parse->all = 1; + } + else if (strcmp (chp, "--thread-group") == 0) + { + ++i; + if (i == args.size ()) + error ("No argument to '--thread-group'"); + parse->set_thread_group (args[i].get (), nullptr); + } + else if (strcmp (chp, "--thread") == 0) + { + ++i; + if (i == args.size ()) + error ("No argument to '--thread'"); + parse->set_thread (args[i].get (), nullptr); + } + else if (strcmp (chp, "--frame") == 0) + { + ++i; + if (i == args.size ()) + error ("No argument to '--frame'"); + parse->set_frame (args[i].get (), nullptr); + } + else if (strcmp (chp, "--language") == 0) + { + ++i; + if (i == args.size ()) + error ("No argument to '--language'"); + parse->set_language (args[i].get (), nullptr); + } + else + parse->argv[parse->argc++] = args[i].release (); + } + + /* Fully parsed, flag as an MI command. */ + parse->op = MI_COMMAND; + return parse; +} + enum print_values mi_parse_print_values (const char *name) { diff --git a/gdb/mi/mi-parse.h b/gdb/mi/mi-parse.h index 19c41f23ed6..6373543529b 100644 --- a/gdb/mi/mi-parse.h +++ b/gdb/mi/mi-parse.h @@ -52,6 +52,15 @@ struct mi_parse static std::unique_ptr make (const char *cmd, char **token); + /* Create an mi_parse object given the command name and a vector + of arguments. Unlike with the other constructor, here the + arguments are treated "as is" -- no escape processing is + done. */ + + static std::unique_ptr make + (gdb::unique_xmalloc_ptr command, + std::vector> args); + ~mi_parse (); DISABLE_COPY_AND_ASSIGN (mi_parse); @@ -61,8 +70,7 @@ struct mi_parse /* Return the full argument string, as used by commands which are implemented as CLI commands. */ - const char *args () const - { return m_args.c_str (); } + const char *args (); enum mi_command_type op = MI_COMMAND; char *command = nullptr;