/* CLI Definitions for GDB, the GNU debugger.

   Copyright (C) 2002-2021 Free Software Foundation, 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/>.  */

#include "defs.h"
#include "cli-interp.h"
#include "interps.h"
#include "event-top.h"
#include "ui-out.h"
#include "cli-out.h"
#include "top.h"		/* for "execute_command" */
#include "infrun.h"
#include "observable.h"
#include "gdbthread.h"
#include "thread-fsm.h"
#include "inferior.h"

cli_interp_base::cli_interp_base (const char *name)
  : interp (name)
{}

cli_interp_base::~cli_interp_base ()
{}

/* The console interpreter.  */

class cli_interp final : public cli_interp_base
{
 public:
  explicit cli_interp (const char *name);
  ~cli_interp ();

  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);
}

cli_interp::~cli_interp ()
{
  delete cli_uiout;
}

/* Suppress notification struct.  */
struct cli_suppress_notification cli_suppress_notification =
  {
    0   /* user_selected_context_changed */
  };

/* Returns the INTERP's data cast as cli_interp if INTERP is a CLI,
   and returns NULL otherwise.  */

static struct cli_interp *
as_cli_interp (struct interp *interp)
{
  return dynamic_cast<cli_interp *> (interp);
}

/* Longjmp-safe wrapper for "execute_command".  */
static struct gdb_exception safe_execute_command (struct ui_out *uiout,
						  const char *command, 
						  int from_tty);

/* See cli-interp.h.

   Breakpoint hits should always be mirrored to a console.  Deciding
   what to mirror to a console wrt to breakpoints and random stops
   gets messy real fast.  E.g., say "s" trips on a breakpoint.  We'd
   clearly want to mirror the event to the console in this case.  But
   what about more complicated cases like "s&; thread n; s&", and one
   of those steps spawning a new thread, and that thread hitting a
   breakpoint?  It's impossible in general to track whether the thread
   had any relation to the commands that had been executed.  So we
   just simplify and always mirror breakpoints and random events to
   all consoles.

   OTOH, we should print the source line to the console when stepping
   or other similar commands, iff the step was started by that console
   (or in MI's case, by a console command), but not if it was started
   with MI's -exec-step or similar.  */

int
should_print_stop_to_console (struct interp *console_interp,
			      struct thread_info *tp)
{
  if ((bpstat_what (tp->control.stop_bpstat).main_action
       == BPSTAT_WHAT_STOP_NOISY)
      || tp->thread_fsm == NULL
      || tp->thread_fsm->command_interp == console_interp
      || !tp->thread_fsm->finished_p ())
    return 1;
  return 0;
}

/* Observers for several run control events.  If the interpreter is
   quiet (i.e., another interpreter is being run with
   interpreter-exec), print nothing.  */

/* Observer for the normal_stop notification.  */

static void
cli_on_normal_stop (struct bpstat *bs, int print_frame)
{
  if (!print_frame)
    return;

  SWITCH_THRU_ALL_UIS ()
    {
      struct interp *interp = top_level_interpreter ();
      struct cli_interp *cli = as_cli_interp (interp);
      struct thread_info *thread;

      if (cli == NULL)
	continue;

      thread = inferior_thread ();
      if (should_print_stop_to_console (interp, thread))
	print_stop_event (cli->cli_uiout);
    }
}

/* Observer for the signal_received notification.  */

static void
cli_on_signal_received (enum gdb_signal siggnal)
{
  SWITCH_THRU_ALL_UIS ()
    {
      struct cli_interp *cli = as_cli_interp (top_level_interpreter ());

      if (cli == NULL)
	continue;

      print_signal_received_reason (cli->cli_uiout, siggnal);
    }
}

/* Observer for the end_stepping_range notification.  */

static void
cli_on_end_stepping_range (void)
{
  SWITCH_THRU_ALL_UIS ()
    {
      struct cli_interp *cli = as_cli_interp (top_level_interpreter ());

      if (cli == NULL)
	continue;

      print_end_stepping_range_reason (cli->cli_uiout);
    }
}

/* Observer for the signalled notification.  */

static void
cli_on_signal_exited (enum gdb_signal siggnal)
{
  SWITCH_THRU_ALL_UIS ()
    {
      struct cli_interp *cli = as_cli_interp (top_level_interpreter ());

      if (cli == NULL)
	continue;

      print_signal_exited_reason (cli->cli_uiout, siggnal);
    }
}

/* Observer for the exited notification.  */

static void
cli_on_exited (int exitstatus)
{
  SWITCH_THRU_ALL_UIS ()
    {
      struct cli_interp *cli = as_cli_interp (top_level_interpreter ());

      if (cli == NULL)
	continue;

      print_exited_reason (cli->cli_uiout, exitstatus);
    }
}

/* Observer for the no_history notification.  */

static void
cli_on_no_history (void)
{
  SWITCH_THRU_ALL_UIS ()
    {
      struct cli_interp *cli = as_cli_interp (top_level_interpreter ());

      if (cli == NULL)
	continue;

      print_no_history_reason (cli->cli_uiout);
    }
}

/* Observer for the sync_execution_done notification.  */

static void
cli_on_sync_execution_done (void)
{
  struct cli_interp *cli = as_cli_interp (top_level_interpreter ());

  if (cli == NULL)
    return;

  display_gdb_prompt (NULL);
}

/* Observer for the command_error notification.  */

static void
cli_on_command_error (void)
{
  struct cli_interp *cli = as_cli_interp (top_level_interpreter ());

  if (cli == NULL)
    return;

  display_gdb_prompt (NULL);
}

/* Observer for the user_selected_context_changed notification.  */

static void
cli_on_user_selected_context_changed (user_selected_what selection)
{
  /* This event is suppressed.  */
  if (cli_suppress_notification.user_selected_context)
    return;

  thread_info *tp = inferior_ptid != null_ptid ? inferior_thread () : NULL;

  SWITCH_THRU_ALL_UIS ()
    {
      struct cli_interp *cli = as_cli_interp (top_level_interpreter ());

      if (cli == NULL)
	continue;

      if (selection & USER_SELECTED_INFERIOR)
	print_selected_inferior (cli->cli_uiout);

      if (tp != NULL
	  && ((selection & (USER_SELECTED_THREAD | USER_SELECTED_FRAME))))
	print_selected_thread_frame (cli->cli_uiout, selection);
    }
}

/* pre_command_loop implementation.  */

void
cli_interp_base::pre_command_loop ()
{
  display_gdb_prompt (0);
}

/* These implement the cli out interpreter: */

void
cli_interp::init (bool top_level)
{
}

void
cli_interp::resume ()
{
  struct ui *ui = current_ui;
  struct cli_interp *cli = this;
  struct ui_file *stream;

  /*sync_execution = 1; */

  /* gdb_setup_readline will change gdb_stdout.  If the CLI was
     previously writing to gdb_stdout, then set it to the new
     gdb_stdout afterwards.  */

  stream = cli->cli_uiout->set_stream (gdb_stdout);
  if (stream != gdb_stdout)
    {
      cli->cli_uiout->set_stream (stream);
      stream = NULL;
    }

  gdb_setup_readline (1);

  ui->input_handler = command_line_handler;

  if (stream != NULL)
    cli->cli_uiout->set_stream (gdb_stdout);
}

void
cli_interp::suspend ()
{
  gdb_disable_readline ();
}

gdb_exception
cli_interp::exec (const char *command_str)
{
  struct cli_interp *cli = this;
  struct ui_file *old_stream;
  struct gdb_exception result;

  /* gdb_stdout could change between the time cli_uiout was
     initialized and now.  Since we're probably using a different
     interpreter which has a new ui_file for gdb_stdout, use that one
     instead of the default.

     It is important that it gets reset everytime, since the user
     could set gdb to use a different interpreter.  */
  old_stream = cli->cli_uiout->set_stream (gdb_stdout);
  result = safe_execute_command (cli->cli_uiout, command_str, 1);
  cli->cli_uiout->set_stream (old_stream);
  return result;
}

bool
cli_interp_base::supports_command_editing ()
{
  return true;
}

static struct gdb_exception
safe_execute_command (struct ui_out *command_uiout, const char *command,
		      int from_tty)
{
  struct gdb_exception e;

  /* Save and override the global ``struct ui_out'' builder.  */
  scoped_restore saved_uiout = make_scoped_restore (&current_uiout,
						    command_uiout);

  try
    {
      execute_command (command, from_tty);
    }
  catch (gdb_exception &exception)
    {
      e = std::move (exception);
    }

  /* FIXME: cagney/2005-01-13: This shouldn't be needed.  Instead the
     caller should print the exception.  */
  exception_print (gdb_stderr, e);
  return e;
}

ui_out *
cli_interp::interp_ui_out ()
{
  struct cli_interp *cli = (struct cli_interp *) this;

  return cli->cli_uiout;
}

/* These hold the pushed copies of the gdb output files.
   If NULL then nothing has yet been pushed.  */
struct saved_output_files
{
  ui_file *out;
  ui_file *err;
  ui_file *log;
  ui_file *targ;
  ui_file *targerr;
  ui_file *file_to_delete;
};
static saved_output_files saved_output;

/* See cli-interp.h.  */

void
cli_interp_base::set_logging (ui_file_up logfile, bool logging_redirect,
			      bool debug_redirect)
{
  if (logfile != nullptr)
    {
      saved_output.out = gdb_stdout;
      saved_output.err = gdb_stderr;
      saved_output.log = gdb_stdlog;
      saved_output.targ = gdb_stdtarg;
      saved_output.targerr = gdb_stdtargerr;

      /* If something is being redirected, then grab logfile.  */
      ui_file *logfile_p = nullptr;
      if (logging_redirect || debug_redirect)
	{
	  logfile_p = logfile.get ();
	  saved_output.file_to_delete = logfile_p;
	}

      /* If something is not being redirected, then a tee containing both the
	 logfile and stdout.  */
      ui_file *tee = nullptr;
      if (!logging_redirect || !debug_redirect)
	{
	  tee = new tee_file (gdb_stdout, std::move (logfile));
	  saved_output.file_to_delete = tee;
	}

      /* Make sure that the call to logfile's dtor does not delete the
         underlying pointer if we still keep a reference to it.  If
         logfile_p is not referenced as the file_to_delete, then either
         the logfile is not used (no redirection) and it should be
         deleted, or a tee took ownership of the pointer. */
      if (logfile_p != nullptr && saved_output.file_to_delete == logfile_p)
	logfile.release ();

      gdb_stdout = logging_redirect ? logfile_p : tee;
      gdb_stdlog = debug_redirect ? logfile_p : tee;
      gdb_stderr = logging_redirect ? logfile_p : tee;
      gdb_stdtarg = logging_redirect ? logfile_p : tee;
      gdb_stdtargerr = logging_redirect ? logfile_p : tee;
    }
  else
    {
      /* Delete the correct file.  If it's the tee then the logfile will also
	 be deleted.  */
      delete saved_output.file_to_delete;

      gdb_stdout = saved_output.out;
      gdb_stderr = saved_output.err;
      gdb_stdlog = saved_output.log;
      gdb_stdtarg = saved_output.targ;
      gdb_stdtargerr = saved_output.targerr;

      saved_output.out = nullptr;
      saved_output.err = nullptr;
      saved_output.log = nullptr;
      saved_output.targ = nullptr;
      saved_output.targerr = nullptr;
      saved_output.file_to_delete = nullptr;
    }
}

/* Factory for CLI interpreters.  */

static struct interp *
cli_interp_factory (const char *name)
{
  return new cli_interp (name);
}

/* Standard gdb initialization hook.  */

void _initialize_cli_interp ();
void
_initialize_cli_interp ()
{
  interp_factory_register (INTERP_CONSOLE, cli_interp_factory);

  /* If changing this, remember to update tui-interp.c as well.  */
  gdb::observers::normal_stop.attach (cli_on_normal_stop, "cli-interp");
  gdb::observers::end_stepping_range.attach (cli_on_end_stepping_range,
					     "cli-interp");
  gdb::observers::signal_received.attach (cli_on_signal_received, "cli-interp");
  gdb::observers::signal_exited.attach (cli_on_signal_exited, "cli-interp");
  gdb::observers::exited.attach (cli_on_exited, "cli-interp");
  gdb::observers::no_history.attach (cli_on_no_history, "cli-interp");
  gdb::observers::sync_execution_done.attach (cli_on_sync_execution_done,
					      "cli-interp");
  gdb::observers::command_error.attach (cli_on_command_error, "cli-interp");
  gdb::observers::user_selected_context_changed.attach
    (cli_on_user_selected_context_changed, "cli-interp");
}
