linux-record: Squash cases with identical handling
[deliverable/binutils-gdb.git] / gdb / valprint.c
index 738fef43719ec713abac15c74053b5fc86af21d5..720942b85e74d55561c98dba0ed344d5f26e57f4 100644 (file)
@@ -1,6 +1,6 @@
 /* Print values for GDB, the GNU debugger.
 
 /* Print values for GDB, the GNU debugger.
 
-   Copyright (C) 1986, 1988-2012 Free Software Foundation, Inc.
+   Copyright (C) 1986-2016 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
    This file is part of GDB.
 
@@ -18,7 +18,6 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
-#include "gdb_string.h"
 #include "symtab.h"
 #include "gdbtypes.h"
 #include "value.h"
 #include "symtab.h"
 #include "gdbtypes.h"
 #include "value.h"
 #include "valprint.h"
 #include "floatformat.h"
 #include "doublest.h"
 #include "valprint.h"
 #include "floatformat.h"
 #include "doublest.h"
-#include "exceptions.h"
 #include "dfp.h"
 #include "dfp.h"
-#include "python/python.h"
+#include "extension.h"
 #include "ada-lang.h"
 #include "gdb_obstack.h"
 #include "charset.h"
 #include "ada-lang.h"
 #include "gdb_obstack.h"
 #include "charset.h"
+#include "typeprint.h"
 #include <ctype.h>
 
 #include <ctype.h>
 
-#include <errno.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;
+};
+
+typedef struct converted_character converted_character_d;
+DEF_VEC_O (converted_character_d);
+
+/* 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,
 
 /* Prototypes for local functions */
 
 static int partial_memory_read (CORE_ADDR memaddr, gdb_byte *myaddr,
-                               int len, int *errnoptr);
+                               int len, int *errptr);
 
 static void show_print (char *, int);
 
 
 static void show_print (char *, int);
 
@@ -61,15 +98,19 @@ static void set_output_radix (char *, int, struct cmd_list_element *);
 
 static void set_output_radix_1 (int, unsigned);
 
 
 static void set_output_radix_1 (int, unsigned);
 
+static void val_print_type_code_flags (struct type *type,
+                                      const gdb_byte *valaddr,
+                                      struct ui_file *stream);
+
 void _initialize_valprint (void);
 
 #define PRINT_MAX_DEFAULT 200  /* Start print_max off at this value.  */
 
 struct value_print_options user_print_options =
 {
 void _initialize_valprint (void);
 
 #define PRINT_MAX_DEFAULT 200  /* Start print_max off at this value.  */
 
 struct value_print_options user_print_options =
 {
-  Val_pretty_default,          /* pretty */
-  0,                           /* prettyprint_arrays */
-  0,                           /* prettyprint_structs */
+  Val_prettyformat_default,    /* prettyformat */
+  0,                           /* prettyformat_arrays */
+  0,                           /* prettyformat_structs */
   0,                           /* vtblprint */
   1,                           /* unionprint */
   1,                           /* addressprint */
   0,                           /* vtblprint */
   1,                           /* unionprint */
   1,                           /* addressprint */
@@ -79,13 +120,13 @@ struct value_print_options user_print_options =
   0,                           /* output_format */
   0,                           /* format */
   0,                           /* stop_print_at_null */
   0,                           /* output_format */
   0,                           /* format */
   0,                           /* stop_print_at_null */
-  0,                           /* inspect_it */
   0,                           /* print_array_indexes */
   0,                           /* deref_ref */
   1,                           /* static_field_print */
   1,                           /* pascal_static_field_print */
   0,                           /* raw */
   0,                           /* print_array_indexes */
   0,                           /* deref_ref */
   1,                           /* static_field_print */
   1,                           /* pascal_static_field_print */
   0,                           /* raw */
-  0                            /* summary */
+  0,                           /* summary */
+  1                            /* symbol_print */
 };
 
 /* Initialize *OPTS to be a copy of the user print options.  */
 };
 
 /* Initialize *OPTS to be a copy of the user print options.  */
@@ -96,12 +137,12 @@ get_user_print_options (struct value_print_options *opts)
 }
 
 /* Initialize *OPTS to be a copy of the user print options, but with
 }
 
 /* Initialize *OPTS to be a copy of the user print options, but with
-   pretty-printing disabled.  */
+   pretty-formatting disabled.  */
 void
 void
-get_raw_print_options (struct value_print_options *opts)
+get_no_prettyformat_print_options (struct value_print_options *opts)
 {  
   *opts = user_print_options;
 {  
   *opts = user_print_options;
-  opts->pretty = Val_no_prettyprint;
+  opts->prettyformat = Val_no_prettyformat;
 }
 
 /* Initialize *OPTS to be a copy of the user print options, but using
 }
 
 /* Initialize *OPTS to be a copy of the user print options, but using
@@ -184,19 +225,19 @@ show_stop_print_at_null (struct ui_file *file, int from_tty,
 /* Controls pretty printing of structures.  */
 
 static void
 /* Controls pretty printing of structures.  */
 
 static void
-show_prettyprint_structs (struct ui_file *file, int from_tty,
+show_prettyformat_structs (struct ui_file *file, int from_tty,
                          struct cmd_list_element *c, const char *value)
 {
                          struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("Prettyprinting of structures is %s.\n"), value);
+  fprintf_filtered (file, _("Pretty formatting of structures is %s.\n"), value);
 }
 
 /* Controls pretty printing of arrays.  */
 
 static void
 }
 
 /* Controls pretty printing of arrays.  */
 
 static void
-show_prettyprint_arrays (struct ui_file *file, int from_tty,
+show_prettyformat_arrays (struct ui_file *file, int from_tty,
                         struct cmd_list_element *c, const char *value)
 {
                         struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("Prettyprinting of arrays is %s.\n"), value);
+  fprintf_filtered (file, _("Pretty formatting of arrays is %s.\n"), value);
 }
 
 /* If nonzero, causes unions inside structures or other unions to be
 }
 
 /* If nonzero, causes unions inside structures or other unions to be
@@ -219,20 +260,30 @@ show_addressprint (struct ui_file *file, int from_tty,
 {
   fprintf_filtered (file, _("Printing of addresses is %s.\n"), 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);
+}
+
 \f
 
 /* 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.  */
 
 \f
 
 /* 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.  */
 
-static int
-scalar_type_p (struct type *type)
+int
+val_print_scalar_type_p (struct type *type)
 {
 {
-  CHECK_TYPEDEF (type);
+  type = check_typedef (type);
   while (TYPE_CODE (type) == TYPE_CODE_REF)
     {
       type = TYPE_TARGET_TYPE (type);
   while (TYPE_CODE (type) == TYPE_CODE_REF)
     {
       type = TYPE_TARGET_TYPE (type);
-      CHECK_TYPEDEF (type);
+      type = check_typedef (type);
     }
   switch (TYPE_CODE (type))
     {
     }
   switch (TYPE_CODE (type))
     {
@@ -241,7 +292,6 @@ scalar_type_p (struct type *type)
     case TYPE_CODE_UNION:
     case TYPE_CODE_SET:
     case TYPE_CODE_STRING:
     case TYPE_CODE_UNION:
     case TYPE_CODE_SET:
     case TYPE_CODE_STRING:
-    case TYPE_CODE_BITSTRING:
       return 0;
     default:
       return 1;
       return 0;
     default:
       return 1;
@@ -256,16 +306,29 @@ valprint_check_validity (struct ui_file *stream,
                         int embedded_offset,
                         const struct value *val)
 {
                         int embedded_offset,
                         const struct value *val)
 {
-  CHECK_TYPEDEF (type);
+  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) != TYPE_CODE_UNION
       && TYPE_CODE (type) != TYPE_CODE_STRUCT
       && TYPE_CODE (type) != TYPE_CODE_ARRAY)
     {
 
   if (TYPE_CODE (type) != TYPE_CODE_UNION
       && TYPE_CODE (type) != TYPE_CODE_STRUCT
       && TYPE_CODE (type) != TYPE_CODE_ARRAY)
     {
-      if (!value_bits_valid (val, TARGET_CHAR_BIT * embedded_offset,
-                            TARGET_CHAR_BIT * TYPE_LENGTH (type)))
+      if (value_bits_any_optimized_out (val,
+                                       TARGET_CHAR_BIT * embedded_offset,
+                                       TARGET_CHAR_BIT * TYPE_LENGTH (type)))
        {
        {
-         val_print_optimized_out (stream);
+         val_print_optimized_out (val, stream);
          return 0;
        }
 
          return 0;
        }
 
@@ -287,9 +350,18 @@ valprint_check_validity (struct ui_file *stream,
 }
 
 void
 }
 
 void
-val_print_optimized_out (struct ui_file *stream)
+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_filtered (stream, _("<optimized out>"));
+}
+
+void
+val_print_not_saved (struct ui_file *stream)
 {
 {
-  fprintf_filtered (stream, _("<optimized out>"));
+  fprintf_filtered (stream, _("<not saved>"));
 }
 
 void
 }
 
 void
@@ -304,210 +376,277 @@ val_print_invalid_address (struct ui_file *stream)
   fprintf_filtered (stream, _("<invalid address>"));
 }
 
   fprintf_filtered (stream, _("<invalid address>"));
 }
 
-/* A generic val_print that is suitable for use by language
-   implementations of the la_val_print method.  This function can
-   handle most type codes, though not all, notably exception
-   TYPE_CODE_UNION and TYPE_CODE_STRUCT, which must be implemented by
-   the caller.
-   
-   Most arguments are as to val_print.
-   
-   The additional DECORATIONS argument can be used to customize the
-   output in some small, language-specific ways.  */
+/* Print a pointer based on the type of its target.
 
 
-void
-generic_val_print (struct type *type, const gdb_byte *valaddr,
+   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 = get_type_arch (type);
+
+  if (TYPE_CODE (elttype) == 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 type *type, const gdb_byte *valaddr,
                   int embedded_offset, CORE_ADDR address,
                   struct ui_file *stream, int recurse,
                   const struct value *original_value,
                   int embedded_offset, CORE_ADDR address,
                   struct ui_file *stream, int recurse,
                   const struct value *original_value,
-                  const struct value_print_options *options,
-                  const struct generic_val_print_decorations *decorations)
+                  const struct value_print_options *options)
 {
 {
-  struct gdbarch *gdbarch = get_type_arch (type);
-  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  unsigned int i = 0;  /* Number of characters printed.  */
-  unsigned len;
-  struct type *elttype, *unresolved_elttype;
-  struct type *unresolved_type = type;
-  unsigned eltlen;
-  LONGEST val;
-  CORE_ADDR addr;
+  struct type *unresolved_elttype = TYPE_TARGET_TYPE (type);
+  struct type *elttype = check_typedef (unresolved_elttype);
 
 
-  CHECK_TYPEDEF (type);
-  switch (TYPE_CODE (type))
+  if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (unresolved_elttype) > 0)
     {
     {
-    case TYPE_CODE_ARRAY:
-      unresolved_elttype = TYPE_TARGET_TYPE (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"));
+
+      if (options->prettyformat_arrays)
        {
        {
-          LONGEST low_bound, high_bound;
+         print_spaces_filtered (2 + 2 * recurse, stream);
+       }
 
 
-          if (!get_array_bounds (type, &low_bound, &high_bound))
-            error (_("Could not determine the array high bound"));
+      fprintf_filtered (stream, "{");
+      val_print_array_elements (type, valaddr, embedded_offset,
+                               address, stream,
+                               recurse, original_value, options, 0);
+      fprintf_filtered (stream, "}");
+    }
+  else
+    {
+      /* Array of unspecified length: treat like pointer to first elt.  */
+      print_unpacked_pointer (type, elttype, address + embedded_offset, stream,
+                             options);
+    }
 
 
-         if (options->prettyprint_arrays)
-           {
-             print_spaces_filtered (2 + 2 * recurse, stream);
-           }
+}
 
 
-         fprintf_filtered (stream, "{");
-         val_print_array_elements (type, valaddr, embedded_offset,
-                                   address, stream,
-                                   recurse, original_value, options, 0);
-         fprintf_filtered (stream, "}");
-         break;
-       }
-      /* Array of unspecified length: treat like pointer to first
-        elt.  */
-      addr = address + embedded_offset;
-      goto print_unpacked_pointer;
+/* generic_val_print helper for TYPE_CODE_PTR.  */
 
 
-    case TYPE_CODE_MEMBERPTR:
+static void
+generic_val_print_ptr (struct type *type, const gdb_byte *valaddr,
+                      int embedded_offset, struct ui_file *stream,
+                      const struct value *original_value,
+                      const struct value_print_options *options)
+{
+  struct gdbarch *gdbarch = get_type_arch (type);
+  int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
+
+  if (options->format && options->format != 's')
+    {
       val_print_scalar_formatted (type, valaddr, embedded_offset,
                                  original_value, options, 0, stream);
       val_print_scalar_formatted (type, valaddr, embedded_offset,
                                  original_value, options, 0, stream);
-      break;
+    }
+  else
+    {
+      struct type *unresolved_elttype = TYPE_TARGET_TYPE(type);
+      struct type *elttype = check_typedef (unresolved_elttype);
+      CORE_ADDR addr = unpack_pointer (type,
+                                      valaddr + embedded_offset * unit_size);
 
 
-    case TYPE_CODE_PTR:
-      if (options->format && options->format != 's')
-       {
-         val_print_scalar_formatted (type, valaddr, embedded_offset,
-                                     original_value, options, 0, stream);
-         break;
-       }
-      unresolved_elttype = TYPE_TARGET_TYPE (type);
-      elttype = check_typedef (unresolved_elttype);
-       {
-         addr = unpack_pointer (type, valaddr + embedded_offset);
-       print_unpacked_pointer:
+      print_unpacked_pointer (type, elttype, addr, stream, options);
+    }
+}
 
 
-         if (TYPE_CODE (elttype) == TYPE_CODE_FUNC)
-           {
-             /* Try to print what function it points to.  */
-             print_function_pointer_address (gdbarch, addr, stream,
-                                             options->addressprint);
-             return;
-           }
 
 
-         if (options->addressprint)
-           fputs_filtered (paddress (gdbarch, addr), stream);
-       }
-      break;
+/* generic_val_print helper for TYPE_CODE_MEMBERPTR.  */
 
 
-    case TYPE_CODE_REF:
-      elttype = check_typedef (TYPE_TARGET_TYPE (type));
-      if (options->addressprint)
-       {
-         CORE_ADDR addr
-           = extract_typed_address (valaddr + embedded_offset, type);
+static void
+generic_val_print_memberptr (struct type *type, const gdb_byte *valaddr,
+                            int embedded_offset, struct ui_file *stream,
+                            const struct value *original_value,
+                            const struct value_print_options *options)
+{
+  val_print_scalar_formatted (type, valaddr, embedded_offset,
+                             original_value, options, 0, stream);
+}
 
 
-         fprintf_filtered (stream, "@");
-         fputs_filtered (paddress (gdbarch, addr), stream);
-         if (options->deref_ref)
-           fputs_filtered (": ", stream);
-       }
-      /* De-reference the reference.  */
+/* generic_val_print helper for TYPE_CODE_REF.  */
+
+static void
+generic_val_print_ref (struct type *type, const gdb_byte *valaddr,
+                      int embedded_offset, struct ui_file *stream, int recurse,
+                      const struct value *original_value,
+                      const struct value_print_options *options)
+{
+  struct gdbarch *gdbarch = get_type_arch (type);
+  struct type *elttype = check_typedef (TYPE_TARGET_TYPE (type));
+
+  if (options->addressprint)
+    {
+      CORE_ADDR addr
+       = extract_typed_address (valaddr + embedded_offset, type);
+
+      fprintf_filtered (stream, "@");
+      fputs_filtered (paddress (gdbarch, addr), stream);
       if (options->deref_ref)
       if (options->deref_ref)
+       fputs_filtered (": ", stream);
+    }
+  /* De-reference the reference.  */
+  if (options->deref_ref)
+    {
+      if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF)
        {
        {
-         if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF)
-           {
-             struct value *deref_val;
-
-             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)));
+         struct value *deref_val;
 
 
-             common_val_print (deref_val, stream, recurse, options,
-                               current_language);
+         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
            }
          else
-           fputs_filtered ("???", stream);
+           deref_val = value_at (TYPE_TARGET_TYPE (type),
+                                 unpack_pointer (type,
+                                                 (valaddr
+                                                  + embedded_offset)));
+
+         common_val_print (deref_val, stream, recurse, options,
+                           current_language);
        }
        }
-      break;
+      else
+       fputs_filtered ("???", stream);
+    }
+}
 
 
-    case TYPE_CODE_ENUM:
-      if (options->format)
+/* 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_NFIELDS (type);
+  for (i = 0; i < len; i++)
+    {
+      QUIT;
+      if (val == TYPE_FIELD_ENUMVAL (type, i))
        {
        {
-         val_print_scalar_formatted (type, valaddr, embedded_offset,
-                                     original_value, options, 0, stream);
          break;
        }
          break;
        }
-      len = TYPE_NFIELDS (type);
-      val = unpack_long (type, valaddr + embedded_offset);
-      for (i = 0; i < len; i++)
+    }
+  if (i < len)
+    {
+      fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
+    }
+  else if (TYPE_FLAG_ENUM (type))
+    {
+      int first = 1;
+
+      /* We have a "flag" enum, so we try to decompose it into
+        pieces as appropriate.  A flag enum has disjoint
+        constants by definition.  */
+      fputs_filtered ("(", stream);
+      for (i = 0; i < len; ++i)
        {
          QUIT;
        {
          QUIT;
-         if (val == TYPE_FIELD_BITPOS (type, i))
+
+         if ((val & TYPE_FIELD_ENUMVAL (type, i)) != 0)
            {
            {
-             break;
+             if (!first)
+               fputs_filtered (" | ", stream);
+             first = 0;
+
+             val &= ~TYPE_FIELD_ENUMVAL (type, i);
+             fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
            }
        }
            }
        }
-      if (i < len)
+
+      if (first || val != 0)
        {
        {
-         fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
+         if (!first)
+           fputs_filtered (" | ", stream);
+         fputs_filtered ("unknown: ", stream);
+         print_longest (stream, 'd', 0, val);
        }
        }
-      else if (TYPE_FLAG_ENUM (type))
-       {
-         int first = 1;
 
 
-         /* We have a "flag" enum, so we try to decompose it into
-            pieces as appropriate.  A flag enum has disjoint
-            constants by definition.  */
-         fputs_filtered ("(", stream);
-         for (i = 0; i < len; ++i)
-           {
-             QUIT;
+      fputs_filtered (")", stream);
+    }
+  else
+    print_longest (stream, 'd', 0, val);
+}
 
 
-             if ((val & TYPE_FIELD_BITPOS (type, i)) != 0)
-               {
-                 if (!first)
-                   fputs_filtered (" | ", stream);
-                 first = 0;
+/* generic_val_print helper for TYPE_CODE_ENUM.  */
 
 
-                 val &= ~TYPE_FIELD_BITPOS (type, i);
-                 fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
-               }
-           }
+static void
+generic_val_print_enum (struct type *type, const gdb_byte *valaddr,
+                       int embedded_offset, struct ui_file *stream,
+                       const struct value *original_value,
+                       const struct value_print_options *options)
+{
+  LONGEST val;
+  struct gdbarch *gdbarch = get_type_arch (type);
+  int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
 
 
-         if (first || val != 0)
-           {
-             if (!first)
-               fputs_filtered (" | ", stream);
-             fputs_filtered ("unknown: ", stream);
-             print_longest (stream, 'd', 0, val);
-           }
+  if (options->format)
+    {
+      val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                 original_value, options, 0, stream);
+      return;
+    }
+  val = unpack_long (type, valaddr + embedded_offset * unit_size);
 
 
-         fputs_filtered (")", stream);
-       }
-      else
-       print_longest (stream, 'd', 0, val);
-      break;
+  generic_val_print_enum_1 (type, val, stream);
+}
 
 
-    case TYPE_CODE_FLAGS:
-      if (options->format)
-       val_print_scalar_formatted (type, valaddr, embedded_offset,
-                                   original_value, options, 0, stream);
-      else
-       val_print_type_code_flags (type, valaddr + embedded_offset,
-                                  stream);
-      break;
+/* generic_val_print helper for TYPE_CODE_FLAGS.  */
 
 
-    case TYPE_CODE_FUNC:
-    case TYPE_CODE_METHOD:
-      if (options->format)
-       {
-         val_print_scalar_formatted (type, valaddr, embedded_offset,
-                                     original_value, options, 0, stream);
-         break;
-       }
+static void
+generic_val_print_flags (struct type *type, const gdb_byte *valaddr,
+                        int embedded_offset, struct ui_file *stream,
+                        const struct value *original_value,
+                        const struct value_print_options *options)
+
+{
+  if (options->format)
+    val_print_scalar_formatted (type, valaddr, embedded_offset, original_value,
+                               options, 0, stream);
+  else
+    val_print_type_code_flags (type, valaddr + embedded_offset, stream);
+}
+
+/* generic_val_print helper for TYPE_CODE_FUNC and TYPE_CODE_METHOD.  */
+
+static void
+generic_val_print_func (struct type *type, const gdb_byte *valaddr,
+                       int embedded_offset, CORE_ADDR address,
+                       struct ui_file *stream,
+                       const struct value *original_value,
+                       const struct value_print_options *options)
+{
+  struct gdbarch *gdbarch = get_type_arch (type);
+
+  if (options->format)
+    {
+      val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                 original_value, options, 0, stream);
+    }
+  else
+    {
       /* FIXME, we should consider, at least for ANSI C language,
          eliminating the distinction made between FUNCs and POINTERs
          to FUNCs.  */
       /* FIXME, we should consider, at least for ANSI C language,
          eliminating the distinction made between FUNCs and POINTERs
          to FUNCs.  */
@@ -515,32 +654,244 @@ generic_val_print (struct type *type, const gdb_byte *valaddr,
       type_print (type, "", stream, -1);
       fprintf_filtered (stream, "} ");
       /* Try to print what function it points to, and its address.  */
       type_print (type, "", stream, -1);
       fprintf_filtered (stream, "} ");
       /* Try to print what function it points to, and its address.  */
-      print_address_demangle (gdbarch, address, stream, demangle);
+      print_address_demangle (options, gdbarch, address, stream, demangle);
+    }
+}
+
+/* generic_val_print helper for TYPE_CODE_BOOL.  */
+
+static void
+generic_val_print_bool (struct type *type, const gdb_byte *valaddr,
+                       int embedded_offset, struct ui_file *stream,
+                       const struct value *original_value,
+                       const struct value_print_options *options,
+                       const struct generic_val_print_decorations *decorations)
+{
+  LONGEST val;
+  struct gdbarch *gdbarch = get_type_arch (type);
+  int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
+
+  if (options->format || options->output_format)
+    {
+      struct value_print_options opts = *options;
+      opts.format = (options->format ? options->format
+                    : options->output_format);
+      val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                 original_value, &opts, 0, stream);
+    }
+  else
+    {
+      val = unpack_long (type, valaddr + embedded_offset * unit_size);
+      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_val_print helper for TYPE_CODE_INT.  */
+
+static void
+generic_val_print_int (struct type *type, const gdb_byte *valaddr,
+                      int embedded_offset, struct ui_file *stream,
+                      const struct value *original_value,
+                      const struct value_print_options *options)
+{
+  struct gdbarch *gdbarch = get_type_arch (type);
+  int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
+
+  if (options->format || options->output_format)
+    {
+      struct value_print_options opts = *options;
+
+      opts.format = (options->format ? options->format
+                    : options->output_format);
+      val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                 original_value, &opts, 0, stream);
+    }
+  else
+    val_print_type_code_int (type, valaddr + embedded_offset * unit_size,
+                            stream);
+}
+
+/* generic_val_print helper for TYPE_CODE_CHAR.  */
+
+static void
+generic_val_print_char (struct type *type, struct type *unresolved_type,
+                       const gdb_byte *valaddr, int embedded_offset,
+                       struct ui_file *stream,
+                       const struct value *original_value,
+                       const struct value_print_options *options)
+{
+  LONGEST val;
+  struct gdbarch *gdbarch = get_type_arch (type);
+  int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
+
+  if (options->format || options->output_format)
+    {
+      struct value_print_options opts = *options;
+
+      opts.format = (options->format ? options->format
+                    : options->output_format);
+      val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                 original_value, &opts, 0, stream);
+    }
+  else
+    {
+      val = unpack_long (type, valaddr + embedded_offset * unit_size);
+      if (TYPE_UNSIGNED (type))
+       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.  */
+
+static void
+generic_val_print_float (struct type *type, const gdb_byte *valaddr,
+                        int embedded_offset, struct ui_file *stream,
+                        const struct value *original_value,
+                        const struct value_print_options *options)
+{
+  struct gdbarch *gdbarch = get_type_arch (type);
+  int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
+
+  if (options->format)
+    {
+      val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                 original_value, options, 0, stream);
+    }
+  else
+    {
+      print_floating (valaddr + embedded_offset * unit_size, type, stream);
+    }
+}
+
+/* generic_val_print helper for TYPE_CODE_DECFLOAT.  */
+
+static void
+generic_val_print_decfloat (struct type *type, const gdb_byte *valaddr,
+                           int embedded_offset, struct ui_file *stream,
+                           const struct value *original_value,
+                           const struct value_print_options *options)
+{
+  struct gdbarch *gdbarch = get_type_arch (type);
+  int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
+
+  if (options->format)
+    val_print_scalar_formatted (type, valaddr, embedded_offset, original_value,
+                               options, 0, stream);
+  else
+    print_decimal_floating (valaddr + embedded_offset * unit_size, type,
+                           stream);
+}
+
+/* generic_val_print helper for TYPE_CODE_COMPLEX.  */
+
+static void
+generic_val_print_complex (struct type *type, const gdb_byte *valaddr,
+                          int embedded_offset, struct ui_file *stream,
+                          const struct value *original_value,
+                          const struct value_print_options *options,
+                          const struct generic_val_print_decorations
+                            *decorations)
+{
+  struct gdbarch *gdbarch = get_type_arch (type);
+  int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
+
+  fprintf_filtered (stream, "%s", decorations->complex_prefix);
+  if (options->format)
+    val_print_scalar_formatted (TYPE_TARGET_TYPE (type), valaddr,
+                               embedded_offset, original_value, options, 0,
+                               stream);
+  else
+    print_floating (valaddr + embedded_offset * unit_size,
+                   TYPE_TARGET_TYPE (type), stream);
+  fprintf_filtered (stream, "%s", decorations->complex_infix);
+  if (options->format)
+    val_print_scalar_formatted (TYPE_TARGET_TYPE (type), valaddr,
+                               embedded_offset
+                               + type_length_units (TYPE_TARGET_TYPE (type)),
+                               original_value, options, 0, stream);
+  else
+    print_floating (valaddr + embedded_offset * unit_size
+                   + TYPE_LENGTH (TYPE_TARGET_TYPE (type)),
+                   TYPE_TARGET_TYPE (type), stream);
+  fprintf_filtered (stream, "%s", decorations->complex_suffix);
+}
+
+/* A generic val_print that is suitable for use by language
+   implementations of the la_val_print method.  This function can
+   handle most type codes, though not all, notably exception
+   TYPE_CODE_UNION and TYPE_CODE_STRUCT, which must be implemented by
+   the caller.
+   
+   Most arguments are as to val_print.
+   
+   The additional DECORATIONS argument can be used to customize the
+   output in some small, language-specific ways.  */
+
+void
+generic_val_print (struct type *type, const gdb_byte *valaddr,
+                  int embedded_offset, CORE_ADDR address,
+                  struct ui_file *stream, int recurse,
+                  const struct value *original_value,
+                  const struct value_print_options *options,
+                  const struct generic_val_print_decorations *decorations)
+{
+  struct type *unresolved_type = type;
+
+  type = check_typedef (type);
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_ARRAY:
+      generic_val_print_array (type, valaddr, embedded_offset, address, stream,
+                              recurse, original_value, options);
+      break;
+
+    case TYPE_CODE_MEMBERPTR:
+      generic_val_print_memberptr (type, valaddr, embedded_offset, stream,
+                                  original_value, options);
+      break;
+
+    case TYPE_CODE_PTR:
+      generic_val_print_ptr (type, valaddr, embedded_offset, stream,
+                            original_value, options);
+      break;
+
+    case TYPE_CODE_REF:
+      generic_val_print_ref (type, valaddr, embedded_offset, stream, recurse,
+                            original_value, options);
+      break;
+
+    case TYPE_CODE_ENUM:
+      generic_val_print_enum (type, valaddr, embedded_offset, stream,
+                             original_value, options);
+      break;
+
+    case TYPE_CODE_FLAGS:
+      generic_val_print_flags (type, valaddr, embedded_offset, stream,
+                              original_value, options);
+      break;
+
+    case TYPE_CODE_FUNC:
+    case TYPE_CODE_METHOD:
+      generic_val_print_func (type, valaddr, embedded_offset, address, stream,
+                             original_value, options);
       break;
 
     case TYPE_CODE_BOOL:
       break;
 
     case TYPE_CODE_BOOL:
-      if (options->format || options->output_format)
-       {
-         struct value_print_options opts = *options;
-         opts.format = (options->format ? options->format
-                        : options->output_format);
-         val_print_scalar_formatted (type, valaddr, embedded_offset,
-                                     original_value, &opts, 0, stream);
-       }
-      else
-       {
-         val = unpack_long (type, valaddr + embedded_offset);
-         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_val_print_bool (type, valaddr, embedded_offset, stream,
+                             original_value, options, decorations);
       break;
 
     case TYPE_CODE_RANGE:
       break;
 
     case TYPE_CODE_RANGE:
-      /* FIXME: create_range_type does not set the unsigned bit in a
+      /* FIXME: create_static_range_type does not set the unsigned bit in a
          range type (I think it probably should copy it from the
          target type), so we won't print values which are too large to
          fit in a signed integer correctly.  */
          range type (I think it probably should copy it from the
          target type), so we won't print values which are too large to
          fit in a signed integer correctly.  */
@@ -549,62 +900,25 @@ generic_val_print (struct type *type, const gdb_byte *valaddr,
          type and the target type might differ).  */
 
       /* FALLTHROUGH */
          type and the target type might differ).  */
 
       /* FALLTHROUGH */
-
-    case TYPE_CODE_INT:
-      if (options->format || options->output_format)
-       {
-         struct value_print_options opts = *options;
-
-         opts.format = (options->format ? options->format
-                        : options->output_format);
-         val_print_scalar_formatted (type, valaddr, embedded_offset,
-                                     original_value, &opts, 0, stream);
-       }
-      else
-       val_print_type_code_int (type, valaddr + embedded_offset, stream);
-      break;
-
-    case TYPE_CODE_CHAR:
-      if (options->format || options->output_format)
-       {
-         struct value_print_options opts = *options;
-
-         opts.format = (options->format ? options->format
-                        : options->output_format);
-         val_print_scalar_formatted (type, valaddr, embedded_offset,
-                                     original_value, &opts, 0, stream);
-       }
-      else
-       {
-         val = unpack_long (type, valaddr + embedded_offset);
-         if (TYPE_UNSIGNED (type))
-           fprintf_filtered (stream, "%u", (unsigned int) val);
-         else
-           fprintf_filtered (stream, "%d", (int) val);
-         fputs_filtered (" ", stream);
-         LA_PRINT_CHAR (val, unresolved_type, stream);
-       }
+
+    case TYPE_CODE_INT:
+      generic_val_print_int (type, valaddr, embedded_offset, stream,
+                            original_value, options);
+      break;
+
+    case TYPE_CODE_CHAR:
+      generic_val_print_char (type, unresolved_type, valaddr, embedded_offset,
+                             stream, original_value, options);
       break;
 
     case TYPE_CODE_FLT:
       break;
 
     case TYPE_CODE_FLT:
-      if (options->format)
-       {
-         val_print_scalar_formatted (type, valaddr, embedded_offset,
-                                     original_value, options, 0, stream);
-       }
-      else
-       {
-         print_floating (valaddr + embedded_offset, type, stream);
-       }
+      generic_val_print_float (type, valaddr, embedded_offset, stream,
+                              original_value, options);
       break;
 
     case TYPE_CODE_DECFLOAT:
       break;
 
     case TYPE_CODE_DECFLOAT:
-      if (options->format)
-       val_print_scalar_formatted (type, valaddr, embedded_offset,
-                                   original_value, options, 0, stream);
-      else
-       print_decimal_floating (valaddr + embedded_offset,
-                               type, stream);
+      generic_val_print_decfloat (type, valaddr, embedded_offset, stream,
+                                 original_value, options);
       break;
 
     case TYPE_CODE_VOID:
       break;
 
     case TYPE_CODE_VOID:
@@ -624,29 +938,8 @@ generic_val_print (struct type *type, const gdb_byte *valaddr,
       break;
 
     case TYPE_CODE_COMPLEX:
       break;
 
     case TYPE_CODE_COMPLEX:
-      fprintf_filtered (stream, "%s", decorations->complex_prefix);
-      if (options->format)
-       val_print_scalar_formatted (TYPE_TARGET_TYPE (type),
-                                   valaddr, embedded_offset,
-                                   original_value, options, 0, stream);
-      else
-       print_floating (valaddr + embedded_offset,
-                       TYPE_TARGET_TYPE (type),
-                       stream);
-      fprintf_filtered (stream, "%s", decorations->complex_infix);
-      if (options->format)
-       val_print_scalar_formatted (TYPE_TARGET_TYPE (type),
-                                   valaddr,
-                                   embedded_offset
-                                   + TYPE_LENGTH (TYPE_TARGET_TYPE (type)),
-                                   original_value,
-                                   options, 0, stream);
-      else
-       print_floating (valaddr + embedded_offset
-                       + TYPE_LENGTH (TYPE_TARGET_TYPE (type)),
-                       TYPE_TARGET_TYPE (type),
-                       stream);
-      fprintf_filtered (stream, "%s", decorations->complex_suffix);
+      generic_val_print_complex (type, valaddr, embedded_offset, stream,
+                                original_value, options, decorations);
       break;
 
     case TYPE_CODE_UNION:
       break;
 
     case TYPE_CODE_UNION:
@@ -686,14 +979,13 @@ val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
           const struct value_print_options *options,
           const struct language_defn *language)
 {
           const struct value_print_options *options,
           const struct language_defn *language)
 {
-  volatile struct gdb_exception except;
   int ret = 0;
   struct value_print_options local_opts = *options;
   struct type *real_type = check_typedef (type);
 
   int ret = 0;
   struct value_print_options local_opts = *options;
   struct type *real_type = check_typedef (type);
 
-  if (local_opts.pretty == Val_pretty_default)
-    local_opts.pretty = (local_opts.prettyprint_structs
-                        ? Val_prettyprint : Val_no_prettyprint);
+  if (local_opts.prettyformat == Val_prettyformat_default)
+    local_opts.prettyformat = (local_opts.prettyformat_structs
+                              ? Val_prettyformat : Val_no_prettyformat);
 
   QUIT;
 
 
   QUIT;
 
@@ -713,29 +1005,32 @@ val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
 
   if (!options->raw)
     {
 
   if (!options->raw)
     {
-      ret = apply_val_pretty_printer (type, valaddr, embedded_offset,
-                                     address, stream, recurse,
-                                     val, options, language);
+      ret = apply_ext_lang_val_pretty_printer (type, valaddr, embedded_offset,
+                                              address, stream, recurse,
+                                              val, options, language);
       if (ret)
        return;
     }
 
   /* Handle summary mode.  If the value is a scalar, print it;
      otherwise, print an ellipsis.  */
       if (ret)
        return;
     }
 
   /* Handle summary mode.  If the value is a scalar, print it;
      otherwise, print an ellipsis.  */
-  if (options->summary && !scalar_type_p (type))
+  if (options->summary && !val_print_scalar_type_p (type))
     {
       fprintf_filtered (stream, "...");
       return;
     }
 
     {
       fprintf_filtered (stream, "...");
       return;
     }
 
-  TRY_CATCH (except, RETURN_MASK_ERROR)
+  TRY
     {
       language->la_val_print (type, valaddr, embedded_offset, address,
                              stream, recurse, val,
                              &local_opts);
     }
     {
       language->la_val_print (type, valaddr, embedded_offset, address,
                              stream, recurse, val,
                              &local_opts);
     }
-  if (except.reason < 0)
-    fprintf_filtered (stream, _("<error reading variable>"));
+  CATCH (except, RETURN_MASK_ERROR)
+    {
+      fprintf_filtered (stream, _("<error reading variable>"));
+    }
+  END_CATCH
 }
 
 /* Check whether the value VAL is printable.  Return 1 if it is;
 }
 
 /* Check whether the value VAL is printable.  Return 1 if it is;
@@ -754,10 +1049,19 @@ value_check_printable (struct value *val, struct ui_file *stream,
 
   if (value_entirely_optimized_out (val))
     {
 
   if (value_entirely_optimized_out (val))
     {
-      if (options->summary && !scalar_type_p (value_type (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
        fprintf_filtered (stream, "...");
       else
-       val_print_optimized_out (stream);
+       val_print_unavailable (stream);
       return 0;
     }
 
       return 0;
     }
 
@@ -768,6 +1072,18 @@ value_check_printable (struct value *val, struct ui_file *stream,
       return 0;
     }
 
       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;
 }
 
   return 1;
 }
 
@@ -810,12 +1126,13 @@ value_print (struct value *val, struct ui_file *stream,
 
   if (!options->raw)
     {
 
   if (!options->raw)
     {
-      int r = apply_val_pretty_printer (value_type (val),
-                                       value_contents_for_printing (val),
-                                       value_embedded_offset (val),
-                                       value_address (val),
-                                       stream, 0,
-                                       val, options, current_language);
+      int r
+       = apply_ext_lang_val_pretty_printer (value_type (val),
+                                            value_contents_for_printing (val),
+                                            value_embedded_offset (val),
+                                            value_address (val),
+                                            stream, 0,
+                                            val, options, current_language);
 
       if (r)
        return;
 
       if (r)
        return;
@@ -861,26 +1178,51 @@ val_print_type_code_int (struct type *type, const gdb_byte *valaddr,
     }
 }
 
     }
 }
 
-void
+static void
 val_print_type_code_flags (struct type *type, const gdb_byte *valaddr,
                           struct ui_file *stream)
 {
   ULONGEST val = unpack_long (type, valaddr);
 val_print_type_code_flags (struct type *type, const gdb_byte *valaddr,
                           struct ui_file *stream)
 {
   ULONGEST val = unpack_long (type, valaddr);
-  int bitpos, nfields = TYPE_NFIELDS (type);
+  int field, nfields = TYPE_NFIELDS (type);
+  struct gdbarch *gdbarch = get_type_arch (type);
+  struct type *bool_type = builtin_type (gdbarch)->builtin_bool;
 
 
-  fputs_filtered ("[ ", stream);
-  for (bitpos = 0; bitpos < nfields; bitpos++)
+  fputs_filtered ("[", stream);
+  for (field = 0; field < nfields; field++)
     {
     {
-      if (TYPE_FIELD_BITPOS (type, bitpos) != -1
-         && (val & ((ULONGEST)1 << bitpos)))
+      if (TYPE_FIELD_NAME (type, field)[0] != '\0')
        {
        {
-         if (TYPE_FIELD_NAME (type, bitpos))
-           fprintf_filtered (stream, "%s ", TYPE_FIELD_NAME (type, bitpos));
+         struct type *field_type = TYPE_FIELD_TYPE (type, field);
+
+         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, " %s",
+                                 TYPE_FIELD_NAME (type, field));
+           }
          else
          else
-           fprintf_filtered (stream, "#%d ", bitpos);
+           {
+             unsigned field_len = TYPE_FIELD_BITSIZE (type, field);
+             ULONGEST field_val
+               = val >> (TYPE_FIELD_BITPOS (type, field) - field_len + 1);
+
+             if (field_len < sizeof (ULONGEST) * TARGET_CHAR_BIT)
+               field_val &= ((ULONGEST) 1 << field_len) - 1;
+             fprintf_filtered (stream, " %s=",
+                               TYPE_FIELD_NAME (type, field));
+             if (TYPE_CODE (field_type) == TYPE_CODE_ENUM)
+               generic_val_print_enum_1 (field_type, field_val, stream);
+             else
+               print_longest (stream, 'd', 0, field_val);
+           }
        }
     }
        }
     }
-  fputs_filtered ("]", stream);
+  fputs_filtered (" ]", stream);
 }
 
 /* Print a scalar of data of type TYPE, pointed to in GDB by VALADDR,
 }
 
 /* Print a scalar of data of type TYPE, pointed to in GDB by VALADDR,
@@ -898,6 +1240,9 @@ val_print_scalar_formatted (struct type *type,
                            int size,
                            struct ui_file *stream)
 {
                            int size,
                            struct ui_file *stream)
 {
+  struct gdbarch *arch = get_type_arch (type);
+  int unit_size = gdbarch_addressable_memory_unit_size (arch);
+
   gdb_assert (val != NULL);
   gdb_assert (valaddr == value_contents_for_printing_const (val));
 
   gdb_assert (val != NULL);
   gdb_assert (valaddr == value_contents_for_printing_const (val));
 
@@ -916,13 +1261,14 @@ val_print_scalar_formatted (struct type *type,
 
   /* A scalar object that does not have all bits available can't be
      printed, because all bits contribute to its representation.  */
 
   /* A scalar object that does not have all bits available can't be
      printed, because all bits contribute to its representation.  */
-  if (!value_bits_valid (val, TARGET_CHAR_BIT * embedded_offset,
-                             TARGET_CHAR_BIT * TYPE_LENGTH (type)))
-    val_print_optimized_out (stream);
+  if (value_bits_any_optimized_out (val,
+                                   TARGET_CHAR_BIT * embedded_offset,
+                                   TARGET_CHAR_BIT * TYPE_LENGTH (type)))
+    val_print_optimized_out (val, stream);
   else if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
     val_print_unavailable (stream);
   else
   else if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
     val_print_unavailable (stream);
   else
-    print_scalar_formatted (valaddr + embedded_offset, type,
+    print_scalar_formatted (valaddr + embedded_offset * unit_size, type,
                            options, size, stream);
 }
 
                            options, size, stream);
 }
 
@@ -1323,7 +1669,7 @@ print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr,
      as the base 16 number, which is 2 digits per byte.  */
 
   decimal_len = len * 2 * 2;
      as the base 16 number, which is 2 digits per byte.  */
 
   decimal_len = len * 2 * 2;
-  digits = xmalloc (decimal_len);
+  digits = (unsigned char *) xmalloc (decimal_len);
 
   for (i = 0; i < decimal_len; i++)
     {
 
   for (i = 0; i < decimal_len; i++)
     {
@@ -1501,10 +1847,10 @@ print_char_chars (struct ui_file *stream, struct type *type,
    stream STREAM.  */
 
 void
    stream STREAM.  */
 
 void
-print_function_pointer_address (struct gdbarch *gdbarch,
+print_function_pointer_address (const struct value_print_options *options,
+                               struct gdbarch *gdbarch,
                                CORE_ADDR address,
                                CORE_ADDR address,
-                               struct ui_file *stream,
-                               int addressprint)
+                               struct ui_file *stream)
 {
   CORE_ADDR func_addr
     = gdbarch_convert_from_func_ptr_addr (gdbarch, address,
 {
   CORE_ADDR func_addr
     = gdbarch_convert_from_func_ptr_addr (gdbarch, address,
@@ -1512,13 +1858,13 @@ print_function_pointer_address (struct gdbarch *gdbarch,
 
   /* If the function pointer is represented by a description, print
      the address of the description.  */
 
   /* If the function pointer is represented by a description, print
      the address of the description.  */
-  if (addressprint && func_addr != address)
+  if (options->addressprint && func_addr != address)
     {
       fputs_filtered ("@", stream);
       fputs_filtered (paddress (gdbarch, address), stream);
       fputs_filtered (": ", stream);
     }
     {
       fputs_filtered ("@", stream);
       fputs_filtered (paddress (gdbarch, address), stream);
       fputs_filtered (": ", stream);
     }
-  print_address_demangle (gdbarch, func_addr, stream, demangle);
+  print_address_demangle (options, gdbarch, func_addr, stream, demangle);
 }
 
 
 }
 
 
@@ -1559,7 +1905,7 @@ val_print_array_elements (struct type *type,
 {
   unsigned int things_printed = 0;
   unsigned len;
 {
   unsigned int things_printed = 0;
   unsigned len;
-  struct type *elttype, *index_type;
+  struct type *elttype, *index_type, *base_index_type;
   unsigned eltlen;
   /* Position of the array element we are examining to see
      whether it is repeated.  */
   unsigned eltlen;
   /* Position of the array element we are examining to see
      whether it is repeated.  */
@@ -1567,22 +1913,41 @@ val_print_array_elements (struct type *type,
   /* Number of repetitions we have detected so far.  */
   unsigned int reps;
   LONGEST low_bound, high_bound;
   /* Number of repetitions we have detected so far.  */
   unsigned int reps;
   LONGEST low_bound, high_bound;
+  LONGEST low_pos, high_pos;
 
   elttype = TYPE_TARGET_TYPE (type);
 
   elttype = TYPE_TARGET_TYPE (type);
-  eltlen = TYPE_LENGTH (check_typedef (elttype));
+  eltlen = type_length_units (check_typedef (elttype));
   index_type = TYPE_INDEX_TYPE (type);
 
   if (get_array_bounds (type, &low_bound, &high_bound))
     {
   index_type = TYPE_INDEX_TYPE (type);
 
   if (get_array_bounds (type, &low_bound, &high_bound))
     {
-      /* The array length should normally be HIGH_BOUND - LOW_BOUND + 1.
+      if (TYPE_CODE (index_type) == TYPE_CODE_RANGE)
+       base_index_type = TYPE_TARGET_TYPE (index_type);
+      else
+       base_index_type = index_type;
+
+      /* Non-contiguous enumerations types can by used as index types
+        in some languages (e.g. Ada).  In this case, the array length
+        shall be computed from the positions of the first and last
+        literal in the enumeration type, and not from the values
+        of these literals.  */
+      if (!discrete_position (base_index_type, low_bound, &low_pos)
+         || !discrete_position (base_index_type, high_bound, &high_pos))
+       {
+         warning (_("unable to get positions in array, use bounds instead"));
+         low_pos = low_bound;
+         high_pos = high_bound;
+       }
+
+      /* The array length should normally be HIGH_POS - LOW_POS + 1.
          But we have to be a little extra careful, because some languages
          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
+        such as Ada allow LOW_POS to be greater than HIGH_POS for
         empty arrays.  In that situation, the array length is just zero,
         not negative!  */
         empty arrays.  In that situation, the array length is just zero,
         not negative!  */
-      if (low_bound > high_bound)
+      if (low_pos > high_pos)
        len = 0;
       else
        len = 0;
       else
-       len = high_bound - low_bound + 1;
+       len = high_pos - low_pos + 1;
     }
   else
     {
     }
   else
     {
@@ -1597,7 +1962,7 @@ val_print_array_elements (struct type *type,
     {
       if (i != 0)
        {
     {
       if (i != 0)
        {
-         if (options->prettyprint_arrays)
+         if (options->prettyformat_arrays)
            {
              fprintf_filtered (stream, ",\n");
              print_spaces_filtered (2 + 2 * recurse, stream);
            {
              fprintf_filtered (stream, ",\n");
              print_spaces_filtered (2 + 2 * recurse, stream);
@@ -1618,12 +1983,12 @@ val_print_array_elements (struct type *type,
       if (options->repeat_count_threshold < UINT_MAX)
        {
          while (rep1 < len
       if (options->repeat_count_threshold < UINT_MAX)
        {
          while (rep1 < len
-                && value_available_contents_eq (val,
-                                                embedded_offset + i * eltlen,
-                                                val,
-                                                (embedded_offset
-                                                 + rep1 * eltlen),
-                                                eltlen))
+                && value_contents_eq (val,
+                                      embedded_offset + i * eltlen,
+                                      val,
+                                      (embedded_offset
+                                       + rep1 * eltlen),
+                                      eltlen))
            {
              ++reps;
              ++rep1;
            {
              ++reps;
              ++rep1;
@@ -1660,15 +2025,15 @@ val_print_array_elements (struct type *type,
 
 /* Read LEN bytes of target memory at address MEMADDR, placing the
    results in GDB's memory at MYADDR.  Returns a count of the bytes
 
 /* 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 an errno value in the location
-   pointed to by ERRNOPTR if ERRNOPTR is non-null.  */
+   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,
 
 /* 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 *errnoptr)
+                    int len, int *errptr)
 {
   int nread;                   /* Number of bytes actually read.  */
   int errcode;                 /* Error from last read.  */
 {
   int nread;                   /* Number of bytes actually read.  */
   int errcode;                 /* Error from last read.  */
@@ -1693,9 +2058,9 @@ partial_memory_read (CORE_ADDR memaddr, gdb_byte *myaddr,
          nread--;
        }
     }
          nread--;
        }
     }
-  if (errnoptr != NULL)
+  if (errptr != NULL)
     {
     {
-      *errnoptr = errcode;
+      *errptr = errcode;
     }
   return (nread);
 }
     }
   return (nread);
 }
@@ -1704,13 +2069,15 @@ partial_memory_read (CORE_ADDR memaddr, gdb_byte *myaddr,
    each.  Fetch at most FETCHLIMIT characters.  BUFFER will be set to a newly
    allocated buffer containing the string, which the caller is responsible to
    free, and BYTES_READ will be set to the number of bytes read.  Returns 0 on
    each.  Fetch at most FETCHLIMIT characters.  BUFFER will be set to a newly
    allocated buffer containing the string, which the caller is responsible to
    free, and BYTES_READ will be set to the number of bytes read.  Returns 0 on
-   success, or errno on failure.
+   success, or a target_xfer_status on failure.
 
 
-   If LEN > 0, reads exactly LEN 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.
+   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
 
    Unless an exception is thrown, BUFFER will always be allocated, even on
    failure.  In this case, some characters might have been read before the
@@ -1726,40 +2093,29 @@ int
 read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit,
             enum bfd_endian byte_order, gdb_byte **buffer, int *bytes_read)
 {
 read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit,
             enum bfd_endian byte_order, gdb_byte **buffer, int *bytes_read)
 {
-  int found_nul;               /* Non-zero if we found the nul char.  */
   int errcode;                 /* Errno returned from bad reads.  */
   unsigned int nfetch;         /* Chars to fetch / chars fetched.  */
   int errcode;                 /* Errno returned from bad reads.  */
   unsigned int nfetch;         /* Chars to fetch / chars fetched.  */
-  unsigned int chunksize;      /* Size of each fetch, in chars.  */
   gdb_byte *bufptr;            /* Pointer to next available byte in
                                   buffer.  */
   gdb_byte *bufptr;            /* Pointer to next available byte in
                                   buffer.  */
-  gdb_byte *limit;             /* First location past end of fetch buffer.  */
   struct cleanup *old_chain = NULL;    /* Top of the old cleanup chain.  */
 
   struct cleanup *old_chain = NULL;    /* Top of the old cleanup chain.  */
 
-  /* Decide how large of chunks to try to read in one operation.  This
-     is also pretty simple.  If LEN >= zero, then we want fetchlimit chars,
-     so we might as well read them all in one operation.  If LEN is -1, 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 = (len == -1 ? min (8, fetchlimit) : fetchlimit);
-
   /* Loop until we either have all the characters, or we encounter
      some error, such as bumping into the end of the address space.  */
 
   /* Loop until we either have all the characters, or we encounter
      some error, such as bumping into the end of the address space.  */
 
-  found_nul = 0;
   *buffer = NULL;
 
   old_chain = make_cleanup (free_current_contents, buffer);
 
   if (len > 0)
     {
   *buffer = NULL;
 
   old_chain = make_cleanup (free_current_contents, buffer);
 
   if (len > 0)
     {
-      *buffer = (gdb_byte *) xmalloc (len * width);
+      /* We want fetchlimit chars, so we might as well read them all in
+        one operation.  */
+      unsigned int fetchlen = min (len, fetchlimit);
+
+      *buffer = (gdb_byte *) xmalloc (fetchlen * width);
       bufptr = *buffer;
 
       bufptr = *buffer;
 
-      nfetch = partial_memory_read (addr, bufptr, len * width, &errcode)
+      nfetch = partial_memory_read (addr, bufptr, fetchlen * width, &errcode)
        / width;
       addr += nfetch * width;
       bufptr += nfetch * width;
        / width;
       addr += nfetch * width;
       bufptr += nfetch * width;
@@ -1767,6 +2123,18 @@ read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit,
   else if (len == -1)
     {
       unsigned long bufsize = 0;
   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 = min (8, fetchlimit);
 
       do
        {
 
       do
        {
@@ -1817,7 +2185,7 @@ read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit,
   else
     {                          /* Length of string is really 0!  */
       /* We always allocate *buffer.  */
   else
     {                          /* Length of string is really 0!  */
       /* We always allocate *buffer.  */
-      *buffer = bufptr = xmalloc (1);
+      *buffer = bufptr = (gdb_byte *) xmalloc (1);
       errcode = 0;
     }
 
       errcode = 0;
     }
 
@@ -1878,72 +2246,77 @@ print_wchar (gdb_wint_t w, const gdb_byte *orig,
   int need_escape = *need_escapep;
 
   *need_escapep = 0;
   int need_escape = *need_escapep;
 
   *need_escapep = 0;
-  if (gdb_iswprint (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
+  /* 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)
     {
     {
-      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:
        {
        {
-       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:
-         {
-           int i;
+         if (wchar_printable (w) && (!need_escape || (!gdb_iswdigit (w)
+                                                      && w != LCST ('8')
+                                                      && w != LCST ('9'))))
+           {
+             gdb_wchar_t wchar = w;
 
 
-           for (i = 0; i + width <= orig_len; i += width)
-             {
-               char octal[30];
-               ULONGEST value;
+             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,
+                 value = extract_unsigned_integer (&orig[i], width,
                                                  byte_order);
                                                  byte_order);
-               /* If the value fits in 3 octal digits, print it that
-                  way.  Otherwise, print it as a hex escape.  */
-               if (value <= 0777)
-                 sprintf (octal, "\\%.3o", (int) (value & 0777));
-               else
-                 sprintf (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];
+                 /* 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];
 
 
-               sprintf (octal, "\\%.3o", orig[i] & 0xff);
-               append_string_as_wide (octal, output);
-               ++i;
-             }
+                 xsnprintf (octal, sizeof (octal), "\\%.3o", orig[i] & 0xff);
+                 append_string_as_wide (octal, output);
+                 ++i;
+               }
 
 
-           *need_escapep = 1;
-         }
+             *need_escapep = 1;
+           }
          break;
        }
     }
          break;
        }
     }
@@ -1965,7 +2338,7 @@ generic_emit_char (int c, struct type *type, struct ui_file *stream,
   struct wchar_iterator *iter;
   int need_escape = 0;
 
   struct wchar_iterator *iter;
   int need_escape = 0;
 
-  buf = alloca (TYPE_LENGTH (type));
+  buf = (gdb_byte *) alloca (TYPE_LENGTH (type));
   pack_long (buf, type, c);
 
   iter = make_wchar_iterator (buf, TYPE_LENGTH (type),
   pack_long (buf, type, c);
 
   iter = make_wchar_iterator (buf, TYPE_LENGTH (type),
@@ -2025,16 +2398,253 @@ generic_emit_char (int c, struct type *type, struct ui_file *stream,
   make_cleanup_obstack_free (&output);
 
   convert_between_encodings (INTERMEDIATE_ENCODING, host_charset (),
   make_cleanup_obstack_free (&output);
 
   convert_between_encodings (INTERMEDIATE_ENCODING, host_charset (),
-                            obstack_base (&wchar_buf),
+                            (gdb_byte *) obstack_base (&wchar_buf),
                             obstack_object_size (&wchar_buf),
                             obstack_object_size (&wchar_buf),
-                            1, &output, translit_char);
+                            sizeof (gdb_wchar_t), &output, translit_char);
   obstack_1grow (&output, '\0');
 
   obstack_1grow (&output, '\0');
 
-  fputs_filtered (obstack_base (&output), stream);
+  fputs_filtered ((const char *) obstack_base (&output), stream);
 
   do_cleanups (cleanups);
 }
 
 
   do_cleanups (cleanups);
 }
 
+/* Return the repeat count of the next character/byte in ITER,
+   storing the result in VEC.  */
+
+static int
+count_next_character (struct wchar_iterator *iter,
+                     VEC (converted_character_d) **vec)
+{
+  struct converted_character *current;
+
+  if (VEC_empty (converted_character_d, *vec))
+    {
+      struct converted_character tmp;
+      gdb_wchar_t *chars;
+
+      tmp.num_chars
+       = wchar_iterate (iter, &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_safe_push (converted_character_d, *vec, &tmp);
+    }
+
+  current = VEC_last (converted_character_d, *vec);
+
+  /* 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
+           = wchar_iterate (iter, &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_safe_push (converted_character_d, *vec, &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 the target byte order.  OPTIONS
+   is the user's print options.  */
+
+static void
+print_converted_chars_to_obstack (struct obstack *obstack,
+                                 VEC (converted_character_d) *chars,
+                                 int quote_char, int width,
+                                 enum bfd_endian byte_order,
+                                 const struct value_print_options *options)
+{
+  unsigned int idx;
+  struct 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;
+           char *s;
+
+           /* 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 ("'"));
+           s = xstrprintf (_(" <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));
+             }
+           xfree (s);
+         }
+         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 outupt 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 = VEC_index (converted_character_d, 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;
 /* 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;
@@ -2054,16 +2664,13 @@ generic_printstr (struct ui_file *stream, struct type *type,
 {
   enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
   unsigned int i;
 {
   enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
   unsigned int i;
-  unsigned int things_printed = 0;
-  int in_quotes = 0;
-  int need_comma = 0;
   int width = TYPE_LENGTH (type);
   struct obstack wchar_buf, output;
   struct cleanup *cleanup;
   struct wchar_iterator *iter;
   int finished = 0;
   int width = TYPE_LENGTH (type);
   struct obstack wchar_buf, output;
   struct cleanup *cleanup;
   struct wchar_iterator *iter;
   int finished = 0;
-  int need_escape = 0;
-  gdb_wchar_t wide_quote_char = gdb_btowc (quote_char);
+  struct converted_character *last;
+  VEC (converted_character_d) *converted_chars;
 
   if (length == -1)
     {
 
   if (length == -1)
     {
@@ -2097,166 +2704,46 @@ generic_printstr (struct ui_file *stream, struct type *type,
   /* Arrange to iterate over the characters, in wchar_t form.  */
   iter = make_wchar_iterator (string, length * width, encoding, width);
   cleanup = make_cleanup_wchar_iterator (iter);
   /* Arrange to iterate over the characters, in wchar_t form.  */
   iter = make_wchar_iterator (string, length * width, encoding, width);
   cleanup = make_cleanup_wchar_iterator (iter);
+  converted_chars = NULL;
+  make_cleanup (VEC_cleanup (converted_character_d), &converted_chars);
 
 
-  /* WCHAR_BUF is the obstack we use to represent the string in
-     wchar_t form.  */
-  obstack_init (&wchar_buf);
-  make_cleanup_obstack_free (&wchar_buf);
-
-  while (!finished && things_printed < options->print_max)
+  /* 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 num_chars;
-      enum wchar_iterate_result result;
-      gdb_wchar_t *chars;
-      const gdb_byte *buf;
-      size_t buflen;
+      int r;
 
       QUIT;
 
 
       QUIT;
 
-      if (need_comma)
-       {
-         obstack_grow_wstr (&wchar_buf, LCST (", "));
-         need_comma = 0;
-       }
-
-      num_chars = wchar_iterate (iter, &result, &chars, &buf, &buflen);
-      /* We only look at repetitions when we were able to convert a
-        single character in isolation.  This makes the code simpler
-        and probably does the sensible thing in the majority of
-        cases.  */
-      while (num_chars == 1 && things_printed < options->print_max)
-       {
-         /* Count the number of repetitions.  */
-         unsigned int reps = 0;
-         gdb_wchar_t current_char = chars[0];
-         const gdb_byte *orig_buf = buf;
-         int orig_len = buflen;
-
-         if (need_comma)
-           {
-             obstack_grow_wstr (&wchar_buf, LCST (", "));
-             need_comma = 0;
-           }
-
-         while (num_chars == 1 && current_char == chars[0])
-           {
-             num_chars = wchar_iterate (iter, &result, &chars,
-                                        &buf, &buflen);
-             ++reps;
-           }
+      /* Grab the next character and repeat count.  */
+      r = count_next_character (iter, &converted_chars);
 
 
-         /* Emit CURRENT_CHAR according to the repetition count and
-            options.  */
-         if (reps > options->repeat_count_threshold)
-           {
-             if (in_quotes)
-               {
-                 if (options->inspect_it)
-                   obstack_grow_wstr (&wchar_buf, LCST ("\\"));
-                 obstack_grow (&wchar_buf, &wide_quote_char,
-                               sizeof (gdb_wchar_t));
-                 obstack_grow_wstr (&wchar_buf, LCST (", "));
-                 in_quotes = 0;
-               }
-             obstack_grow_wstr (&wchar_buf, LCST ("'"));
-             need_escape = 0;
-             print_wchar (current_char, orig_buf, orig_len, width,
-                          byte_order, &wchar_buf, '\'', &need_escape);
-             obstack_grow_wstr (&wchar_buf, LCST ("'"));
-             {
-               /* Painful gyrations.  */
-               int j;
-               char *s = xstrprintf (_(" <repeats %u times>"), reps);
-
-               for (j = 0; s[j]; ++j)
-                 {
-                   gdb_wchar_t w = gdb_btowc (s[j]);
-                   obstack_grow (&wchar_buf, &w, sizeof (gdb_wchar_t));
-                 }
-               xfree (s);
-             }
-             things_printed += options->repeat_count_threshold;
-             need_comma = 1;
-           }
-         else
-           {
-             /* Saw the character one or more times, but fewer than
-                the repetition threshold.  */
-             if (!in_quotes)
-               {
-                 if (options->inspect_it)
-                   obstack_grow_wstr (&wchar_buf, LCST ("\\"));
-                 obstack_grow (&wchar_buf, &wide_quote_char,
-                               sizeof (gdb_wchar_t));
-                 in_quotes = 1;
-                 need_escape = 0;
-               }
+      /* If less than zero, the end of the input string was reached.  */
+      if (r < 0)
+       break;
 
 
-             while (reps-- > 0)
-               {
-                 print_wchar (current_char, orig_buf,
-                              orig_len, width,
-                              byte_order, &wchar_buf,
-                              quote_char, &need_escape);
-                 ++things_printed;
-               }
-           }
-       }
+      /* Otherwise, add the count to the total print count and get
+        the next character.  */
+      i += r;
+    }
 
 
-      /* NUM_CHARS and the other outputs from wchar_iterate are valid
-        here regardless of which branch was taken above.  */
-      if (num_chars < 0)
-       {
-         /* Hit EOF.  */
-         finished = 1;
-         break;
-       }
+  /* Get the last element and determine if the entire string was
+     processed.  */
+  last = VEC_last (converted_character_d, converted_chars);
+  finished = (last->result == wchar_iterate_eof);
 
 
-      switch (result)
-       {
-       case wchar_iterate_invalid:
-         if (!in_quotes)
-           {
-             if (options->inspect_it)
-               obstack_grow_wstr (&wchar_buf, LCST ("\\"));
-             obstack_grow (&wchar_buf, &wide_quote_char,
-                           sizeof (gdb_wchar_t));
-             in_quotes = 1;
-           }
-         need_escape = 0;
-         print_wchar (gdb_WEOF, buf, buflen, width, byte_order,
-                      &wchar_buf, quote_char, &need_escape);
-         break;
+  /* Ensure that CONVERTED_CHARS is terminated.  */
+  last->result = wchar_iterate_eof;
 
 
-       case wchar_iterate_incomplete:
-         if (in_quotes)
-           {
-             if (options->inspect_it)
-               obstack_grow_wstr (&wchar_buf, LCST ("\\"));
-             obstack_grow (&wchar_buf, &wide_quote_char,
-                           sizeof (gdb_wchar_t));
-             obstack_grow_wstr (&wchar_buf, LCST (","));
-             in_quotes = 0;
-           }
-         obstack_grow_wstr (&wchar_buf,
-                            LCST (" <incomplete sequence "));
-         print_wchar (gdb_WEOF, buf, buflen, width,
-                      byte_order, &wchar_buf,
-                      0, &need_escape);
-         obstack_grow_wstr (&wchar_buf, LCST (">"));
-         finished = 1;
-         break;
-       }
-    }
+  /* WCHAR_BUF is the obstack we use to represent the string in
+     wchar_t form.  */
+  obstack_init (&wchar_buf);
+  make_cleanup_obstack_free (&wchar_buf);
 
 
-  /* Terminate the quotes if necessary.  */
-  if (in_quotes)
-    {
-      if (options->inspect_it)
-       obstack_grow_wstr (&wchar_buf, LCST ("\\"));
-      obstack_grow (&wchar_buf, &wide_quote_char,
-                   sizeof (gdb_wchar_t));
-    }
+  /* 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 ("..."));
 
   if (force_ellipses || !finished)
     obstack_grow_wstr (&wchar_buf, LCST ("..."));
@@ -2266,12 +2753,12 @@ generic_printstr (struct ui_file *stream, struct type *type,
   make_cleanup_obstack_free (&output);
 
   convert_between_encodings (INTERMEDIATE_ENCODING, host_charset (),
   make_cleanup_obstack_free (&output);
 
   convert_between_encodings (INTERMEDIATE_ENCODING, host_charset (),
-                            obstack_base (&wchar_buf),
+                            (gdb_byte *) obstack_base (&wchar_buf),
                             obstack_object_size (&wchar_buf),
                             obstack_object_size (&wchar_buf),
-                            1, &output, translit_char);
+                            sizeof (gdb_wchar_t), &output, translit_char);
   obstack_1grow (&output, '\0');
 
   obstack_1grow (&output, '\0');
 
-  fputs_filtered (obstack_base (&output), stream);
+  fputs_filtered ((const char *) obstack_base (&output), stream);
 
   do_cleanups (cleanup);
 }
 
   do_cleanups (cleanup);
 }
@@ -2291,7 +2778,7 @@ val_print_string (struct type *elttype, const char *encoding,
                  const struct value_print_options *options)
 {
   int force_ellipsis = 0;      /* Force ellipsis to be printed if nonzero.  */
                  const struct value_print_options *options)
 {
   int force_ellipsis = 0;      /* Force ellipsis to be printed if nonzero.  */
-  int errcode;                 /* Errno returned from bad reads.  */
+  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;
   int found_nul;               /* Non-zero if we found the nul char.  */
   unsigned int fetchlimit;     /* Maximum number of chars to print.  */
   int bytes_read;
@@ -2312,8 +2799,8 @@ val_print_string (struct type *elttype, const char *encoding,
   fetchlimit = (len == -1 ? options->print_max : min (len,
                                                      options->print_max));
 
   fetchlimit = (len == -1 ? options->print_max : min (len,
                                                      options->print_max));
 
-  errcode = read_string (addr, len, width, fetchlimit, byte_order,
-                        &buffer, &bytes_read);
+  err = read_string (addr, len, width, fetchlimit, byte_order,
+                    &buffer, &bytes_read);
   old_chain = make_cleanup (xfree, buffer);
 
   addr += bytes_read;
   old_chain = make_cleanup (xfree, buffer);
 
   addr += bytes_read;
@@ -2323,8 +2810,10 @@ val_print_string (struct type *elttype, const char *encoding,
      LEN is -1.  */
 
   /* Determine found_nul by looking at the last character read.  */
      LEN is -1.  */
 
   /* Determine found_nul by looking at the last character read.  */
-  found_nul = extract_unsigned_integer (buffer + bytes_read - width, width,
-                                       byte_order) == 0;
+  found_nul = 0;
+  if (bytes_read >= width)
+    found_nul = extract_unsigned_integer (buffer + bytes_read - width, width,
+                                         byte_order) == 0;
   if (len == -1 && !found_nul)
     {
       gdb_byte *peekbuf;
   if (len == -1 && !found_nul)
     {
       gdb_byte *peekbuf;
@@ -2339,7 +2828,7 @@ val_print_string (struct type *elttype, const char *encoding,
          && extract_unsigned_integer (peekbuf, width, byte_order) != 0)
        force_ellipsis = 1;
     }
          && extract_unsigned_integer (peekbuf, width, byte_order) != 0)
        force_ellipsis = 1;
     }
-  else if ((len >= 0 && errcode != 0) || (len > bytes_read / width))
+  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
     {
       /* Getting an error when we have a requested length, or fetching less
          than the number of characters actually requested, always make us
@@ -2350,30 +2839,22 @@ val_print_string (struct type *elttype, const char *encoding,
   /* 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 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 (errcode == 0 || bytes_read > 0)
+  if (err == 0 || bytes_read > 0)
     {
     {
-      if (options->addressprint)
-       {
-         fputs_filtered (" ", stream);
-       }
       LA_PRINT_STRING (stream, elttype, buffer, bytes_read / width,
                       encoding, force_ellipsis, options);
     }
 
       LA_PRINT_STRING (stream, elttype, buffer, bytes_read / width,
                       encoding, force_ellipsis, options);
     }
 
-  if (errcode != 0)
+  if (err != 0)
     {
     {
-      if (errcode == EIO)
-       {
-         fprintf_filtered (stream, " <Address ");
-         fputs_filtered (paddress (gdbarch, addr), stream);
-         fprintf_filtered (stream, " out of bounds>");
-       }
-      else
-       {
-         fprintf_filtered (stream, " <Error reading address ");
-         fputs_filtered (paddress (gdbarch, addr), stream);
-         fprintf_filtered (stream, ": %s>", safe_strerror (errcode));
-       }
+      char *str;
+
+      str = memory_error_message (TARGET_XFER_E_IO, gdbarch, addr);
+      make_cleanup (xfree, str);
+
+      fprintf_filtered (stream, "<error: ");
+      fputs_filtered (str, stream);
+      fprintf_filtered (stream, ">");
     }
 
   gdb_flush (stream);
     }
 
   gdb_flush (stream);
@@ -2522,7 +3003,7 @@ set_print (char *arg, int from_tty)
 {
   printf_unfiltered (
      "\"set print\" must be followed by the name of a print subcommand.\n");
 {
   printf_unfiltered (
      "\"set print\" must be followed by the name of a print subcommand.\n");
-  help_list (setprintlist, "set print ", -1, gdb_stdout);
+  help_list (setprintlist, "set print ", all_commands, gdb_stdout);
 }
 
 static void
 }
 
 static void
@@ -2530,6 +3011,21 @@ show_print (char *args, int from_tty)
 {
   cmd_show_list (showprintlist, from_tty, "");
 }
 {
   cmd_show_list (showprintlist, from_tty, "");
 }
+
+static void
+set_print_raw (char *arg, int from_tty)
+{
+  printf_unfiltered (
+     "\"set print raw\" must be followed by the name of a \"print raw\" subcommand.\n");
+  help_list (setprintrawlist, "set print raw ", all_commands, gdb_stdout);
+}
+
+static void
+show_print_raw (char *args, int from_tty)
+{
+  cmd_show_list (showprintrawlist, from_tty, "");
+}
+
 \f
 void
 _initialize_valprint (void)
 \f
 void
 _initialize_valprint (void)
@@ -2547,11 +3043,19 @@ _initialize_valprint (void)
   add_alias_cmd ("p", "print", no_class, 1, &showlist);
   add_alias_cmd ("pr", "print", no_class, 1, &showlist);
 
   add_alias_cmd ("p", "print", no_class, 1, &showlist);
   add_alias_cmd ("pr", "print", no_class, 1, &showlist);
 
+  add_prefix_cmd ("raw", no_class, set_print_raw,
+                 _("\
+Generic command for setting what things to print in \"raw\" mode."),
+                 &setprintrawlist, "set print raw ", 0, &setprintlist);
+  add_prefix_cmd ("raw", no_class, show_print_raw,
+                 _("Generic command for showing \"print raw\" settings."),
+                 &showprintrawlist, "show print raw ", 0, &showprintlist);
+
   add_setshow_uinteger_cmd ("elements", no_class,
                            &user_print_options.print_max, _("\
 Set limit on string chars or array elements to print."), _("\
 Show limit on string chars or array elements to print."), _("\
   add_setshow_uinteger_cmd ("elements", no_class,
                            &user_print_options.print_max, _("\
 Set limit on string chars or array elements to print."), _("\
 Show limit on string chars or array elements to print."), _("\
-\"set print elements 0\" causes there to be no limit."),
+\"set print elements unlimited\" causes there to be no limit."),
                            NULL,
                            show_print_max,
                            &setprintlist, &showprintlist);
                            NULL,
                            show_print_max,
                            &setprintlist, &showprintlist);
@@ -2568,17 +3072,17 @@ Show printing of char arrays to stop at first null char."), NULL,
                            &user_print_options.repeat_count_threshold, _("\
 Set threshold for repeated print elements."), _("\
 Show threshold for repeated print elements."), _("\
                            &user_print_options.repeat_count_threshold, _("\
 Set threshold for repeated print elements."), _("\
 Show threshold for repeated print elements."), _("\
-\"set print repeats 0\" causes all elements to be individually printed."),
+\"set print repeats unlimited\" causes all elements to be individually printed."),
                            NULL,
                            show_repeat_count_threshold,
                            &setprintlist, &showprintlist);
 
   add_setshow_boolean_cmd ("pretty", class_support,
                            NULL,
                            show_repeat_count_threshold,
                            &setprintlist, &showprintlist);
 
   add_setshow_boolean_cmd ("pretty", class_support,
-                          &user_print_options.prettyprint_structs, _("\
-Set prettyprinting of structures."), _("\
-Show prettyprinting of structures."), NULL,
+                          &user_print_options.prettyformat_structs, _("\
+Set pretty formatting of structures."), _("\
+Show pretty formatting of structures."), NULL,
                           NULL,
                           NULL,
-                          show_prettyprint_structs,
+                          show_prettyformat_structs,
                           &setprintlist, &showprintlist);
 
   add_setshow_boolean_cmd ("union", class_support,
                           &setprintlist, &showprintlist);
 
   add_setshow_boolean_cmd ("union", class_support,
@@ -2590,11 +3094,11 @@ Show printing of unions interior to structures."), NULL,
                           &setprintlist, &showprintlist);
 
   add_setshow_boolean_cmd ("array", class_support,
                           &setprintlist, &showprintlist);
 
   add_setshow_boolean_cmd ("array", class_support,
-                          &user_print_options.prettyprint_arrays, _("\
-Set prettyprinting of arrays."), _("\
-Show prettyprinting of arrays."), NULL,
+                          &user_print_options.prettyformat_arrays, _("\
+Set pretty formatting of arrays."), _("\
+Show pretty formatting of arrays."), NULL,
                           NULL,
                           NULL,
-                          show_prettyprint_arrays,
+                          show_prettyformat_arrays,
                           &setprintlist, &showprintlist);
 
   add_setshow_boolean_cmd ("address", class_support,
                           &setprintlist, &showprintlist);
 
   add_setshow_boolean_cmd ("address", class_support,
@@ -2605,6 +3109,14 @@ Show printing of addresses."), NULL,
                           show_addressprint,
                           &setprintlist, &showprintlist);
 
                           show_addressprint,
                           &setprintlist, &showprintlist);
 
+  add_setshow_boolean_cmd ("symbol", class_support,
+                          &user_print_options.symbol_print, _("\
+Set printing of symbol names when printing pointers."), _("\
+Show printing of symbol names when printing pointers."),
+                          NULL, NULL,
+                          show_symbol_print,
+                          &setprintlist, &showprintlist);
+
   add_setshow_zuinteger_cmd ("input-radix", class_support, &input_radix_1,
                             _("\
 Set default input radix for entering numbers."), _("\
   add_setshow_zuinteger_cmd ("input-radix", class_support, &input_radix_1,
                             _("\
 Set default input radix for entering numbers."), _("\
This page took 0.051547 seconds and 4 git commands to generate.