/* GDB/Scheme pretty-printing.

   Copyright (C) 2008-2023 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 "top.h"		/* For quit_force().  */
#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 guile_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.  */

struct pretty_printer_smob
{
  /* 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.  */
};

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

struct pretty_printer_worker_smob
{
  /* 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;
};

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)
{
  std::string msg = string_printf ("%s: ~S", message);
  return gdbscm_make_error (pp_type_error_symbol,
			    NULL /* func */, msg.c_str (),
			    scm_list_1 (object), scm_list_1 (object));
}

/* 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;

      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)
{
  for (objfile *objfile : current_program_space->objfiles ())
    {
      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
    {
      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 (const gdb_exception_forced_quit &except)
    {
      quit_force (NULL, 0);
    }
  catch (const gdb_exception &except)
    {
    }

  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)))
    {
      gdb::unique_xmalloc_ptr<char> msg
	= gdbscm_exception_message_to_string (exception);

      /* This "shouldn't happen", but play it safe.  */
      if (msg == NULL || msg.get ()[0] == '\0')
	gdb_printf (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.  */
	  char *msg_text = msg.get ();
	  size_t len = strlen (msg_text);

	  if (msg_text[len - 1] == '\n')
	    msg_text[len - 1] = '\0';
	  gdb_printf (stream, _("<error reading variable: %s>"), msg_text);
	}
    }
  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 guile_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 guile_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 = false;
      common_val_print (replacement, stream, recurse, &opts, language);
      result = STRING_REPR_OK;
    }
  else if (scm_is_string (str_scm))
    {
      size_t length;
      gdb::unique_xmalloc_ptr<char> string
	= gdbscm_scm_to_string (str_scm, &length,
				target_charset (gdbarch), 0 /*!strict*/, NULL);

      if (hint == HINT_STRING)
	{
	  struct type *type = builtin_type (gdbarch)->builtin_char;
	  
	  language->printstr (stream, type, (gdb_byte *) string.get (),
			      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.get ()[i] == '\0')
		gdb_puts ("\\000", stream);
	      else
		gdb_putc (string.get ()[i], stream);
	    }
	}
      result = STRING_REPR_OK;
    }
  else if (lsscm_is_lazy_string (str_scm))
    {
      struct value_print_options local_opts = *options;

      local_opts.addressprint = false;
      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;
  SCM iter = SCM_BOOL_F; /* -Wall */

  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;
    }

  /* 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)
    {
      SCM scm_name, v_scm;
      SCM item = itscm_safe_call_next_x (iter, gdbscm_memory_error_p);

      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;
	}
      gdb::unique_xmalloc_ptr<char> name
	= gdbscm_scm_to_c_string (scm_name);

      /* Print initial "=" to separate print_string_repr output and
	 children.  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)
	    gdb_puts (" = ", stream);
	}
      else if (! is_map || i % 2 == 0)
	gdb_puts (pretty ? "," : ", ", stream);

      /* Skip printing children if max_depth has been reached.  This check
	 is performed after print_string_repr and the "=" separator so that
	 these steps are not skipped if the variable is located within the
	 permitted depth.  */
      if (val_print_check_max_depth (stream, recurse, options, language))
	goto done;
      else if (i == 0)
	/* Print initial "{" to bookend children.  */
	gdb_puts ("{", 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)
	    {
	      gdb_puts ("\n", stream);
	      print_spaces (2 + 2 * recurse, stream);
	    }
	  else
	    stream->wrap_here (2 + 2 *recurse);
	}

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

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

	  local_opts.addressprint = false;
	  lsscm_val_print_lazy_string (v_scm, stream, &local_opts);
	}
      else if (scm_is_string (v_scm))
	{
	  gdb::unique_xmalloc_ptr<char> output
	    = gdbscm_scm_to_c_string (v_scm);
	  gdb_puts (output.get (), stream);
	}
      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;
	    }
	  else
	    {
	      /* When printing the key of a map we allow one additional
		 level of depth.  This means the key will print before the
		 value does.  */
	      struct value_print_options opt = *options;
	      if (is_map && i % 2 == 0
		  && opt.max_depth != -1
		  && opt.max_depth < INT_MAX)
		++opt.max_depth;
	      common_val_print (value, stream, recurse + 1, &opt, language);
	    }
	}

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

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

 done:
  /* 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 value *value,
				 struct ui_file *stream, int recurse,
				 const struct value_print_options *options,
				 const struct language_defn *language)
{
  struct type *type = value->type ();
  struct gdbarch *gdbarch = type->arch ();
  SCM exception = SCM_BOOL_F;
  SCM printer = SCM_BOOL_F;
  SCM val_obj = SCM_BOOL_F;
  enum display_hint hint;
  enum ext_lang_rc result = EXT_LANG_RC_NOP;
  enum guile_string_repr_result print_result;

  if (value->lazy ())
    value->fetch_lazy ();

  /* No pretty-printer support for unavailable values.  */
  if (!value->bytes_available (0, type->length ()))
    return EXT_LANG_RC_NOP;

  if (!gdb_scheme_initialized)
    return EXT_LANG_RC_NOP;

  /* Instantiate the printer.  */
  val_obj = vlscm_scm_from_value_no_release (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);
  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");
}
