/* GDB/Scheme pretty-printing.

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

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

#include "defs.h"
#include "charset.h"
#include "symtab.h" /* Needed by language.h.  */
#include "language.h"
#include "objfiles.h"
#include "value.h"
#include "valprint.h"
#include "guile-internal.h"

/* Return type of print_string_repr.  */

enum string_repr_result
{
  /* The string method returned None.  */
  STRING_REPR_NONE,
  /* The string method had an error.  */
  STRING_REPR_ERROR,
  /* Everything ok.  */
  STRING_REPR_OK
};

/* Display hints.  */

enum display_hint
{
  /* No display hint.  */
  HINT_NONE,
  /* The display hint has a bad value.  */
  HINT_ERROR,
  /* Print as an array.  */
  HINT_ARRAY,
  /* Print as a map.  */
  HINT_MAP,
  /* Print as a string.  */
  HINT_STRING
};

/* The <gdb:pretty-printer> smob.  */

typedef struct
{
  /* This must appear first.  */
  gdb_smob base;

  /* A string representing the name of the printer.  */
  SCM name;

  /* A boolean indicating whether the printer is enabled.  */
  SCM enabled;

  /* A procedure called to look up the printer for the given value.
     The procedure is called as (lookup gdb:pretty-printer value).
     The result should either be a gdb:pretty-printer object that will print
     the value, or #f if the value is not recognized.  */     
  SCM lookup;

  /* Note: Attaching subprinters to this smob is left to Scheme.  */
} pretty_printer_smob;

/* The <gdb:pretty-printer-worker> smob.  */

typedef struct
{
  /* This must appear first.  */
  gdb_smob base;

  /* Either #f or one of the supported display hints: map, array, string.
     If neither of those then the display hint is ignored (treated as #f).  */
  SCM display_hint;

  /* A procedure called to pretty-print the value.
     (lambda (printer) ...) -> string | <gdb:lazy-string> | <gdb:value>  */
  SCM to_string;

  /* A procedure called to print children of the value.
     (lambda (printer) ...) -> <gdb:iterator>
     The iterator returns a pair for each iteration: (name . value),
     where "value" can have the same types as to_string.  */
  SCM children;
} pretty_printer_worker_smob;

static const char pretty_printer_smob_name[] =
  "gdb:pretty-printer";
static const char pretty_printer_worker_smob_name[] =
  "gdb:pretty-printer-worker";

/* The tag Guile knows the pretty-printer smobs by.  */
static scm_t_bits pretty_printer_smob_tag;
static scm_t_bits pretty_printer_worker_smob_tag;

/* The global pretty-printer list.  */
static SCM pretty_printer_list;

/* gdb:pp-type-error.  */
static SCM pp_type_error_symbol;

/* Pretty-printer display hints are specified by strings.  */
static SCM ppscm_map_string;
static SCM ppscm_array_string;
static SCM ppscm_string_string;

/* Administrivia for pretty-printer matcher smobs.  */

/* The smob "print" function for <gdb:pretty-printer>.  */

static int
ppscm_print_pretty_printer_smob (SCM self, SCM port, scm_print_state *pstate)
{
  pretty_printer_smob *pp_smob = (pretty_printer_smob *) SCM_SMOB_DATA (self);

  gdbscm_printf (port, "#<%s ", pretty_printer_smob_name);
  scm_write (pp_smob->name, port);
  scm_puts (gdbscm_is_true (pp_smob->enabled) ? " enabled" : " disabled",
	    port);
  scm_puts (">", port);

  scm_remember_upto_here_1 (self);

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

/* (make-pretty-printer string procedure) -> <gdb:pretty-printer> */

static SCM
gdbscm_make_pretty_printer (SCM name, SCM lookup)
{
  pretty_printer_smob *pp_smob = (pretty_printer_smob *)
    scm_gc_malloc (sizeof (pretty_printer_smob),
		   pretty_printer_smob_name);
  SCM smob;

  SCM_ASSERT_TYPE (scm_is_string (name), name, SCM_ARG1, FUNC_NAME,
		   _("string"));
  SCM_ASSERT_TYPE (gdbscm_is_procedure (lookup), lookup, SCM_ARG2, FUNC_NAME,
		   _("procedure"));

  pp_smob->name = name;
  pp_smob->lookup = lookup;
  pp_smob->enabled = SCM_BOOL_T;
  smob = scm_new_smob (pretty_printer_smob_tag, (scm_t_bits) pp_smob);
  gdbscm_init_gsmob (&pp_smob->base);

  return smob;
}

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

static int
ppscm_is_pretty_printer (SCM scm)
{
  return SCM_SMOB_PREDICATE (pretty_printer_smob_tag, scm);
}

/* (pretty-printer? object) -> boolean */

static SCM
gdbscm_pretty_printer_p (SCM scm)
{
  return scm_from_bool (ppscm_is_pretty_printer (scm));
}

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

static SCM
ppscm_get_pretty_printer_arg_unsafe (SCM self, int arg_pos,
				     const char *func_name)
{
  SCM_ASSERT_TYPE (ppscm_is_pretty_printer (self), self, arg_pos, func_name,
		   pretty_printer_smob_name);

  return self;
}

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

static pretty_printer_smob *
ppscm_get_pretty_printer_smob_arg_unsafe (SCM self, int arg_pos,
					  const char *func_name)
{
  SCM pp_scm = ppscm_get_pretty_printer_arg_unsafe (self, arg_pos, func_name);
  pretty_printer_smob *pp_smob
    = (pretty_printer_smob *) SCM_SMOB_DATA (pp_scm);

  return pp_smob;
}

/* Pretty-printer methods.  */

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

static SCM
gdbscm_pretty_printer_enabled_p (SCM self)
{
  pretty_printer_smob *pp_smob
    = ppscm_get_pretty_printer_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  return pp_smob->enabled;
}

/* (set-pretty-printer-enabled! <gdb:pretty-printer> boolean)
     -> unspecified */

static SCM
gdbscm_set_pretty_printer_enabled_x (SCM self, SCM enabled)
{
  pretty_printer_smob *pp_smob
    = ppscm_get_pretty_printer_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  pp_smob->enabled = scm_from_bool (gdbscm_is_true (enabled));

  return SCM_UNSPECIFIED;
}

/* (pretty-printers) -> list
   Returns the list of global pretty-printers.  */

static SCM
gdbscm_pretty_printers (void)
{
  return pretty_printer_list;
}

/* (set-pretty-printers! list) -> unspecified
   Set the global pretty-printers list.  */

static SCM
gdbscm_set_pretty_printers_x (SCM printers)
{
  SCM_ASSERT_TYPE (gdbscm_is_true (scm_list_p (printers)), printers,
		   SCM_ARG1, FUNC_NAME, _("list"));

  pretty_printer_list = printers;

  return SCM_UNSPECIFIED;
}

/* Administrivia for pretty-printer-worker smobs.
   These are created when a matcher recognizes a value.  */

/* The smob "print" function for <gdb:pretty-printer-worker>.  */

static int
ppscm_print_pretty_printer_worker_smob (SCM self, SCM port,
					scm_print_state *pstate)
{
  pretty_printer_worker_smob *w_smob
    = (pretty_printer_worker_smob *) SCM_SMOB_DATA (self);

  gdbscm_printf (port, "#<%s ", pretty_printer_worker_smob_name);
  scm_write (w_smob->display_hint, port);
  scm_puts (" ", port);
  scm_write (w_smob->to_string, port);
  scm_puts (" ", port);
  scm_write (w_smob->children, port);
  scm_puts (">", port);

  scm_remember_upto_here_1 (self);

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

/* (make-pretty-printer-worker string procedure procedure)
     -> <gdb:pretty-printer-worker> */

static SCM
gdbscm_make_pretty_printer_worker (SCM display_hint, SCM to_string,
				   SCM children)
{
  pretty_printer_worker_smob *w_smob = (pretty_printer_worker_smob *)
    scm_gc_malloc (sizeof (pretty_printer_worker_smob),
		   pretty_printer_worker_smob_name);
  SCM w_scm;

  w_smob->display_hint = display_hint;
  w_smob->to_string = to_string;
  w_smob->children = children;
  w_scm = scm_new_smob (pretty_printer_worker_smob_tag, (scm_t_bits) w_smob);
  gdbscm_init_gsmob (&w_smob->base);
  return w_scm;
}

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

static int
ppscm_is_pretty_printer_worker (SCM scm)
{
  return SCM_SMOB_PREDICATE (pretty_printer_worker_smob_tag, scm);
}

/* (pretty-printer-worker? object) -> boolean */

static SCM
gdbscm_pretty_printer_worker_p (SCM scm)
{
  return scm_from_bool (ppscm_is_pretty_printer_worker (scm));
}

/* Helper function to create a <gdb:exception> object indicating that the
   type of some value returned from a pretty-printer is invalid.  */

static SCM
ppscm_make_pp_type_error_exception (const char *message, SCM object)
{
  char *msg = xstrprintf ("%s: ~S", message);
  struct cleanup *cleanup = make_cleanup (xfree, msg);
  SCM exception
    = gdbscm_make_error (pp_type_error_symbol,
			 NULL /* func */, msg,
			 scm_list_1 (object), scm_list_1 (object));

  do_cleanups (cleanup);

  return exception;
}

/* Print MESSAGE as an exception (meaning it is controlled by
   "guile print-stack").
   Called from the printer code when the Scheme code returns an invalid type
   for something.  */

static void
ppscm_print_pp_type_error (const char *message, SCM object)
{
  SCM exception = ppscm_make_pp_type_error_exception (message, object);

  gdbscm_print_gdb_exception (SCM_BOOL_F, exception);
}

/* Helper function for find_pretty_printer which iterates over a list,
   calls each function and inspects output.  This will return a
   <gdb:pretty-printer> object if one recognizes VALUE.  If no printer is
   found, it will return #f.  On error, it will return a <gdb:exception>
   object.

   Note: This has to be efficient and careful.
   We don't want to excessively slow down printing of values, but any kind of
   random crud can appear in the pretty-printer list, and we can't crash
   because of it.  */

static SCM
ppscm_search_pp_list (SCM list, SCM value)
{
  SCM orig_list = list;

  if (scm_is_null (list))
    return SCM_BOOL_F;
  if (gdbscm_is_false (scm_list_p (list))) /* scm_is_pair? */
    {
      return ppscm_make_pp_type_error_exception
	(_("pretty-printer list is not a list"), list);
    }

  for ( ; scm_is_pair (list); list = scm_cdr (list))
    {
      SCM matcher = scm_car (list);
      SCM worker;
      pretty_printer_smob *pp_smob;
      int rc;

      if (!ppscm_is_pretty_printer (matcher))
	{
	  return ppscm_make_pp_type_error_exception
	    (_("pretty-printer list contains non-pretty-printer object"),
	     matcher);
	}

      pp_smob = (pretty_printer_smob *) SCM_SMOB_DATA (matcher);

      /* Skip if disabled.  */
      if (gdbscm_is_false (pp_smob->enabled))
	continue;

      if (!gdbscm_is_procedure (pp_smob->lookup))
	{
	  return ppscm_make_pp_type_error_exception
	    (_("invalid lookup object in pretty-printer matcher"),
	     pp_smob->lookup);
	}

      worker = gdbscm_safe_call_2 (pp_smob->lookup, matcher,
				   value, gdbscm_memory_error_p);
      if (!gdbscm_is_false (worker))
	{
	  if (gdbscm_is_exception (worker))
	    return worker;
	  if (ppscm_is_pretty_printer_worker (worker))
	    return worker;
	  return ppscm_make_pp_type_error_exception
	    (_("invalid result from pretty-printer lookup"), worker);
	}
    }

  if (!scm_is_null (list))
    {
      return ppscm_make_pp_type_error_exception
	(_("pretty-printer list is not a list"), orig_list);
    }

  return SCM_BOOL_F;
}

/* Subroutine of find_pretty_printer to simplify it.
   Look for a pretty-printer to print VALUE in all objfiles.
   If there's an error an exception smob is returned.
   The result is #f, if no pretty-printer was found.
   Otherwise the result is the pretty-printer smob.  */

static SCM
ppscm_find_pretty_printer_from_objfiles (SCM value)
{
  struct objfile *objfile;

  ALL_OBJFILES (objfile)
  {
    objfile_smob *o_smob = ofscm_objfile_smob_from_objfile (objfile);
    SCM pp = ppscm_search_pp_list (ofscm_objfile_smob_pretty_printers (o_smob),
				   value);

    /* Note: This will return if pp is a <gdb:exception> object,
       which is what we want.  */
    if (gdbscm_is_true (pp))
      return pp;
  }

  return SCM_BOOL_F;
}

/* Subroutine of find_pretty_printer to simplify it.
   Look for a pretty-printer to print VALUE in the current program space.
   If there's an error an exception smob is returned.
   The result is #f, if no pretty-printer was found.
   Otherwise the result is the pretty-printer smob.  */

static SCM
ppscm_find_pretty_printer_from_progspace (SCM value)
{
  pspace_smob *p_smob = psscm_pspace_smob_from_pspace (current_program_space);
  SCM pp
    = ppscm_search_pp_list (psscm_pspace_smob_pretty_printers (p_smob), value);

  return pp;
}

/* Subroutine of find_pretty_printer to simplify it.
   Look for a pretty-printer to print VALUE in the gdb module.
   If there's an error a Scheme exception is returned.
   The result is #f, if no pretty-printer was found.
   Otherwise the result is the pretty-printer smob.  */

static SCM
ppscm_find_pretty_printer_from_gdb (SCM value)
{
  SCM pp = ppscm_search_pp_list (pretty_printer_list, value);

  return pp;
}

/* Find the pretty-printing constructor function for VALUE.  If no
   pretty-printer exists, return #f.  If one exists, return the
   gdb:pretty-printer smob that implements it.  On error, an exception smob
   is returned.

   Note: In the end it may be better to call out to Scheme once, and then
   do all of the lookup from Scheme.  TBD.  */

static SCM
ppscm_find_pretty_printer (SCM value)
{
  SCM pp;

  /* Look at the pretty-printer list for each objfile
     in the current program-space.  */
  pp = ppscm_find_pretty_printer_from_objfiles (value);
  /* Note: This will return if function is a <gdb:exception> object,
     which is what we want.  */
  if (gdbscm_is_true (pp))
    return pp;

  /* Look at the pretty-printer list for the current program-space.  */
  pp = ppscm_find_pretty_printer_from_progspace (value);
  /* Note: This will return if function is a <gdb:exception> object,
     which is what we want.  */
  if (gdbscm_is_true (pp))
    return pp;

  /* Look at the pretty-printer list in the gdb module.  */
  pp = ppscm_find_pretty_printer_from_gdb (value);
  return pp;
}

/* Pretty-print a single value, via the PRINTER, which must be a
   <gdb:pretty-printer-worker> object.
   The caller is responsible for ensuring PRINTER is valid.
   If the function returns a string, an SCM containing the string
   is returned.  If the function returns #f that means the pretty
   printer returned #f as a value.  Otherwise, if the function returns a
   <gdb:value> object, *OUT_VALUE is set to the value and #t is returned.
   It is an error if the printer returns #t.
   On error, an exception smob is returned.  */

static SCM
ppscm_pretty_print_one_value (SCM printer, struct value **out_value,
			      struct gdbarch *gdbarch,
			      const struct language_defn *language)
{
  SCM result = SCM_BOOL_F;

  *out_value = NULL;
  TRY
    {
      int rc;
      pretty_printer_worker_smob *w_smob
	= (pretty_printer_worker_smob *) SCM_SMOB_DATA (printer);

      result = gdbscm_safe_call_1 (w_smob->to_string, printer,
				   gdbscm_memory_error_p);
      if (gdbscm_is_false (result))
	; /* Done.  */
      else if (scm_is_string (result)
	       || lsscm_is_lazy_string (result))
	; /* Done.  */
      else if (vlscm_is_value (result))
	{
	  SCM except_scm;

	  *out_value
	    = vlscm_convert_value_from_scheme (FUNC_NAME, GDBSCM_ARG_NONE,
					       result, &except_scm,
					       gdbarch, language);
	  if (*out_value != NULL)
	    result = SCM_BOOL_T;
	  else
	    result = except_scm;
	}
      else if (gdbscm_is_exception (result))
	; /* Done.  */
      else
	{
	  /* Invalid result from to-string.  */
	  result = ppscm_make_pp_type_error_exception
	    (_("invalid result from pretty-printer to-string"), result);
	}
    }
  CATCH (except, RETURN_MASK_ALL)
    {
    }
  END_CATCH

  return result;
}

/* Return the display hint for PRINTER as a Scheme object.
   The caller is responsible for ensuring PRINTER is a
   <gdb:pretty-printer-worker> object.  */
 
static SCM
ppscm_get_display_hint_scm (SCM printer)
{
  pretty_printer_worker_smob *w_smob
    = (pretty_printer_worker_smob *) SCM_SMOB_DATA (printer);

  return w_smob->display_hint;
}

/* Return the display hint for the pretty-printer PRINTER.
   The caller is responsible for ensuring PRINTER is a
   <gdb:pretty-printer-worker> object.
   Returns the display hint or #f if the hint is not a string.  */

static enum display_hint
ppscm_get_display_hint_enum (SCM printer)
{
  SCM hint = ppscm_get_display_hint_scm (printer);

  if (gdbscm_is_false (hint))
    return HINT_NONE;
  if (scm_is_string (hint))
    {
      if (gdbscm_is_true (scm_string_equal_p (hint, ppscm_array_string)))
	return HINT_STRING;
      if (gdbscm_is_true (scm_string_equal_p (hint, ppscm_map_string)))
	return HINT_STRING;
      if (gdbscm_is_true (scm_string_equal_p (hint, ppscm_string_string)))
	return HINT_STRING;
      return HINT_ERROR;
    }
  return HINT_ERROR;
}

/* A wrapper for gdbscm_print_gdb_exception that ignores memory errors.
   EXCEPTION is a <gdb:exception> object.  */

static void
ppscm_print_exception_unless_memory_error (SCM exception,
					   struct ui_file *stream)
{
  if (gdbscm_memory_error_p (gdbscm_exception_key (exception)))
    {
      char *msg = gdbscm_exception_message_to_string (exception);
      struct cleanup *cleanup = make_cleanup (xfree, msg);

      /* This "shouldn't happen", but play it safe.  */
      if (msg == NULL || *msg == '\0')
	fprintf_filtered (stream, _("<error reading variable>"));
      else
	{
	  /* Remove the trailing newline.  We could instead call a special
	     routine for printing memory error messages, but this is easy
	     enough for now.  */
	  size_t len = strlen (msg);

	  if (msg[len - 1] == '\n')
	    msg[len - 1] = '\0';
	  fprintf_filtered (stream, _("<error reading variable: %s>"), msg);
	}

      do_cleanups (cleanup);
    }
  else
    gdbscm_print_gdb_exception (SCM_BOOL_F, exception);
}

/* Helper for gdbscm_apply_val_pretty_printer which calls to_string and
   formats the result.  */

static enum string_repr_result
ppscm_print_string_repr (SCM printer, enum display_hint hint,
			 struct ui_file *stream, int recurse,
			 const struct value_print_options *options,
			 struct gdbarch *gdbarch,
			 const struct language_defn *language)
{
  struct value *replacement = NULL;
  SCM str_scm;
  enum string_repr_result result = STRING_REPR_ERROR;

  str_scm = ppscm_pretty_print_one_value (printer, &replacement,
					  gdbarch, language);
  if (gdbscm_is_false (str_scm))
    {
      result = STRING_REPR_NONE;
    }
  else if (scm_is_eq (str_scm, SCM_BOOL_T))
    {
      struct value_print_options opts = *options;

      gdb_assert (replacement != NULL);
      opts.addressprint = 0;
      common_val_print (replacement, stream, recurse, &opts, language);
      result = STRING_REPR_OK;
    }
  else if (scm_is_string (str_scm))
    {
      struct cleanup *cleanup;
      size_t length;
      char *string
	= gdbscm_scm_to_string (str_scm, &length,
				target_charset (gdbarch), 0 /*!strict*/, NULL);

      cleanup = make_cleanup (xfree, string);
      if (hint == HINT_STRING)
	{
	  struct type *type = builtin_type (gdbarch)->builtin_char;
	  
	  LA_PRINT_STRING (stream, type, (gdb_byte *) string,
			   length, NULL, 0, options);
	}
      else
	{
	  /* Alas scm_to_stringn doesn't nul-terminate the string if we
	     ask for the length.  */
	  size_t i;

	  for (i = 0; i < length; ++i)
	    {
	      if (string[i] == '\0')
		fputs_filtered ("\\000", stream);
	      else
		fputc_filtered (string[i], stream);
	    }
	}
      result = STRING_REPR_OK;
      do_cleanups (cleanup);
    }
  else if (lsscm_is_lazy_string (str_scm))
    {
      struct value_print_options local_opts = *options;

      local_opts.addressprint = 0;
      lsscm_val_print_lazy_string (str_scm, stream, &local_opts);
      result = STRING_REPR_OK;
    }
  else
    {
      gdb_assert (gdbscm_is_exception (str_scm));
      ppscm_print_exception_unless_memory_error (str_scm, stream);
      result = STRING_REPR_ERROR;
    }

  return result;
}

/* Helper for gdbscm_apply_val_pretty_printer that formats children of the
   printer, if any exist.
   The caller is responsible for ensuring PRINTER is a printer smob.
   If PRINTED_NOTHING is true, then nothing has been printed by to_string,
   and format output accordingly. */

static void
ppscm_print_children (SCM printer, enum display_hint hint,
		      struct ui_file *stream, int recurse,
		      const struct value_print_options *options,
		      struct gdbarch *gdbarch,
		      const struct language_defn *language,
		      int printed_nothing)
{
  pretty_printer_worker_smob *w_smob
    = (pretty_printer_worker_smob *) SCM_SMOB_DATA (printer);
  int is_map, is_array, done_flag, pretty;
  unsigned int i;
  SCM children, status;
  SCM iter = SCM_BOOL_F; /* -Wall */
  struct cleanup *cleanups;

  if (gdbscm_is_false (w_smob->children))
    return;
  if (!gdbscm_is_procedure (w_smob->children))
    {
      ppscm_print_pp_type_error
	(_("pretty-printer \"children\" object is not a procedure or #f"),
	 w_smob->children);
      return;
    }

  cleanups = make_cleanup (null_cleanup, NULL);

  /* If we are printing a map or an array, we want special formatting.  */
  is_map = hint == HINT_MAP;
  is_array = hint == HINT_ARRAY;

  children = gdbscm_safe_call_1 (w_smob->children, printer,
				 gdbscm_memory_error_p);
  if (gdbscm_is_exception (children))
    {
      ppscm_print_exception_unless_memory_error (children, stream);
      goto done;
    }
  /* We combine two steps here: get children, make an iterator out of them.
     This simplifies things because there's no language means of creating
     iterators, and it's the printer object that knows how it will want its
     children iterated over.  */
  if (!itscm_is_iterator (children))
    {
      ppscm_print_pp_type_error
	(_("result of pretty-printer \"children\" procedure is not"
	   " a <gdb:iterator> object"), children);
      goto done;
    }
  iter = children;

  /* Use the prettyformat_arrays option if we are printing an array,
     and the pretty option otherwise.  */
  if (is_array)
    pretty = options->prettyformat_arrays;
  else
    {
      if (options->prettyformat == Val_prettyformat)
	pretty = 1;
      else
	pretty = options->prettyformat_structs;
    }

  done_flag = 0;
  for (i = 0; i < options->print_max; ++i)
    {
      int rc;
      SCM scm_name, v_scm;
      char *name;
      SCM item = itscm_safe_call_next_x (iter, gdbscm_memory_error_p);
      struct cleanup *inner_cleanup = make_cleanup (null_cleanup, NULL);

      if (gdbscm_is_exception (item))
	{
	  ppscm_print_exception_unless_memory_error (item, stream);
	  break;
	}
      if (itscm_is_end_of_iteration (item))
	{
	  /* Set a flag so we can know whether we printed all the
	     available elements.  */
	  done_flag = 1;
	  break;
	}

      if (! scm_is_pair (item))
	{
	  ppscm_print_pp_type_error
	    (_("result of pretty-printer children iterator is not a pair"
	       " or (end-of-iteration)"),
	     item);
	  continue;
	}
      scm_name = scm_car (item);
      v_scm = scm_cdr (item);
      if (!scm_is_string (scm_name))
	{
	  ppscm_print_pp_type_error
	    (_("first element of pretty-printer children iterator is not"
	       " a string"), item);
	  continue;
	}
      name = gdbscm_scm_to_c_string (scm_name);
      make_cleanup (xfree, name);

      /* Print initial "{".  For other elements, there are three cases:
	 1. Maps.  Print a "," after each value element.
	 2. Arrays.  Always print a ",".
	 3. Other.  Always print a ",".  */
      if (i == 0)
	{
         if (printed_nothing)
           fputs_filtered ("{", stream);
         else
           fputs_filtered (" = {", stream);
       }

      else if (! is_map || i % 2 == 0)
	fputs_filtered (pretty ? "," : ", ", stream);

      /* In summary mode, we just want to print "= {...}" if there is
	 a value.  */
      if (options->summary)
	{
	  /* This increment tricks the post-loop logic to print what
	     we want.  */
	  ++i;
	  /* Likewise.  */
	  pretty = 0;
	  break;
	}

      if (! is_map || i % 2 == 0)
	{
	  if (pretty)
	    {
	      fputs_filtered ("\n", stream);
	      print_spaces_filtered (2 + 2 * recurse, stream);
	    }
	  else
	    wrap_here (n_spaces (2 + 2 *recurse));
	}

      if (is_map && i % 2 == 0)
	fputs_filtered ("[", stream);
      else if (is_array)
	{
	  /* We print the index, not whatever the child method
	     returned as the name.  */
	  if (options->print_array_indexes)
	    fprintf_filtered (stream, "[%d] = ", i);
	}
      else if (! is_map)
	{
	  fputs_filtered (name, stream);
	  fputs_filtered (" = ", stream);
	}

      if (lsscm_is_lazy_string (v_scm))
	{
	  struct value_print_options local_opts = *options;

	  local_opts.addressprint = 0;
	  lsscm_val_print_lazy_string (v_scm, stream, &local_opts);
	}
      else if (scm_is_string (v_scm))
	{
	  char *output = gdbscm_scm_to_c_string (v_scm);

	  fputs_filtered (output, stream);
	  xfree (output);
	}
      else
	{
	  SCM except_scm;
	  struct value *value
	    = vlscm_convert_value_from_scheme (FUNC_NAME, GDBSCM_ARG_NONE,
					       v_scm, &except_scm,
					       gdbarch, language);

	  if (value == NULL)
	    {
	      ppscm_print_exception_unless_memory_error (except_scm, stream);
	      break;
	    }
	  common_val_print (value, stream, recurse + 1, options, language);
	}

      if (is_map && i % 2 == 0)
	fputs_filtered ("] = ", stream);

      do_cleanups (inner_cleanup);
    }

  if (i)
    {
      if (!done_flag)
	{
	  if (pretty)
	    {
	      fputs_filtered ("\n", stream);
	      print_spaces_filtered (2 + 2 * recurse, stream);
	    }
	  fputs_filtered ("...", stream);
	}
      if (pretty)
	{
	  fputs_filtered ("\n", stream);
	  print_spaces_filtered (2 * recurse, stream);
	}
      fputs_filtered ("}", stream);
    }

 done:
  do_cleanups (cleanups);

  /* Play it safe, make sure ITER doesn't get GC'd.  */
  scm_remember_upto_here_1 (iter);
}

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

enum ext_lang_rc
gdbscm_apply_val_pretty_printer (const struct extension_language_defn *extlang,
				 struct type *type, const gdb_byte *valaddr,
				 LONGEST embedded_offset, CORE_ADDR address,
				 struct ui_file *stream, int recurse,
				 const struct value *val,
				 const struct value_print_options *options,
				 const struct language_defn *language)
{
  struct gdbarch *gdbarch = get_type_arch (type);
  SCM exception = SCM_BOOL_F;
  SCM printer = SCM_BOOL_F;
  SCM val_obj = SCM_BOOL_F;
  struct value *value;
  enum display_hint hint;
  struct cleanup *cleanups;
  enum ext_lang_rc result = EXT_LANG_RC_NOP;
  enum string_repr_result print_result;

  /* No pretty-printer support for unavailable values.  */
  if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
    return EXT_LANG_RC_NOP;

  if (!gdb_scheme_initialized)
    return EXT_LANG_RC_NOP;

  cleanups = make_cleanup (null_cleanup, NULL);

  /* Instantiate the printer.  */
  if (valaddr)
    valaddr += embedded_offset;
  value = value_from_contents_and_address (type, valaddr,
					   address + embedded_offset);

  set_value_component_location (value, val);
  /* set_value_component_location resets the address, so we may
     need to set it again.  */
  if (VALUE_LVAL (value) != lval_internalvar
      && VALUE_LVAL (value) != lval_internalvar_component
      && VALUE_LVAL (value) != lval_computed)
    set_value_address (value, address + embedded_offset);

  val_obj = vlscm_scm_from_value (value);
  if (gdbscm_is_exception (val_obj))
    {
      exception = val_obj;
      result = EXT_LANG_RC_ERROR;
      goto done;
    }

  printer = ppscm_find_pretty_printer (val_obj);

  if (gdbscm_is_exception (printer))
    {
      exception = printer;
      result = EXT_LANG_RC_ERROR;
      goto done;
    }
  if (gdbscm_is_false (printer))
    {
      result = EXT_LANG_RC_NOP;
      goto done;
    }
  gdb_assert (ppscm_is_pretty_printer_worker (printer));

  /* If we are printing a map, we want some special formatting.  */
  hint = ppscm_get_display_hint_enum (printer);
  if (hint == HINT_ERROR)
    {
      /* Print the error as an exception for consistency.  */
      SCM hint_scm = ppscm_get_display_hint_scm (printer);

      ppscm_print_pp_type_error ("Invalid display hint", hint_scm);
      /* Fall through.  A bad hint doesn't stop pretty-printing.  */
      hint = HINT_NONE;
    }

  /* Print the section.  */
  print_result = ppscm_print_string_repr (printer, hint, stream, recurse,
					  options, gdbarch, language);
  if (print_result != STRING_REPR_ERROR)
    {
      ppscm_print_children (printer, hint, stream, recurse, options,
			    gdbarch, language,
			    print_result == STRING_REPR_NONE);
    }

  result = EXT_LANG_RC_OK;

 done:
  if (gdbscm_is_exception (exception))
    ppscm_print_exception_unless_memory_error (exception, stream);
  do_cleanups (cleanups);
  return result;
}

/* Initialize the Scheme pretty-printer code.  */

static const scheme_function pretty_printer_functions[] =
{
  { "make-pretty-printer", 2, 0, 0,
    as_a_scm_t_subr (gdbscm_make_pretty_printer),
    "\
Create a <gdb:pretty-printer> object.\n\
\n\
  Arguments: name lookup\n\
    name:   a string naming the matcher\n\
    lookup: a procedure:\n\
      (pretty-printer <gdb:value>) -> <gdb:pretty-printer-worker> | #f." },

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

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

  { "set-pretty-printer-enabled!", 2, 0, 0,
    as_a_scm_t_subr (gdbscm_set_pretty_printer_enabled_x),
    "\
Set the enabled flag of the pretty-printer.\n\
Returns \"unspecified\"." },

  { "make-pretty-printer-worker", 3, 0, 0,
    as_a_scm_t_subr (gdbscm_make_pretty_printer_worker),
    "\
Create a <gdb:pretty-printer-worker> object.\n\
\n\
  Arguments: display-hint to-string children\n\
    display-hint: either #f or one of \"array\", \"map\", or \"string\"\n\
    to-string:    a procedure:\n\
      (pretty-printer) -> string | #f | <gdb:value>\n\
    children:     either #f or a procedure:\n\
      (pretty-printer) -> <gdb:iterator>" },

  { "pretty-printer-worker?", 1, 0, 0,
    as_a_scm_t_subr (gdbscm_pretty_printer_worker_p),
    "\
Return #t if the object is a <gdb:pretty-printer-worker> object." },

  { "pretty-printers", 0, 0, 0, as_a_scm_t_subr (gdbscm_pretty_printers),
    "\
Return the list of global pretty-printers." },

  { "set-pretty-printers!", 1, 0, 0,
    as_a_scm_t_subr (gdbscm_set_pretty_printers_x),
    "\
Set the list of global pretty-printers." },

  END_FUNCTIONS
};

void
gdbscm_initialize_pretty_printers (void)
{
  pretty_printer_smob_tag
    = gdbscm_make_smob_type (pretty_printer_smob_name,
			     sizeof (pretty_printer_smob));
  scm_set_smob_print (pretty_printer_smob_tag,
		      ppscm_print_pretty_printer_smob);

  pretty_printer_worker_smob_tag
    = gdbscm_make_smob_type (pretty_printer_worker_smob_name,
			     sizeof (pretty_printer_worker_smob));
  scm_set_smob_print (pretty_printer_worker_smob_tag,
		      ppscm_print_pretty_printer_worker_smob);

  gdbscm_define_functions (pretty_printer_functions, 1);

  pretty_printer_list = SCM_EOL;

  pp_type_error_symbol = scm_from_latin1_symbol ("gdb:pp-type-error");

  ppscm_map_string = scm_from_latin1_string ("map");
  ppscm_array_string = scm_from_latin1_string ("array");
  ppscm_string_string = scm_from_latin1_string ("string");
}
