/* Guile interface to program spaces.

   Copyright (C) 2010-2016 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);
  struct objfile *objfile;
  SCM result;

  result = SCM_EOL;

  ALL_PSPACE_OBJFILES (p_smob->pspace, objfile)
  {
    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)
{
  struct program_space *ps;
  SCM result;

  result = SCM_EOL;

  ALL_PSPACES (ps)
  {
    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);
}
