/* Scheme interface to breakpoints.

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

#include "defs.h"
#include "value.h"
#include "breakpoint.h"
#include "gdbcmd.h"
#include "gdbthread.h"
#include "observable.h"
#include "cli/cli-script.h"
#include "ada-lang.h"
#include "arch-utils.h"
#include "language.h"
#include "guile-internal.h"
#include "location.h"

/* The <gdb:breakpoint> smob.
   N.B.: The name of this struct is known to breakpoint.h.

   Note: Breakpoints are added to gdb using a two step process:
   1) Call make-breakpoint to create a <gdb:breakpoint> object.
   2) Call register-breakpoint! to add the breakpoint to gdb.
   It is done this way so that the constructor, make-breakpoint, doesn't have
   any side-effects.  This means that the smob needs to store everything
   that was passed to make-breakpoint.  */

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

  /* Non-zero if this breakpoint was created with make-breakpoint.  */
  int is_scheme_bkpt;

  /* For breakpoints created with make-breakpoint, these are the parameters
     that were passed to make-breakpoint.  These values are not used except
     to register the breakpoint with GDB.  */
  struct
  {
    /* The string representation of the breakpoint.
       Space for this lives in GC space.  */
    char *location;

    /* The kind of breakpoint.
       At the moment this can only be one of bp_breakpoint, bp_watchpoint.  */
    enum bptype type;

    /* If a watchpoint, the kind of watchpoint.  */
    enum target_hw_bp_type access_type;

    /* Non-zero if the breakpoint is an "internal" breakpoint.  */
    int is_internal;

    /* Non-zero if the breakpoint is temporary.  */
    int is_temporary;
  } spec;

  /* The breakpoint number according to gdb.
     For breakpoints created from Scheme, this has the value -1 until the
     breakpoint is registered with gdb.
     This is recorded here because BP will be NULL when deleted.  */
  int number;

  /* The gdb breakpoint object, or NULL if the breakpoint has not been
     registered yet, or has been deleted.  */
  struct breakpoint *bp;

  /* Backlink to our containing <gdb:breakpoint> smob.
     This is needed when we are deleted, we need to unprotect the object
     from GC.  */
  SCM containing_scm;

  /* A stop condition or #f.  */
  SCM stop;
} breakpoint_smob;

static const char breakpoint_smob_name[] = "gdb:breakpoint";

/* The tag Guile knows the breakpoint smob by.  */
static scm_t_bits breakpoint_smob_tag;

/* Variables used to pass information between the breakpoint_smob
   constructor and the breakpoint-created hook function.  */
static SCM pending_breakpoint_scm = SCM_BOOL_F;

/* Keywords used by create-breakpoint!.  */
static SCM type_keyword;
static SCM wp_class_keyword;
static SCM internal_keyword;
static SCM temporary_keyword;

/* Administrivia for breakpoint smobs.  */

/* The smob "free" function for <gdb:breakpoint>.  */

static size_t
bpscm_free_breakpoint_smob (SCM self)
{
  breakpoint_smob *bp_smob = (breakpoint_smob *) SCM_SMOB_DATA (self);

  if (bp_smob->bp)
    bp_smob->bp->scm_bp_object = NULL;

  /* Not necessary, done to catch bugs.  */
  bp_smob->bp = NULL;
  bp_smob->containing_scm = SCM_UNDEFINED;
  bp_smob->stop = SCM_UNDEFINED;

  return 0;
}

/* Return the name of TYPE.
   This doesn't handle all types, just the ones we export.  */

static const char *
bpscm_type_to_string (enum bptype type)
{
  switch (type)
    {
    case bp_none: return "BP_NONE";
    case bp_breakpoint: return "BP_BREAKPOINT";
    case bp_watchpoint: return "BP_WATCHPOINT";
    case bp_hardware_watchpoint: return "BP_HARDWARE_WATCHPOINT";
    case bp_read_watchpoint: return "BP_READ_WATCHPOINT";
    case bp_access_watchpoint: return "BP_ACCESS_WATCHPOINT";
    case bp_catchpoint: return "BP_CATCHPOINT";
    default: return "internal/other";
    }
}

/* Return the name of ENABLE_STATE.  */

static const char *
bpscm_enable_state_to_string (enum enable_state enable_state)
{
  switch (enable_state)
    {
    case bp_disabled: return "disabled";
    case bp_enabled: return "enabled";
    case bp_call_disabled: return "call_disabled";
    default: return "unknown";
    }
}

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

static int
bpscm_print_breakpoint_smob (SCM self, SCM port, scm_print_state *pstate)
{
  breakpoint_smob *bp_smob = (breakpoint_smob *) SCM_SMOB_DATA (self);
  struct breakpoint *b = bp_smob->bp;

  gdbscm_printf (port, "#<%s", breakpoint_smob_name);

  /* Only print what we export to the user.
     The rest are possibly internal implementation details.  */

  gdbscm_printf (port, " #%d", bp_smob->number);

  /* Careful, the breakpoint may be invalid.  */
  if (b != NULL)
    {
      gdbscm_printf (port, " %s %s %s",
		     bpscm_type_to_string (b->type),
		     bpscm_enable_state_to_string (b->enable_state),
		     b->silent ? "silent" : "noisy");

      gdbscm_printf (port, " hit:%d", b->hit_count);
      gdbscm_printf (port, " ignore:%d", b->ignore_count);

      if (b->location != nullptr)
	{
	  const char *str = event_location_to_string (b->location.get ());
	  if (str != nullptr)
	    gdbscm_printf (port, " @%s", str);
	}
    }

  scm_puts (">", port);

  scm_remember_upto_here_1 (self);

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

/* Low level routine to create a <gdb:breakpoint> object.  */

static SCM
bpscm_make_breakpoint_smob (void)
{
  breakpoint_smob *bp_smob = (breakpoint_smob *)
    scm_gc_malloc (sizeof (breakpoint_smob), breakpoint_smob_name);
  SCM bp_scm;

  memset (bp_smob, 0, sizeof (*bp_smob));
  bp_smob->number = -1;
  bp_smob->stop = SCM_BOOL_F;
  bp_scm = scm_new_smob (breakpoint_smob_tag, (scm_t_bits) bp_smob);
  bp_smob->containing_scm = bp_scm;
  gdbscm_init_gsmob (&bp_smob->base);

  return bp_scm;
}

/* Return non-zero if we want a Scheme wrapper for breakpoint B.
   If FROM_SCHEME is non-zero,this is called for a breakpoint created
   by the user from Scheme.  Otherwise it is zero.  */

static int
bpscm_want_scm_wrapper_p (struct breakpoint *bp, int from_scheme)
{
  /* Don't create <gdb:breakpoint> objects for internal GDB breakpoints.  */
  if (bp->number < 0 && !from_scheme)
    return 0;

  /* The others are not supported.  */
  if (bp->type != bp_breakpoint
      && bp->type != bp_watchpoint
      && bp->type != bp_hardware_watchpoint
      && bp->type != bp_read_watchpoint
      && bp->type != bp_access_watchpoint
      && bp->type != bp_catchpoint)
    return 0;

  return 1;
}

/* Install the Scheme side of a breakpoint, CONTAINING_SCM, in
   the gdb side BP.  */

static void
bpscm_attach_scm_to_breakpoint (struct breakpoint *bp, SCM containing_scm)
{
  breakpoint_smob *bp_smob;

  bp_smob = (breakpoint_smob *) SCM_SMOB_DATA (containing_scm);
  bp_smob->number = bp->number;
  bp_smob->bp = bp;
  bp_smob->containing_scm = containing_scm;
  bp_smob->bp->scm_bp_object = bp_smob;

  /* The owner of this breakpoint is not in GC-controlled memory, so we need
     to protect it from GC until the breakpoint is deleted.  */
  scm_gc_protect_object (containing_scm);
}

/* Return non-zero if SCM is a breakpoint smob.  */

static int
bpscm_is_breakpoint (SCM scm)
{
  return SCM_SMOB_PREDICATE (breakpoint_smob_tag, scm);
}

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

static SCM
gdbscm_breakpoint_p (SCM scm)
{
  return scm_from_bool (bpscm_is_breakpoint (scm));
}

/* Returns the <gdb:breakpoint> object in SELF.
   Throws an exception if SELF is not a <gdb:breakpoint> object.  */

static SCM
bpscm_get_breakpoint_arg_unsafe (SCM self, int arg_pos, const char *func_name)
{
  SCM_ASSERT_TYPE (bpscm_is_breakpoint (self), self, arg_pos, func_name,
		   breakpoint_smob_name);

  return self;
}

/* Returns a pointer to the breakpoint smob of SELF.
   Throws an exception if SELF is not a <gdb:breakpoint> object.  */

static breakpoint_smob *
bpscm_get_breakpoint_smob_arg_unsafe (SCM self, int arg_pos,
				      const char *func_name)
{
  SCM bp_scm = bpscm_get_breakpoint_arg_unsafe (self, arg_pos, func_name);
  breakpoint_smob *bp_smob = (breakpoint_smob *) SCM_SMOB_DATA (bp_scm);

  return bp_smob;
}

/* Return non-zero if breakpoint BP_SMOB is valid.  */

static int
bpscm_is_valid (breakpoint_smob *bp_smob)
{
  return bp_smob->bp != NULL;
}

/* Returns the breakpoint smob in SELF, verifying it's valid.
   Throws an exception if SELF is not a <gdb:breakpoint> object,
   or is invalid.  */

static breakpoint_smob *
bpscm_get_valid_breakpoint_smob_arg_unsafe (SCM self, int arg_pos,
					    const char *func_name)
{
  breakpoint_smob *bp_smob
    = bpscm_get_breakpoint_smob_arg_unsafe (self, arg_pos, func_name);

  if (!bpscm_is_valid (bp_smob))
    {
      gdbscm_invalid_object_error (func_name, arg_pos, self,
				   _("<gdb:breakpoint>"));
    }

  return bp_smob;
}

/* Breakpoint methods.  */

/* (make-breakpoint string [#:type integer] [#:wp-class integer]
    [#:internal boolean] [#:temporary boolean]) -> <gdb:breakpoint>

   The result is the <gdb:breakpoint> Scheme object.
   The breakpoint is not available to be used yet, however.
   It must still be added to gdb with register-breakpoint!.  */

static SCM
gdbscm_make_breakpoint (SCM location_scm, SCM rest)
{
  const SCM keywords[] = {
    type_keyword, wp_class_keyword, internal_keyword,
    temporary_keyword, SCM_BOOL_F
  };
  char *s;
  char *location;
  int type_arg_pos = -1, access_type_arg_pos = -1,
      internal_arg_pos = -1, temporary_arg_pos = -1;
  enum bptype type = bp_breakpoint;
  enum target_hw_bp_type access_type = hw_write;
  int internal = 0;
  int temporary = 0;
  SCM result;
  breakpoint_smob *bp_smob;

  gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, keywords, "s#iitt",
			      location_scm, &location, rest,
			      &type_arg_pos, &type,
			      &access_type_arg_pos, &access_type,
			      &internal_arg_pos, &internal,
			      &temporary_arg_pos, &temporary);

  result = bpscm_make_breakpoint_smob ();
  bp_smob = (breakpoint_smob *) SCM_SMOB_DATA (result);

  s = location;
  location = gdbscm_gc_xstrdup (s);
  xfree (s);

  switch (type)
    {
    case bp_breakpoint:
      if (access_type_arg_pos > 0)
	{
	  gdbscm_misc_error (FUNC_NAME, access_type_arg_pos,
			     scm_from_int (access_type),
			     _("access type with breakpoint is not allowed"));
	}
      break;
    case bp_watchpoint:
      switch (access_type)
	{
	case hw_write:
	case hw_access:
	case hw_read:
	  break;
	default:
	  gdbscm_out_of_range_error (FUNC_NAME, access_type_arg_pos,
				     scm_from_int (access_type),
				     _("invalid watchpoint class"));
	}
      break;
    case bp_none:
    case bp_hardware_watchpoint:
    case bp_read_watchpoint:
    case bp_access_watchpoint:
    case bp_catchpoint:
      {
	const char *type_name = bpscm_type_to_string (type);
	gdbscm_misc_error (FUNC_NAME, type_arg_pos,
			   gdbscm_scm_from_c_string (type_name),
			   _("unsupported breakpoint type"));
      }
      break;
    default:
      gdbscm_out_of_range_error (FUNC_NAME, type_arg_pos,
				 scm_from_int (type),
				 _("invalid breakpoint type"));
    }

  bp_smob->is_scheme_bkpt = 1;
  bp_smob->spec.location = location;
  bp_smob->spec.type = type;
  bp_smob->spec.access_type = access_type;
  bp_smob->spec.is_internal = internal;
  bp_smob->spec.is_temporary = temporary;

  return result;
}

/* (register-breakpoint! <gdb:breakpoint>) -> unspecified

   It is an error to register a breakpoint created outside of Guile,
   or an already-registered breakpoint.  */

static SCM
gdbscm_register_breakpoint_x (SCM self)
{
  breakpoint_smob *bp_smob
    = bpscm_get_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  gdbscm_gdb_exception except {};
  const char *location, *copy;

  /* We only support registering breakpoints created with make-breakpoint.  */
  if (!bp_smob->is_scheme_bkpt)
    scm_misc_error (FUNC_NAME, _("not a Scheme breakpoint"), SCM_EOL);

  if (bpscm_is_valid (bp_smob))
    scm_misc_error (FUNC_NAME, _("breakpoint is already registered"), SCM_EOL);

  pending_breakpoint_scm = self;
  location = bp_smob->spec.location;
  copy = skip_spaces (location);
  event_location_up eloc
    = string_to_event_location_basic (&copy,
				      current_language,
				      symbol_name_match_type::WILD);

  try
    {
      int internal = bp_smob->spec.is_internal;
      int temporary = bp_smob->spec.is_temporary;

      switch (bp_smob->spec.type)
	{
	case bp_breakpoint:
	  {
	    const breakpoint_ops *ops =
	      breakpoint_ops_for_event_location (eloc.get (), false);
	    create_breakpoint (get_current_arch (),
			       eloc.get (), NULL, -1, NULL, false,
			       0,
			       temporary, bp_breakpoint,
			       0,
			       AUTO_BOOLEAN_TRUE,
			       ops,
			       0, 1, internal, 0);
	    break;
	  }
	case bp_watchpoint:
	  {
	    enum target_hw_bp_type access_type = bp_smob->spec.access_type;

	    if (access_type == hw_write)
	      watch_command_wrapper (location, 0, internal);
	    else if (access_type == hw_access)
	      awatch_command_wrapper (location, 0, internal);
	    else if (access_type == hw_read)
	      rwatch_command_wrapper (location, 0, internal);
	    else
	      gdb_assert_not_reached ("invalid access type");
	    break;
	  }
	default:
	  gdb_assert_not_reached ("invalid breakpoint type");
	}
    }
  catch (const gdb_exception &ex)
    {
      except = unpack (ex);
    }

  /* Ensure this gets reset, even if there's an error.  */
  pending_breakpoint_scm = SCM_BOOL_F;
  GDBSCM_HANDLE_GDB_EXCEPTION (except);

  return SCM_UNSPECIFIED;
}

/* (delete-breakpoint! <gdb:breakpoint>) -> unspecified
   Scheme function which deletes (removes) the underlying GDB breakpoint
   from GDB's list of breakpoints.  This triggers the breakpoint_deleted
   observer which will call gdbscm_breakpoint_deleted; that function cleans
   up the Scheme bits.  */

static SCM
gdbscm_delete_breakpoint_x (SCM self)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  gdbscm_gdb_exception exc {};
  try
    {
      delete_breakpoint (bp_smob->bp);
    }
  catch (const gdb_exception &except)
    {
      exc = unpack (except);
    }

  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
  return SCM_UNSPECIFIED;
}

/* iterate_over_breakpoints function for gdbscm_breakpoints.  */

static void
bpscm_build_bp_list (struct breakpoint *bp, SCM *list)
{
  breakpoint_smob *bp_smob = bp->scm_bp_object;

  /* Lazily create wrappers for breakpoints created outside Scheme.  */

  if (bp_smob == NULL)
    {
      if (bpscm_want_scm_wrapper_p (bp, 0))
	{
	  SCM bp_scm;

	  bp_scm = bpscm_make_breakpoint_smob ();
	  bpscm_attach_scm_to_breakpoint (bp, bp_scm);
	  /* Refetch it.  */
	  bp_smob = bp->scm_bp_object;
	}
    }

  /* Not all breakpoints will have a companion Scheme object.
     Only breakpoints that trigger the created_breakpoint observer call,
     and satisfy certain conditions (see bpscm_want_scm_wrapper_p),
     get a companion object (this includes Scheme-created breakpoints).  */

  if (bp_smob != NULL)
    *list = scm_cons (bp_smob->containing_scm, *list);
}

/* (breakpoints) -> list
   Return a list of all breakpoints.  */

static SCM
gdbscm_breakpoints (void)
{
  SCM list = SCM_EOL;

  for (breakpoint *bp : all_breakpoints ())
    bpscm_build_bp_list (bp, &list);

  return scm_reverse_x (list, SCM_EOL);
}

/* (breakpoint-valid? <gdb:breakpoint>) -> boolean
   Returns #t if SELF is still valid.  */

static SCM
gdbscm_breakpoint_valid_p (SCM self)
{
  breakpoint_smob *bp_smob
    = bpscm_get_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  return scm_from_bool (bpscm_is_valid (bp_smob));
}

/* (breakpoint-enabled? <gdb:breakpoint>) -> boolean */

static SCM
gdbscm_breakpoint_enabled_p (SCM self)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  return scm_from_bool (bp_smob->bp->enable_state == bp_enabled);
}

/* (set-breakpoint-enabled? <gdb:breakpoint> boolean) -> unspecified */

static SCM
gdbscm_set_breakpoint_enabled_x (SCM self, SCM newvalue)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  SCM_ASSERT_TYPE (gdbscm_is_bool (newvalue), newvalue, SCM_ARG2, FUNC_NAME,
		   _("boolean"));

  gdbscm_gdb_exception exc {};
  try
    {
      if (gdbscm_is_true (newvalue))
	enable_breakpoint (bp_smob->bp);
      else
	disable_breakpoint (bp_smob->bp);
    }
  catch (const gdb_exception &except)
    {
      exc = unpack (except);
    }

  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
  return SCM_UNSPECIFIED;
}

/* (breakpoint-silent? <gdb:breakpoint>) -> boolean */

static SCM
gdbscm_breakpoint_silent_p (SCM self)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  return scm_from_bool (bp_smob->bp->silent);
}

/* (set-breakpoint-silent?! <gdb:breakpoint> boolean) -> unspecified */

static SCM
gdbscm_set_breakpoint_silent_x (SCM self, SCM newvalue)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  SCM_ASSERT_TYPE (gdbscm_is_bool (newvalue), newvalue, SCM_ARG2, FUNC_NAME,
		   _("boolean"));

  gdbscm_gdb_exception exc {};
  try
    {
      breakpoint_set_silent (bp_smob->bp, gdbscm_is_true (newvalue));
    }
  catch (const gdb_exception &except)
    {
      exc = unpack (except);
    }

  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
  return SCM_UNSPECIFIED;
}

/* (breakpoint-ignore-count <gdb:breakpoint>) -> integer */

static SCM
gdbscm_breakpoint_ignore_count (SCM self)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  return scm_from_long (bp_smob->bp->ignore_count);
}

/* (set-breakpoint-ignore-count! <gdb:breakpoint> integer)
     -> unspecified */

static SCM
gdbscm_set_breakpoint_ignore_count_x (SCM self, SCM newvalue)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  long value;

  SCM_ASSERT_TYPE (scm_is_signed_integer (newvalue, LONG_MIN, LONG_MAX),
		   newvalue, SCM_ARG2, FUNC_NAME, _("integer"));

  value = scm_to_long (newvalue);
  if (value < 0)
    value = 0;

  gdbscm_gdb_exception exc {};
  try
    {
      set_ignore_count (bp_smob->number, (int) value, 0);
    }
  catch (const gdb_exception &except)
    {
      exc = unpack (except);
    }

  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
  return SCM_UNSPECIFIED;
}

/* (breakpoint-hit-count <gdb:breakpoint>) -> integer */

static SCM
gdbscm_breakpoint_hit_count (SCM self)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  return scm_from_long (bp_smob->bp->hit_count);
}

/* (set-breakpoint-hit-count! <gdb:breakpoint> integer) -> unspecified */

static SCM
gdbscm_set_breakpoint_hit_count_x (SCM self, SCM newvalue)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  long value;

  SCM_ASSERT_TYPE (scm_is_signed_integer (newvalue, LONG_MIN, LONG_MAX),
		   newvalue, SCM_ARG2, FUNC_NAME, _("integer"));

  value = scm_to_long (newvalue);
  if (value < 0)
    value = 0;

  if (value != 0)
    {
      gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, newvalue,
				 _("hit-count must be zero"));
    }

  bp_smob->bp->hit_count = 0;

  return SCM_UNSPECIFIED;
}

/* (breakpoint-thread <gdb:breakpoint>) -> integer */

static SCM
gdbscm_breakpoint_thread (SCM self)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  if (bp_smob->bp->thread == -1)
    return SCM_BOOL_F;

  return scm_from_long (bp_smob->bp->thread);
}

/* (set-breakpoint-thread! <gdb:breakpoint> integer) -> unspecified */

static SCM
gdbscm_set_breakpoint_thread_x (SCM self, SCM newvalue)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  long id;

  if (scm_is_signed_integer (newvalue, LONG_MIN, LONG_MAX))
    {
      id = scm_to_long (newvalue);
      if (!valid_global_thread_id (id))
	{
	  gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, newvalue,
				     _("invalid thread id"));
	}
    }
  else if (gdbscm_is_false (newvalue))
    id = -1;
  else
    SCM_ASSERT_TYPE (0, newvalue, SCM_ARG2, FUNC_NAME, _("integer or #f"));

  breakpoint_set_thread (bp_smob->bp, id);

  return SCM_UNSPECIFIED;
}

/* (breakpoint-task <gdb:breakpoint>) -> integer */

static SCM
gdbscm_breakpoint_task (SCM self)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  if (bp_smob->bp->task == 0)
    return SCM_BOOL_F;

  return scm_from_long (bp_smob->bp->task);
}

/* (set-breakpoint-task! <gdb:breakpoint> integer) -> unspecified */

static SCM
gdbscm_set_breakpoint_task_x (SCM self, SCM newvalue)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  long id;
  int valid_id = 0;

  if (scm_is_signed_integer (newvalue, LONG_MIN, LONG_MAX))
    {
      id = scm_to_long (newvalue);

      gdbscm_gdb_exception exc {};
      try
	{
	  valid_id = valid_task_id (id);
	}
      catch (const gdb_exception &except)
	{
	  exc = unpack (except);
	}

      GDBSCM_HANDLE_GDB_EXCEPTION (exc);
      if (! valid_id)
	{
	  gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, newvalue,
				     _("invalid task id"));
	}
    }
  else if (gdbscm_is_false (newvalue))
    id = 0;
  else
    SCM_ASSERT_TYPE (0, newvalue, SCM_ARG2, FUNC_NAME, _("integer or #f"));

  gdbscm_gdb_exception exc {};
  try
    {
      breakpoint_set_task (bp_smob->bp, id);
    }
  catch (const gdb_exception &except)
    {
      exc = unpack (except);
    }

  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
  return SCM_UNSPECIFIED;
}

/* (breakpoint-location <gdb:breakpoint>) -> string */

static SCM
gdbscm_breakpoint_location (SCM self)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  const char *str;

  if (bp_smob->bp->type != bp_breakpoint)
    return SCM_BOOL_F;

  str = event_location_to_string (bp_smob->bp->location.get ());
  if (! str)
    str = "";

  return gdbscm_scm_from_c_string (str);
}

/* (breakpoint-expression <gdb:breakpoint>) -> string
   This is only valid for watchpoints.
   Returns #f for non-watchpoints.  */

static SCM
gdbscm_breakpoint_expression (SCM self)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct watchpoint *wp;

  if (!is_watchpoint (bp_smob->bp))
    return SCM_BOOL_F;

  wp = (struct watchpoint *) bp_smob->bp;

  const char *str = wp->exp_string;
  if (! str)
    str = "";

  return gdbscm_scm_from_c_string (str);
}

/* (breakpoint-condition <gdb:breakpoint>) -> string */

static SCM
gdbscm_breakpoint_condition (SCM self)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  char *str;

  str = bp_smob->bp->cond_string;
  if (! str)
    return SCM_BOOL_F;

  return gdbscm_scm_from_c_string (str);
}

/* (set-breakpoint-condition! <gdb:breakpoint> string|#f)
   -> unspecified */

static SCM
gdbscm_set_breakpoint_condition_x (SCM self, SCM newvalue)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  SCM_ASSERT_TYPE (scm_is_string (newvalue) || gdbscm_is_false (newvalue),
		   newvalue, SCM_ARG2, FUNC_NAME,
		   _("string or #f"));

  return gdbscm_wrap ([=]
    {
      gdb::unique_xmalloc_ptr<char> exp
	= (gdbscm_is_false (newvalue)
	   ? nullptr
	   : gdbscm_scm_to_c_string (newvalue));

      set_breakpoint_condition (bp_smob->bp, exp ? exp.get () : "", 0, false);

      return SCM_UNSPECIFIED;
    });
}

/* (breakpoint-stop <gdb:breakpoint>) -> procedure or #f */

static SCM
gdbscm_breakpoint_stop (SCM self)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  return bp_smob->stop;
}

/* (set-breakpoint-stop! <gdb:breakpoint> procedure|#f)
   -> unspecified */

static SCM
gdbscm_set_breakpoint_stop_x (SCM self, SCM newvalue)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  const struct extension_language_defn *extlang = NULL;

  SCM_ASSERT_TYPE (gdbscm_is_procedure (newvalue)
		   || gdbscm_is_false (newvalue),
		   newvalue, SCM_ARG2, FUNC_NAME,
		   _("procedure or #f"));

  if (bp_smob->bp->cond_string != NULL)
    extlang = get_ext_lang_defn (EXT_LANG_GDB);
  if (extlang == NULL)
    extlang = get_breakpoint_cond_ext_lang (bp_smob->bp, EXT_LANG_GUILE);
  if (extlang != NULL)
    {
      char *error_text
	= xstrprintf (_("Only one stop condition allowed.  There is"
			" currently a %s stop condition defined for"
			" this breakpoint."),
		      ext_lang_capitalized_name (extlang));

      scm_dynwind_begin ((scm_t_dynwind_flags) 0);
      gdbscm_dynwind_xfree (error_text);
      gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self, error_text);
      /* The following line, while unnecessary, is present for completeness
	 sake.  */
      scm_dynwind_end ();
    }

  bp_smob->stop = newvalue;

  return SCM_UNSPECIFIED;
}

/* (breakpoint-commands <gdb:breakpoint>) -> string */

static SCM
gdbscm_breakpoint_commands (SCM self)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct breakpoint *bp;
  SCM result;

  bp = bp_smob->bp;

  if (bp->commands == NULL)
    return SCM_BOOL_F;

  string_file buf;

  current_uiout->redirect (&buf);
  gdbscm_gdb_exception exc {};
  try
    {
      print_command_lines (current_uiout, breakpoint_commands (bp), 0);
    }
  catch (const gdb_exception &except)
    {
      exc = unpack (except);
    }

  current_uiout->redirect (NULL);
  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
  result = gdbscm_scm_from_c_string (buf.c_str ());

  return result;
}

/* (breakpoint-type <gdb:breakpoint>) -> integer */

static SCM
gdbscm_breakpoint_type (SCM self)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  return scm_from_long (bp_smob->bp->type);
}

/* (breakpoint-visible? <gdb:breakpoint>) -> boolean */

static SCM
gdbscm_breakpoint_visible (SCM self)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  return scm_from_bool (bp_smob->bp->number >= 0);
}

/* (breakpoint-number <gdb:breakpoint>) -> integer */

static SCM
gdbscm_breakpoint_number (SCM self)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  return scm_from_long (bp_smob->number);
}

/* (breakpoint-temporary? <gdb:breakpoint>) -> boolean */

static SCM
gdbscm_breakpoint_temporary (SCM self)
{
  breakpoint_smob *bp_smob
    = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  return scm_from_bool (bp_smob->bp->disposition == disp_del
			|| bp_smob->bp->disposition == disp_del_at_next_stop);
}

/* Return TRUE if "stop" has been set for this breakpoint.

   This is the extension_language_ops.breakpoint_has_cond "method".  */

int
gdbscm_breakpoint_has_cond (const struct extension_language_defn *extlang,
			    struct breakpoint *b)
{
  breakpoint_smob *bp_smob = b->scm_bp_object;

  if (bp_smob == NULL)
    return 0;

  return gdbscm_is_procedure (bp_smob->stop);
}

/* Call the "stop" method in the breakpoint class.
   This must only be called if gdbscm_breakpoint_has_cond returns true.
   If the stop method returns #t, the inferior will be stopped at the
   breakpoint.  Otherwise the inferior will be allowed to continue
   (assuming other conditions don't indicate "stop").

   This is the extension_language_ops.breakpoint_cond_says_stop "method".  */

enum ext_lang_bp_stop
gdbscm_breakpoint_cond_says_stop
  (const struct extension_language_defn *extlang, struct breakpoint *b)
{
  breakpoint_smob *bp_smob = b->scm_bp_object;
  SCM predicate_result;
  int stop;

  if (bp_smob == NULL)
    return EXT_LANG_BP_STOP_UNSET;
  if (!gdbscm_is_procedure (bp_smob->stop))
    return EXT_LANG_BP_STOP_UNSET;

  stop = 1;

  predicate_result
    = gdbscm_safe_call_1 (bp_smob->stop, bp_smob->containing_scm, NULL);

  if (gdbscm_is_exception (predicate_result))
    ; /* Exception already printed.  */
  /* If the "stop" function returns #f that means
     the Scheme breakpoint wants GDB to continue.  */
  else if (gdbscm_is_false (predicate_result))
    stop = 0;

  return stop ? EXT_LANG_BP_STOP_YES : EXT_LANG_BP_STOP_NO;
}

/* Event callback functions.  */

/* Callback that is used when a breakpoint is created.
   For breakpoints created by Scheme, i.e., gdbscm_create_breakpoint_x, finish
   object creation by connecting the Scheme wrapper to the gdb object.
   We ignore breakpoints created from gdb or python here, we create the
   Scheme wrapper for those when there's a need to, e.g.,
   gdbscm_breakpoints.  */

static void
bpscm_breakpoint_created (struct breakpoint *bp)
{
  SCM bp_scm;

  if (gdbscm_is_false (pending_breakpoint_scm))
    return;

  /* Verify our caller error checked the user's request.  */
  gdb_assert (bpscm_want_scm_wrapper_p (bp, 1));

  bp_scm = pending_breakpoint_scm;
  pending_breakpoint_scm = SCM_BOOL_F;

  bpscm_attach_scm_to_breakpoint (bp, bp_scm);
}

/* Callback that is used when a breakpoint is deleted.  This will
   invalidate the corresponding Scheme object.  */

static void
bpscm_breakpoint_deleted (struct breakpoint *b)
{
  int num = b->number;
  struct breakpoint *bp;

  /* TODO: Why the lookup?  We have B.  */

  bp = get_breakpoint (num);
  if (bp)
    {
      breakpoint_smob *bp_smob = bp->scm_bp_object;

      if (bp_smob)
	{
	  bp_smob->bp = NULL;
	  bp_smob->number = -1;
	  bp_smob->stop = SCM_BOOL_F;
	  scm_gc_unprotect_object (bp_smob->containing_scm);
	}
    }
}

/* Initialize the Scheme breakpoint code.  */

static const scheme_integer_constant breakpoint_integer_constants[] =
{
  { "BP_NONE", bp_none },
  { "BP_BREAKPOINT", bp_breakpoint },
  { "BP_WATCHPOINT", bp_watchpoint },
  { "BP_HARDWARE_WATCHPOINT", bp_hardware_watchpoint },
  { "BP_READ_WATCHPOINT", bp_read_watchpoint },
  { "BP_ACCESS_WATCHPOINT", bp_access_watchpoint },
  { "BP_CATCHPOINT", bp_catchpoint },

  { "WP_READ", hw_read },
  { "WP_WRITE", hw_write },
  { "WP_ACCESS", hw_access },

  END_INTEGER_CONSTANTS
};

static const scheme_function breakpoint_functions[] =
{
  { "make-breakpoint", 1, 0, 1, as_a_scm_t_subr (gdbscm_make_breakpoint),
    "\
Create a GDB breakpoint object.\n\
\n\
  Arguments:\n\
    location [#:type <type>] [#:wp-class <wp-class>] [#:internal <bool>] [#:temporary <bool>]\n\
  Returns:\n\
    <gdb:breakpoint> object" },

  { "register-breakpoint!", 1, 0, 0,
    as_a_scm_t_subr (gdbscm_register_breakpoint_x),
    "\
Register a <gdb:breakpoint> object with GDB." },

  { "delete-breakpoint!", 1, 0, 0, as_a_scm_t_subr (gdbscm_delete_breakpoint_x),
    "\
Delete the breakpoint from GDB." },

  { "breakpoints", 0, 0, 0, as_a_scm_t_subr (gdbscm_breakpoints),
    "\
Return a list of all GDB breakpoints.\n\
\n\
  Arguments: none" },

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

  { "breakpoint-valid?", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_valid_p),
    "\
Return #t if the breakpoint has not been deleted from GDB." },

  { "breakpoint-number", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_number),
    "\
Return the breakpoint's number." },

  { "breakpoint-temporary?", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_temporary),
    "\
Return #t if the breakpoint is a temporary breakpoint." },

  { "breakpoint-type", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_type),
    "\
Return the type of the breakpoint." },

  { "breakpoint-visible?", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_visible),
    "\
Return #t if the breakpoint is visible to the user." },

  { "breakpoint-location", 1, 0, 0,
    as_a_scm_t_subr (gdbscm_breakpoint_location),
    "\
Return the location of the breakpoint as specified by the user." },

  { "breakpoint-expression", 1, 0, 0,
    as_a_scm_t_subr (gdbscm_breakpoint_expression),
    "\
Return the expression of the breakpoint as specified by the user.\n\
Valid for watchpoints only, returns #f for non-watchpoints." },

  { "breakpoint-enabled?", 1, 0, 0,
    as_a_scm_t_subr (gdbscm_breakpoint_enabled_p),
    "\
Return #t if the breakpoint is enabled." },

  { "set-breakpoint-enabled!", 2, 0, 0,
    as_a_scm_t_subr (gdbscm_set_breakpoint_enabled_x),
    "\
Set the breakpoint's enabled state.\n\
\n\
  Arguments: <gdb:breakpoint> boolean" },

  { "breakpoint-silent?", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_silent_p),
    "\
Return #t if the breakpoint is silent." },

  { "set-breakpoint-silent!", 2, 0, 0,
    as_a_scm_t_subr (gdbscm_set_breakpoint_silent_x),
    "\
Set the breakpoint's silent state.\n\
\n\
  Arguments: <gdb:breakpoint> boolean" },

  { "breakpoint-ignore-count", 1, 0, 0,
    as_a_scm_t_subr (gdbscm_breakpoint_ignore_count),
    "\
Return the breakpoint's \"ignore\" count." },

  { "set-breakpoint-ignore-count!", 2, 0, 0,
    as_a_scm_t_subr (gdbscm_set_breakpoint_ignore_count_x),
    "\
Set the breakpoint's \"ignore\" count.\n\
\n\
  Arguments: <gdb:breakpoint> count" },

  { "breakpoint-hit-count", 1, 0, 0,
    as_a_scm_t_subr (gdbscm_breakpoint_hit_count),
    "\
Return the breakpoint's \"hit\" count." },

  { "set-breakpoint-hit-count!", 2, 0, 0,
    as_a_scm_t_subr (gdbscm_set_breakpoint_hit_count_x),
    "\
Set the breakpoint's \"hit\" count.  The value must be zero.\n\
\n\
  Arguments: <gdb:breakpoint> 0" },

  { "breakpoint-thread", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_thread),
    "\
Return the breakpoint's global thread id or #f if there isn't one." },

  { "set-breakpoint-thread!", 2, 0, 0,
    as_a_scm_t_subr (gdbscm_set_breakpoint_thread_x),
    "\
Set the global thread id for this breakpoint.\n\
\n\
  Arguments: <gdb:breakpoint> global-thread-id" },

  { "breakpoint-task", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_task),
    "\
Return the breakpoint's Ada task-id or #f if there isn't one." },

  { "set-breakpoint-task!", 2, 0, 0,
    as_a_scm_t_subr (gdbscm_set_breakpoint_task_x),
    "\
Set the breakpoint's Ada task-id.\n\
\n\
  Arguments: <gdb:breakpoint> task-id" },

  { "breakpoint-condition", 1, 0, 0,
    as_a_scm_t_subr (gdbscm_breakpoint_condition),
    "\
Return the breakpoint's condition as specified by the user.\n\
Return #f if there isn't one." },

  { "set-breakpoint-condition!", 2, 0, 0,
    as_a_scm_t_subr (gdbscm_set_breakpoint_condition_x),
    "\
Set the breakpoint's condition.\n\
\n\
  Arguments: <gdb:breakpoint> condition\n\
    condition: a string" },

  { "breakpoint-stop", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_stop),
    "\
Return the breakpoint's stop predicate.\n\
Return #f if there isn't one." },

  { "set-breakpoint-stop!", 2, 0, 0,
    as_a_scm_t_subr (gdbscm_set_breakpoint_stop_x),
    "\
Set the breakpoint's stop predicate.\n\
\n\
  Arguments: <gdb:breakpoint> procedure\n\
    procedure: A procedure of one argument, the breakpoint.\n\
      Its result is true if program execution should stop." },

  { "breakpoint-commands", 1, 0, 0,
    as_a_scm_t_subr (gdbscm_breakpoint_commands),
    "\
Return the breakpoint's commands." },

  END_FUNCTIONS
};

void
gdbscm_initialize_breakpoints (void)
{
  breakpoint_smob_tag
    = gdbscm_make_smob_type (breakpoint_smob_name, sizeof (breakpoint_smob));
  scm_set_smob_free (breakpoint_smob_tag, bpscm_free_breakpoint_smob);
  scm_set_smob_print (breakpoint_smob_tag, bpscm_print_breakpoint_smob);

  gdb::observers::breakpoint_created.attach (bpscm_breakpoint_created,
					     "scm-breakpoint");
  gdb::observers::breakpoint_deleted.attach (bpscm_breakpoint_deleted,
					     "scm-breakpoint");

  gdbscm_define_integer_constants (breakpoint_integer_constants, 1);
  gdbscm_define_functions (breakpoint_functions, 1);

  type_keyword = scm_from_latin1_keyword ("type");
  wp_class_keyword = scm_from_latin1_keyword ("wp-class");
  internal_keyword = scm_from_latin1_keyword ("internal");
  temporary_keyword = scm_from_latin1_keyword ("temporary");
}
