public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Andrew Burgess <aburgess@redhat.com>
To: Simon Marchi via Gdb-patches <gdb-patches@sourceware.org>,
	gdb-patches@sourceware.org
Cc: Simon Marchi <simon.marchi@efficios.com>
Subject: Re: [PATCH 04/21] gdb: make interp_lookup a method of struct ui
Date: Tue, 12 Sep 2023 10:15:14 +0100	[thread overview]
Message-ID: <87ledbkb19.fsf@redhat.com> (raw)
In-Reply-To: <20230908190227.96319-5-simon.marchi@efficios.com>

Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> writes:

> This requires exposing some things about interpreter factories in
> interps.h, for ui.c to use it.  No behavior changes expected.
>
> Change-Id: I7a9e93621c0588e367b5356916d4dad90757bb3d
> ---
>  gdb/cli/cli-script.c |  2 +-
>  gdb/interps.c        | 58 ++++++++++++--------------------------------
>  gdb/interps.h        | 25 ++++++++++++++-----
>  gdb/mi/mi-interp.c   |  4 +--
>  gdb/python/python.c  |  2 +-
>  gdb/ui.c             | 25 ++++++++++++++++++-
>  gdb/ui.h             |  6 +++++
>  7 files changed, 68 insertions(+), 54 deletions(-)
>
> diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c
> index 8ec5689ebcfd..49ba854c2a09 100644
> --- a/gdb/cli/cli-script.c
> +++ b/gdb/cli/cli-script.c
> @@ -702,7 +702,7 @@ execute_control_command (struct command_line *cmd, int from_tty)
>  
>    /* Make sure we use the console uiout.  It's possible that we are executing
>       breakpoint commands while running the MI interpreter.  */
> -  interp *console = interp_lookup (current_ui, INTERP_CONSOLE);
> +  interp *console = current_ui->lookup_interp (INTERP_CONSOLE);
>    scoped_restore save_uiout
>      = make_scoped_restore (&current_uiout, console->interp_ui_out ());
>  
> diff --git a/gdb/interps.c b/gdb/interps.c
> index b05a6c4eb875..bd95c3175adb 100644
> --- a/gdb/interps.c
> +++ b/gdb/interps.c
> @@ -48,22 +48,6 @@ interp::interp (const char *name)
>  
>  interp::~interp () = default;
>  
> -/* An interpreter factory.  Maps an interpreter name to the factory
> -   function that instantiates an interpreter by that name.  */
> -
> -struct interp_factory
> -{
> -  interp_factory (const char *name_, interp_factory_func func_)
> -  : name (name_), func (func_)
> -  {}
> -
> -  /* This is the name in "-i=INTERP" and "interpreter-exec INTERP".  */
> -  const char *name;
> -
> -  /* The function that creates the interpreter.  */
> -  interp_factory_func func;
> -};
> -
>  /* The registered interpreter factories.  */
>  static std::vector<interp_factory> interpreter_factories;
>  
> @@ -83,6 +67,18 @@ interp_factory_register (const char *name, interp_factory_func func)
>    interpreter_factories.emplace_back (name, func);
>  }
>  
> +/* See interps.h.  */
> +
> +const interp_factory *
> +find_interp_factory (const char *name)
> +{
> +  for (const interp_factory &factory : interpreter_factories)
> +    if (strcmp (factory.name, name) == 0)
> +      return &factory;
> +
> +  return nullptr;
> +}
> +
>  /* This sets the current interpreter to be INTERP.  If INTERP has not
>     been initialized, then this will also run the init method.
>  
> @@ -145,35 +141,11 @@ interp_set (struct interp *interp, bool top_level)
>  
>  /* See interps.h.  */
>  
> -struct interp *
> -interp_lookup (struct ui *ui, const char *name)
> -{
> -  if (name == NULL || strlen (name) == 0)
> -    return NULL;
> -
> -  /* Only create each interpreter once per top level.  */
> -  interp *interp = ui->lookup_existing_interp (name);
> -  if (interp != NULL)
> -    return interp;
> -
> -  for (const interp_factory &factory : interpreter_factories)
> -    if (strcmp (factory.name, name) == 0)
> -      {
> -	interp = factory.func (factory.name);
> -	ui->add_interp (interp);
> -	return interp;
> -      }
> -
> -  return NULL;
> -}
> -
> -/* See interps.h.  */
> -
>  void
>  set_top_level_interpreter (const char *name)
>  {
>    /* Find it.  */
> -  struct interp *interp = interp_lookup (current_ui, name);
> +  struct interp *interp = current_ui->lookup_interp (name);
>  
>    if (interp == NULL)
>      error (_("Interpreter `%s' unrecognized"), name);
> @@ -194,7 +166,7 @@ current_interp_set_logging (ui_file_up logfile, bool logging_redirect,
>  struct interp *
>  scoped_restore_interp::set_interp (const char *name)
>  {
> -  struct interp *interp = interp_lookup (current_ui, name);
> +  struct interp *interp = current_ui->lookup_interp (name);
>    struct interp *old_interp = current_ui->current_interpreter;
>  
>    if (interp)
> @@ -290,7 +262,7 @@ interpreter_exec_cmd (const char *args, int from_tty)
>  
>    interp *old_interp = current_ui->current_interpreter;
>  
> -  interp_to_use = interp_lookup (current_ui, prules[0]);
> +  interp_to_use = current_ui->lookup_interp (prules[0]);
>    if (interp_to_use == NULL)
>      error (_("Could not find interpreter \"%s\"."), prules[0]);
>  
> diff --git a/gdb/interps.h b/gdb/interps.h
> index 287df2c8c810..433d92439eba 100644
> --- a/gdb/interps.h
> +++ b/gdb/interps.h
> @@ -36,6 +36,22 @@ struct trace_state_variable;
>  
>  typedef struct interp *(*interp_factory_func) (const char *name);
>  
> +/* An interpreter factory.  Maps an interpreter name to the factory
> +   function that instantiates an interpreter by that name.  */
> +
> +struct interp_factory
> +{
> +  interp_factory (const char *name_, interp_factory_func func_)
> +  : name (name_), func (func_)
> +  {}
> +
> +  /* This is the name in "-i=INTERP" and "interpreter-exec INTERP".  */
> +  const char *name;
> +
> +  /* The function that creates the interpreter.  */
> +  interp_factory_func func;
> +};
> +
>  /* Each interpreter kind (CLI, MI, etc.) registers itself with a call
>     to this function, passing along its name, and a pointer to a
>     function that creates a new instance of an interpreter with that
> @@ -45,6 +61,9 @@ typedef struct interp *(*interp_factory_func) (const char *name);
>  extern void interp_factory_register (const char *name,
>  				     interp_factory_func func);
>  
> +/* Return the interpreter factory for NAME.  Return nullptr if not found.  */
> +extern const interp_factory *find_interp_factory (const char *name);
> +
>  extern void interp_exec (struct interp *interp, const char *command);
>  
>  class interp : public intrusive_list_node<interp>
> @@ -193,12 +212,6 @@ class interp : public intrusive_list_node<interp>
>    bool inited = false;
>  };
>  
> -/* Look up the interpreter for NAME, creating one if none exists yet.
> -   If NAME is not a interpreter type previously registered with
> -   interp_factory_register, return NULL; otherwise return a pointer to
> -   the interpreter.  */
> -extern struct interp *interp_lookup (struct ui *ui, const char *name);
> -
>  /* Set the current UI's top level interpreter to the interpreter named
>     NAME.  Throws an error if NAME is not a known interpreter or the
>     interpreter fails to initialize.  */
> diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
> index b3b0f5bb1f51..946fed5867c4 100644
> --- a/gdb/mi/mi-interp.c
> +++ b/gdb/mi/mi-interp.c
> @@ -162,7 +162,7 @@ mi_cmd_interpreter_exec (const char *command, const char *const *argv,
>      error (_("-interpreter-exec: "
>  	     "Usage: -interpreter-exec interp command"));
>  
> -  interp_to_use = interp_lookup (current_ui, argv[0]);
> +  interp_to_use = current_ui->lookup_interp (argv[0]);
>    if (interp_to_use == NULL)
>      error (_("-interpreter-exec: could not find interpreter \"%s\""),
>  	   argv[0]);
> @@ -416,7 +416,7 @@ mi_interp::on_normal_stop (struct bpstat *bs, int print_frame)
>  	  mi_uiout->field_string ("reason", async_reason_lookup (reason));
>  	}
>  
> -      interp *console_interp = interp_lookup (current_ui, INTERP_CONSOLE);
> +      interp *console_interp = current_ui->lookup_interp (INTERP_CONSOLE);
>  
>        /* We only want to print the displays once, and we want it to
>  	 look just how it would on the console, so we use this to
> diff --git a/gdb/python/python.c b/gdb/python/python.c
> index 6a978d632e9a..a1aaa29d0ce5 100644
> --- a/gdb/python/python.c
> +++ b/gdb/python/python.c
> @@ -683,7 +683,7 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
>  
>  	/* Use the console interpreter uiout to have the same print format
>  	   for console or MI.  */
> -	interp = interp_lookup (current_ui, "console");
> +	interp = current_ui->lookup_interp ("console");

Might as well take this opportunity to replace "console" with
INTERP_CONSOLE which is what we use everywhere else.

>  	current_uiout = interp->interp_ui_out ();
>  
>  	if (to_string)
> diff --git a/gdb/ui.c b/gdb/ui.c
> index 624187ac73c3..a7b81c077e9a 100644
> --- a/gdb/ui.c
> +++ b/gdb/ui.c
> @@ -169,7 +169,30 @@ ui::add_interp (interp *interp)
>    this->interp_list.push_back (*interp);
>  }
>  
> -/* See top.h.  */
> +/* See interps.h.  */
> +
> +interp *
> +ui::lookup_interp (const char *name)
> +{
> +  if (name == nullptr || strlen (name) == 0)
> +    return nullptr;
> +
> +  /* Only create each interpreter once per UI.  */
> +  interp *interp = this->lookup_existing_interp (name);
> +  if (interp != nullptr)
> +    return interp;
> +
> +  const interp_factory *factory = find_interp_factory (name);
> +  if (factory == nullptr)
> +    return nullptr;
> +
> +  interp = factory->func (factory->name);
> +  this->add_interp (interp);
> +
> +  return interp;
> +}

Rather than exposing the interpreter factor stuff outside of interp.c, I
think a better approach would be either move ui::lookup_interp into
interp.c -- personally, I'm happy to see different parts of an object in
different .c files when that makes sense.

But if you prefer all to keep ui implementation in ui.c, rather than
calling find_interp_factory and then factory->func, we could just have a
new function `create_interp (name)` which creates an interpreter, or
returns nullptr, then we can write:

  interp = create_interp (name);
  if (interp != nullptr)
    this->add_interp (interp);
  return interp;

And all the factory stuff can remain private to interp.c.

Thoughts?

Thanks,
Andrew

> +
> +/* See ui.h.  */
>  
>  void
>  ui::unregister_file_handler ()
> diff --git a/gdb/ui.h b/gdb/ui.h
> index 48cad96b3fb8..aeb26c68823a 100644
> --- a/gdb/ui.h
> +++ b/gdb/ui.h
> @@ -163,6 +163,12 @@ struct ui : public intrusive_list_node<ui>
>       return nullptr, otherwise return a pointer to the interpreter.  */
>    interp *lookup_existing_interp (const char *name) const;
>  
> +  /* Look up the interpreter for NAME, creating one if none exists yet.
> +     If NAME is not a interpreter type previously registered with
> +     interp_factory_register, return nullptr; otherwise return a pointer to
> +     the interpreter.  */
> +  interp *lookup_interp (const char *name);
> +
>    /* Add interpreter INTERP to this UI's interpreter list.  The
>       interpreter must not have previously been added.  */
>    void add_interp (interp *interp);
> -- 
> 2.42.0


  reply	other threads:[~2023-09-12  9:15 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-08 18:22 [PATCH 00/21] ui / interp cleansup Simon Marchi
2023-09-08 18:22 ` [PATCH 01/21] gdb: use intrusive_list for struct ui linked list Simon Marchi
2023-09-08 18:22 ` [PATCH 02/21] gdb: make interp_lookup_existing a method of struct ui Simon Marchi
2023-09-08 18:22 ` [PATCH 03/21] gdb: make interp_add " Simon Marchi
2023-09-08 18:22 ` [PATCH 04/21] gdb: make interp_lookup " Simon Marchi
2023-09-12  9:15   ` Andrew Burgess [this message]
2023-09-12 14:38     ` Simon Marchi
2023-09-08 18:22 ` [PATCH 05/21] gdb: remove ui:::add_interp and ui::lookup_existing_interp Simon Marchi
2023-09-08 18:23 ` [PATCH 06/21] gdb: uncover some current_ui uses in interp_set Simon Marchi
2023-09-08 18:23 ` [PATCH 07/21] gdb: add backlink to ui in interp Simon Marchi
2023-09-08 18:23 ` [PATCH 08/21] gdb: pass ui down to gdb_setup_readline and gdb_disable_readline Simon Marchi
2023-09-08 18:23 ` [PATCH 09/21] gdb/python: use m_ui instead of current_ui in dap_interp::init Simon Marchi
2023-09-08 18:23 ` [PATCH 10/21] gdb/mi: use m_ui instead of current_ui in mi_interp::init Simon Marchi
2023-09-08 18:23 ` [PATCH 11/21] gdb/cli: use m_ui instead of current_ui in cli_interp::resume Simon Marchi
2023-09-12 10:40   ` Andrew Burgess
2023-09-12 15:42     ` Simon Marchi
2023-09-08 18:23 ` [PATCH 12/21] gdb/tui: use m_ui instead of current_ui in tui_interp::resume Simon Marchi
2023-09-12 10:41   ` Andrew Burgess
2023-09-08 18:23 ` [PATCH 13/21] gdb/mi: use m_ui instead of current_ui in mi_interp::resume Simon Marchi
2023-09-12 10:44   ` Andrew Burgess
2023-09-12 16:36     ` Simon Marchi
2023-09-08 18:23 ` [PATCH 14/21] gdb/cli: use m_ui instead of current_ui in cli_interp::suspend Simon Marchi
2023-09-08 18:23 ` [PATCH 15/21] gdb/tui: use m_ui instead of current_ui in tui_interp::suspend Simon Marchi
2023-09-08 18:23 ` [PATCH 16/21] gdb/mi: use m_ui instead of current_ui in mi_interp::suspend Simon Marchi
2023-09-08 18:23 ` [PATCH 17/21] gdb: pass current_ui down to interp_set Simon Marchi
2023-09-12 10:54   ` Andrew Burgess
2023-09-12 17:17     ` Simon Marchi
2023-09-08 18:23 ` [PATCH 18/21] gdb: make interp_set a method of struct ui Simon Marchi
2023-09-12 10:58   ` Andrew Burgess
2023-09-12 17:23     ` Simon Marchi
2023-09-12 13:41   ` Tom Tromey
2023-09-12 17:32     ` Simon Marchi
2023-09-08 18:23 ` [PATCH 19/21] gdb: pass down current_ui to set_top_level_interpreter Simon Marchi
2023-09-11 15:15   ` Simon Marchi
2023-09-08 18:23 ` [PATCH 20/21] gdb: make set_top_level_interpreter a method of struct ui Simon Marchi
2023-09-12 11:20   ` Andrew Burgess
2023-09-12 17:41     ` Simon Marchi
2023-09-08 18:23 ` [PATCH 21/21] gdb: make top_level_interpreter " Simon Marchi
2023-09-12 11:35   ` Andrew Burgess
2023-09-12 17:54     ` Simon Marchi
2023-09-12 11:38 ` [PATCH 00/21] ui / interp cleansup Andrew Burgess
2023-09-12 17:51   ` Simon Marchi
2023-09-12 18:06   ` Tom Tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87ledbkb19.fsf@redhat.com \
    --to=aburgess@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=simon.marchi@efficios.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).