/* Print values for GDB, the GNU debugger.

   Copyright (C) 1986-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 "symtab.h"
#include "gdbtypes.h"
#include "value.h"
#include "gdbcore.h"
#include "gdbcmd.h"
#include "target.h"
#include "language.h"
#include "annotate.h"
#include "valprint.h"
#include "target-float.h"
#include "extension.h"
#include "ada-lang.h"
#include "gdb_obstack.h"
#include "charset.h"
#include "typeprint.h"
#include <ctype.h>
#include <algorithm>
#include "gdbsupport/byte-vector.h"
#include "cli/cli-option.h"
#include "gdbarch.h"
#include "cli/cli-style.h"
#include "count-one-bits.h"
#include "c-lang.h"
#include "cp-abi.h"
#include "inferior.h"
#include "gdbsupport/selftest.h"
#include "selftest-arch.h"

/* Maximum number of wchars returned from wchar_iterate.  */
#define MAX_WCHARS 4

/* A convenience macro to compute the size of a wchar_t buffer containing X
   characters.  */
#define WCHAR_BUFLEN(X) ((X) * sizeof (gdb_wchar_t))

/* Character buffer size saved while iterating over wchars.  */
#define WCHAR_BUFLEN_MAX WCHAR_BUFLEN (MAX_WCHARS)

/* A structure to encapsulate state information from iterated
   character conversions.  */
struct converted_character
{
  /* The number of characters converted.  */
  int num_chars;

  /* The result of the conversion.  See charset.h for more.  */
  enum wchar_iterate_result result;

  /* The (saved) converted character(s).  */
  gdb_wchar_t chars[WCHAR_BUFLEN_MAX];

  /* The first converted target byte.  */
  const gdb_byte *buf;

  /* The number of bytes converted.  */
  size_t buflen;

  /* How many times this character(s) is repeated.  */
  int repeat_count;
};

/* Command lists for set/show print raw.  */
struct cmd_list_element *setprintrawlist;
struct cmd_list_element *showprintrawlist;

/* Prototypes for local functions */

static int partial_memory_read (CORE_ADDR memaddr, gdb_byte *myaddr,
				int len, int *errptr);

static void set_input_radix_1 (int, unsigned);

static void set_output_radix_1 (int, unsigned);

static void val_print_type_code_flags (struct type *type,
				       struct value *original_value,
				       int embedded_offset,
				       struct ui_file *stream);

#define PRINT_MAX_DEFAULT 200	/* Start print_max off at this value.  */
#define PRINT_MAX_DEPTH_DEFAULT 20	/* Start print_max_depth off at this value. */

struct value_print_options user_print_options =
{
  Val_prettyformat_default,	/* prettyformat */
  0,				/* prettyformat_arrays */
  0,				/* prettyformat_structs */
  0,				/* vtblprint */
  1,				/* unionprint */
  1,				/* addressprint */
  0,				/* objectprint */
  PRINT_MAX_DEFAULT,		/* print_max */
  10,				/* repeat_count_threshold */
  0,				/* output_format */
  0,				/* format */
  1,				/* memory_tag_violations */
  0,				/* stop_print_at_null */
  0,				/* print_array_indexes */
  0,				/* deref_ref */
  1,				/* static_field_print */
  1,				/* pascal_static_field_print */
  0,				/* raw */
  0,				/* summary */
  1,				/* symbol_print */
  PRINT_MAX_DEPTH_DEFAULT,	/* max_depth */
  1				/* finish_print */
};

/* Initialize *OPTS to be a copy of the user print options.  */
void
get_user_print_options (struct value_print_options *opts)
{
  *opts = user_print_options;
}

/* Initialize *OPTS to be a copy of the user print options, but with
   pretty-formatting disabled.  */
void
get_no_prettyformat_print_options (struct value_print_options *opts)
{  
  *opts = user_print_options;
  opts->prettyformat = Val_no_prettyformat;
}

/* Initialize *OPTS to be a copy of the user print options, but using
   FORMAT as the formatting option.  */
void
get_formatted_print_options (struct value_print_options *opts,
			     char format)
{
  *opts = user_print_options;
  opts->format = format;
}

static void
show_print_max (struct ui_file *file, int from_tty,
		struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file,
		    _("Limit on string chars or array "
		      "elements to print is %s.\n"),
		    value);
}


/* Default input and output radixes, and output format letter.  */

unsigned input_radix = 10;
static void
show_input_radix (struct ui_file *file, int from_tty,
		  struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file,
		    _("Default input radix for entering numbers is %s.\n"),
		    value);
}

unsigned output_radix = 10;
static void
show_output_radix (struct ui_file *file, int from_tty,
		   struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file,
		    _("Default output radix for printing of values is %s.\n"),
		    value);
}

/* By default we print arrays without printing the index of each element in
   the array.  This behavior can be changed by setting PRINT_ARRAY_INDEXES.  */

static void
show_print_array_indexes (struct ui_file *file, int from_tty,
			  struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("Printing of array indexes is %s.\n"), value);
}

/* Print repeat counts if there are more than this many repetitions of an
   element in an array.  Referenced by the low level language dependent
   print routines.  */

static void
show_repeat_count_threshold (struct ui_file *file, int from_tty,
			     struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("Threshold for repeated print elements is %s.\n"),
		    value);
}

/* If nonzero, prints memory tag violations for pointers.  */

static void
show_memory_tag_violations (struct ui_file *file, int from_tty,
			    struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file,
		    _("Printing of memory tag violations is %s.\n"),
		    value);
}

/* If nonzero, stops printing of char arrays at first null.  */

static void
show_stop_print_at_null (struct ui_file *file, int from_tty,
			 struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file,
		    _("Printing of char arrays to stop "
		      "at first null char is %s.\n"),
		    value);
}

/* Controls pretty printing of structures.  */

static void
show_prettyformat_structs (struct ui_file *file, int from_tty,
			  struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("Pretty formatting of structures is %s.\n"), value);
}

/* Controls pretty printing of arrays.  */

static void
show_prettyformat_arrays (struct ui_file *file, int from_tty,
			 struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("Pretty formatting of arrays is %s.\n"), value);
}

/* If nonzero, causes unions inside structures or other unions to be
   printed.  */

static void
show_unionprint (struct ui_file *file, int from_tty,
		 struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file,
		    _("Printing of unions interior to structures is %s.\n"),
		    value);
}

/* If nonzero, causes machine addresses to be printed in certain contexts.  */

static void
show_addressprint (struct ui_file *file, int from_tty,
		   struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("Printing of addresses is %s.\n"), value);
}

static void
show_symbol_print (struct ui_file *file, int from_tty,
		   struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file,
		    _("Printing of symbols when printing pointers is %s.\n"),
		    value);
}



/* A helper function for val_print.  When printing in "summary" mode,
   we want to print scalar arguments, but not aggregate arguments.
   This function distinguishes between the two.  */

int
val_print_scalar_type_p (struct type *type)
{
  type = check_typedef (type);
  while (TYPE_IS_REFERENCE (type))
    {
      type = TYPE_TARGET_TYPE (type);
      type = check_typedef (type);
    }
  switch (type->code ())
    {
    case TYPE_CODE_ARRAY:
    case TYPE_CODE_STRUCT:
    case TYPE_CODE_UNION:
    case TYPE_CODE_SET:
    case TYPE_CODE_STRING:
      return 0;
    default:
      return 1;
    }
}

/* A helper function for val_print.  When printing with limited depth we
   want to print string and scalar arguments, but not aggregate arguments.
   This function distinguishes between the two.  */

static bool
val_print_scalar_or_string_type_p (struct type *type,
				   const struct language_defn *language)
{
  return (val_print_scalar_type_p (type)
	  || language->is_string_type_p (type));
}

/* See valprint.h.  */

int
valprint_check_validity (struct ui_file *stream,
			 struct type *type,
			 LONGEST embedded_offset,
			 const struct value *val)
{
  type = check_typedef (type);

  if (type_not_associated (type))
    {
      val_print_not_associated (stream);
      return 0;
    }

  if (type_not_allocated (type))
    {
      val_print_not_allocated (stream);
      return 0;
    }

  if (type->code () != TYPE_CODE_UNION
      && type->code () != TYPE_CODE_STRUCT
      && type->code () != TYPE_CODE_ARRAY)
    {
      if (value_bits_any_optimized_out (val,
					TARGET_CHAR_BIT * embedded_offset,
					TARGET_CHAR_BIT * TYPE_LENGTH (type)))
	{
	  val_print_optimized_out (val, stream);
	  return 0;
	}

      if (value_bits_synthetic_pointer (val, TARGET_CHAR_BIT * embedded_offset,
					TARGET_CHAR_BIT * TYPE_LENGTH (type)))
	{
	  const int is_ref = type->code () == TYPE_CODE_REF;
	  int ref_is_addressable = 0;

	  if (is_ref)
	    {
	      const struct value *deref_val = coerce_ref_if_computed (val);

	      if (deref_val != NULL)
		ref_is_addressable = value_lval_const (deref_val) == lval_memory;
	    }

	  if (!is_ref || !ref_is_addressable)
	    fputs_styled (_("<synthetic pointer>"), metadata_style.style (),
			  stream);

	  /* C++ references should be valid even if they're synthetic.  */
	  return is_ref;
	}

      if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
	{
	  val_print_unavailable (stream);
	  return 0;
	}
    }

  return 1;
}

void
val_print_optimized_out (const struct value *val, struct ui_file *stream)
{
  if (val != NULL && value_lval_const (val) == lval_register)
    val_print_not_saved (stream);
  else
    fprintf_styled (stream, metadata_style.style (), _("<optimized out>"));
}

void
val_print_not_saved (struct ui_file *stream)
{
  fprintf_styled (stream, metadata_style.style (), _("<not saved>"));
}

void
val_print_unavailable (struct ui_file *stream)
{
  fprintf_styled (stream, metadata_style.style (), _("<unavailable>"));
}

void
val_print_invalid_address (struct ui_file *stream)
{
  fprintf_styled (stream, metadata_style.style (), _("<invalid address>"));
}

/* Print a pointer based on the type of its target.

   Arguments to this functions are roughly the same as those in
   generic_val_print.  A difference is that ADDRESS is the address to print,
   with embedded_offset already added.  ELTTYPE represents
   the pointed type after check_typedef.  */

static void
print_unpacked_pointer (struct type *type, struct type *elttype,
			CORE_ADDR address, struct ui_file *stream,
			const struct value_print_options *options)
{
  struct gdbarch *gdbarch = type->arch ();

  if (elttype->code () == TYPE_CODE_FUNC)
    {
      /* Try to print what function it points to.  */
      print_function_pointer_address (options, gdbarch, address, stream);
      return;
    }

  if (options->symbol_print)
    print_address_demangle (options, gdbarch, address, stream, demangle);
  else if (options->addressprint)
    fputs_filtered (paddress (gdbarch, address), stream);
}

/* generic_val_print helper for TYPE_CODE_ARRAY.  */

static void
generic_val_print_array (struct value *val,
			 struct ui_file *stream, int recurse,
			 const struct value_print_options *options,
			 const struct
			     generic_val_print_decorations *decorations)
{
  struct type *type = check_typedef (value_type (val));
  struct type *unresolved_elttype = TYPE_TARGET_TYPE (type);
  struct type *elttype = check_typedef (unresolved_elttype);

  if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (unresolved_elttype) > 0)
    {
      LONGEST low_bound, high_bound;

      if (!get_array_bounds (type, &low_bound, &high_bound))
	error (_("Could not determine the array high bound"));

      fputs_filtered (decorations->array_start, stream);
      value_print_array_elements (val, stream, recurse, options, 0);
      fputs_filtered (decorations->array_end, stream);
    }
  else
    {
      /* Array of unspecified length: treat like pointer to first elt.  */
      print_unpacked_pointer (type, elttype, value_address (val),
			      stream, options);
    }

}

/* generic_value_print helper for TYPE_CODE_PTR.  */

static void
generic_value_print_ptr (struct value *val, struct ui_file *stream,
			 const struct value_print_options *options)
{

  if (options->format && options->format != 's')
    value_print_scalar_formatted (val, options, 0, stream);
  else
    {
      struct type *type = check_typedef (value_type (val));
      struct type *elttype = check_typedef (TYPE_TARGET_TYPE (type));
      const gdb_byte *valaddr = value_contents_for_printing (val);
      CORE_ADDR addr = unpack_pointer (type, valaddr);

      print_unpacked_pointer (type, elttype, addr, stream, options);
    }
}


/* Print '@' followed by the address contained in ADDRESS_BUFFER.  */

static void
print_ref_address (struct type *type, const gdb_byte *address_buffer,
		  int embedded_offset, struct ui_file *stream)
{
  struct gdbarch *gdbarch = type->arch ();

  if (address_buffer != NULL)
    {
      CORE_ADDR address
	= extract_typed_address (address_buffer + embedded_offset, type);

      fprintf_filtered (stream, "@");
      fputs_filtered (paddress (gdbarch, address), stream);
    }
  /* Else: we have a non-addressable value, such as a DW_AT_const_value.  */
}

/* If VAL is addressable, return the value contents buffer of a value that
   represents a pointer to VAL.  Otherwise return NULL.  */

static const gdb_byte *
get_value_addr_contents (struct value *deref_val)
{
  gdb_assert (deref_val != NULL);

  if (value_lval_const (deref_val) == lval_memory)
    return value_contents_for_printing_const (value_addr (deref_val));
  else
    {
      /* We have a non-addressable value, such as a DW_AT_const_value.  */
      return NULL;
    }
}

/* generic_val_print helper for TYPE_CODE_{RVALUE_,}REF.  */

static void
generic_val_print_ref (struct type *type,
		       int embedded_offset, struct ui_file *stream, int recurse,
		       struct value *original_value,
		       const struct value_print_options *options)
{
  struct type *elttype = check_typedef (TYPE_TARGET_TYPE (type));
  struct value *deref_val = NULL;
  const int value_is_synthetic
    = value_bits_synthetic_pointer (original_value,
				    TARGET_CHAR_BIT * embedded_offset,
				    TARGET_CHAR_BIT * TYPE_LENGTH (type));
  const int must_coerce_ref = ((options->addressprint && value_is_synthetic)
			       || options->deref_ref);
  const int type_is_defined = elttype->code () != TYPE_CODE_UNDEF;
  const gdb_byte *valaddr = value_contents_for_printing (original_value);

  if (must_coerce_ref && type_is_defined)
    {
      deref_val = coerce_ref_if_computed (original_value);

      if (deref_val != NULL)
	{
	  /* More complicated computed references are not supported.  */
	  gdb_assert (embedded_offset == 0);
	}
      else
	deref_val = value_at (TYPE_TARGET_TYPE (type),
			      unpack_pointer (type, valaddr + embedded_offset));
    }
  /* Else, original_value isn't a synthetic reference or we don't have to print
     the reference's contents.

     Notice that for references to TYPE_CODE_STRUCT, 'set print object on' will
     cause original_value to be a not_lval instead of an lval_computed,
     which will make value_bits_synthetic_pointer return false.
     This happens because if options->objectprint is true, c_value_print will
     overwrite original_value's contents with the result of coercing
     the reference through value_addr, and then set its type back to
     TYPE_CODE_REF.  In that case we don't have to coerce the reference again;
     we can simply treat it as non-synthetic and move on.  */

  if (options->addressprint)
    {
      const gdb_byte *address = (value_is_synthetic && type_is_defined
				 ? get_value_addr_contents (deref_val)
				 : valaddr);

      print_ref_address (type, address, embedded_offset, stream);

      if (options->deref_ref)
	fputs_filtered (": ", stream);
    }

  if (options->deref_ref)
    {
      if (type_is_defined)
	common_val_print (deref_val, stream, recurse, options,
			  current_language);
      else
	fputs_filtered ("???", stream);
    }
}

/* Helper function for generic_val_print_enum.
   This is also used to print enums in TYPE_CODE_FLAGS values.  */

static void
generic_val_print_enum_1 (struct type *type, LONGEST val,
			  struct ui_file *stream)
{
  unsigned int i;
  unsigned int len;

  len = type->num_fields ();
  for (i = 0; i < len; i++)
    {
      QUIT;
      if (val == TYPE_FIELD_ENUMVAL (type, i))
	{
	  break;
	}
    }
  if (i < len)
    {
      fputs_styled (type->field (i).name (), variable_name_style.style (),
		    stream);
    }
  else if (type->is_flag_enum ())
    {
      int first = 1;

      /* We have a "flag" enum, so we try to decompose it into pieces as
	 appropriate.  The enum may have multiple enumerators representing
	 the same bit, in which case we choose to only print the first one
	 we find.  */
      for (i = 0; i < len; ++i)
	{
	  QUIT;

	  ULONGEST enumval = TYPE_FIELD_ENUMVAL (type, i);
	  int nbits = count_one_bits_ll (enumval);

	  gdb_assert (nbits == 0 || nbits == 1);

	  if ((val & enumval) != 0)
	    {
	      if (first)
		{
		  fputs_filtered ("(", stream);
		  first = 0;
		}
	      else
		fputs_filtered (" | ", stream);

	      val &= ~TYPE_FIELD_ENUMVAL (type, i);
	      fputs_styled (type->field (i).name (),
			    variable_name_style.style (), stream);
	    }
	}

      if (val != 0)
	{
	  /* There are leftover bits, print them.  */
	  if (first)
	    fputs_filtered ("(", stream);
	  else
	    fputs_filtered (" | ", stream);

	  fputs_filtered ("unknown: 0x", stream);
	  print_longest (stream, 'x', 0, val);
	  fputs_filtered (")", stream);
	}
      else if (first)
	{
	  /* Nothing has been printed and the value is 0, the enum value must
	     have been 0.  */
	  fputs_filtered ("0", stream);
	}
      else
	{
	  /* Something has been printed, close the parenthesis.  */
	  fputs_filtered (")", stream);
	}
    }
  else
    print_longest (stream, 'd', 0, val);
}

/* generic_val_print helper for TYPE_CODE_ENUM.  */

static void
generic_val_print_enum (struct type *type,
			int embedded_offset, struct ui_file *stream,
			struct value *original_value,
			const struct value_print_options *options)
{
  LONGEST val;
  struct gdbarch *gdbarch = type->arch ();
  int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);

  gdb_assert (!options->format);

  const gdb_byte *valaddr = value_contents_for_printing (original_value);

  val = unpack_long (type, valaddr + embedded_offset * unit_size);

  generic_val_print_enum_1 (type, val, stream);
}

/* generic_val_print helper for TYPE_CODE_FUNC and TYPE_CODE_METHOD.  */

static void
generic_val_print_func (struct type *type,
			int embedded_offset, CORE_ADDR address,
			struct ui_file *stream,
			struct value *original_value,
			const struct value_print_options *options)
{
  struct gdbarch *gdbarch = type->arch ();

  gdb_assert (!options->format);

  /* FIXME, we should consider, at least for ANSI C language,
     eliminating the distinction made between FUNCs and POINTERs to
     FUNCs.  */
  fprintf_filtered (stream, "{");
  type_print (type, "", stream, -1);
  fprintf_filtered (stream, "} ");
  /* Try to print what function it points to, and its address.  */
  print_address_demangle (options, gdbarch, address, stream, demangle);
}

/* generic_value_print helper for TYPE_CODE_BOOL.  */

static void
generic_value_print_bool
  (struct value *value, struct ui_file *stream,
   const struct value_print_options *options,
   const struct generic_val_print_decorations *decorations)
{
  if (options->format || options->output_format)
    {
      struct value_print_options opts = *options;
      opts.format = (options->format ? options->format
		     : options->output_format);
      value_print_scalar_formatted (value, &opts, 0, stream);
    }
  else
    {
      const gdb_byte *valaddr = value_contents_for_printing (value);
      struct type *type = check_typedef (value_type (value));
      LONGEST val = unpack_long (type, valaddr);
      if (val == 0)
	fputs_filtered (decorations->false_name, stream);
      else if (val == 1)
	fputs_filtered (decorations->true_name, stream);
      else
	print_longest (stream, 'd', 0, val);
    }
}

/* generic_value_print helper for TYPE_CODE_INT.  */

static void
generic_value_print_int (struct value *val, struct ui_file *stream,
			 const struct value_print_options *options)
{
  struct value_print_options opts = *options;

  opts.format = (options->format ? options->format
		 : options->output_format);
  value_print_scalar_formatted (val, &opts, 0, stream);
}

/* generic_value_print helper for TYPE_CODE_CHAR.  */

static void
generic_value_print_char (struct value *value, struct ui_file *stream,
			  const struct value_print_options *options)
{
  if (options->format || options->output_format)
    {
      struct value_print_options opts = *options;

      opts.format = (options->format ? options->format
		     : options->output_format);
      value_print_scalar_formatted (value, &opts, 0, stream);
    }
  else
    {
      struct type *unresolved_type = value_type (value);
      struct type *type = check_typedef (unresolved_type);
      const gdb_byte *valaddr = value_contents_for_printing (value);

      LONGEST val = unpack_long (type, valaddr);
      if (type->is_unsigned ())
	fprintf_filtered (stream, "%u", (unsigned int) val);
      else
	fprintf_filtered (stream, "%d", (int) val);
      fputs_filtered (" ", stream);
      LA_PRINT_CHAR (val, unresolved_type, stream);
    }
}

/* generic_val_print helper for TYPE_CODE_FLT and TYPE_CODE_DECFLOAT.  */

static void
generic_val_print_float (struct type *type, struct ui_file *stream,
			 struct value *original_value,
			 const struct value_print_options *options)
{
  gdb_assert (!options->format);

  const gdb_byte *valaddr = value_contents_for_printing (original_value);

  print_floating (valaddr, type, stream);
}

/* generic_val_print helper for TYPE_CODE_FIXED_POINT.  */

static void
generic_val_print_fixed_point (struct value *val, struct ui_file *stream,
			       const struct value_print_options *options)
{
  if (options->format)
    value_print_scalar_formatted (val, options, 0, stream);
  else
    {
      struct type *type = value_type (val);

      const gdb_byte *valaddr = value_contents_for_printing (val);
      gdb_mpf f;

      f.read_fixed_point (gdb::make_array_view (valaddr, TYPE_LENGTH (type)),
			  type_byte_order (type), type->is_unsigned (),
			  type->fixed_point_scaling_factor ());

      const char *fmt = TYPE_LENGTH (type) < 4 ? "%.11Fg" : "%.17Fg";
      std::string str = gmp_string_printf (fmt, f.val);
      fprintf_filtered (stream, "%s", str.c_str ());
    }
}

/* generic_value_print helper for TYPE_CODE_COMPLEX.  */

static void
generic_value_print_complex (struct value *val, struct ui_file *stream,
			     const struct value_print_options *options,
			     const struct generic_val_print_decorations
			       *decorations)
{
  fprintf_filtered (stream, "%s", decorations->complex_prefix);

  struct value *real_part = value_real_part (val);
  value_print_scalar_formatted (real_part, options, 0, stream);
  fprintf_filtered (stream, "%s", decorations->complex_infix);

  struct value *imag_part = value_imaginary_part (val);
  value_print_scalar_formatted (imag_part, options, 0, stream);
  fprintf_filtered (stream, "%s", decorations->complex_suffix);
}

/* generic_value_print helper for TYPE_CODE_MEMBERPTR.  */

static void
generic_value_print_memberptr
  (struct value *val, struct ui_file *stream,
   int recurse,
   const struct value_print_options *options,
   const struct generic_val_print_decorations *decorations)
{
  if (!options->format)
    {
      /* Member pointers are essentially specific to C++, and so if we
	 encounter one, we should print it according to C++ rules.  */
      struct type *type = check_typedef (value_type (val));
      const gdb_byte *valaddr = value_contents_for_printing (val);
      cp_print_class_member (valaddr, type, stream, "&");
    }
  else
    generic_value_print (val, stream, recurse, options, decorations);
}

/* See valprint.h.  */

void
generic_value_print (struct value *val, struct ui_file *stream, int recurse,
		     const struct value_print_options *options,
		     const struct generic_val_print_decorations *decorations)
{
  struct type *type = value_type (val);

  type = check_typedef (type);

  if (is_fixed_point_type (type))
    type = type->fixed_point_type_base_type ();

  switch (type->code ())
    {
    case TYPE_CODE_ARRAY:
      generic_val_print_array (val, stream, recurse, options, decorations);
      break;

    case TYPE_CODE_MEMBERPTR:
      generic_value_print_memberptr (val, stream, recurse, options,
				     decorations);
      break;

    case TYPE_CODE_PTR:
      generic_value_print_ptr (val, stream, options);
      break;

    case TYPE_CODE_REF:
    case TYPE_CODE_RVALUE_REF:
      generic_val_print_ref (type, 0, stream, recurse,
			     val, options);
      break;

    case TYPE_CODE_ENUM:
      if (options->format)
	value_print_scalar_formatted (val, options, 0, stream);
      else
	generic_val_print_enum (type, 0, stream, val, options);
      break;

    case TYPE_CODE_FLAGS:
      if (options->format)
	value_print_scalar_formatted (val, options, 0, stream);
      else
	val_print_type_code_flags (type, val, 0, stream);
      break;

    case TYPE_CODE_FUNC:
    case TYPE_CODE_METHOD:
      if (options->format)
	value_print_scalar_formatted (val, options, 0, stream);
      else
	generic_val_print_func (type, 0, value_address (val), stream,
				val, options);
      break;

    case TYPE_CODE_BOOL:
      generic_value_print_bool (val, stream, options, decorations);
      break;

    case TYPE_CODE_RANGE:
    case TYPE_CODE_INT:
      generic_value_print_int (val, stream, options);
      break;

    case TYPE_CODE_CHAR:
      generic_value_print_char (val, stream, options);
      break;

    case TYPE_CODE_FLT:
    case TYPE_CODE_DECFLOAT:
      if (options->format)
	value_print_scalar_formatted (val, options, 0, stream);
      else
	generic_val_print_float (type, stream, val, options);
      break;

    case TYPE_CODE_FIXED_POINT:
      generic_val_print_fixed_point (val, stream, options);
      break;

    case TYPE_CODE_VOID:
      fputs_filtered (decorations->void_name, stream);
      break;

    case TYPE_CODE_ERROR:
      fprintf_filtered (stream, "%s", TYPE_ERROR_NAME (type));
      break;

    case TYPE_CODE_UNDEF:
      /* This happens (without TYPE_STUB set) on systems which don't use
	 dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar"
	 and no complete type for struct foo in that file.  */
      fprintf_styled (stream, metadata_style.style (), _("<incomplete type>"));
      break;

    case TYPE_CODE_COMPLEX:
      generic_value_print_complex (val, stream, options, decorations);
      break;

    case TYPE_CODE_METHODPTR:
      cplus_print_method_ptr (value_contents_for_printing (val), type,
			      stream);
      break;

    case TYPE_CODE_UNION:
    case TYPE_CODE_STRUCT:
    default:
      error (_("Unhandled type code %d in symbol table."),
	     type->code ());
    }
}

/* Helper function for val_print and common_val_print that does the
   work.  Arguments are as to val_print, but FULL_VALUE, if given, is
   the value to be printed.  */

static void
do_val_print (struct value *value, struct ui_file *stream, int recurse,
	      const struct value_print_options *options,
	      const struct language_defn *language)
{
  int ret = 0;
  struct value_print_options local_opts = *options;
  struct type *type = value_type (value);
  struct type *real_type = check_typedef (type);

  if (local_opts.prettyformat == Val_prettyformat_default)
    local_opts.prettyformat = (local_opts.prettyformat_structs
			       ? Val_prettyformat : Val_no_prettyformat);

  QUIT;

  /* Ensure that the type is complete and not just a stub.  If the type is
     only a stub and we can't find and substitute its complete type, then
     print appropriate string and return.  */

  if (real_type->is_stub ())
    {
      fprintf_styled (stream, metadata_style.style (), _("<incomplete type>"));
      return;
    }

  if (!valprint_check_validity (stream, real_type, 0, value))
    return;

  if (!options->raw)
    {
      ret = apply_ext_lang_val_pretty_printer (value, stream, recurse, options,
					       language);
      if (ret)
	return;
    }

  /* Handle summary mode.  If the value is a scalar, print it;
     otherwise, print an ellipsis.  */
  if (options->summary && !val_print_scalar_type_p (type))
    {
      fprintf_filtered (stream, "...");
      return;
    }

  /* If this value is too deep then don't print it.  */
  if (!val_print_scalar_or_string_type_p (type, language)
      && val_print_check_max_depth (stream, recurse, options, language))
    return;

  try
    {
      language->value_print_inner (value, stream, recurse, &local_opts);
    }
  catch (const gdb_exception_error &except)
    {
      fprintf_styled (stream, metadata_style.style (),
		      _("<error reading variable>"));
    }
}

/* See valprint.h.  */

bool
val_print_check_max_depth (struct ui_file *stream, int recurse,
			   const struct value_print_options *options,
			   const struct language_defn *language)
{
  if (options->max_depth > -1 && recurse >= options->max_depth)
    {
      gdb_assert (language->struct_too_deep_ellipsis () != NULL);
      fputs_filtered (language->struct_too_deep_ellipsis (), stream);
      return true;
    }

  return false;
}

/* Check whether the value VAL is printable.  Return 1 if it is;
   return 0 and print an appropriate error message to STREAM according to
   OPTIONS if it is not.  */

static int
value_check_printable (struct value *val, struct ui_file *stream,
		       const struct value_print_options *options)
{
  if (val == 0)
    {
      fprintf_styled (stream, metadata_style.style (),
		      _("<address of value unknown>"));
      return 0;
    }

  if (value_entirely_optimized_out (val))
    {
      if (options->summary && !val_print_scalar_type_p (value_type (val)))
	fprintf_filtered (stream, "...");
      else
	val_print_optimized_out (val, stream);
      return 0;
    }

  if (value_entirely_unavailable (val))
    {
      if (options->summary && !val_print_scalar_type_p (value_type (val)))
	fprintf_filtered (stream, "...");
      else
	val_print_unavailable (stream);
      return 0;
    }

  if (value_type (val)->code () == TYPE_CODE_INTERNAL_FUNCTION)
    {
      fprintf_styled (stream, metadata_style.style (),
		      _("<internal function %s>"),
		      value_internal_function_name (val));
      return 0;
    }

  if (type_not_associated (value_type (val)))
    {
      val_print_not_associated (stream);
      return 0;
    }

  if (type_not_allocated (value_type (val)))
    {
      val_print_not_allocated (stream);
      return 0;
    }

  return 1;
}

/* Print using the given LANGUAGE the value VAL onto stream STREAM according
   to OPTIONS.

   This is a preferable interface to val_print, above, because it uses
   GDB's value mechanism.  */

void
common_val_print (struct value *val, struct ui_file *stream, int recurse,
		  const struct value_print_options *options,
		  const struct language_defn *language)
{
  if (language->la_language == language_ada)
    /* The value might have a dynamic type, which would cause trouble
       below when trying to extract the value contents (since the value
       size is determined from the type size which is unknown).  So
       get a fixed representation of our value.  */
    val = ada_to_fixed_value (val);

  if (value_lazy (val))
    value_fetch_lazy (val);

  do_val_print (val, stream, recurse, options, language);
}

/* See valprint.h.  */

void
common_val_print_checked (struct value *val, struct ui_file *stream,
			  int recurse,
			  const struct value_print_options *options,
			  const struct language_defn *language)
{
  if (!value_check_printable (val, stream, options))
    return;
  common_val_print (val, stream, recurse, options, language);
}

/* Print on stream STREAM the value VAL according to OPTIONS.  The value
   is printed using the current_language syntax.  */

void
value_print (struct value *val, struct ui_file *stream,
	     const struct value_print_options *options)
{
  scoped_value_mark free_values;

  if (!value_check_printable (val, stream, options))
    return;

  if (!options->raw)
    {
      int r
	= apply_ext_lang_val_pretty_printer (val, stream, 0, options,
					     current_language);

      if (r)
	return;
    }

  current_language->value_print (val, stream, options);
}

static void
val_print_type_code_flags (struct type *type, struct value *original_value,
			   int embedded_offset, struct ui_file *stream)
{
  const gdb_byte *valaddr = (value_contents_for_printing (original_value)
			     + embedded_offset);
  ULONGEST val = unpack_long (type, valaddr);
  int field, nfields = type->num_fields ();
  struct gdbarch *gdbarch = type->arch ();
  struct type *bool_type = builtin_type (gdbarch)->builtin_bool;

  fputs_filtered ("[", stream);
  for (field = 0; field < nfields; field++)
    {
      if (type->field (field).name ()[0] != '\0')
	{
	  struct type *field_type = type->field (field).type ();

	  if (field_type == bool_type
	      /* We require boolean types here to be one bit wide.  This is a
		 problematic place to notify the user of an internal error
		 though.  Instead just fall through and print the field as an
		 int.  */
	      && TYPE_FIELD_BITSIZE (type, field) == 1)
	    {
	      if (val & ((ULONGEST)1 << TYPE_FIELD_BITPOS (type, field)))
		fprintf_filtered
		  (stream, " %ps",
		   styled_string (variable_name_style.style (),
				  type->field (field).name ()));
	    }
	  else
	    {
	      unsigned field_len = TYPE_FIELD_BITSIZE (type, field);
	      ULONGEST field_val = val >> TYPE_FIELD_BITPOS (type, field);

	      if (field_len < sizeof (ULONGEST) * TARGET_CHAR_BIT)
		field_val &= ((ULONGEST) 1 << field_len) - 1;
	      fprintf_filtered (stream, " %ps=",
				styled_string (variable_name_style.style (),
					       type->field (field).name ()));
	      if (field_type->code () == TYPE_CODE_ENUM)
		generic_val_print_enum_1 (field_type, field_val, stream);
	      else
		print_longest (stream, 'd', 0, field_val);
	    }
	}
    }
  fputs_filtered (" ]", stream);
}

/* See valprint.h.  */

void
value_print_scalar_formatted (struct value *val,
			      const struct value_print_options *options,
			      int size,
			      struct ui_file *stream)
{
  struct type *type = check_typedef (value_type (val));

  gdb_assert (val != NULL);

  /* If we get here with a string format, try again without it.  Go
     all the way back to the language printers, which may call us
     again.  */
  if (options->format == 's')
    {
      struct value_print_options opts = *options;
      opts.format = 0;
      opts.deref_ref = 0;
      common_val_print (val, stream, 0, &opts, current_language);
      return;
    }

  /* value_contents_for_printing fetches all VAL's contents.  They are
     needed to check whether VAL is optimized-out or unavailable
     below.  */
  const gdb_byte *valaddr = value_contents_for_printing (val);

  /* A scalar object that does not have all bits available can't be
     printed, because all bits contribute to its representation.  */
  if (value_bits_any_optimized_out (val, 0,
				    TARGET_CHAR_BIT * TYPE_LENGTH (type)))
    val_print_optimized_out (val, stream);
  else if (!value_bytes_available (val, 0, TYPE_LENGTH (type)))
    val_print_unavailable (stream);
  else
    print_scalar_formatted (valaddr, type, options, size, stream);
}

/* Print a number according to FORMAT which is one of d,u,x,o,b,h,w,g.
   The raison d'etre of this function is to consolidate printing of 
   LONG_LONG's into this one function.  The format chars b,h,w,g are 
   from print_scalar_formatted().  Numbers are printed using C
   format.

   USE_C_FORMAT means to use C format in all cases.  Without it, 
   'o' and 'x' format do not include the standard C radix prefix
   (leading 0 or 0x). 
   
   Hilfinger/2004-09-09: USE_C_FORMAT was originally called USE_LOCAL
   and was intended to request formatting according to the current
   language and would be used for most integers that GDB prints.  The
   exceptional cases were things like protocols where the format of
   the integer is a protocol thing, not a user-visible thing).  The
   parameter remains to preserve the information of what things might
   be printed with language-specific format, should we ever resurrect
   that capability.  */

void
print_longest (struct ui_file *stream, int format, int use_c_format,
	       LONGEST val_long)
{
  const char *val;

  switch (format)
    {
    case 'd':
      val = int_string (val_long, 10, 1, 0, 1); break;
    case 'u':
      val = int_string (val_long, 10, 0, 0, 1); break;
    case 'x':
      val = int_string (val_long, 16, 0, 0, use_c_format); break;
    case 'b':
      val = int_string (val_long, 16, 0, 2, 1); break;
    case 'h':
      val = int_string (val_long, 16, 0, 4, 1); break;
    case 'w':
      val = int_string (val_long, 16, 0, 8, 1); break;
    case 'g':
      val = int_string (val_long, 16, 0, 16, 1); break;
      break;
    case 'o':
      val = int_string (val_long, 8, 0, 0, use_c_format); break;
    default:
      internal_error (__FILE__, __LINE__,
		      _("failed internal consistency check"));
    } 
  fputs_filtered (val, stream);
}

/* This used to be a macro, but I don't think it is called often enough
   to merit such treatment.  */
/* Convert a LONGEST to an int.  This is used in contexts (e.g. number of
   arguments to a function, number in a value history, register number, etc.)
   where the value must not be larger than can fit in an int.  */

int
longest_to_int (LONGEST arg)
{
  /* Let the compiler do the work.  */
  int rtnval = (int) arg;

  /* Check for overflows or underflows.  */
  if (sizeof (LONGEST) > sizeof (int))
    {
      if (rtnval != arg)
	{
	  error (_("Value out of range."));
	}
    }
  return (rtnval);
}

/* Print a floating point value of floating-point type TYPE,
   pointed to in GDB by VALADDR, on STREAM.  */

void
print_floating (const gdb_byte *valaddr, struct type *type,
		struct ui_file *stream)
{
  std::string str = target_float_to_string (valaddr, type);
  fputs_filtered (str.c_str (), stream);
}

void
print_binary_chars (struct ui_file *stream, const gdb_byte *valaddr,
		    unsigned len, enum bfd_endian byte_order, bool zero_pad)
{
  const gdb_byte *p;
  unsigned int i;
  int b;
  bool seen_a_one = false;

  /* Declared "int" so it will be signed.
     This ensures that right shift will shift in zeros.  */

  const int mask = 0x080;

  if (byte_order == BFD_ENDIAN_BIG)
    {
      for (p = valaddr;
	   p < valaddr + len;
	   p++)
	{
	  /* Every byte has 8 binary characters; peel off
	     and print from the MSB end.  */

	  for (i = 0; i < (HOST_CHAR_BIT * sizeof (*p)); i++)
	    {
	      if (*p & (mask >> i))
		b = '1';
	      else
		b = '0';

	      if (zero_pad || seen_a_one || b == '1')
		fputc_filtered (b, stream);
	      if (b == '1')
		seen_a_one = true;
	    }
	}
    }
  else
    {
      for (p = valaddr + len - 1;
	   p >= valaddr;
	   p--)
	{
	  for (i = 0; i < (HOST_CHAR_BIT * sizeof (*p)); i++)
	    {
	      if (*p & (mask >> i))
		b = '1';
	      else
		b = '0';

	      if (zero_pad || seen_a_one || b == '1')
		fputc_filtered (b, stream);
	      if (b == '1')
		seen_a_one = true;
	    }
	}
    }

  /* When not zero-padding, ensure that something is printed when the
     input is 0.  */
  if (!zero_pad && !seen_a_one)
    fputc_filtered ('0', stream);
}

/* A helper for print_octal_chars that emits a single octal digit,
   optionally suppressing it if is zero and updating SEEN_A_ONE.  */

static void
emit_octal_digit (struct ui_file *stream, bool *seen_a_one, int digit)
{
  if (*seen_a_one || digit != 0)
    fprintf_filtered (stream, "%o", digit);
  if (digit != 0)
    *seen_a_one = true;
}

/* VALADDR points to an integer of LEN bytes.
   Print it in octal on stream or format it in buf.  */

void
print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr,
		   unsigned len, enum bfd_endian byte_order)
{
  const gdb_byte *p;
  unsigned char octa1, octa2, octa3, carry;
  int cycle;

  /* Octal is 3 bits, which doesn't fit.  Yuk.  So we have to track
   * the extra bits, which cycle every three bytes:
   *
   * Byte side:       0            1             2          3
   *                         |             |            |            |
   * bit number   123 456 78 | 9 012 345 6 | 78 901 234 | 567 890 12 |
   *
   * Octal side:   0   1   carry  3   4  carry ...
   *
   * Cycle number:    0             1            2
   *
   * But of course we are printing from the high side, so we have to
   * figure out where in the cycle we are so that we end up with no
   * left over bits at the end.
   */
#define BITS_IN_OCTAL 3
#define HIGH_ZERO     0340
#define LOW_ZERO      0034
#define CARRY_ZERO    0003
  static_assert (HIGH_ZERO + LOW_ZERO + CARRY_ZERO == 0xff,
		 "cycle zero constants are wrong");
#define HIGH_ONE      0200
#define MID_ONE       0160
#define LOW_ONE       0016
#define CARRY_ONE     0001
  static_assert (HIGH_ONE + MID_ONE + LOW_ONE + CARRY_ONE == 0xff,
		 "cycle one constants are wrong");
#define HIGH_TWO      0300
#define MID_TWO       0070
#define LOW_TWO       0007
  static_assert (HIGH_TWO + MID_TWO + LOW_TWO == 0xff,
		 "cycle two constants are wrong");

  /* For 32 we start in cycle 2, with two bits and one bit carry;
     for 64 in cycle in cycle 1, with one bit and a two bit carry.  */

  cycle = (len * HOST_CHAR_BIT) % BITS_IN_OCTAL;
  carry = 0;

  fputs_filtered ("0", stream);
  bool seen_a_one = false;
  if (byte_order == BFD_ENDIAN_BIG)
    {
      for (p = valaddr;
	   p < valaddr + len;
	   p++)
	{
	  switch (cycle)
	    {
	    case 0:
	      /* No carry in, carry out two bits.  */

	      octa1 = (HIGH_ZERO & *p) >> 5;
	      octa2 = (LOW_ZERO & *p) >> 2;
	      carry = (CARRY_ZERO & *p);
	      emit_octal_digit (stream, &seen_a_one, octa1);
	      emit_octal_digit (stream, &seen_a_one, octa2);
	      break;

	    case 1:
	      /* Carry in two bits, carry out one bit.  */

	      octa1 = (carry << 1) | ((HIGH_ONE & *p) >> 7);
	      octa2 = (MID_ONE & *p) >> 4;
	      octa3 = (LOW_ONE & *p) >> 1;
	      carry = (CARRY_ONE & *p);
	      emit_octal_digit (stream, &seen_a_one, octa1);
	      emit_octal_digit (stream, &seen_a_one, octa2);
	      emit_octal_digit (stream, &seen_a_one, octa3);
	      break;

	    case 2:
	      /* Carry in one bit, no carry out.  */

	      octa1 = (carry << 2) | ((HIGH_TWO & *p) >> 6);
	      octa2 = (MID_TWO & *p) >> 3;
	      octa3 = (LOW_TWO & *p);
	      carry = 0;
	      emit_octal_digit (stream, &seen_a_one, octa1);
	      emit_octal_digit (stream, &seen_a_one, octa2);
	      emit_octal_digit (stream, &seen_a_one, octa3);
	      break;

	    default:
	      error (_("Internal error in octal conversion;"));
	    }

	  cycle++;
	  cycle = cycle % BITS_IN_OCTAL;
	}
    }
  else
    {
      for (p = valaddr + len - 1;
	   p >= valaddr;
	   p--)
	{
	  switch (cycle)
	    {
	    case 0:
	      /* Carry out, no carry in */

	      octa1 = (HIGH_ZERO & *p) >> 5;
	      octa2 = (LOW_ZERO & *p) >> 2;
	      carry = (CARRY_ZERO & *p);
	      emit_octal_digit (stream, &seen_a_one, octa1);
	      emit_octal_digit (stream, &seen_a_one, octa2);
	      break;

	    case 1:
	      /* Carry in, carry out */

	      octa1 = (carry << 1) | ((HIGH_ONE & *p) >> 7);
	      octa2 = (MID_ONE & *p) >> 4;
	      octa3 = (LOW_ONE & *p) >> 1;
	      carry = (CARRY_ONE & *p);
	      emit_octal_digit (stream, &seen_a_one, octa1);
	      emit_octal_digit (stream, &seen_a_one, octa2);
	      emit_octal_digit (stream, &seen_a_one, octa3);
	      break;

	    case 2:
	      /* Carry in, no carry out */

	      octa1 = (carry << 2) | ((HIGH_TWO & *p) >> 6);
	      octa2 = (MID_TWO & *p) >> 3;
	      octa3 = (LOW_TWO & *p);
	      carry = 0;
	      emit_octal_digit (stream, &seen_a_one, octa1);
	      emit_octal_digit (stream, &seen_a_one, octa2);
	      emit_octal_digit (stream, &seen_a_one, octa3);
	      break;

	    default:
	      error (_("Internal error in octal conversion;"));
	    }

	  cycle++;
	  cycle = cycle % BITS_IN_OCTAL;
	}
    }

}

/* Possibly negate the integer represented by BYTES.  It contains LEN
   bytes in the specified byte order.  If the integer is negative,
   copy it into OUT_VEC, negate it, and return true.  Otherwise, do
   nothing and return false.  */

static bool
maybe_negate_by_bytes (const gdb_byte *bytes, unsigned len,
		       enum bfd_endian byte_order,
		       gdb::byte_vector *out_vec)
{
  gdb_byte sign_byte;
  gdb_assert (len > 0);
  if (byte_order == BFD_ENDIAN_BIG)
    sign_byte = bytes[0];
  else
    sign_byte = bytes[len - 1];
  if ((sign_byte & 0x80) == 0)
    return false;

  out_vec->resize (len);

  /* Compute -x == 1 + ~x.  */
  if (byte_order == BFD_ENDIAN_LITTLE)
    {
      unsigned carry = 1;
      for (unsigned i = 0; i < len; ++i)
	{
	  unsigned tem = (0xff & ~bytes[i]) + carry;
	  (*out_vec)[i] = tem & 0xff;
	  carry = tem / 256;
	}
    }
  else
    {
      unsigned carry = 1;
      for (unsigned i = len; i > 0; --i)
	{
	  unsigned tem = (0xff & ~bytes[i - 1]) + carry;
	  (*out_vec)[i - 1] = tem & 0xff;
	  carry = tem / 256;
	}
    }

  return true;
}

/* VALADDR points to an integer of LEN bytes.
   Print it in decimal on stream or format it in buf.  */

void
print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr,
		     unsigned len, bool is_signed,
		     enum bfd_endian byte_order)
{
#define TEN             10
#define CARRY_OUT(  x ) ((x) / TEN)	/* extend char to int */
#define CARRY_LEFT( x ) ((x) % TEN)
#define SHIFT( x )      ((x) << 4)
#define LOW_NIBBLE(  x ) ( (x) & 0x00F)
#define HIGH_NIBBLE( x ) (((x) & 0x0F0) >> 4)

  const gdb_byte *p;
  int carry;
  int decimal_len;
  int i, j, decimal_digits;
  int dummy;
  int flip;

  gdb::byte_vector negated_bytes;
  if (is_signed
      && maybe_negate_by_bytes (valaddr, len, byte_order, &negated_bytes))
    {
      fputs_filtered ("-", stream);
      valaddr = negated_bytes.data ();
    }

  /* Base-ten number is less than twice as many digits
     as the base 16 number, which is 2 digits per byte.  */

  decimal_len = len * 2 * 2;
  std::vector<unsigned char> digits (decimal_len, 0);

  /* Ok, we have an unknown number of bytes of data to be printed in
   * decimal.
   *
   * Given a hex number (in nibbles) as XYZ, we start by taking X and
   * decimalizing it as "x1 x2" in two decimal nibbles.  Then we multiply
   * the nibbles by 16, add Y and re-decimalize.  Repeat with Z.
   *
   * The trick is that "digits" holds a base-10 number, but sometimes
   * the individual digits are > 10.
   *
   * Outer loop is per nibble (hex digit) of input, from MSD end to
   * LSD end.
   */
  decimal_digits = 0;		/* Number of decimal digits so far */
  p = (byte_order == BFD_ENDIAN_BIG) ? valaddr : valaddr + len - 1;
  flip = 0;
  while ((byte_order == BFD_ENDIAN_BIG) ? (p < valaddr + len) : (p >= valaddr))
    {
      /*
       * Multiply current base-ten number by 16 in place.
       * Each digit was between 0 and 9, now is between
       * 0 and 144.
       */
      for (j = 0; j < decimal_digits; j++)
	{
	  digits[j] = SHIFT (digits[j]);
	}

      /* Take the next nibble off the input and add it to what
       * we've got in the LSB position.  Bottom 'digit' is now
       * between 0 and 159.
       *
       * "flip" is used to run this loop twice for each byte.
       */
      if (flip == 0)
	{
	  /* Take top nibble.  */

	  digits[0] += HIGH_NIBBLE (*p);
	  flip = 1;
	}
      else
	{
	  /* Take low nibble and bump our pointer "p".  */

	  digits[0] += LOW_NIBBLE (*p);
	  if (byte_order == BFD_ENDIAN_BIG)
	    p++;
	  else
	    p--;
	  flip = 0;
	}

      /* Re-decimalize.  We have to do this often enough
       * that we don't overflow, but once per nibble is
       * overkill.  Easier this way, though.  Note that the
       * carry is often larger than 10 (e.g. max initial
       * carry out of lowest nibble is 15, could bubble all
       * the way up greater than 10).  So we have to do
       * the carrying beyond the last current digit.
       */
      carry = 0;
      for (j = 0; j < decimal_len - 1; j++)
	{
	  digits[j] += carry;

	  /* "/" won't handle an unsigned char with
	   * a value that if signed would be negative.
	   * So extend to longword int via "dummy".
	   */
	  dummy = digits[j];
	  carry = CARRY_OUT (dummy);
	  digits[j] = CARRY_LEFT (dummy);

	  if (j >= decimal_digits && carry == 0)
	    {
	      /*
	       * All higher digits are 0 and we
	       * no longer have a carry.
	       *
	       * Note: "j" is 0-based, "decimal_digits" is
	       *       1-based.
	       */
	      decimal_digits = j + 1;
	      break;
	    }
	}
    }

  /* Ok, now "digits" is the decimal representation, with
     the "decimal_digits" actual digits.  Print!  */

  for (i = decimal_digits - 1; i > 0 && digits[i] == 0; --i)
    ;

  for (; i >= 0; i--)
    {
      fprintf_filtered (stream, "%1d", digits[i]);
    }
}

/* VALADDR points to an integer of LEN bytes.  Print it in hex on stream.  */

void
print_hex_chars (struct ui_file *stream, const gdb_byte *valaddr,
		 unsigned len, enum bfd_endian byte_order,
		 bool zero_pad)
{
  const gdb_byte *p;

  fputs_filtered ("0x", stream);
  if (byte_order == BFD_ENDIAN_BIG)
    {
      p = valaddr;

      if (!zero_pad)
	{
	  /* Strip leading 0 bytes, but be sure to leave at least a
	     single byte at the end.  */
	  for (; p < valaddr + len - 1 && !*p; ++p)
	    ;
	}

      const gdb_byte *first = p;
      for (;
	   p < valaddr + len;
	   p++)
	{
	  /* When not zero-padding, use a different format for the
	     very first byte printed.  */
	  if (!zero_pad && p == first)
	    fprintf_filtered (stream, "%x", *p);
	  else
	    fprintf_filtered (stream, "%02x", *p);
	}
    }
  else
    {
      p = valaddr + len - 1;

      if (!zero_pad)
	{
	  /* Strip leading 0 bytes, but be sure to leave at least a
	     single byte at the end.  */
	  for (; p >= valaddr + 1 && !*p; --p)
	    ;
	}

      const gdb_byte *first = p;
      for (;
	   p >= valaddr;
	   p--)
	{
	  /* When not zero-padding, use a different format for the
	     very first byte printed.  */
	  if (!zero_pad && p == first)
	    fprintf_filtered (stream, "%x", *p);
	  else
	    fprintf_filtered (stream, "%02x", *p);
	}
    }
}

/* Print function pointer with inferior address ADDRESS onto stdio
   stream STREAM.  */

void
print_function_pointer_address (const struct value_print_options *options,
				struct gdbarch *gdbarch,
				CORE_ADDR address,
				struct ui_file *stream)
{
  CORE_ADDR func_addr = gdbarch_convert_from_func_ptr_addr
    (gdbarch, address, current_inferior ()->top_target ());

  /* If the function pointer is represented by a description, print
     the address of the description.  */
  if (options->addressprint && func_addr != address)
    {
      fputs_filtered ("@", stream);
      fputs_filtered (paddress (gdbarch, address), stream);
      fputs_filtered (": ", stream);
    }
  print_address_demangle (options, gdbarch, func_addr, stream, demangle);
}


/* Print on STREAM using the given OPTIONS the index for the element
   at INDEX of an array whose index type is INDEX_TYPE.  */
    
void  
maybe_print_array_index (struct type *index_type, LONGEST index,
			 struct ui_file *stream,
			 const struct value_print_options *options)
{
  if (!options->print_array_indexes)
    return; 

  current_language->print_array_index (index_type, index, stream, options);
}

/* See valprint.h.  */

void
value_print_array_elements (struct value *val, struct ui_file *stream,
			    int recurse,
			    const struct value_print_options *options,
			    unsigned int i)
{
  unsigned int things_printed = 0;
  unsigned len;
  struct type *elttype, *index_type;
  unsigned eltlen;
  /* Position of the array element we are examining to see
     whether it is repeated.  */
  unsigned int rep1;
  /* Number of repetitions we have detected so far.  */
  unsigned int reps;
  LONGEST low_bound, high_bound;

  struct type *type = check_typedef (value_type (val));

  elttype = TYPE_TARGET_TYPE (type);
  eltlen = type_length_units (check_typedef (elttype));
  index_type = type->index_type ();
  if (index_type->code () == TYPE_CODE_RANGE)
    index_type = TYPE_TARGET_TYPE (index_type);

  if (get_array_bounds (type, &low_bound, &high_bound))
    {
      /* The array length should normally be HIGH_BOUND - LOW_BOUND +
	 1.  But we have to be a little extra careful, because some
	 languages such as Ada allow LOW_BOUND to be greater than
	 HIGH_BOUND for empty arrays.  In that situation, the array
	 length is just zero, not negative!  */
      if (low_bound > high_bound)
	len = 0;
      else
	len = high_bound - low_bound + 1;
    }
  else
    {
      warning (_("unable to get bounds of array, assuming null array"));
      low_bound = 0;
      len = 0;
    }

  annotate_array_section_begin (i, elttype);

  for (; i < len && things_printed < options->print_max; i++)
    {
      scoped_value_mark free_values;

      if (i != 0)
	{
	  if (options->prettyformat_arrays)
	    {
	      fprintf_filtered (stream, ",\n");
	      print_spaces_filtered (2 + 2 * recurse, stream);
	    }
	  else
	    fprintf_filtered (stream, ", ");
	}
      else if (options->prettyformat_arrays)
	{
	  fprintf_filtered (stream, "\n");
	  print_spaces_filtered (2 + 2 * recurse, stream);
	}
      wrap_here (n_spaces (2 + 2 * recurse));
      maybe_print_array_index (index_type, i + low_bound,
			       stream, options);

      rep1 = i + 1;
      reps = 1;
      /* Only check for reps if repeat_count_threshold is not set to
	 UINT_MAX (unlimited).  */
      if (options->repeat_count_threshold < UINT_MAX)
	{
	  while (rep1 < len
		 && value_contents_eq (val, i * eltlen,
				       val, rep1 * eltlen,
				       eltlen))
	    {
	      ++reps;
	      ++rep1;
	    }
	}

      struct value *element = value_from_component (val, elttype, eltlen * i);
      common_val_print (element, stream, recurse + 1, options,
			current_language);

      if (reps > options->repeat_count_threshold)
	{
	  annotate_elt_rep (reps);
	  fprintf_filtered (stream, " %p[<repeats %u times>%p]",
			    metadata_style.style ().ptr (), reps, nullptr);
	  annotate_elt_rep_end ();

	  i = rep1 - 1;
	  things_printed += options->repeat_count_threshold;
	}
      else
	{
	  annotate_elt ();
	  things_printed++;
	}
    }
  annotate_array_section_end ();
  if (i < len)
    fprintf_filtered (stream, "...");
  if (options->prettyformat_arrays)
    {
      fprintf_filtered (stream, "\n");
      print_spaces_filtered (2 * recurse, stream);
    }
}

/* Read LEN bytes of target memory at address MEMADDR, placing the
   results in GDB's memory at MYADDR.  Returns a count of the bytes
   actually read, and optionally a target_xfer_status value in the
   location pointed to by ERRPTR if ERRPTR is non-null.  */

/* FIXME: cagney/1999-10-14: Only used by val_print_string.  Can this
   function be eliminated.  */

static int
partial_memory_read (CORE_ADDR memaddr, gdb_byte *myaddr,
		     int len, int *errptr)
{
  int nread;			/* Number of bytes actually read.  */
  int errcode;			/* Error from last read.  */

  /* First try a complete read.  */
  errcode = target_read_memory (memaddr, myaddr, len);
  if (errcode == 0)
    {
      /* Got it all.  */
      nread = len;
    }
  else
    {
      /* Loop, reading one byte at a time until we get as much as we can.  */
      for (errcode = 0, nread = 0; len > 0 && errcode == 0; nread++, len--)
	{
	  errcode = target_read_memory (memaddr++, myaddr++, 1);
	}
      /* If an error, the last read was unsuccessful, so adjust count.  */
      if (errcode != 0)
	{
	  nread--;
	}
    }
  if (errptr != NULL)
    {
      *errptr = errcode;
    }
  return (nread);
}

/* Read a string from the inferior, at ADDR, with LEN characters of
   WIDTH bytes each.  Fetch at most FETCHLIMIT characters.  BUFFER
   will be set to a newly allocated buffer containing the string, and
   BYTES_READ will be set to the number of bytes read.  Returns 0 on
   success, or a target_xfer_status on failure.

   If LEN > 0, reads the lesser of LEN or FETCHLIMIT characters
   (including eventual NULs in the middle or end of the string).

   If LEN is -1, stops at the first null character (not necessarily
   the first null byte) up to a maximum of FETCHLIMIT characters.  Set
   FETCHLIMIT to UINT_MAX to read as many characters as possible from
   the string.

   Unless an exception is thrown, BUFFER will always be allocated, even on
   failure.  In this case, some characters might have been read before the
   failure happened.  Check BYTES_READ to recognize this situation.  */

int
read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit,
	     enum bfd_endian byte_order, gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
	     int *bytes_read)
{
  int errcode;			/* Errno returned from bad reads.  */
  unsigned int nfetch;		/* Chars to fetch / chars fetched.  */
  gdb_byte *bufptr;		/* Pointer to next available byte in
				   buffer.  */

  /* Loop until we either have all the characters, or we encounter
     some error, such as bumping into the end of the address space.  */

  buffer->reset (nullptr);

  if (len > 0)
    {
      /* We want fetchlimit chars, so we might as well read them all in
	 one operation.  */
      unsigned int fetchlen = std::min ((unsigned) len, fetchlimit);

      buffer->reset ((gdb_byte *) xmalloc (fetchlen * width));
      bufptr = buffer->get ();

      nfetch = partial_memory_read (addr, bufptr, fetchlen * width, &errcode)
	/ width;
      addr += nfetch * width;
      bufptr += nfetch * width;
    }
  else if (len == -1)
    {
      unsigned long bufsize = 0;
      unsigned int chunksize;	/* Size of each fetch, in chars.  */
      int found_nul;		/* Non-zero if we found the nul char.  */
      gdb_byte *limit;		/* First location past end of fetch buffer.  */

      found_nul = 0;
      /* We are looking for a NUL terminator to end the fetching, so we
	 might as well read in blocks that are large enough to be efficient,
	 but not so large as to be slow if fetchlimit happens to be large.
	 So we choose the minimum of 8 and fetchlimit.  We used to use 200
	 instead of 8 but 200 is way too big for remote debugging over a
	  serial line.  */
      chunksize = std::min (8u, fetchlimit);

      do
	{
	  QUIT;
	  nfetch = std::min ((unsigned long) chunksize, fetchlimit - bufsize);

	  if (*buffer == NULL)
	    buffer->reset ((gdb_byte *) xmalloc (nfetch * width));
	  else
	    buffer->reset ((gdb_byte *) xrealloc (buffer->release (),
						  (nfetch + bufsize) * width));

	  bufptr = buffer->get () + bufsize * width;
	  bufsize += nfetch;

	  /* Read as much as we can.  */
	  nfetch = partial_memory_read (addr, bufptr, nfetch * width, &errcode)
		    / width;

	  /* Scan this chunk for the null character that terminates the string
	     to print.  If found, we don't need to fetch any more.  Note
	     that bufptr is explicitly left pointing at the next character
	     after the null character, or at the next character after the end
	     of the buffer.  */

	  limit = bufptr + nfetch * width;
	  while (bufptr < limit)
	    {
	      unsigned long c;

	      c = extract_unsigned_integer (bufptr, width, byte_order);
	      addr += width;
	      bufptr += width;
	      if (c == 0)
		{
		  /* We don't care about any error which happened after
		     the NUL terminator.  */
		  errcode = 0;
		  found_nul = 1;
		  break;
		}
	    }
	}
      while (errcode == 0	/* no error */
	     && bufptr - buffer->get () < fetchlimit * width	/* no overrun */
	     && !found_nul);	/* haven't found NUL yet */
    }
  else
    {				/* Length of string is really 0!  */
      /* We always allocate *buffer.  */
      buffer->reset ((gdb_byte *) xmalloc (1));
      bufptr = buffer->get ();
      errcode = 0;
    }

  /* bufptr and addr now point immediately beyond the last byte which we
     consider part of the string (including a '\0' which ends the string).  */
  *bytes_read = bufptr - buffer->get ();

  QUIT;

  return errcode;
}

/* Return true if print_wchar can display W without resorting to a
   numeric escape, false otherwise.  */

static int
wchar_printable (gdb_wchar_t w)
{
  return (gdb_iswprint (w)
	  || w == LCST ('\a') || w == LCST ('\b')
	  || w == LCST ('\f') || w == LCST ('\n')
	  || w == LCST ('\r') || w == LCST ('\t')
	  || w == LCST ('\v'));
}

/* A helper function that converts the contents of STRING to wide
   characters and then appends them to OUTPUT.  */

static void
append_string_as_wide (const char *string,
		       struct obstack *output)
{
  for (; *string; ++string)
    {
      gdb_wchar_t w = gdb_btowc (*string);
      obstack_grow (output, &w, sizeof (gdb_wchar_t));
    }
}

/* Print a wide character W to OUTPUT.  ORIG is a pointer to the
   original (target) bytes representing the character, ORIG_LEN is the
   number of valid bytes.  WIDTH is the number of bytes in a base
   characters of the type.  OUTPUT is an obstack to which wide
   characters are emitted.  QUOTER is a (narrow) character indicating
   the style of quotes surrounding the character to be printed.
   NEED_ESCAPE is an in/out flag which is used to track numeric
   escapes across calls.  */

static void
print_wchar (gdb_wint_t w, const gdb_byte *orig,
	     int orig_len, int width,
	     enum bfd_endian byte_order,
	     struct obstack *output,
	     int quoter, int *need_escapep)
{
  int need_escape = *need_escapep;

  *need_escapep = 0;

  /* iswprint implementation on Windows returns 1 for tab character.
     In order to avoid different printout on this host, we explicitly
     use wchar_printable function.  */
  switch (w)
    {
      case LCST ('\a'):
	obstack_grow_wstr (output, LCST ("\\a"));
	break;
      case LCST ('\b'):
	obstack_grow_wstr (output, LCST ("\\b"));
	break;
      case LCST ('\f'):
	obstack_grow_wstr (output, LCST ("\\f"));
	break;
      case LCST ('\n'):
	obstack_grow_wstr (output, LCST ("\\n"));
	break;
      case LCST ('\r'):
	obstack_grow_wstr (output, LCST ("\\r"));
	break;
      case LCST ('\t'):
	obstack_grow_wstr (output, LCST ("\\t"));
	break;
      case LCST ('\v'):
	obstack_grow_wstr (output, LCST ("\\v"));
	break;
      default:
	{
	  if (wchar_printable (w) && (!need_escape || (!gdb_iswdigit (w)
						       && w != LCST ('8')
						       && w != LCST ('9'))))
	    {
	      gdb_wchar_t wchar = w;

	      if (w == gdb_btowc (quoter) || w == LCST ('\\'))
		obstack_grow_wstr (output, LCST ("\\"));
	      obstack_grow (output, &wchar, sizeof (gdb_wchar_t));
	    }
	  else
	    {
	      int i;

	      for (i = 0; i + width <= orig_len; i += width)
		{
		  char octal[30];
		  ULONGEST value;

		  value = extract_unsigned_integer (&orig[i], width,
						  byte_order);
		  /* If the value fits in 3 octal digits, print it that
		     way.  Otherwise, print it as a hex escape.  */
		  if (value <= 0777)
		    xsnprintf (octal, sizeof (octal), "\\%.3o",
			       (int) (value & 0777));
		  else
		    xsnprintf (octal, sizeof (octal), "\\x%lx", (long) value);
		  append_string_as_wide (octal, output);
		}
	      /* If we somehow have extra bytes, print them now.  */
	      while (i < orig_len)
		{
		  char octal[5];

		  xsnprintf (octal, sizeof (octal), "\\%.3o", orig[i] & 0xff);
		  append_string_as_wide (octal, output);
		  ++i;
		}

	      *need_escapep = 1;
	    }
	  break;
	}
    }
}

/* Print the character C on STREAM as part of the contents of a
   literal string whose delimiter is QUOTER.  ENCODING names the
   encoding of C.  */

void
generic_emit_char (int c, struct type *type, struct ui_file *stream,
		   int quoter, const char *encoding)
{
  enum bfd_endian byte_order
    = type_byte_order (type);
  gdb_byte *c_buf;
  int need_escape = 0;

  c_buf = (gdb_byte *) alloca (TYPE_LENGTH (type));
  pack_long (c_buf, type, c);

  wchar_iterator iter (c_buf, TYPE_LENGTH (type), encoding, TYPE_LENGTH (type));

  /* This holds the printable form of the wchar_t data.  */
  auto_obstack wchar_buf;

  while (1)
    {
      int num_chars;
      gdb_wchar_t *chars;
      const gdb_byte *buf;
      size_t buflen;
      int print_escape = 1;
      enum wchar_iterate_result result;

      num_chars = iter.iterate (&result, &chars, &buf, &buflen);
      if (num_chars < 0)
	break;
      if (num_chars > 0)
	{
	  /* If all characters are printable, print them.  Otherwise,
	     we're going to have to print an escape sequence.  We
	     check all characters because we want to print the target
	     bytes in the escape sequence, and we don't know character
	     boundaries there.  */
	  int i;

	  print_escape = 0;
	  for (i = 0; i < num_chars; ++i)
	    if (!wchar_printable (chars[i]))
	      {
		print_escape = 1;
		break;
	      }

	  if (!print_escape)
	    {
	      for (i = 0; i < num_chars; ++i)
		print_wchar (chars[i], buf, buflen,
			     TYPE_LENGTH (type), byte_order,
			     &wchar_buf, quoter, &need_escape);
	    }
	}

      /* This handles the NUM_CHARS == 0 case as well.  */
      if (print_escape)
	print_wchar (gdb_WEOF, buf, buflen, TYPE_LENGTH (type),
		     byte_order, &wchar_buf, quoter, &need_escape);
    }

  /* The output in the host encoding.  */
  auto_obstack output;

  convert_between_encodings (INTERMEDIATE_ENCODING, host_charset (),
			     (gdb_byte *) obstack_base (&wchar_buf),
			     obstack_object_size (&wchar_buf),
			     sizeof (gdb_wchar_t), &output, translit_char);
  obstack_1grow (&output, '\0');

  fputs_filtered ((const char *) obstack_base (&output), stream);
}

/* Return the repeat count of the next character/byte in ITER,
   storing the result in VEC.  */

static int
count_next_character (wchar_iterator *iter,
		      std::vector<converted_character> *vec)
{
  struct converted_character *current;

  if (vec->empty ())
    {
      struct converted_character tmp;
      gdb_wchar_t *chars;

      tmp.num_chars
	= iter->iterate (&tmp.result, &chars, &tmp.buf, &tmp.buflen);
      if (tmp.num_chars > 0)
	{
	  gdb_assert (tmp.num_chars < MAX_WCHARS);
	  memcpy (tmp.chars, chars, tmp.num_chars * sizeof (gdb_wchar_t));
	}
      vec->push_back (tmp);
    }

  current = &vec->back ();

  /* Count repeated characters or bytes.  */
  current->repeat_count = 1;
  if (current->num_chars == -1)
    {
      /* EOF  */
      return -1;
    }
  else
    {
      gdb_wchar_t *chars;
      struct converted_character d;
      int repeat;

      d.repeat_count = 0;

      while (1)
	{
	  /* Get the next character.  */
	  d.num_chars = iter->iterate (&d.result, &chars, &d.buf, &d.buflen);

	  /* If a character was successfully converted, save the character
	     into the converted character.  */
	  if (d.num_chars > 0)
	    {
	      gdb_assert (d.num_chars < MAX_WCHARS);
	      memcpy (d.chars, chars, WCHAR_BUFLEN (d.num_chars));
	    }

	  /* Determine if the current character is the same as this
	     new character.  */
	  if (d.num_chars == current->num_chars && d.result == current->result)
	    {
	      /* There are two cases to consider:

		 1) Equality of converted character (num_chars > 0)
		 2) Equality of non-converted character (num_chars == 0)  */
	      if ((current->num_chars > 0
		   && memcmp (current->chars, d.chars,
			      WCHAR_BUFLEN (current->num_chars)) == 0)
		  || (current->num_chars == 0
		      && current->buflen == d.buflen
		      && memcmp (current->buf, d.buf, current->buflen) == 0))
		++current->repeat_count;
	      else
		break;
	    }
	  else
	    break;
	}

      /* Push this next converted character onto the result vector.  */
      repeat = current->repeat_count;
      vec->push_back (d);
      return repeat;
    }
}

/* Print the characters in CHARS to the OBSTACK.  QUOTE_CHAR is the quote
   character to use with string output.  WIDTH is the size of the output
   character type.  BYTE_ORDER is the target byte order.  OPTIONS
   is the user's print options.  */

static void
print_converted_chars_to_obstack (struct obstack *obstack,
				  const std::vector<converted_character> &chars,
				  int quote_char, int width,
				  enum bfd_endian byte_order,
				  const struct value_print_options *options)
{
  unsigned int idx;
  const converted_character *elem;
  enum {START, SINGLE, REPEAT, INCOMPLETE, FINISH} state, last;
  gdb_wchar_t wide_quote_char = gdb_btowc (quote_char);
  int need_escape = 0;

  /* Set the start state.  */
  idx = 0;
  last = state = START;
  elem = NULL;

  while (1)
    {
      switch (state)
	{
	case START:
	  /* Nothing to do.  */
	  break;

	case SINGLE:
	  {
	    int j;

	    /* We are outputting a single character
	       (< options->repeat_count_threshold).  */

	    if (last != SINGLE)
	      {
		/* We were outputting some other type of content, so we
		   must output and a comma and a quote.  */
		if (last != START)
		  obstack_grow_wstr (obstack, LCST (", "));
		obstack_grow (obstack, &wide_quote_char, sizeof (gdb_wchar_t));
	      }
	    /* Output the character.  */
	    for (j = 0; j < elem->repeat_count; ++j)
	      {
		if (elem->result == wchar_iterate_ok)
		  print_wchar (elem->chars[0], elem->buf, elem->buflen, width,
			       byte_order, obstack, quote_char, &need_escape);
		else
		  print_wchar (gdb_WEOF, elem->buf, elem->buflen, width,
			       byte_order, obstack, quote_char, &need_escape);
	      }
	  }
	  break;

	case REPEAT:
	  {
	    int j;

	    /* We are outputting a character with a repeat count
	       greater than options->repeat_count_threshold.  */

	    if (last == SINGLE)
	      {
		/* We were outputting a single string.  Terminate the
		   string.  */
		obstack_grow (obstack, &wide_quote_char, sizeof (gdb_wchar_t));
	      }
	    if (last != START)
	      obstack_grow_wstr (obstack, LCST (", "));

	    /* Output the character and repeat string.  */
	    obstack_grow_wstr (obstack, LCST ("'"));
	    if (elem->result == wchar_iterate_ok)
	      print_wchar (elem->chars[0], elem->buf, elem->buflen, width,
			   byte_order, obstack, quote_char, &need_escape);
	    else
	      print_wchar (gdb_WEOF, elem->buf, elem->buflen, width,
			   byte_order, obstack, quote_char, &need_escape);
	    obstack_grow_wstr (obstack, LCST ("'"));
	    std::string s = string_printf (_(" <repeats %u times>"),
					   elem->repeat_count);
	    for (j = 0; s[j]; ++j)
	      {
		gdb_wchar_t w = gdb_btowc (s[j]);
		obstack_grow (obstack, &w, sizeof (gdb_wchar_t));
	      }
	  }
	  break;

	case INCOMPLETE:
	  /* We are outputting an incomplete sequence.  */
	  if (last == SINGLE)
	    {
	      /* If we were outputting a string of SINGLE characters,
		 terminate the quote.  */
	      obstack_grow (obstack, &wide_quote_char, sizeof (gdb_wchar_t));
	    }
	  if (last != START)
	    obstack_grow_wstr (obstack, LCST (", "));

	  /* Output the incomplete sequence string.  */
	  obstack_grow_wstr (obstack, LCST ("<incomplete sequence "));
	  print_wchar (gdb_WEOF, elem->buf, elem->buflen, width, byte_order,
		       obstack, 0, &need_escape);
	  obstack_grow_wstr (obstack, LCST (">"));

	  /* We do not attempt to output anything after this.  */
	  state = FINISH;
	  break;

	case FINISH:
	  /* All done.  If we were outputting a string of SINGLE
	     characters, the string must be terminated.  Otherwise,
	     REPEAT and INCOMPLETE are always left properly terminated.  */
	  if (last == SINGLE)
	    obstack_grow (obstack, &wide_quote_char, sizeof (gdb_wchar_t));

	  return;
	}

      /* Get the next element and state.  */
      last = state;
      if (state != FINISH)
	{
	  elem = &chars[idx++];
	  switch (elem->result)
	    {
	    case wchar_iterate_ok:
	    case wchar_iterate_invalid:
	      if (elem->repeat_count > options->repeat_count_threshold)
		state = REPEAT;
	      else
		state = SINGLE;
	      break;

	    case wchar_iterate_incomplete:
	      state = INCOMPLETE;
	      break;

	    case wchar_iterate_eof:
	      state = FINISH;
	      break;
	    }
	}
    }
}

/* Print the character string STRING, printing at most LENGTH
   characters.  LENGTH is -1 if the string is nul terminated.  TYPE is
   the type of each character.  OPTIONS holds the printing options;
   printing stops early if the number hits print_max; repeat counts
   are printed as appropriate.  Print ellipses at the end if we had to
   stop before printing LENGTH characters, or if FORCE_ELLIPSES.
   QUOTE_CHAR is the character to print at each end of the string.  If
   C_STYLE_TERMINATOR is true, and the last character is 0, then it is
   omitted.  */

void
generic_printstr (struct ui_file *stream, struct type *type, 
		  const gdb_byte *string, unsigned int length, 
		  const char *encoding, int force_ellipses,
		  int quote_char, int c_style_terminator,
		  const struct value_print_options *options)
{
  enum bfd_endian byte_order = type_byte_order (type);
  unsigned int i;
  int width = TYPE_LENGTH (type);
  int finished = 0;
  struct converted_character *last;

  if (length == -1)
    {
      unsigned long current_char = 1;

      for (i = 0; current_char; ++i)
	{
	  QUIT;
	  current_char = extract_unsigned_integer (string + i * width,
						   width, byte_order);
	}
      length = i;
    }

  /* If the string was not truncated due to `set print elements', and
     the last byte of it is a null, we don't print that, in
     traditional C style.  */
  if (c_style_terminator
      && !force_ellipses
      && length > 0
      && (extract_unsigned_integer (string + (length - 1) * width,
				    width, byte_order) == 0))
    length--;

  if (length == 0)
    {
      fputs_filtered ("\"\"", stream);
      return;
    }

  /* Arrange to iterate over the characters, in wchar_t form.  */
  wchar_iterator iter (string, length * width, encoding, width);
  std::vector<converted_character> converted_chars;

  /* Convert characters until the string is over or the maximum
     number of printed characters has been reached.  */
  i = 0;
  while (i < options->print_max)
    {
      int r;

      QUIT;

      /* Grab the next character and repeat count.  */
      r = count_next_character (&iter, &converted_chars);

      /* If less than zero, the end of the input string was reached.  */
      if (r < 0)
	break;

      /* Otherwise, add the count to the total print count and get
	 the next character.  */
      i += r;
    }

  /* Get the last element and determine if the entire string was
     processed.  */
  last = &converted_chars.back ();
  finished = (last->result == wchar_iterate_eof);

  /* Ensure that CONVERTED_CHARS is terminated.  */
  last->result = wchar_iterate_eof;

  /* WCHAR_BUF is the obstack we use to represent the string in
     wchar_t form.  */
  auto_obstack wchar_buf;

  /* Print the output string to the obstack.  */
  print_converted_chars_to_obstack (&wchar_buf, converted_chars, quote_char,
				    width, byte_order, options);

  if (force_ellipses || !finished)
    obstack_grow_wstr (&wchar_buf, LCST ("..."));

  /* OUTPUT is where we collect `char's for printing.  */
  auto_obstack output;

  convert_between_encodings (INTERMEDIATE_ENCODING, host_charset (),
			     (gdb_byte *) obstack_base (&wchar_buf),
			     obstack_object_size (&wchar_buf),
			     sizeof (gdb_wchar_t), &output, translit_char);
  obstack_1grow (&output, '\0');

  fputs_filtered ((const char *) obstack_base (&output), stream);
}

/* Print a string from the inferior, starting at ADDR and printing up to LEN
   characters, of WIDTH bytes a piece, to STREAM.  If LEN is -1, printing
   stops at the first null byte, otherwise printing proceeds (including null
   bytes) until either print_max or LEN characters have been printed,
   whichever is smaller.  ENCODING is the name of the string's
   encoding.  It can be NULL, in which case the target encoding is
   assumed.  */

int
val_print_string (struct type *elttype, const char *encoding,
		  CORE_ADDR addr, int len,
		  struct ui_file *stream,
		  const struct value_print_options *options)
{
  int force_ellipsis = 0;	/* Force ellipsis to be printed if nonzero.  */
  int err;			/* Non-zero if we got a bad read.  */
  int found_nul;		/* Non-zero if we found the nul char.  */
  unsigned int fetchlimit;	/* Maximum number of chars to print.  */
  int bytes_read;
  gdb::unique_xmalloc_ptr<gdb_byte> buffer;	/* Dynamically growable fetch buffer.  */
  struct gdbarch *gdbarch = elttype->arch ();
  enum bfd_endian byte_order = type_byte_order (elttype);
  int width = TYPE_LENGTH (elttype);

  /* First we need to figure out the limit on the number of characters we are
     going to attempt to fetch and print.  This is actually pretty simple.  If
     LEN >= zero, then the limit is the minimum of LEN and print_max.  If
     LEN is -1, then the limit is print_max.  This is true regardless of
     whether print_max is zero, UINT_MAX (unlimited), or something in between,
     because finding the null byte (or available memory) is what actually
     limits the fetch.  */

  fetchlimit = (len == -1 ? options->print_max : std::min ((unsigned) len,
							   options->print_max));

  err = read_string (addr, len, width, fetchlimit, byte_order,
		     &buffer, &bytes_read);

  addr += bytes_read;

  /* We now have either successfully filled the buffer to fetchlimit,
     or terminated early due to an error or finding a null char when
     LEN is -1.  */

  /* Determine found_nul by looking at the last character read.  */
  found_nul = 0;
  if (bytes_read >= width)
    found_nul = extract_unsigned_integer (buffer.get () + bytes_read - width,
					  width, byte_order) == 0;
  if (len == -1 && !found_nul)
    {
      gdb_byte *peekbuf;

      /* We didn't find a NUL terminator we were looking for.  Attempt
	 to peek at the next character.  If not successful, or it is not
	 a null byte, then force ellipsis to be printed.  */

      peekbuf = (gdb_byte *) alloca (width);

      if (target_read_memory (addr, peekbuf, width) == 0
	  && extract_unsigned_integer (peekbuf, width, byte_order) != 0)
	force_ellipsis = 1;
    }
  else if ((len >= 0 && err != 0) || (len > bytes_read / width))
    {
      /* Getting an error when we have a requested length, or fetching less
	 than the number of characters actually requested, always make us
	 print ellipsis.  */
      force_ellipsis = 1;
    }

  /* If we get an error before fetching anything, don't print a string.
     But if we fetch something and then get an error, print the string
     and then the error message.  */
  if (err == 0 || bytes_read > 0)
    {
      LA_PRINT_STRING (stream, elttype, buffer.get (), bytes_read / width,
		       encoding, force_ellipsis, options);
    }

  if (err != 0)
    {
      std::string str = memory_error_message (TARGET_XFER_E_IO, gdbarch, addr);

      fprintf_filtered (stream, _("<error: %ps>"),
			styled_string (metadata_style.style (),
				       str.c_str ()));
    }

  return (bytes_read / width);
}

/* Handle 'show print max-depth'.  */

static void
show_print_max_depth (struct ui_file *file, int from_tty,
		      struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("Maximum print depth is %s.\n"), value);
}


/* The 'set input-radix' command writes to this auxiliary variable.
   If the requested radix is valid, INPUT_RADIX is updated; otherwise,
   it is left unchanged.  */

static unsigned input_radix_1 = 10;

/* Validate an input or output radix setting, and make sure the user
   knows what they really did here.  Radix setting is confusing, e.g.
   setting the input radix to "10" never changes it!  */

static void
set_input_radix (const char *args, int from_tty, struct cmd_list_element *c)
{
  set_input_radix_1 (from_tty, input_radix_1);
}

static void
set_input_radix_1 (int from_tty, unsigned radix)
{
  /* We don't currently disallow any input radix except 0 or 1, which don't
     make any mathematical sense.  In theory, we can deal with any input
     radix greater than 1, even if we don't have unique digits for every
     value from 0 to radix-1, but in practice we lose on large radix values.
     We should either fix the lossage or restrict the radix range more.
     (FIXME).  */

  if (radix < 2)
    {
      input_radix_1 = input_radix;
      error (_("Nonsense input radix ``decimal %u''; input radix unchanged."),
	     radix);
    }
  input_radix_1 = input_radix = radix;
  if (from_tty)
    {
      printf_filtered (_("Input radix now set to "
			 "decimal %u, hex %x, octal %o.\n"),
		       radix, radix, radix);
    }
}

/* The 'set output-radix' command writes to this auxiliary variable.
   If the requested radix is valid, OUTPUT_RADIX is updated,
   otherwise, it is left unchanged.  */

static unsigned output_radix_1 = 10;

static void
set_output_radix (const char *args, int from_tty, struct cmd_list_element *c)
{
  set_output_radix_1 (from_tty, output_radix_1);
}

static void
set_output_radix_1 (int from_tty, unsigned radix)
{
  /* Validate the radix and disallow ones that we aren't prepared to
     handle correctly, leaving the radix unchanged.  */
  switch (radix)
    {
    case 16:
      user_print_options.output_format = 'x';	/* hex */
      break;
    case 10:
      user_print_options.output_format = 0;	/* decimal */
      break;
    case 8:
      user_print_options.output_format = 'o';	/* octal */
      break;
    default:
      output_radix_1 = output_radix;
      error (_("Unsupported output radix ``decimal %u''; "
	       "output radix unchanged."),
	     radix);
    }
  output_radix_1 = output_radix = radix;
  if (from_tty)
    {
      printf_filtered (_("Output radix now set to "
			 "decimal %u, hex %x, octal %o.\n"),
		       radix, radix, radix);
    }
}

/* Set both the input and output radix at once.  Try to set the output radix
   first, since it has the most restrictive range.  An radix that is valid as
   an output radix is also valid as an input radix.

   It may be useful to have an unusual input radix.  If the user wishes to
   set an input radix that is not valid as an output radix, he needs to use
   the 'set input-radix' command.  */

static void
set_radix (const char *arg, int from_tty)
{
  unsigned radix;

  radix = (arg == NULL) ? 10 : parse_and_eval_long (arg);
  set_output_radix_1 (0, radix);
  set_input_radix_1 (0, radix);
  if (from_tty)
    {
      printf_filtered (_("Input and output radices now set to "
			 "decimal %u, hex %x, octal %o.\n"),
		       radix, radix, radix);
    }
}

/* Show both the input and output radices.  */

static void
show_radix (const char *arg, int from_tty)
{
  if (from_tty)
    {
      if (input_radix == output_radix)
	{
	  printf_filtered (_("Input and output radices set to "
			     "decimal %u, hex %x, octal %o.\n"),
			   input_radix, input_radix, input_radix);
	}
      else
	{
	  printf_filtered (_("Input radix set to decimal "
			     "%u, hex %x, octal %o.\n"),
			   input_radix, input_radix, input_radix);
	  printf_filtered (_("Output radix set to decimal "
			     "%u, hex %x, octal %o.\n"),
			   output_radix, output_radix, output_radix);
	}
    }
}


/* Controls printing of vtbl's.  */
static void
show_vtblprint (struct ui_file *file, int from_tty,
		struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("\
Printing of C++ virtual function tables is %s.\n"),
		    value);
}

/* Controls looking up an object's derived type using what we find in
   its vtables.  */
static void
show_objectprint (struct ui_file *file, int from_tty,
		  struct cmd_list_element *c,
		  const char *value)
{
  fprintf_filtered (file, _("\
Printing of object's derived type based on vtable info is %s.\n"),
		    value);
}

static void
show_static_field_print (struct ui_file *file, int from_tty,
			 struct cmd_list_element *c,
			 const char *value)
{
  fprintf_filtered (file,
		    _("Printing of C++ static members is %s.\n"),
		    value);
}



/* A couple typedefs to make writing the options a bit more
   convenient.  */
using boolean_option_def
  = gdb::option::boolean_option_def<value_print_options>;
using uinteger_option_def
  = gdb::option::uinteger_option_def<value_print_options>;
using zuinteger_unlimited_option_def
  = gdb::option::zuinteger_unlimited_option_def<value_print_options>;

/* Definitions of options for the "print" and "compile print"
   commands.  */
static const gdb::option::option_def value_print_option_defs[] = {

  boolean_option_def {
    "address",
    [] (value_print_options *opt) { return &opt->addressprint; },
    show_addressprint, /* show_cmd_cb */
    N_("Set printing of addresses."),
    N_("Show printing of addresses."),
    NULL, /* help_doc */
  },

  boolean_option_def {
    "array",
    [] (value_print_options *opt) { return &opt->prettyformat_arrays; },
    show_prettyformat_arrays, /* show_cmd_cb */
    N_("Set pretty formatting of arrays."),
    N_("Show pretty formatting of arrays."),
    NULL, /* help_doc */
  },

  boolean_option_def {
    "array-indexes",
    [] (value_print_options *opt) { return &opt->print_array_indexes; },
    show_print_array_indexes, /* show_cmd_cb */
    N_("Set printing of array indexes."),
    N_("Show printing of array indexes."),
    NULL, /* help_doc */
  },

  uinteger_option_def {
    "elements",
    [] (value_print_options *opt) { return &opt->print_max; },
    show_print_max, /* show_cmd_cb */
    N_("Set limit on string chars or array elements to print."),
    N_("Show limit on string chars or array elements to print."),
    N_("\"unlimited\" causes there to be no limit."),
  },

  zuinteger_unlimited_option_def {
    "max-depth",
    [] (value_print_options *opt) { return &opt->max_depth; },
    show_print_max_depth, /* show_cmd_cb */
    N_("Set maximum print depth for nested structures, unions and arrays."),
    N_("Show maximum print depth for nested structures, unions, and arrays."),
    N_("When structures, unions, or arrays are nested beyond this depth then they\n\
will be replaced with either '{...}' or '(...)' depending on the language.\n\
Use \"unlimited\" to print the complete structure.")
  },

  boolean_option_def {
    "memory-tag-violations",
    [] (value_print_options *opt) { return &opt->memory_tag_violations; },
    show_memory_tag_violations, /* show_cmd_cb */
    N_("Set printing of memory tag violations for pointers."),
    N_("Show printing of memory tag violations for pointers."),
    N_("Issue a warning when the printed value is a pointer\n\
whose logical tag doesn't match the allocation tag of the memory\n\
location it points to."),
  },

  boolean_option_def {
    "null-stop",
    [] (value_print_options *opt) { return &opt->stop_print_at_null; },
    show_stop_print_at_null, /* show_cmd_cb */
    N_("Set printing of char arrays to stop at first null char."),
    N_("Show printing of char arrays to stop at first null char."),
    NULL, /* help_doc */
  },

  boolean_option_def {
    "object",
    [] (value_print_options *opt) { return &opt->objectprint; },
    show_objectprint, /* show_cmd_cb */
    _("Set printing of C++ virtual function tables."),
    _("Show printing of C++ virtual function tables."),
    NULL, /* help_doc */
  },

  boolean_option_def {
    "pretty",
    [] (value_print_options *opt) { return &opt->prettyformat_structs; },
    show_prettyformat_structs, /* show_cmd_cb */
    N_("Set pretty formatting of structures."),
    N_("Show pretty formatting of structures."),
    NULL, /* help_doc */
  },

  boolean_option_def {
    "raw-values",
    [] (value_print_options *opt) { return &opt->raw; },
    NULL, /* show_cmd_cb */
    N_("Set whether to print values in raw form."),
    N_("Show whether to print values in raw form."),
    N_("If set, values are printed in raw form, bypassing any\n\
pretty-printers for that value.")
  },

  uinteger_option_def {
    "repeats",
    [] (value_print_options *opt) { return &opt->repeat_count_threshold; },
    show_repeat_count_threshold, /* show_cmd_cb */
    N_("Set threshold for repeated print elements."),
    N_("Show threshold for repeated print elements."),
    N_("\"unlimited\" causes all elements to be individually printed."),
  },

  boolean_option_def {
    "static-members",
    [] (value_print_options *opt) { return &opt->static_field_print; },
    show_static_field_print, /* show_cmd_cb */
    N_("Set printing of C++ static members."),
    N_("Show printing of C++ static members."),
    NULL, /* help_doc */
  },

  boolean_option_def {
    "symbol",
    [] (value_print_options *opt) { return &opt->symbol_print; },
    show_symbol_print, /* show_cmd_cb */
    N_("Set printing of symbol names when printing pointers."),
    N_("Show printing of symbol names when printing pointers."),
    NULL, /* help_doc */
  },

  boolean_option_def {
    "union",
    [] (value_print_options *opt) { return &opt->unionprint; },
    show_unionprint, /* show_cmd_cb */
    N_("Set printing of unions interior to structures."),
    N_("Show printing of unions interior to structures."),
    NULL, /* help_doc */
  },

  boolean_option_def {
    "vtbl",
    [] (value_print_options *opt) { return &opt->vtblprint; },
    show_vtblprint, /* show_cmd_cb */
    N_("Set printing of C++ virtual function tables."),
    N_("Show printing of C++ virtual function tables."),
    NULL, /* help_doc */
  },
};

/* See valprint.h.  */

gdb::option::option_def_group
make_value_print_options_def_group (value_print_options *opts)
{
  return {{value_print_option_defs}, opts};
}

#if GDB_SELF_TEST

/* Test printing of TYPE_CODE_FLAGS values.  */

static void
test_print_flags (gdbarch *arch)
{
  type *flags_type = arch_flags_type (arch, "test_type", 32);
  type *field_type = builtin_type (arch)->builtin_uint32;

  /* Value:  1010 1010
     Fields: CCCB BAAA */
  append_flags_type_field (flags_type, 0, 3, field_type, "A");
  append_flags_type_field (flags_type, 3, 2, field_type, "B");
  append_flags_type_field (flags_type, 5, 3, field_type, "C");

  value *val = allocate_value (flags_type);
  gdb_byte *contents = value_contents_writeable (val);
  store_unsigned_integer (contents, 4, gdbarch_byte_order (arch), 0xaa);

  string_file out;
  val_print_type_code_flags (flags_type, val, 0, &out);
  SELF_CHECK (out.string () == "[ A=2 B=1 C=5 ]");
}

#endif

void _initialize_valprint ();
void
_initialize_valprint ()
{
#if GDB_SELF_TEST
  selftests::register_test_foreach_arch ("print-flags", test_print_flags);
#endif

  cmd_list_element *cmd;

  cmd_list_element *set_print_cmd
    = add_basic_prefix_cmd ("print", no_class,
			    _("Generic command for setting how things print."),
			    &setprintlist, 0, &setlist);
  add_alias_cmd ("p", set_print_cmd, no_class, 1, &setlist);
  /* Prefer set print to set prompt.  */
  add_alias_cmd ("pr", set_print_cmd, no_class, 1, &setlist);

  cmd_list_element *show_print_cmd
    = add_show_prefix_cmd ("print", no_class,
			   _("Generic command for showing print settings."),
			   &showprintlist, 0, &showlist);
  add_alias_cmd ("p", show_print_cmd, no_class, 1, &showlist);
  add_alias_cmd ("pr", show_print_cmd, no_class, 1, &showlist);

  cmd = add_basic_prefix_cmd ("raw", no_class,
			      _("\
Generic command for setting what things to print in \"raw\" mode."),
			      &setprintrawlist, 0, &setprintlist);
  deprecate_cmd (cmd, nullptr);

  cmd = add_show_prefix_cmd ("raw", no_class,
			     _("Generic command for showing \"print raw\" settings."),
			     &showprintrawlist, 0, &showprintlist);
  deprecate_cmd (cmd, nullptr);

  gdb::option::add_setshow_cmds_for_options
    (class_support, &user_print_options, value_print_option_defs,
     &setprintlist, &showprintlist);

  add_setshow_zuinteger_cmd ("input-radix", class_support, &input_radix_1,
			     _("\
Set default input radix for entering numbers."), _("\
Show default input radix for entering numbers."), NULL,
			     set_input_radix,
			     show_input_radix,
			     &setlist, &showlist);

  add_setshow_zuinteger_cmd ("output-radix", class_support, &output_radix_1,
			     _("\
Set default output radix for printing of values."), _("\
Show default output radix for printing of values."), NULL,
			     set_output_radix,
			     show_output_radix,
			     &setlist, &showlist);

  /* The "set radix" and "show radix" commands are special in that
     they are like normal set and show commands but allow two normally
     independent variables to be either set or shown with a single
     command.  So the usual deprecated_add_set_cmd() and [deleted]
     add_show_from_set() commands aren't really appropriate.  */
  /* FIXME: i18n: With the new add_setshow_integer command, that is no
     longer true - show can display anything.  */
  add_cmd ("radix", class_support, set_radix, _("\
Set default input and output number radices.\n\
Use 'set input-radix' or 'set output-radix' to independently set each.\n\
Without an argument, sets both radices back to the default value of 10."),
	   &setlist);
  add_cmd ("radix", class_support, show_radix, _("\
Show the default input and output number radices.\n\
Use 'show input-radix' or 'show output-radix' to independently show each."),
	   &showlist);
}
