/* GDB/Scheme exception support.

   Copyright (C) 2014-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/>.  */

/* See README file in this directory for implementation notes, coding
   conventions, et.al.  */

/* Notes:

   IWBN to support SRFI 34/35.  At the moment we follow Guile's own
   exception mechanism.

   The non-static functions in this file have prefix gdbscm_ and
   not exscm_ on purpose.  */

#include "defs.h"
#include <signal.h>
#include "guile-internal.h"

/* The <gdb:exception> smob.
   This is used to record and handle Scheme exceptions.
   One important invariant is that <gdb:exception> smobs are never a valid
   result of a function, other than to signify an exception occurred.  */

struct exception_smob
{
  /* This always appears first.  */
  gdb_smob base;

  /* The key and args parameters to "throw".  */
  SCM key;
  SCM args;
};

static const char exception_smob_name[] = "gdb:exception";

/* The tag Guile knows the exception smob by.  */
static scm_t_bits exception_smob_tag;

/* A generic error in struct gdb_exception.
   I.e., not RETURN_QUIT and not MEMORY_ERROR.  */
static SCM error_symbol;

/* An error occurred accessing inferior memory.
   This is not a Scheme programming error.  */
static SCM memory_error_symbol;

/* User interrupt, e.g., RETURN_QUIT in struct gdb_exception.  */
static SCM signal_symbol;

/* A user error, e.g., bad arg to gdb command.  */
static SCM user_error_symbol;

/* Printing the stack is done by first capturing the stack and recording it in
   a <gdb:exception> object with this key and with the ARGS field set to
   (cons real-key (cons stack real-args)).
   See gdbscm_make_exception_with_stack.  */
static SCM with_stack_error_symbol;

/* The key to use for an invalid object exception.  An invalid object is one
   where the underlying object has been removed from GDB.  */
SCM gdbscm_invalid_object_error_symbol;

/* Values for "guile print-stack" as symbols.  */
static SCM none_symbol;
static SCM message_symbol;
static SCM full_symbol;

static const char percent_print_exception_message_name[] =
  "%print-exception-message";

/* Variable containing %print-exception-message.
   It is not defined until late in initialization, after our init routine
   has run.  Cope by looking it up lazily.  */
static SCM percent_print_exception_message_var = SCM_BOOL_F;

static const char percent_print_exception_with_stack_name[] =
  "%print-exception-with-stack";

/* Variable containing %print-exception-with-stack.
   It is not defined until late in initialization, after our init routine
   has run.  Cope by looking it up lazily.  */
static SCM percent_print_exception_with_stack_var = SCM_BOOL_F;

/* Counter to keep track of the number of times we create a <gdb:exception>
   object, for performance monitoring purposes.  */
static unsigned long gdbscm_exception_count = 0;

/* Administrivia for exception smobs.  */

/* The smob "print" function for <gdb:exception>.  */

static int
exscm_print_exception_smob (SCM self, SCM port, scm_print_state *pstate)
{
  exception_smob *e_smob = (exception_smob *) SCM_SMOB_DATA (self);

  gdbscm_printf (port, "#<%s ", exception_smob_name);
  scm_write (e_smob->key, port);
  scm_puts (" ", port);
  scm_write (e_smob->args, port);
  scm_puts (">", port);

  scm_remember_upto_here_1 (self);

  /* Non-zero means success.  */
  return 1;
}

/* (make-exception key args) -> <gdb:exception> */

SCM
gdbscm_make_exception (SCM key, SCM args)
{
  exception_smob *e_smob = (exception_smob *)
    scm_gc_malloc (sizeof (exception_smob), exception_smob_name);
  SCM smob;

  e_smob->key = key;
  e_smob->args = args;
  smob = scm_new_smob (exception_smob_tag, (scm_t_bits) e_smob);
  gdbscm_init_gsmob (&e_smob->base);

  ++gdbscm_exception_count;

  return smob;
}

/* Return non-zero if SCM is a <gdb:exception> object.  */

int
gdbscm_is_exception (SCM scm)
{
  return SCM_SMOB_PREDICATE (exception_smob_tag, scm);
}

/* (exception? scm) -> boolean */

static SCM
gdbscm_exception_p (SCM scm)
{
  return scm_from_bool (gdbscm_is_exception (scm));
}

/* (exception-key <gdb:exception>) -> key */

SCM
gdbscm_exception_key (SCM self)
{
  exception_smob *e_smob;

  SCM_ASSERT_TYPE (gdbscm_is_exception (self), self, SCM_ARG1, FUNC_NAME,
		   "gdb:exception");

  e_smob = (exception_smob *) SCM_SMOB_DATA (self);
  return e_smob->key;
}

/* (exception-args <gdb:exception>) -> arg-list */

SCM
gdbscm_exception_args (SCM self)
{
  exception_smob *e_smob;

  SCM_ASSERT_TYPE (gdbscm_is_exception (self), self, SCM_ARG1, FUNC_NAME,
		   "gdb:exception");

  e_smob = (exception_smob *) SCM_SMOB_DATA (self);
  return e_smob->args;
}

/* Wrap an exception in a <gdb:exception> object that includes STACK.
   gdbscm_print_exception_with_stack knows how to unwrap it.  */

SCM
gdbscm_make_exception_with_stack (SCM key, SCM args, SCM stack)
{
  return gdbscm_make_exception (with_stack_error_symbol,
				scm_cons (key, scm_cons (stack, args)));
}

/* Version of scm_error_scm that creates a gdb:exception object that can later
   be passed to gdbscm_throw.
   KEY is a symbol denoting the kind of error.
   SUBR is either #f or a string marking the function in which the error
   occurred.
   MESSAGE is either #f or the error message string.  It may contain ~a and ~s
   modifiers, provided by ARGS.
   ARGS is a list of args to MESSAGE.
   DATA is an arbitrary object, its value depends on KEY.  The value to pass
   here is a bit underspecified by Guile.  */

SCM
gdbscm_make_error_scm (SCM key, SCM subr, SCM message, SCM args, SCM data)
{
  return gdbscm_make_exception (key, scm_list_4 (subr, message, args, data));
}

/* Version of scm_error that creates a gdb:exception object that can later
   be passed to gdbscm_throw.
   See gdbscm_make_error_scm for a description of the arguments.  */

SCM
gdbscm_make_error (SCM key, const char *subr, const char *message,
		   SCM args, SCM data)
{
  return gdbscm_make_error_scm
    (key,
     subr == NULL ? SCM_BOOL_F : scm_from_latin1_string (subr),
     message == NULL ? SCM_BOOL_F : scm_from_latin1_string (message),
     args, data);
}

/* Version of SCM_ASSERT_TYPE/scm_wrong_type_arg_msg that creates a
   gdb:exception object that can later be passed to gdbscm_throw.  */

SCM
gdbscm_make_type_error (const char *subr, int arg_pos, SCM bad_value,
			const char *expected_type)
{
  char *msg;
  SCM result;

  if (arg_pos > 0)
    {
      if (expected_type != NULL)
	{
	  msg = xstrprintf (_("Wrong type argument in position %d"
			      " (expecting %s): ~S"),
			    arg_pos, expected_type);
	}
      else
	{
	  msg = xstrprintf (_("Wrong type argument in position %d: ~S"),
			    arg_pos);
	}
    }
  else
    {
      if (expected_type != NULL)
	{
	  msg = xstrprintf (_("Wrong type argument (expecting %s): ~S"),
			    expected_type);
	}
      else
	msg = xstrprintf (_("Wrong type argument: ~S"));
    }

  result = gdbscm_make_error (scm_arg_type_key, subr, msg,
			      scm_list_1 (bad_value), scm_list_1 (bad_value));
  xfree (msg);
  return result;
}

/* A variant of gdbscm_make_type_error for non-type argument errors.
   ERROR_PREFIX and ERROR are combined to build the error message.
   Care needs to be taken so that the i18n composed form is still
   reasonable, but no one is going to translate these anyway so we don't
   worry too much.
   ERROR_PREFIX may be NULL, ERROR may not be NULL.  */

static SCM
gdbscm_make_arg_error (SCM key, const char *subr, int arg_pos, SCM bad_value,
		       const char *error_prefix, const char *error)
{
  char *msg;
  SCM result;

  if (error_prefix != NULL)
    {
      if (arg_pos > 0)
	{
	  msg = xstrprintf (_("%s %s in position %d: ~S"),
			    error_prefix, error, arg_pos);
	}
      else
	msg = xstrprintf (_("%s %s: ~S"), error_prefix, error);
    }
  else
    {
      if (arg_pos > 0)
	msg = xstrprintf (_("%s in position %d: ~S"), error, arg_pos);
      else
	msg = xstrprintf (_("%s: ~S"), error);
    }

  result = gdbscm_make_error (key, subr, msg,
			      scm_list_1 (bad_value), scm_list_1 (bad_value));
  xfree (msg);
  return result;
}

/* Make an invalid-object error <gdb:exception> object.
   OBJECT is the name of the kind of object that is invalid.  */

SCM
gdbscm_make_invalid_object_error (const char *subr, int arg_pos, SCM bad_value,
				  const char *object)
{
  return gdbscm_make_arg_error (gdbscm_invalid_object_error_symbol,
				subr, arg_pos, bad_value,
				_("Invalid object:"), object);
}

/* Throw an invalid-object error.
   OBJECT is the name of the kind of object that is invalid.  */

void
gdbscm_invalid_object_error (const char *subr, int arg_pos, SCM bad_value,
			     const char *object)
{
  SCM exception
    = gdbscm_make_invalid_object_error (subr, arg_pos, bad_value, object);

  gdbscm_throw (exception);
}

/* Make an out-of-range error <gdb:exception> object.  */

SCM
gdbscm_make_out_of_range_error (const char *subr, int arg_pos, SCM bad_value,
				const char *error)
{
  return gdbscm_make_arg_error (scm_out_of_range_key,
				subr, arg_pos, bad_value,
				_("Out of range:"), error);
}

/* Throw an out-of-range error.
   This is the standard Guile out-of-range exception.  */

void
gdbscm_out_of_range_error (const char *subr, int arg_pos, SCM bad_value,
			   const char *error)
{
  SCM exception
    = gdbscm_make_out_of_range_error (subr, arg_pos, bad_value, error);

  gdbscm_throw (exception);
}

/* Make a misc-error <gdb:exception> object.  */

SCM
gdbscm_make_misc_error (const char *subr, int arg_pos, SCM bad_value,
			const char *error)
{
  return gdbscm_make_arg_error (scm_misc_error_key,
				subr, arg_pos, bad_value, NULL, error);
}

/* Throw a misc-error error.  */

void
gdbscm_misc_error (const char *subr, int arg_pos, SCM bad_value,
		   const char *error)
{
  SCM exception = gdbscm_make_misc_error (subr, arg_pos, bad_value, error);

  gdbscm_throw (exception);
}

/* Return a <gdb:exception> object for gdb:memory-error.  */

SCM
gdbscm_make_memory_error (const char *subr, const char *msg, SCM args)
{
  return gdbscm_make_error (memory_error_symbol, subr, msg, args,
			    SCM_EOL);
}

/* Throw a gdb:memory-error exception.  */

void
gdbscm_memory_error (const char *subr, const char *msg, SCM args)
{
  SCM exception = gdbscm_make_memory_error (subr, msg, args);

  gdbscm_throw (exception);
}

/* Return non-zero if KEY is gdb:memory-error.
   Note: This is an excp_matcher_func function.  */

int
gdbscm_memory_error_p (SCM key)
{
  return scm_is_eq (key, memory_error_symbol);
}

/* Return non-zero if KEY is gdb:user-error.
   Note: This is an excp_matcher_func function.  */

int
gdbscm_user_error_p (SCM key)
{
  return scm_is_eq (key, user_error_symbol);
}

/* Wrapper around scm_throw to throw a gdb:exception.
   This function does not return.
   This function cannot be called from inside TRY_CATCH.  */

void
gdbscm_throw (SCM exception)
{
  scm_throw (gdbscm_exception_key (exception),
	     gdbscm_exception_args (exception));
  gdb_assert_not_reached ("scm_throw returned");
}

/* Convert a GDB exception to a <gdb:exception> object.  */

SCM
gdbscm_scm_from_gdb_exception (const gdbscm_gdb_exception &exception)
{
  SCM key;

  if (exception.reason == RETURN_QUIT)
    {
      /* Handle this specially to be consistent with top-repl.scm.  */
      return gdbscm_make_error (signal_symbol, NULL, _("User interrupt"),
				SCM_EOL, scm_list_1 (scm_from_int (SIGINT)));
    }

  if (exception.error == MEMORY_ERROR)
    key = memory_error_symbol;
  else
    key = error_symbol;

  return gdbscm_make_error (key, NULL, "~A",
			    scm_list_1 (gdbscm_scm_from_c_string
					(exception.message)),
			    SCM_BOOL_F);
}

/* Convert a GDB exception to the appropriate Scheme exception and throw it.
   This function does not return.  */

void
gdbscm_throw_gdb_exception (gdbscm_gdb_exception exception)
{
  SCM scm_exception = gdbscm_scm_from_gdb_exception (exception);
  xfree (exception.message);
  gdbscm_throw (scm_exception);
}

/* Print the error message portion of an exception.
   If PORT is #f, use the standard error port.
   KEY cannot be gdb:with-stack.

   Basically this function is just a wrapper around calling
   %print-exception-message.  */

static void
gdbscm_print_exception_message (SCM port, SCM frame, SCM key, SCM args)
{
  SCM printer, status;

  if (gdbscm_is_false (port))
    port = scm_current_error_port ();

  gdb_assert (!scm_is_eq (key, with_stack_error_symbol));

  /* This does not use scm_print_exception because we tweak the output a bit.
     Compare Guile's print-exception with our %print-exception-message for
     details.  */
  if (gdbscm_is_false (percent_print_exception_message_var))
    {
      percent_print_exception_message_var
	= scm_c_private_variable (gdbscm_init_module_name,
				  percent_print_exception_message_name);
      /* If we can't find %print-exception-message, there's a problem on the
	 Scheme side.  Don't kill GDB, just flag an error and leave it at
	 that.  */
      if (gdbscm_is_false (percent_print_exception_message_var))
	{
	  gdbscm_printf (port, _("Error in Scheme exception printing,"
				 " can't find %s.\n"),
			 percent_print_exception_message_name);
	  return;
	}
    }
  printer = scm_variable_ref (percent_print_exception_message_var);

  status = gdbscm_safe_call_4 (printer, port, frame, key, args, NULL);

  /* If that failed still tell the user something.
     But don't use the exception printing machinery!  */
  if (gdbscm_is_exception (status))
    {
      gdbscm_printf (port, _("Error in Scheme exception printing:\n"));
      scm_display (status, port);
      scm_newline (port);
    }
}

/* Print the description of exception KEY, ARGS to PORT, according to the
   setting of "set guile print-stack".
   If PORT is #f, use the standard error port.
   If STACK is #f, never print the stack, regardless of whether printing it
   is enabled.  If STACK is #t, then print it if it is contained in ARGS
   (i.e., KEY is gdb:with-stack).  Otherwise STACK is the result of calling
   scm_make_stack (which will be ignored in favor of the stack in ARGS if
   KEY is gdb:with-stack).
   KEY, ARGS are the standard arguments to scm_throw, et.al.

   Basically this function is just a wrapper around calling
   %print-exception-with-stack.  */

void
gdbscm_print_exception_with_stack (SCM port, SCM stack, SCM key, SCM args)
{
  SCM printer, status;

  if (gdbscm_is_false (port))
    port = scm_current_error_port ();

  if (gdbscm_is_false (percent_print_exception_with_stack_var))
    {
      percent_print_exception_with_stack_var
	= scm_c_private_variable (gdbscm_init_module_name,
				  percent_print_exception_with_stack_name);
      /* If we can't find %print-exception-with-stack, there's a problem on the
	 Scheme side.  Don't kill GDB, just flag an error and leave it at
	 that.  */
      if (gdbscm_is_false (percent_print_exception_with_stack_var))
	{
	  gdbscm_printf (port, _("Error in Scheme exception printing,"
				 " can't find %s.\n"),
			 percent_print_exception_with_stack_name);
	  return;
	}
    }
  printer = scm_variable_ref (percent_print_exception_with_stack_var);

  status = gdbscm_safe_call_4 (printer, port, stack, key, args, NULL);

  /* If that failed still tell the user something.
     But don't use the exception printing machinery!  */
  if (gdbscm_is_exception (status))
    {
      gdbscm_printf (port, _("Error in Scheme exception printing:\n"));
      scm_display (status, port);
      scm_newline (port);
    }
}

/* Print EXCEPTION, a <gdb:exception> object, to PORT.
   If PORT is #f, use the standard error port.  */

void
gdbscm_print_gdb_exception (SCM port, SCM exception)
{
  gdb_assert (gdbscm_is_exception (exception));

  gdbscm_print_exception_with_stack (port, SCM_BOOL_T,
				     gdbscm_exception_key (exception),
				     gdbscm_exception_args (exception));
}

/* Return a string description of <gdb:exception> EXCEPTION.
   If EXCEPTION is a gdb:with-stack exception, unwrap it, a backtrace
   is never returned as part of the result.  */

gdb::unique_xmalloc_ptr<char>
gdbscm_exception_message_to_string (SCM exception)
{
  SCM port = scm_open_output_string ();
  SCM key, args;

  gdb_assert (gdbscm_is_exception (exception));

  key = gdbscm_exception_key (exception);
  args = gdbscm_exception_args (exception);

  if (scm_is_eq (key, with_stack_error_symbol)
      /* Don't crash on a badly generated gdb:with-stack exception.  */
      && scm_is_pair (args)
      && scm_is_pair (scm_cdr (args)))
    {
      key = scm_car (args);
      args = scm_cddr (args);
    }

  gdbscm_print_exception_message (port, SCM_BOOL_F, key, args);
  gdb::unique_xmalloc_ptr<char> result
    = gdbscm_scm_to_c_string (scm_get_output_string (port));
  scm_close_port (port);
  return result;
}

/* Return the value of the "guile print-stack" option as one of:
   'none, 'message, 'full.  */

static SCM
gdbscm_percent_exception_print_style (void)
{
  if (gdbscm_print_excp == gdbscm_print_excp_none)
    return none_symbol;
  if (gdbscm_print_excp == gdbscm_print_excp_message)
    return message_symbol;
  if (gdbscm_print_excp == gdbscm_print_excp_full)
    return full_symbol;
  gdb_assert_not_reached ("bad value for \"guile print-stack\"");
}

/* Return the current <gdb:exception> counter.
   This is for debugging purposes.  */

static SCM
gdbscm_percent_exception_count (void)
{
  return scm_from_ulong (gdbscm_exception_count);
}

/* Initialize the Scheme exception support.  */

static const scheme_function exception_functions[] =
{
  { "make-exception", 2, 0, 0, as_a_scm_t_subr (gdbscm_make_exception),
    "\
Create a <gdb:exception> object.\n\
\n\
  Arguments: key args\n\
    These are the standard key,args arguments of \"throw\"." },

  { "exception?", 1, 0, 0, as_a_scm_t_subr (gdbscm_exception_p),
    "\
Return #t if the object is a <gdb:exception> object." },

  { "exception-key", 1, 0, 0, as_a_scm_t_subr (gdbscm_exception_key),
    "\
Return the exception's key." },

  { "exception-args", 1, 0, 0, as_a_scm_t_subr (gdbscm_exception_args),
    "\
Return the exception's arg list." },

  END_FUNCTIONS
};

static const scheme_function private_exception_functions[] =
{
  { "%exception-print-style", 0, 0, 0,
    as_a_scm_t_subr (gdbscm_percent_exception_print_style),
    "\
Return the value of the \"guile print-stack\" option." },

  { "%exception-count", 0, 0, 0,
    as_a_scm_t_subr (gdbscm_percent_exception_count),
    "\
Return a count of the number of <gdb:exception> objects created.\n\
This is for debugging purposes." },

  END_FUNCTIONS
};

void
gdbscm_initialize_exceptions (void)
{
  exception_smob_tag = gdbscm_make_smob_type (exception_smob_name,
					      sizeof (exception_smob));
  scm_set_smob_print (exception_smob_tag, exscm_print_exception_smob);

  gdbscm_define_functions (exception_functions, 1);
  gdbscm_define_functions (private_exception_functions, 0);

  error_symbol = scm_from_latin1_symbol ("gdb:error");

  memory_error_symbol = scm_from_latin1_symbol ("gdb:memory-error");

  user_error_symbol = scm_from_latin1_symbol ("gdb:user-error");

  gdbscm_invalid_object_error_symbol
    = scm_from_latin1_symbol ("gdb:invalid-object-error");

  with_stack_error_symbol = scm_from_latin1_symbol ("gdb:with-stack");

  /* The text of this symbol is taken from Guile's top-repl.scm.  */
  signal_symbol = scm_from_latin1_symbol ("signal");

  none_symbol = scm_from_latin1_symbol ("none");
  message_symbol = scm_from_latin1_symbol ("message");
  full_symbol = scm_from_latin1_symbol ("full");
}
