This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] C++-fy struct interp/cli_interp/tui_interp/mi_interp


Since "struct interp"-related things showed up on the radar, I decided
to convert the interp hierarchy to real C++ classes...

I didn't want to spend much time on this at this time, so I resisted
doing any significant redesign.  I went for 1-1 conversion.  I also
didn't try to do the obvious next step of making the class data fields
private.  We can probably do more cleaning up and merging of the CLI
and TUI interpreters.  Anyhow, I think this is a sufficient
improvement as is.

- The interp->data field disappears, since we can put data in the
  interpreter directly now.  I left the "init" method in place, but it
  now returns void.

- A few places check if the interpreter method is NULL before calling
  it, and also check whether the method returns true/false.  While
  removing the NULL check, I noticed that for some methods, all
  implementations always return true.  For those cases, I made the
  C++-fied method return void instead.  I didn't bother splitting that
  to a separate patch since it would require touching the exact same
  lines twice.

Tested on x86_64 Fedora 23.

gdb/ChangeLog:
2017-02-02  Pedro Alves  <palves@redhat.com>

	* cli/cli-interp.c (cli_interp_base::cli_interp_base)
	(cli_interp_base::~cli_interp_base): New.
	(cli_interp): New struct.
	(as_cli_interp): Cast the interp itself to cli_interp.
	(cli_interpreter_pre_command_loop): Rename to ...
	(cli_interp_base::pre_command_loop): ... this.  Remove 'self'
	parameter.
	(cli_interpreter_init): Rename to ...
	(cli_interp::init): ... this.  Remove 'self' parameter.  Use
	boolean.  Make extern.
	(cli_interpreter_resume): Rename to ...
	(cli_interp::resume): ... this.  Remove 'data' parameter.  Make
	extern.
	(cli_interpreter_suspend): Rename to ...
	(cli_interp::suspend): ... this.  Remove 'data' parameter.  Make
	extern.
	(cli_interpreter_exec): Rename to ...
	(cli_interp::exec): ... this.  Remove 'data' parameter.  Make
	extern.
	(cli_interpreter_supports_command_editing): Rename to ...
	(cli_interp_base::supports_command_editing): ... this.  Remove
	'interp' parameter.  Make extern.
	(cli_ui_out): Rename to ...
	(cli_interp::interp_ui_out): ... this.  Remove 'interp' parameter.
	Make extern.
	(cli_set_logging): Rename to ...
	(cli_interp_base::set_logging): ... this.  Remove 'interp'
	parameter.  Make extern.
	(cli_interp_procs): Delete.
	(cli_interp_factory): Adjust to use "new".
	* cli/cli-interp.h: Include "interps.h".
	(struct cli_interp_base): New struct.
	* interps.c (struct interp): Delete.  Fields moved to interps.h.
	(interp_new): Delete.
	(interp::interp, interp::~interp): New.
	(interp_set): Use bool, and return void.  Assume the interpreter
	has suspend, init and resume methods, and that the all return
	void.
	(set_top_level_interpreter): interp_set returns void.
	(interp_ui_out): Adapt.
	(current_interp_set_logging): Adapt.
	(interp_data): Delete.
	(interp_pre_command_loop, interp_supports_command_editing): Adapt.
	(interp_exec): Adapt.
	(top_level_interpreter_data): Delete.
	* interps.h (interp_init_ftype, interp_resume_ftype)
	(interp_suspend_ftype, interp_exec_ftype)
	(interp_pre_command_loop_ftype, interp_ui_out_ftype): Delete.
	(class interp): New.
	(interp_new): Delete.
	(interp_set): Now returns void.  Use bool.
	(interp_data, top_level_interpreter_data): Delete.
	* mi/mi-common.h: Include interps.h.
	(class mi_interp): Inherit from interp.  Define a ctor.  Declare
	init, resume, suspect, exec, interp_ui_out, set_logging and
	pre_command_loop methods.
	* mi/mi-interp.c (as_mi_interp): Cast the interp itself.
	(mi_interpreter_init): Rename to ...
	(mi_interp::init): ... this.  Remove the 'interp' parameter, use
	bool, return void and make extern.  Adjust.
	(mi_interpreter_resume): ... Rename to ...
	(mi_interp::resume): ... this.  Remove the 'data' parameter,
	return void and make extern.  Adjust.
	(mi_interpreter_suspend): ... Rename to ...
	(mi_interp::suspend): ... this.  Remove the 'data' parameter,
	return void and make extern.  Adjust.
	(mi_interpreter_exec): ... Rename to ...
	(mi_interp::exec): ... this.  Remove the 'data' parameter and make
	extern.  Adjust.
	(mi_interpreter_pre_command_loop): ... Rename to ...
	(mi_interp::pre_command_loop): ... this.  Remove the 'self'
	parameter and make extern.
	(mi_on_normal_stop_1): Adjust.
	(mi_ui_out): Rename to ...
	(mi_interp::interp_ui_out): ... this.  Remove the 'interp'
	parameter and make extern.  Adjust.
	(mi_set_logging): Rename to ...
	(mi_interp::set_logging): ... this.  Remove the 'interp'
	parameter and make extern.  Adjust.
	(mi_interp_procs): Delete.
	(mi_interp_factory): Adjust to use 'new'.
	* mi/mi-main.c (mi_cmd_gdb_exit, captured_mi_execute_command)
	(mi_print_exception, mi_execute_command, mi_load_progress):
	Adjust.
	* tui/tui-interp.c (tui_interp): New class.
	(as_tui_interp): Return a tui_interp pointer.
	(tui_on_normal_stop, tui_on_signal_received)
	(tui_on_end_stepping_range, tui_on_signal_exited, tui_on_exited)
	(tui_on_no_history, tui_on_user_selected_context_changed): Adjust
	to use interp::interp_ui_out.
	(tui_init): Rename to ...
	(tui_interp::init): ... this.  Remove the 'self' parameter, use
	bool, return void and make extern.  Adjust.
	(tui_resume): Rename to ...
	(tui_interp::resume): ... this.  Remove the 'data' parameter,
	return void and make extern.  Adjust.
	(tui_suspend): Rename to ...
	(tui_interp::suspend): ... this.  Remove the 'data' parameter,
	return void and make extern.  Adjust.
	(tui_ui_out): Rename to ...
	(tui_interp::interp_ui_out): ... this.  Remove the 'self'
	parameter, and make extern.  Adjust.
	(tui_exec): Rename to ...
	(tui_interp::exec): ... this.  Remove the 'data' parameter and
	make extern.
	(tui_interp_procs): Delete.
	(tui_interp_factory): Use "new".
---
 gdb/cli/cli-interp.c |  89 ++++++++++++++++++------------------
 gdb/cli/cli-interp.h |  15 ++++++-
 gdb/interps.c        | 124 ++++++++++-----------------------------------------
 gdb/interps.h        |  62 ++++++++++++++------------
 gdb/mi/mi-common.h   |  19 +++++++-
 gdb/mi/mi-interp.c   |  69 ++++++++++------------------
 gdb/mi/mi-main.c     |  14 +++---
 gdb/tui/tui-interp.c |  74 +++++++++++++++---------------
 8 files changed, 197 insertions(+), 269 deletions(-)

diff --git a/gdb/cli/cli-interp.c b/gdb/cli/cli-interp.c
index e0327f6..8712c75 100644
--- a/gdb/cli/cli-interp.c
+++ b/gdb/cli/cli-interp.c
@@ -30,13 +30,37 @@
 #include "gdbthread.h"
 #include "thread-fsm.h"
 
+cli_interp_base::cli_interp_base (const char *name)
+  : interp (name)
+{}
+
+cli_interp_base::~cli_interp_base ()
+{}
+
 /* The console interpreter.  */
-struct cli_interp
+
+class cli_interp final : public cli_interp_base
 {
+ public:
+  explicit cli_interp (const char *name);
+
+  void init (bool top_level) override;
+  void resume () override;
+  void suspend () override;
+  gdb_exception exec (const char *command_str) override;
+  ui_out *interp_ui_out () override;
+
   /* The ui_out for the console interpreter.  */
   cli_ui_out *cli_uiout;
 };
 
+cli_interp::cli_interp (const char *name)
+  : cli_interp_base (name)
+{
+  /* Create a default uiout builder for the CLI.  */
+  this->cli_uiout = cli_out_new (gdb_stdout);
+}
+
 /* Suppress notification struct.  */
 struct cli_suppress_notification cli_suppress_notification =
   {
@@ -50,7 +74,7 @@ static struct cli_interp *
 as_cli_interp (struct interp *interp)
 {
   if (strcmp (interp_name (interp), INTERP_CONSOLE) == 0)
-    return (struct cli_interp *) interp_data (interp);
+    return (struct cli_interp *) interp;
   return NULL;
 }
 
@@ -255,24 +279,23 @@ cli_on_user_selected_context_changed (user_selected_what selection)
 /* pre_command_loop implementation.  */
 
 void
-cli_interpreter_pre_command_loop (struct interp *self)
+cli_interp_base::pre_command_loop ()
 {
   display_gdb_prompt (0);
 }
 
 /* These implement the cli out interpreter: */
 
-static void *
-cli_interpreter_init (struct interp *self, int top_level)
+void
+cli_interp::init (bool top_level)
 {
-  return interp_data (self);
 }
 
-static int
-cli_interpreter_resume (void *data)
+void
+cli_interp::resume ()
 {
   struct ui *ui = current_ui;
-  struct cli_interp *cli = (struct cli_interp *) data;
+  struct cli_interp *cli = this;
   struct ui_file *stream;
 
   /*sync_execution = 1; */
@@ -294,21 +317,18 @@ cli_interpreter_resume (void *data)
 
   if (stream != NULL)
     cli->cli_uiout->set_stream (gdb_stdout);
-
-  return 1;
 }
 
-static int
-cli_interpreter_suspend (void *data)
+void
+cli_interp::suspend ()
 {
   gdb_disable_readline ();
-  return 1;
 }
 
-static struct gdb_exception
-cli_interpreter_exec (void *data, const char *command_str)
+gdb_exception
+cli_interp::exec (const char *command_str)
 {
-  struct cli_interp *cli = (struct cli_interp *) data;
+  struct cli_interp *cli = this;
   struct ui_file *old_stream;
   struct gdb_exception result;
 
@@ -330,10 +350,10 @@ cli_interpreter_exec (void *data, const char *command_str)
   return result;
 }
 
-int
-cli_interpreter_supports_command_editing (struct interp *interp)
+bool
+cli_interp_base::supports_command_editing ()
 {
-  return 1;
+  return true;
 }
 
 static struct gdb_exception
@@ -365,10 +385,10 @@ safe_execute_command (struct ui_out *command_uiout, char *command, int from_tty)
   return e;
 }
 
-static struct ui_out *
-cli_ui_out (struct interp *self)
+ui_out *
+cli_interp::interp_ui_out ()
 {
-  struct cli_interp *cli = (struct cli_interp *) interp_data (self);
+  struct cli_interp *cli = (struct cli_interp *) this;
 
   return cli->cli_uiout;
 }
@@ -388,8 +408,7 @@ static saved_output_files saved_output;
 /* See cli-interp.h.  */
 
 void
-cli_set_logging (struct interp *interp,
-		 ui_file_up logfile, bool logging_redirect)
+cli_interp_base::set_logging (ui_file_up logfile, bool logging_redirect)
 {
   if (logfile != NULL)
     {
@@ -430,30 +449,12 @@ cli_set_logging (struct interp *interp,
     }
 }
 
-/* The CLI interpreter's vtable.  */
-
-static const struct interp_procs cli_interp_procs = {
-  cli_interpreter_init,		/* init_proc */
-  cli_interpreter_resume,	/* resume_proc */
-  cli_interpreter_suspend,	/* suspend_proc */
-  cli_interpreter_exec,		/* exec_proc */
-  cli_ui_out,			/* ui_out_proc */
-  cli_set_logging,		/* set_logging_proc */
-  cli_interpreter_pre_command_loop, /* pre_command_loop_proc */
-  cli_interpreter_supports_command_editing, /* supports_command_editing_proc */
-};
-
 /* Factory for CLI interpreters.  */
 
 static struct interp *
 cli_interp_factory (const char *name)
 {
-  struct cli_interp *cli = XNEW (struct cli_interp);
-
-  /* Create a default uiout builder for the CLI.  */
-  cli->cli_uiout = cli_out_new (gdb_stdout);
-
-  return interp_new (name, &cli_interp_procs, cli);
+  return new cli_interp (name);
 }
 
 /* Standard gdb initialization hook.  */
diff --git a/gdb/cli/cli-interp.h b/gdb/cli/cli-interp.h
index f93548c..de9da83 100644
--- a/gdb/cli/cli-interp.h
+++ b/gdb/cli/cli-interp.h
@@ -18,7 +18,20 @@
 #ifndef CLI_INTERP_H
 #define CLI_INTERP_H 1
 
-struct interp;
+#include "interps.h"
+
+/* A console-like interpreter.  Implements functionality common to the
+   CLI and the TUI.  */
+class cli_interp_base : public interp
+{
+public:
+  explicit cli_interp_base (const char *name);
+  virtual ~cli_interp_base () = 0;
+
+  void set_logging (ui_file_up logfile, bool logging_redirect) override;
+  void pre_command_loop () override;
+  bool supports_command_editing () override;
+};
 
 /* Make the output ui_file to use when logging is enabled.
    CURR_OUTPUT is the stream where output is currently being sent to
diff --git a/gdb/interps.c b/gdb/interps.c
index 06e7ccf..116dee4 100644
--- a/gdb/interps.c
+++ b/gdb/interps.c
@@ -72,28 +72,6 @@ get_current_interp_info (void)
   return get_interp_info (current_ui);
 }
 
-struct interp
-{
-  /* This is the name in "-i=" and set interpreter.  */
-  const char *name;
-
-  /* Interpreters are stored in a linked list, this is the next
-     one...  */
-  struct interp *next;
-
-  /* This is a cookie that an instance of the interpreter can use.
-     This is a bit confused right now as the exact initialization
-     sequence for it, and how it relates to the interpreter's uiout
-     object is a bit confused.  */
-  void *data;
-
-  /* Has the init_proc been run?  */
-  int inited;
-
-  const struct interp_procs *procs;
-  int quiet_p;
-};
-
 /* The magic initialization routine for this module.  */
 
 void _initialize_interpreter (void);
@@ -101,25 +79,16 @@ void _initialize_interpreter (void);
 static struct interp *interp_lookup_existing (struct ui *ui,
 					      const char *name);
 
-/* interp_new - This allocates space for a new interpreter,
-   fills the fields from the inputs, and returns a pointer to the
-   interpreter.  */
-struct interp *
-interp_new (const char *name, const struct interp_procs *procs, void *data)
+interp::interp (const char *name)
 {
-  struct interp *new_interp;
-
-  new_interp = XNEW (struct interp);
-
-  new_interp->name = xstrdup (name);
-  new_interp->data = data;
-  new_interp->quiet_p = 0;
-  new_interp->procs = procs;
-  new_interp->inited = 0;
-
-  return new_interp;
+  this->name = xstrdup (name);
+  this->quiet_p = false;
+  this->inited = false;
 }
 
+interp::~interp ()
+{}
+
 /* An interpreter factory.  Maps an interpreter name to the factory
    function that instantiates an interpreter by that name.  */
 
@@ -177,11 +146,7 @@ interp_add (struct ui *ui, struct interp *interp)
 }
 
 /* This sets the current interpreter to be INTERP.  If INTERP has not
-   been initialized, then this will also run the init proc.  If the
-   init proc is successful, return 1, if it fails, set the old
-   interpreter back in place and return 0.  If we can't restore the
-   old interpreter, then raise an internal error, since we are in
-   pretty bad shape at this point.
+   been initialized, then this will also run the init method.
 
    The TOP_LEVEL parameter tells if this new interpreter is
    the top-level one.  The top-level is what is requested
@@ -190,8 +155,9 @@ interp_add (struct ui *ui, struct interp *interp)
    MI is the top-level interpreter, then it will always report
    events such as target stops and new thread creation, even if they
    are caused by CLI commands.  */
-int
-interp_set (struct interp *interp, int top_level)
+
+void
+interp_set (struct interp *interp, bool top_level)
 {
   struct ui_interp_info *ui_interp = get_current_interp_info ();
   struct interp *old_interp = ui_interp->current_interpreter;
@@ -206,12 +172,7 @@ interp_set (struct interp *interp, int top_level)
   if (old_interp != NULL)
     {
       current_uiout->flush ();
-      if (old_interp->procs->suspend_proc
-	  && !old_interp->procs->suspend_proc (old_interp->data))
-	{
-	  error (_("Could not suspend interpreter \"%s\"."),
-		 old_interp->name);
-	}
+      old_interp->suspend ();
     }
   else
     {
@@ -236,28 +197,17 @@ interp_set (struct interp *interp, int top_level)
 
   if (!interp->inited)
     {
-      if (interp->procs->init_proc != NULL)
-	{
-	  interp->data = interp->procs->init_proc (interp, top_level);
-	}
-      interp->inited = 1;
+      interp->init (top_level);
+      interp->inited = true;
     }
 
   /* Do this only after the interpreter is initialized.  */
-  current_uiout = interp->procs->ui_out_proc (interp);
+  current_uiout = interp->interp_ui_out ();
 
   /* Clear out any installed interpreter hooks/event handlers.  */
   clear_interpreter_hooks ();
 
-  if (interp->procs->resume_proc != NULL
-      && (!interp->procs->resume_proc (interp->data)))
-    {
-      if (old_interp == NULL || !interp_set (old_interp, 0))
-	internal_error (__FILE__, __LINE__,
-			_("Failed to initialize new interp \"%s\" %s"),
-			interp->name, "and could not restore old interp!\n");
-      return 0;
-    }
+  interp->resume ();
 
   if (!first_time && !interp_quiet_p (interp))
     {
@@ -265,8 +215,6 @@ interp_set (struct interp *interp, int top_level)
 		 "Switching to interpreter \"%.24s\".\n", interp->name);
       current_uiout->text (buffer);
     }
-
-  return 1;
 }
 
 /* Look up the interpreter for NAME.  If no such interpreter exists,
@@ -330,8 +278,7 @@ set_top_level_interpreter (const char *name)
   if (interp == NULL)
     error (_("Interpreter `%s' unrecognized"), name);
   /* Install it.  */
-  if (!interp_set (interp, 1))
-    error (_("Interpreter `%s' failed to initialize."), name);
+  interp_set (interp, true);
 }
 
 /* Returns the current interpreter.  */
@@ -343,7 +290,7 @@ interp_ui_out (struct interp *interp)
 
   if (interp == NULL)
     interp = ui_interp->current_interpreter;
-  return interp->procs->ui_out_proc (interp);
+  return interp->interp_ui_out ();
 }
 
 void
@@ -353,8 +300,7 @@ current_interp_set_logging (ui_file_up logfile,
   struct ui_interp_info *ui_interp = get_current_interp_info ();
   struct interp *interp = ui_interp->current_interpreter;
 
-  return interp->procs->set_logging_proc (interp, std::move (logfile),
-					  logging_redirect);
+  return interp->set_logging (std::move (logfile), logging_redirect);
 }
 
 /* Temporarily overrides the current interpreter.  */
@@ -370,14 +316,6 @@ interp_set_temp (const char *name)
   return old_interp;
 }
 
-/* Returns the interpreter's cookie.  */
-
-void *
-interp_data (struct interp *interp)
-{
-  return interp->data;
-}
-
 /* Returns the interpreter's name.  */
 
 const char *
@@ -427,8 +365,7 @@ interp_pre_command_loop (struct interp *interp)
 {
   gdb_assert (interp != NULL);
 
-  if (interp->procs->pre_command_loop_proc != NULL)
-    interp->procs->pre_command_loop_proc (interp);
+  interp->pre_command_loop ();
 }
 
 /* See interp.h  */
@@ -436,9 +373,7 @@ interp_pre_command_loop (struct interp *interp)
 int
 interp_supports_command_editing (struct interp *interp)
 {
-  if (interp->procs->supports_command_editing_proc != NULL)
-    return interp->procs->supports_command_editing_proc (interp);
-  return 0;
+  return interp->supports_command_editing ();
 }
 
 int
@@ -472,13 +407,11 @@ interp_exec (struct interp *interp, const char *command_str)
   struct gdb_exception ex;
   struct interp *save_command_interp;
 
-  gdb_assert (interp->procs->exec_proc != NULL);
-
   /* See `command_interp' for why we do this.  */
   save_command_interp = ui_interp->command_interpreter;
   ui_interp->command_interpreter = interp;
 
-  ex = interp->procs->exec_proc (interp->data, command_str);
+  ex = interp->exec (command_str);
 
   ui_interp->command_interpreter = save_command_interp;
 
@@ -539,8 +472,7 @@ interpreter_exec_cmd (char *args, int from_tty)
   old_quiet = interp_set_quiet (old_interp, 1);
   use_quiet = interp_set_quiet (interp_to_use, 1);
 
-  if (!interp_set (interp_to_use, 0))
-    error (_("Could not switch to interpreter \"%s\"."), prules[0]);
+  interp_set (interp_to_use, false);
 
   for (i = 1; i < nrules; i++)
     {
@@ -612,16 +544,6 @@ top_level_interpreter (void)
   return ui_interp->top_level_interpreter;
 }
 
-void *
-top_level_interpreter_data (void)
-{
-  struct interp *interp;
-
-  interp = top_level_interpreter ();
-  gdb_assert (interp != NULL);
-  return interp->data;
-}
-
 /* See interps.h.  */
 
 struct interp *
diff --git a/gdb/interps.h b/gdb/interps.h
index ef2ceeb..e9a4d23 100644
--- a/gdb/interps.h
+++ b/gdb/interps.h
@@ -41,53 +41,61 @@ extern struct gdb_exception interp_exec (struct interp *interp,
 					 const char *command);
 extern int interp_quiet_p (struct interp *interp);
 
-typedef void *(interp_init_ftype) (struct interp *self, int top_level);
-typedef int (interp_resume_ftype) (void *data);
-typedef int (interp_suspend_ftype) (void *data);
-typedef struct gdb_exception (interp_exec_ftype) (void *data,
-						  const char *command);
-typedef void (interp_pre_command_loop_ftype) (struct interp *self);
-typedef struct ui_out *(interp_ui_out_ftype) (struct interp *self);
+class interp
+{
+public:
+  explicit interp (const char *name);
+  virtual ~interp () = 0;
 
-typedef void (interp_set_logging_ftype) (struct interp *self,
-					 ui_file_up logfile,
-					 bool logging_redirect);
+  virtual void init (bool top_level)
+  {}
 
-typedef int (interp_supports_command_editing_ftype) (struct interp *self);
+  virtual void resume ()
+  {}
 
-struct interp_procs
-{
-  interp_init_ftype *init_proc;
-  interp_resume_ftype *resume_proc;
-  interp_suspend_ftype *suspend_proc;
-  interp_exec_ftype *exec_proc;
+  virtual void suspend ()
+  {}
+
+  virtual gdb_exception exec (const char *command)
+  { return exception_none; }
 
   /* Returns the ui_out currently used to collect results for this
      interpreter.  It can be a formatter for stdout, as is the case
      for the console & mi outputs, or it might be a result
      formatter.  */
-  interp_ui_out_ftype *ui_out_proc;
+  virtual ui_out *interp_ui_out () = 0;
 
   /* Provides a hook for interpreters to do any additional
      setup/cleanup that they might need when logging is enabled or
      disabled.  */
-  interp_set_logging_ftype *set_logging_proc;
+  virtual void set_logging (ui_file_up logfile, bool logging_redirect) = 0;
 
   /* Called before starting an event loop, to give the interpreter a
      chance to e.g., print a prompt.  */
-  interp_pre_command_loop_ftype *pre_command_loop_proc;
+  virtual void pre_command_loop ()
+  {}
 
   /* Returns true if this interpreter supports using the readline
      library; false if it uses GDB's own simplified readline
      emulation.  */
-  interp_supports_command_editing_ftype *supports_command_editing_proc;
+  virtual bool supports_command_editing ()
+  { return false; }
+
+  /* This is the name in "-i=" and "set interpreter".  */
+  const char *name;
+
+  /* Interpreters are stored in a linked list, this is the next
+     one...  */
+  struct interp *next;
+
+  /* Has the init method been run?  */
+  bool inited;
+
+  bool quiet_p;
 };
 
-extern struct interp *interp_new (const char *name,
-				  const struct interp_procs *procs,
-				  void *data);
 extern void interp_add (struct ui *ui, struct interp *interp);
-extern int interp_set (struct interp *interp, int top_level);
+extern void interp_set (struct interp *interp, bool top_level);
 
 /* Look up the interpreter for NAME, creating one if none exists yet.
    If NAME is not a interpreter type previously registered with
@@ -101,7 +109,6 @@ extern struct interp *interp_lookup (struct ui *ui, const char *name);
 extern void set_top_level_interpreter (const char *name);
 
 extern struct ui_out *interp_ui_out (struct interp *interp);
-extern void *interp_data (struct interp *interp);
 extern const char *interp_name (struct interp *interp);
 extern struct interp *interp_set_temp (const char *name);
 
@@ -119,8 +126,7 @@ extern int current_interp_named_p (const char *name);
 extern void current_interp_set_logging (ui_file_up logfile,
 					bool logging_redirect);
 
-/* Returns opaque data associated with the top-level interpreter.  */
-extern void *top_level_interpreter_data (void);
+/* Returns the top-level interpreter.  */
 extern struct interp *top_level_interpreter (void);
 
 /* Return the current UI's current interpreter.  */
diff --git a/gdb/mi/mi-common.h b/gdb/mi/mi-common.h
index 9ee38b0..8fa9c9d 100644
--- a/gdb/mi/mi-common.h
+++ b/gdb/mi/mi-common.h
@@ -19,6 +19,8 @@
 #ifndef MI_COMMON_H
 #define MI_COMMON_H
 
+#include "interps.h"
+
 struct mi_console_file;
 
 /* Represents the reason why GDB is sending an asynchronous command to
@@ -50,8 +52,23 @@ enum async_reply_reason
 
 const char *async_reason_lookup (enum async_reply_reason reason);
 
-struct mi_interp
+/* An MI interpreter.  */
+
+class mi_interp final : public interp
 {
+public:
+  mi_interp (const char *name)
+    : interp (name)
+  {}
+
+  void init (bool top_level) override;
+  void resume () override;
+  void suspend () override;
+  gdb_exception exec (const char *command_str) override;
+  ui_out *interp_ui_out () override;
+  void set_logging (ui_file_up logfile, bool logging_redirect) override;
+  void pre_command_loop () override;
+
   /* MI's output channels */
   mi_console_file *out;
   mi_console_file *err;
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index aa76989..86340e4 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -108,14 +108,14 @@ static struct mi_interp *
 as_mi_interp (struct interp *interp)
 {
   if (interp_ui_out (interp)->is_mi_like_p ())
-    return (struct mi_interp *) interp_data (interp);
+    return (struct mi_interp *) interp;
   return NULL;
 }
 
-static void *
-mi_interpreter_init (struct interp *interp, int top_level)
+void
+mi_interp::init (bool top_level)
 {
-  struct mi_interp *mi = XNEW (struct mi_interp);
+  mi_interp *mi = this;
   const char *name;
   int mi_version;
 
@@ -132,7 +132,7 @@ mi_interpreter_init (struct interp *interp, int top_level)
   mi->targ = new mi_console_file (mi->raw_stdout, "@", '"');
   mi->event_channel = new mi_console_file (mi->raw_stdout, "=", 0);
 
-  name = interp_name (interp);
+  name = interp_name (this);
   /* INTERP_MI selects the most recent released version.  "mi2" was
      released as part of GDB 6.0.  */
   if (strcmp (name, INTERP_MI) == 0)
@@ -157,14 +157,12 @@ mi_interpreter_init (struct interp *interp, int top_level)
 	 up-front.  */
       iterate_over_inferiors (report_initial_inferior, mi);
     }
-
-  return mi;
 }
 
-static int
-mi_interpreter_resume (void *data)
+void
+mi_interp::resume ()
 {
-  struct mi_interp *mi = (struct mi_interp *) data;
+  struct mi_interp *mi = this;
   struct ui *ui = current_ui;
 
   /* As per hack note in mi_interpreter_init, swap in the output
@@ -188,19 +186,16 @@ mi_interpreter_resume (void *data)
   clear_interpreter_hooks ();
 
   deprecated_show_load_progress = mi_load_progress;
-
-  return 1;
 }
 
-static int
-mi_interpreter_suspend (void *data)
+void
+mi_interp::suspend ()
 {
   gdb_disable_readline ();
-  return 1;
 }
 
-static struct gdb_exception
-mi_interpreter_exec (void *data, const char *command)
+gdb_exception
+mi_interp::exec (const char *command)
 {
   mi_execute_command_wrapper (command);
   return exception_none;
@@ -327,10 +322,10 @@ mi_execute_command_input_handler (char *cmd)
     display_mi_prompt (mi);
 }
 
-static void
-mi_interpreter_pre_command_loop (struct interp *self)
+void
+mi_interp::pre_command_loop ()
 {
-  struct mi_interp *mi = (struct mi_interp *) interp_data (self);
+  struct mi_interp *mi = this;
 
   /* Turn off 8 bit strings in quoted output.  Any character with the
      high bit set is printed using C's octal format.  */
@@ -658,7 +653,7 @@ mi_on_normal_stop_1 (struct bpstats *bs, int print_frame)
      using cli interpreter, be sure to use MI uiout for output,
      not the current one.  */
   struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
-  struct mi_interp *mi = (struct mi_interp *) top_level_interpreter_data ();
+  struct mi_interp *mi = (struct mi_interp *) top_level_interpreter ();
 
   if (print_frame)
     {
@@ -1362,24 +1357,19 @@ report_initial_inferior (struct inferior *inf, void *closure)
   return 0;
 }
 
-static struct ui_out *
-mi_ui_out (struct interp *interp)
+ui_out *
+mi_interp::interp_ui_out ()
 {
-  struct mi_interp *mi = (struct mi_interp *) interp_data (interp);
-
-  return mi->mi_uiout;
+  return this->mi_uiout;
 }
 
 /* Do MI-specific logging actions; save raw_stdout, and change all
    the consoles to use the supplied ui-file(s).  */
 
-static void
-mi_set_logging (struct interp *interp,
-	        ui_file_up logfile, bool logging_redirect)
+void
+mi_interp::set_logging (ui_file_up logfile, bool logging_redirect)
 {
-  struct mi_interp *mi = (struct mi_interp *) interp_data (interp);
-
-  gdb_assert (mi != NULL);
+  struct mi_interp *mi = this;
 
   if (logfile != NULL)
     {
@@ -1403,25 +1393,12 @@ mi_set_logging (struct interp *interp,
   mi->event_channel->set_raw (mi->raw_stdout);
 }
 
-/* The MI interpreter's vtable.  */
-
-static const struct interp_procs mi_interp_procs =
-{
-  mi_interpreter_init,		/* init_proc */
-  mi_interpreter_resume,	/* resume_proc */
-  mi_interpreter_suspend,	/* suspend_proc */
-  mi_interpreter_exec,		/* exec_proc */
-  mi_ui_out, 			/* ui_out_proc */
-  mi_set_logging,		/* set_logging_proc */
-  mi_interpreter_pre_command_loop /* pre_command_loop_proc */
-};
-
 /* Factory for MI interpreters.  */
 
 static struct interp *
 mi_interp_factory (const char *name)
 {
-  return interp_new (name, &mi_interp_procs, NULL);
+  return new mi_interp (name);
 }
 
 extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index b249f2d..cf4e45a 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -147,8 +147,7 @@ static void print_diff (struct ui_file *file, struct mi_timestamp *start,
 void
 mi_cmd_gdb_exit (char *command, char **argv, int argc)
 {
-  struct mi_interp *mi
-    = (struct mi_interp *) interp_data (current_interpreter ());
+  struct mi_interp *mi = (struct mi_interp *) current_interpreter ();
 
   /* We have to print everything right here because we never return.  */
   if (current_token)
@@ -1974,7 +1973,7 @@ mi_cmd_remove_inferior (char *command, char **argv, int argc)
 static void
 captured_mi_execute_command (struct ui_out *uiout, struct mi_parse *context)
 {
-  struct mi_interp *mi = (struct mi_interp *) interp_data (command_interp ());
+  struct mi_interp *mi = (struct mi_interp *) command_interp ();
   struct cleanup *cleanup;
 
   if (do_timings)
@@ -2066,8 +2065,7 @@ captured_mi_execute_command (struct ui_out *uiout, struct mi_parse *context)
 static void
 mi_print_exception (const char *token, struct gdb_exception exception)
 {
-  struct mi_interp *mi
-    = (struct mi_interp *) interp_data (current_interpreter ());
+  struct mi_interp *mi = (struct mi_interp *) current_interpreter ();
 
   fputs_unfiltered (token, mi->raw_stdout);
   fputs_unfiltered ("^error,msg=\"", mi->raw_stdout);
@@ -2190,8 +2188,7 @@ mi_execute_command (const char *cmd, int from_tty)
 	     again.  */
 	  && !command_notifies_uscc_observer (command))
 	{
-	  struct mi_interp *mi
-	    = (struct mi_interp *) top_level_interpreter_data ();
+	  struct mi_interp *mi = (struct mi_interp *) top_level_interpreter ();
 	  int report_change = 0;
 
 	  if (command->thread == -1)
@@ -2378,8 +2375,7 @@ mi_load_progress (const char *section_name,
   int new_section;
   struct ui_out *saved_uiout;
   struct ui_out *uiout;
-  struct mi_interp *mi
-    = (struct mi_interp *) interp_data (current_interpreter ());
+  struct mi_interp *mi = (struct mi_interp *) current_interpreter ();
 
   /* This function is called through deprecated_show_load_progress
      which means uiout may not be correct.  Fix it for the duration
diff --git a/gdb/tui/tui-interp.c b/gdb/tui/tui-interp.c
index e2c0605..702c342 100644
--- a/gdb/tui/tui-interp.c
+++ b/gdb/tui/tui-interp.c
@@ -34,20 +34,32 @@
 #include "observer.h"
 #include "gdbthread.h"
 
-static struct ui_out *tui_ui_out (struct interp *self);
-
 /* Set to 1 when the TUI mode must be activated when we first start
    gdb.  */
 static int tui_start_enabled = 0;
 
+class tui_interp final : public cli_interp_base
+{
+public:
+  explicit tui_interp (const char *name)
+    : cli_interp_base (name)
+  {}
+
+  void init (bool top_level) override;
+  void resume () override;
+  void suspend () override;
+  gdb_exception exec (const char *command_str) override;
+  ui_out *interp_ui_out () override;
+};
+
 /* Returns the INTERP if the INTERP is a TUI, and returns NULL
    otherwise.  */
 
-static struct interp *
+static tui_interp *
 as_tui_interp (struct interp *interp)
 {
   if (strcmp (interp_name (interp), INTERP_TUI) == 0)
-    return interp;
+    return (tui_interp *) interp;
   return NULL;
 }
 
@@ -84,7 +96,7 @@ tui_on_normal_stop (struct bpstats *bs, int print_frame)
 
       thread = inferior_thread ();
       if (should_print_stop_to_console (interp, thread))
-	print_stop_event (tui_ui_out (tui));
+	print_stop_event (tui->interp_ui_out ());
     }
 }
 
@@ -100,7 +112,7 @@ tui_on_signal_received (enum gdb_signal siggnal)
       if (tui == NULL)
 	continue;
 
-      print_signal_received_reason (tui_ui_out (tui), siggnal);
+      print_signal_received_reason (tui->interp_ui_out (), siggnal);
     }
 }
 
@@ -116,7 +128,7 @@ tui_on_end_stepping_range (void)
       if (tui == NULL)
 	continue;
 
-      print_end_stepping_range_reason (tui_ui_out (tui));
+      print_end_stepping_range_reason (tui->interp_ui_out ());
     }
 }
 
@@ -132,7 +144,7 @@ tui_on_signal_exited (enum gdb_signal siggnal)
       if (tui == NULL)
 	continue;
 
-      print_signal_exited_reason (tui_ui_out (tui), siggnal);
+      print_signal_exited_reason (tui->interp_ui_out (), siggnal);
     }
 }
 
@@ -148,7 +160,7 @@ tui_on_exited (int exitstatus)
       if (tui == NULL)
 	continue;
 
-      print_exited_reason (tui_ui_out (tui), exitstatus);
+      print_exited_reason (tui->interp_ui_out (), exitstatus);
     }
 }
 
@@ -164,7 +176,7 @@ tui_on_no_history (void)
       if (tui == NULL)
 	continue;
 
-      print_no_history_reason (tui_ui_out (tui));
+      print_no_history_reason (tui->interp_ui_out ());
     }
 }
 
@@ -215,19 +227,19 @@ tui_on_user_selected_context_changed (user_selected_what selection)
 	continue;
 
       if (selection & USER_SELECTED_INFERIOR)
-	print_selected_inferior (tui_ui_out (tui));
+	print_selected_inferior (tui->interp_ui_out ());
 
       if (tp != NULL
 	  && ((selection & (USER_SELECTED_THREAD | USER_SELECTED_FRAME))))
-	print_selected_thread_frame (tui_ui_out (tui), selection);
+	print_selected_thread_frame (tui->interp_ui_out (), selection);
 
     }
 }
 
 /* These implement the TUI interpreter.  */
 
-static void *
-tui_init (struct interp *self, int top_level)
+void
+tui_interp::init (bool top_level)
 {
   /* Install exit handler to leave the screen in a good shape.  */
   atexit (tui_exit);
@@ -238,12 +250,10 @@ tui_init (struct interp *self, int top_level)
   tui_initialize_win ();
   if (ui_file_isatty (gdb_stdout))
     tui_initialize_readline ();
-
-  return NULL;
 }
 
-static int
-tui_resume (void *data)
+void
+tui_interp::resume ()
 {
   struct ui *ui = current_ui;
   struct ui_file *stream;
@@ -268,19 +278,17 @@ tui_resume (void *data)
 
   if (tui_start_enabled)
     tui_enable ();
-  return 1;
 }
 
-static int
-tui_suspend (void *data)
+void
+tui_interp::suspend ()
 {
   tui_start_enabled = tui_active;
   tui_disable ();
-  return 1;
 }
 
-static struct ui_out *
-tui_ui_out (struct interp *self)
+ui_out *
+tui_interp::interp_ui_out ()
 {
   if (tui_active)
     return tui_out;
@@ -288,31 +296,19 @@ tui_ui_out (struct interp *self)
     return tui_old_uiout;
 }
 
-static struct gdb_exception
-tui_exec (void *data, const char *command_str)
+gdb_exception
+tui_interp::exec (const char *command_str)
 {
   internal_error (__FILE__, __LINE__, _("tui_exec called"));
 }
 
-/* The TUI interpreter's vtable.  */
-
-static const struct interp_procs tui_interp_procs = {
-  tui_init,
-  tui_resume,
-  tui_suspend,
-  tui_exec,
-  tui_ui_out,
-  cli_set_logging,
-  cli_interpreter_pre_command_loop,
-  cli_interpreter_supports_command_editing,
-};
 
 /* Factory for TUI interpreters.  */
 
 static struct interp *
 tui_interp_factory (const char *name)
 {
-  return interp_new (name, &tui_interp_procs, NULL);
+  return new tui_interp (name);
 }
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
-- 
2.5.5


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]