/* Manages interpreters for GDB, the GNU debugger.

   Copyright (C) 2000-2024 Free Software Foundation, Inc.

   Written by Jim Ingham <jingham@apple.com> of Apple Computer, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

/* This is just a first cut at separating out the "interpreter"
   functions of gdb into self-contained modules.  There are a couple
   of open areas that need to be sorted out:

   1) The interpreter explicitly contains a UI_OUT, and can insert itself
   into the event loop, but it doesn't explicitly contain hooks for readline.
   I did this because it seems to me many interpreters won't want to use
   the readline command interface, and it is probably simpler to just let
   them take over the input in their resume proc.  */

#include "cli/cli-cmds.h"
#include "ui-out.h"
#include "gdbsupport/event-loop.h"
#include "event-top.h"
#include "interps.h"
#include "completer.h"
#include "ui.h"
#include "main.h"
#include "gdbsupport/buildargv.h"
#include "gdbsupport/scope-exit.h"

/* The magic initialization routine for this module.  */

static struct interp *interp_lookup_existing (struct ui *ui,
					      const char *name);

interp::interp (const char *name)
  : m_name (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;

/* See interps.h.  */

void
interp_factory_register (const char *name, interp_factory_func func)
{
  /* Assert that no factory for NAME is already registered.  */
  for (const interp_factory &f : interpreter_factories)
    if (strcmp (f.name, name) == 0)
      {
	internal_error (_("interpreter factory already registered: \"%s\"\n"),
			name);
      }

  interpreter_factories.emplace_back (name, func);
}

/* Add interpreter INTERP to the gdb interpreter list.  The
   interpreter must not have previously been added.  */
static void
interp_add (struct ui *ui, struct interp *interp)
{
  gdb_assert (interp_lookup_existing (ui, interp->name ()) == NULL);

  ui->interp_list.push_back (*interp);
}

/* This sets the current interpreter to be INTERP.  If INTERP has not
   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
   on the command line, and is responsible for reporting general
   notification about target state changes.  For example, if
   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.  */

static void
interp_set (struct interp *interp, bool top_level)
{
  struct interp *old_interp = current_ui->current_interpreter;

  /* If we already have an interpreter, then trying to
     set top level interpreter is kinda pointless.  */
  gdb_assert (!top_level || !current_ui->current_interpreter);
  gdb_assert (!top_level || !current_ui->top_level_interpreter);

  if (old_interp != NULL)
    {
      current_uiout->flush ();
      old_interp->suspend ();
    }

  current_ui->current_interpreter = interp;
  if (top_level)
    current_ui->top_level_interpreter = interp;

  if (interpreter_p != interp->name ())
    interpreter_p = interp->name ();

  /* Run the init proc.  */
  if (!interp->inited)
    {
      interp->init (top_level);
      interp->inited = true;
    }

  /* Do this only after the interpreter is initialized.  */
  current_uiout = interp->interp_ui_out ();

  /* Clear out any installed interpreter hooks/event handlers.  */
  clear_interpreter_hooks ();

  interp->resume ();
}

/* Look up the interpreter for NAME.  If no such interpreter exists,
   return NULL, otherwise return a pointer to the interpreter.  */

static struct interp *
interp_lookup_existing (struct ui *ui, const char *name)
{
  for (interp &interp : ui->interp_list)
    if (strcmp (interp.name (), name) == 0)
      return &interp;

  return nullptr;
}

/* 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.  */
  struct interp *interp = interp_lookup_existing (ui, name);
  if (interp != NULL)
    return interp;

  for (const interp_factory &factory : interpreter_factories)
    if (strcmp (factory.name, name) == 0)
      {
	interp = factory.func (factory.name);
	interp_add (ui, interp);
	return interp;
      }

  return NULL;
}

/* See interps.h.  */

void
set_top_level_interpreter (const char *name, bool for_new_ui)
{
  /* Find it.  */
  struct interp *interp = interp_lookup (current_ui, name);

  if (interp == NULL)
    error (_("Interpreter `%s' unrecognized"), name);
  if (for_new_ui && !interp->supports_new_ui ())
    error (_("interpreter '%s' cannot be used with a new UI"), name);

  /* Install it.  */
  interp_set (interp, true);
}

void
current_interp_set_logging (ui_file_up logfile, bool logging_redirect,
			    bool debug_redirect)
{
  struct interp *interp = current_ui->current_interpreter;

  interp->set_logging (std::move (logfile), logging_redirect, debug_redirect);
}

/* Temporarily overrides the current interpreter.  */
struct interp *
scoped_restore_interp::set_interp (const char *name)
{
  struct interp *interp = interp_lookup (current_ui, name);
  struct interp *old_interp = current_ui->current_interpreter;

  if (interp)
    current_ui->current_interpreter = interp;

  return old_interp;
}

/* Returns true if the current interp is the passed in name.  */
int
current_interp_named_p (const char *interp_name)
{
  interp *interp = current_ui->current_interpreter;

  if (interp != NULL)
    return (strcmp (interp->name (), interp_name) == 0);

  return 0;
}

/* The interpreter that was active when a command was executed.
   Normally that'd always be CURRENT_INTERPRETER, except that MI's
   -interpreter-exec command doesn't actually flip the current
   interpreter when running its sub-command.  The
   `command_interpreter' global tracks when interp_exec is called
   (IOW, when -interpreter-exec is called).  If that is set, it is
   INTERP in '-interpreter-exec INTERP "CMD"' or in 'interpreter-exec
   INTERP "CMD".  Otherwise, interp_exec isn't active, and so the
   interpreter running the command is the current interpreter.  */

struct interp *
command_interp (void)
{
  if (current_ui->command_interpreter != nullptr)
    return current_ui->command_interpreter;
  else
    return current_ui->current_interpreter;
}

/* interp_exec - This executes COMMAND_STR in the current 
   interpreter.  */

void
interp_exec (struct interp *interp, const char *command_str)
{
  /* See `command_interp' for why we do this.  */
  scoped_restore save_command_interp
    = make_scoped_restore (&current_ui->command_interpreter, interp);

  interp->exec (command_str);
}

/* A convenience routine that nulls out all the common command hooks.
   Use it when removing your interpreter in its suspend proc.  */
void
clear_interpreter_hooks (void)
{
  deprecated_print_frame_info_listing_hook = 0;
  /*print_frame_more_info_hook = 0; */
  deprecated_query_hook = 0;
  deprecated_readline_begin_hook = 0;
  deprecated_readline_hook = 0;
  deprecated_readline_end_hook = 0;
  deprecated_context_hook = 0;
  deprecated_call_command_hook = 0;
  deprecated_error_begin_hook = 0;
}

static void
interpreter_exec_cmd (const char *args, int from_tty)
{
  struct interp *interp_to_use;
  unsigned int nrules;
  unsigned int i;

  /* Interpreters may clobber stdout/stderr (e.g.  in mi_interp::resume at time
     of writing), preserve their state here.  */
  scoped_restore save_stdout = make_scoped_restore (&gdb_stdout);
  scoped_restore save_stderr = make_scoped_restore (&gdb_stderr);
  scoped_restore save_stdlog = make_scoped_restore (&gdb_stdlog);
  scoped_restore save_stdtarg = make_scoped_restore (&gdb_stdtarg);

  if (args == NULL)
    error_no_arg (_("interpreter-exec command"));

  gdb_argv prules (args);
  nrules = prules.count ();

  if (nrules < 2)
    error (_("Usage: interpreter-exec INTERPRETER COMMAND..."));

  interp *old_interp = current_ui->current_interpreter;

  interp_to_use = interp_lookup (current_ui, prules[0]);
  if (interp_to_use == NULL)
    error (_("Could not find interpreter \"%s\"."), prules[0]);

  interp_set (interp_to_use, false);
  SCOPE_EXIT
    {
      interp_set (old_interp, false);
    };

  for (i = 1; i < nrules; i++)
    interp_exec (interp_to_use, prules[i]);
}

/* See interps.h.  */

void
interpreter_completer (struct cmd_list_element *ignore,
		       completion_tracker &tracker,
		       const char *text, const char *word)
{
  int textlen = strlen (text);

  for (const interp_factory &interp : interpreter_factories)
    {
      if (strncmp (interp.name, text, textlen) == 0)
	{
	  tracker.add_completion
	    (make_completion_match_str (interp.name, text, word));
	}
    }
}

struct interp *
top_level_interpreter (void)
{
  return current_ui->top_level_interpreter;
}

/* See interps.h.  */

struct interp *
current_interpreter (void)
{
  return current_ui->current_interpreter;
}

/* Helper interps_notify_* functions.  Call METHOD on the top-level interpreter
   of all UIs.  */

template <typename MethodType, typename ...Args>
void
interps_notify (MethodType method, Args&&... args)
{
  SWITCH_THRU_ALL_UIS ()
    {
      interp *tli = top_level_interpreter ();
      if (tli != nullptr)
	(tli->*method) (std::forward<Args> (args)...);
    }
}

/* See interps.h.  */

void
interps_notify_signal_received (gdb_signal sig)
{
  interps_notify (&interp::on_signal_received, sig);
}

/* See interps.h.  */

void
interps_notify_signal_exited (gdb_signal sig)
{
  interps_notify (&interp::on_signal_exited, sig);
}

/* See interps.h.  */

void
interps_notify_no_history ()
{
  interps_notify (&interp::on_no_history);
}

/* See interps.h.  */

void
interps_notify_normal_stop (bpstat *bs, int print_frame)
{
  interps_notify (&interp::on_normal_stop, bs, print_frame);
}

/* See interps.h.  */

void
interps_notify_exited (int status)
{
  interps_notify (&interp::on_exited, status);
}

/* See interps.h.  */

void
interps_notify_user_selected_context_changed (user_selected_what selection)
{
  interps_notify (&interp::on_user_selected_context_changed, selection);
}

/* See interps.h.  */

void
interps_notify_new_thread (thread_info *t)
{
  interps_notify (&interp::on_new_thread, t);
}

/* See interps.h.  */

void
interps_notify_thread_exited (thread_info *t,
			      std::optional<ULONGEST> exit_code,
			      int silent)
{
  interps_notify (&interp::on_thread_exited, t, exit_code, silent);
}

/* See interps.h.  */

void
interps_notify_inferior_added (inferior *inf)
{
  interps_notify (&interp::on_inferior_added, inf);
}

/* See interps.h.  */

void
interps_notify_inferior_appeared (inferior *inf)
{
  interps_notify (&interp::on_inferior_appeared, inf);
}

/* See interps.h.  */

void
interps_notify_inferior_disappeared (inferior *inf)
{
  interps_notify (&interp::on_inferior_disappeared, inf);
}

/* See interps.h.  */

void
interps_notify_inferior_removed (inferior *inf)
{
  interps_notify (&interp::on_inferior_removed, inf);
}

/* See interps.h.  */

void
interps_notify_record_changed (inferior *inf, int started, const char *method,
			       const char *format)
{
  interps_notify (&interp::on_record_changed, inf, started, method, format);
}

/* See interps.h.  */

void
interps_notify_target_resumed (ptid_t ptid)
{
  interps_notify (&interp::on_target_resumed, ptid);
}

/* See interps.h.  */

void
interps_notify_solib_loaded (const solib &so)
{
  interps_notify (&interp::on_solib_loaded, so);
}

/* See interps.h.  */

void
interps_notify_solib_unloaded (const solib &so)
{
  interps_notify (&interp::on_solib_unloaded, so);
}

/* See interps.h.  */

void
interps_notify_traceframe_changed (int tfnum, int tpnum)
{
  interps_notify (&interp::on_traceframe_changed, tfnum, tpnum);
}

/* See interps.h.  */

void
interps_notify_tsv_created (const trace_state_variable *tsv)
{
  interps_notify (&interp::on_tsv_created, tsv);
}

/* See interps.h.  */

void
interps_notify_tsv_deleted (const trace_state_variable *tsv)
{
  interps_notify (&interp::on_tsv_deleted, tsv);
}

/* See interps.h.  */

void
interps_notify_tsv_modified (const trace_state_variable *tsv)
{
  interps_notify (&interp::on_tsv_modified, tsv);
}

/* See interps.h.  */

void
interps_notify_breakpoint_created (breakpoint *b)
{
  interps_notify (&interp::on_breakpoint_created, b);
}

/* See interps.h.  */

void
interps_notify_breakpoint_deleted (breakpoint *b)
{
  interps_notify (&interp::on_breakpoint_deleted, b);
}

/* See interps.h.  */

void
interps_notify_breakpoint_modified (breakpoint *b)
{
  interps_notify (&interp::on_breakpoint_modified, b);
}

/* See interps.h.  */

void
interps_notify_param_changed (const char *param, const char *value)
{
  interps_notify (&interp::on_param_changed, param, value);
}

/* See interps.h.  */

void
interps_notify_memory_changed (inferior *inf, CORE_ADDR addr, ssize_t len,
			       const bfd_byte *data)
{
  interps_notify (&interp::on_memory_changed, inf, addr, len, data);
}

/* This just adds the "interpreter-exec" command.  */
void _initialize_interpreter ();
void
_initialize_interpreter ()
{
  struct cmd_list_element *c;

  c = add_cmd ("interpreter-exec", class_support,
	       interpreter_exec_cmd, _("\
Execute a command in an interpreter.\n\
Usage: interpreter-exec INTERPRETER COMMAND...\n\
The first argument is the name of the interpreter to use.\n\
The following arguments are the commands to execute.\n\
A command can have arguments, separated by spaces.\n\
These spaces must be escaped using \\ or the command\n\
and its arguments must be enclosed in double quotes."), &cmdlist);
  set_cmd_completer (c, interpreter_completer);
}
