/* Guile interface to program spaces.

   Copyright (C) 2010-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 "charset.h"
#include "progspace.h"
#include "objfiles.h"
#include "language.h"
#include "arch-utils.h"
#include "guile-internal.h"

/* NOTE: Python exports the name "Progspace", so we export "progspace".
   Internally we shorten that to "pspace".  */

/* The <gdb:progspace> smob.
   The typedef for this struct is in guile-internal.h.  */

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

  /* The corresponding pspace.  */
  struct program_space *pspace;

  /* The pretty-printer list of functions.  */
  SCM pretty_printers;

  /* The <gdb:progspace> object we are contained in, needed to
     protect/unprotect the object since a reference to it comes from
     non-gc-managed space (the progspace).  */
  SCM containing_scm;
};

static const char pspace_smob_name[] = "gdb:progspace";

/* The tag Guile knows the pspace smob by.  */
static scm_t_bits pspace_smob_tag;

static const struct program_space_data *psscm_pspace_data_key;

/* Return the list of pretty-printers registered with P_SMOB.  */

SCM
psscm_pspace_smob_pretty_printers (const pspace_smob *p_smob)
{
  return p_smob->pretty_printers;
}

/* Administrivia for progspace smobs.  */

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

static int
psscm_print_pspace_smob (SCM self, SCM port, scm_print_state *pstate)
{
  pspace_smob *p_smob = (pspace_smob *) SCM_SMOB_DATA (self);

  gdbscm_printf (port, "#<%s ", pspace_smob_name);
  if (p_smob->pspace != NULL)
    {
      struct objfile *objfile = p_smob->pspace->symfile_object_file;

      gdbscm_printf (port, "%s",
		     objfile != NULL
		     ? objfile_name (objfile)
		     : "{no symfile}");
    }
  else
    scm_puts ("{invalid}", port);
  scm_puts (">", port);

  scm_remember_upto_here_1 (self);

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

/* Low level routine to create a <gdb:progspace> object.
   It's empty in the sense that a progspace still needs to be associated
   with it.  */

static SCM
psscm_make_pspace_smob (void)
{
  pspace_smob *p_smob = (pspace_smob *)
    scm_gc_malloc (sizeof (pspace_smob), pspace_smob_name);
  SCM p_scm;

  p_smob->pspace = NULL;
  p_smob->pretty_printers = SCM_EOL;
  p_scm = scm_new_smob (pspace_smob_tag, (scm_t_bits) p_smob);
  p_smob->containing_scm = p_scm;
  gdbscm_init_gsmob (&p_smob->base);

  return p_scm;
}

/* Clear the progspace pointer in P_SMOB and unprotect the object from GC.  */

static void
psscm_release_pspace (pspace_smob *p_smob)
{
  p_smob->pspace = NULL;
  scm_gc_unprotect_object (p_smob->containing_scm);
}

/* Progspace registry cleanup handler for when a progspace is deleted.  */

static void
psscm_handle_pspace_deleted (struct program_space *pspace, void *datum)
{
  pspace_smob *p_smob = (pspace_smob *) datum;

  gdb_assert (p_smob->pspace == pspace);

  psscm_release_pspace (p_smob);
}

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

static int
psscm_is_pspace (SCM scm)
{
  return SCM_SMOB_PREDICATE (pspace_smob_tag, scm);
}

/* (progspace? object) -> boolean */

static SCM
gdbscm_progspace_p (SCM scm)
{
  return scm_from_bool (psscm_is_pspace (scm));
}

/* Return a pointer to the progspace_smob that encapsulates PSPACE,
   creating one if necessary.
   The result is cached so that we have only one copy per objfile.  */

pspace_smob *
psscm_pspace_smob_from_pspace (struct program_space *pspace)
{
  pspace_smob *p_smob;

  p_smob = (pspace_smob *) program_space_data (pspace, psscm_pspace_data_key);
  if (p_smob == NULL)
    {
      SCM p_scm = psscm_make_pspace_smob ();

      p_smob = (pspace_smob *) SCM_SMOB_DATA (p_scm);
      p_smob->pspace = pspace;

      set_program_space_data (pspace, psscm_pspace_data_key, p_smob);
      scm_gc_protect_object (p_smob->containing_scm);
    }

  return p_smob;
}

/* Return the <gdb:progspace> object that encapsulates PSPACE.  */

SCM
psscm_scm_from_pspace (struct program_space *pspace)
{
  pspace_smob *p_smob = psscm_pspace_smob_from_pspace (pspace);

  return p_smob->containing_scm;
}

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

static SCM
psscm_get_pspace_arg_unsafe (SCM self, int arg_pos, const char *func_name)
{
  SCM_ASSERT_TYPE (psscm_is_pspace (self), self, arg_pos, func_name,
		   pspace_smob_name);

  return self;
}

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

static pspace_smob *
psscm_get_pspace_smob_arg_unsafe (SCM self, int arg_pos,
				  const char *func_name)
{
  SCM p_scm = psscm_get_pspace_arg_unsafe (self, arg_pos, func_name);
  pspace_smob *p_smob = (pspace_smob *) SCM_SMOB_DATA (p_scm);

  return p_smob;
}

/* Return non-zero if pspace P_SMOB is valid.  */

static int
psscm_is_valid (pspace_smob *p_smob)
{
  return p_smob->pspace != NULL;
}

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

static pspace_smob *
psscm_get_valid_pspace_smob_arg_unsafe (SCM self, int arg_pos,
					const char *func_name)
{
  pspace_smob *p_smob
    = psscm_get_pspace_smob_arg_unsafe (self, arg_pos, func_name);

  if (!psscm_is_valid (p_smob))
    {
      gdbscm_invalid_object_error (func_name, arg_pos, self,
				   _("<gdb:progspace>"));
    }

  return p_smob;
}

/* Program space methods.  */

/* (progspace-valid? <gdb:progspace>) -> boolean
   Returns #t if this program space still exists in GDB.  */

static SCM
gdbscm_progspace_valid_p (SCM self)
{
  pspace_smob *p_smob
    = psscm_get_pspace_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  return scm_from_bool (p_smob->pspace != NULL);
}

/* (progspace-filename <gdb:progspace>) -> string
   Returns the name of the main symfile associated with the progspace,
   or #f if there isn't one.
   Throw's an exception if the underlying pspace is invalid.  */

static SCM
gdbscm_progspace_filename (SCM self)
{
  pspace_smob *p_smob
    = psscm_get_valid_pspace_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct objfile *objfile = p_smob->pspace->symfile_object_file;

  if (objfile != NULL)
    return gdbscm_scm_from_c_string (objfile_name (objfile));
  return SCM_BOOL_F;
}

/* (progspace-objfiles <gdb:progspace>) -> list
   Return the list of objfiles in the progspace.
   Objfiles that are separate debug objfiles are *not* included in the result,
   only the "original/real" one appears in the result.
   The order of appearance of objfiles in the result is arbitrary.
   Throw's an exception if the underlying pspace is invalid.

   Some apps can have 1000s of shared libraries.  Seriously.
   A future extension here could be to provide, e.g., a regexp to select
   just the ones the caller is interested in (rather than building the list
   and then selecting the desired ones).  Another alternative is passing a
   predicate, then the filter criteria can be more general.  */

static SCM
gdbscm_progspace_objfiles (SCM self)
{
  pspace_smob *p_smob
    = psscm_get_valid_pspace_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  SCM result;

  result = SCM_EOL;

  for (objfile *objfile : p_smob->pspace->objfiles ())
    {
      if (objfile->separate_debug_objfile_backlink == NULL)
	{
	  SCM item = ofscm_scm_from_objfile (objfile);

	  result = scm_cons (item, result);
	}
    }

  /* We don't really have to return the list in the same order as recorded
     internally, but for consistency we do.  We still advertise that one
     cannot assume anything about the order.  */
  return scm_reverse_x (result, SCM_EOL);
}

/* (progspace-pretty-printers <gdb:progspace>) -> list
   Returns the list of pretty-printers for this program space.  */

static SCM
gdbscm_progspace_pretty_printers (SCM self)
{
  pspace_smob *p_smob
    = psscm_get_pspace_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  return p_smob->pretty_printers;
}

/* (set-progspace-pretty-printers! <gdb:progspace> list) -> unspecified
   Set the pretty-printers for this program space.  */

static SCM
gdbscm_set_progspace_pretty_printers_x (SCM self, SCM printers)
{
  pspace_smob *p_smob
    = psscm_get_pspace_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  SCM_ASSERT_TYPE (gdbscm_is_true (scm_list_p (printers)), printers,
		   SCM_ARG2, FUNC_NAME, _("list"));

  p_smob->pretty_printers = printers;

  return SCM_UNSPECIFIED;
}

/* (current-progspace) -> <gdb:progspace>
   Return the current program space.  There always is one.  */

static SCM
gdbscm_current_progspace (void)
{
  SCM result;

  result = psscm_scm_from_pspace (current_program_space);

  return result;
}

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

static SCM
gdbscm_progspaces (void)
{
  SCM result;

  result = SCM_EOL;

  for (struct program_space *ps : program_spaces)
    {
      SCM item = psscm_scm_from_pspace (ps);

      result = scm_cons (item, result);
    }

  return scm_reverse_x (result, SCM_EOL);
}

/* Initialize the Scheme program space support.  */

static const scheme_function pspace_functions[] =
{
  { "progspace?", 1, 0, 0, as_a_scm_t_subr (gdbscm_progspace_p),
    "\
Return #t if the object is a <gdb:objfile> object." },

  { "progspace-valid?", 1, 0, 0, as_a_scm_t_subr (gdbscm_progspace_valid_p),
    "\
Return #t if the progspace is valid (hasn't been deleted from gdb)." },

  { "progspace-filename", 1, 0, 0, as_a_scm_t_subr (gdbscm_progspace_filename),
    "\
Return the name of the main symbol file of the progspace." },

  { "progspace-objfiles", 1, 0, 0, as_a_scm_t_subr (gdbscm_progspace_objfiles),
    "\
Return the list of objfiles associated with the progspace.\n\
Objfiles that are separate debug objfiles are not included in the result.\n\
The order of appearance of objfiles in the result is arbitrary." },

  { "progspace-pretty-printers", 1, 0, 0,
    as_a_scm_t_subr (gdbscm_progspace_pretty_printers),
    "\
Return a list of pretty-printers of the progspace." },

  { "set-progspace-pretty-printers!", 2, 0, 0,
    as_a_scm_t_subr (gdbscm_set_progspace_pretty_printers_x),
    "\
Set the list of pretty-printers of the progspace." },

  { "current-progspace", 0, 0, 0, as_a_scm_t_subr (gdbscm_current_progspace),
    "\
Return the current program space if there is one or #f if there isn't one." },

  { "progspaces", 0, 0, 0, as_a_scm_t_subr (gdbscm_progspaces),
    "\
Return a list of all program spaces." },

  END_FUNCTIONS
};

void
gdbscm_initialize_pspaces (void)
{
  pspace_smob_tag
    = gdbscm_make_smob_type (pspace_smob_name, sizeof (pspace_smob));
  scm_set_smob_print (pspace_smob_tag, psscm_print_pspace_smob);

  gdbscm_define_functions (pspace_functions, 1);

  psscm_pspace_data_key
    = register_program_space_data_with_cleanup (NULL,
						psscm_handle_pspace_deleted);
}
