]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Rewrite Ada character printer
authorTom Tromey <tom@tromey.com>
Tue, 23 Dec 2025 21:40:19 +0000 (14:40 -0700)
committerTom Tromey <tom@tromey.com>
Sat, 31 Jan 2026 18:38:47 +0000 (11:38 -0700)
This adds a Ada-specific subclass of wchar_printer and arranges to
use it.

gdb/ada-lang.c
gdb/ada-lang.h
gdb/ada-valprint.c

index 7e453d7118c0c30881b2402fc43b9585c65361e4..4c89776777f2fdcb15241205db09387a019e7c7d 100644 (file)
@@ -64,6 +64,7 @@
 #include "ada-exp.h"
 #include "charset.h"
 #include "ax-gdb.h"
+#include "char-print.h"
 
 static struct type *desc_base_type (struct type *);
 
@@ -13480,6 +13481,56 @@ ada_get_symbol_name_matcher (const lookup_name_info &lookup_name)
     }
 }
 
+class ada_wchar_printer : public wchar_printer
+{
+public:
+
+  using wchar_printer::wchar_printer;
+
+protected:
+
+  bool printable (gdb_wchar_t w) const override
+  {
+    return gdb_iswprint (w);
+  }
+
+  void print_char (gdb_wchar_t w) override;
+  void print_escape (const gdb_byte *orig, int orig_len) override;
+};
+
+void
+ada_wchar_printer::print_char (gdb_wchar_t w)
+{
+  if (w == gdb_btowc (m_quoter) && m_quoter == '"')
+    m_file.write (LCST ("\"\""));
+  else
+    m_file.write (w);
+}
+
+void
+ada_wchar_printer::print_escape (const gdb_byte *orig, int orig_len)
+{
+  int i;
+
+  for (i = 0; i + m_width <= orig_len; i += m_width)
+    {
+      ULONGEST value = extract_unsigned_integer (&orig[i], m_width,
+                                                m_byte_order);
+      /* Follow GNAT's lead here and only use 6 digits for
+        wide_wide_character.  */
+      gdb_printf (&m_file, "[\"%0*lx\"]",
+                 std::min (6, m_width * 2),
+                 (unsigned long) value);
+    }
+
+  /* If we somehow have extra bytes, print them now.  */
+  while (i < orig_len)
+    {
+      gdb_printf (&m_file, "[\"%02x\"]", orig[i] & 0xff);
+      ++i;
+    }
+}
+
 /* Class representing the Ada language.  */
 
 class ada_language : public language_defn
@@ -13896,7 +13947,7 @@ public:
   void printchar (int ch, struct type *chtype,
                  struct ui_file *stream) const override
   {
-    ada_printchar (ch, chtype, stream);
+    ada_wchar_printer (chtype, '\'').print (ch, stream);
   }
 
   /* See language.h.  */
@@ -13913,8 +13964,10 @@ public:
       generic_printstr (stream, elttype, string, length, encoding,
                        force_ellipses, '"', 0, options);
     else
-      ada_printstr (stream, elttype, string, length, encoding,
-                   force_ellipses, options);
+      {
+       ada_wchar_printer printer (elttype, '"', encoding);
+       printer.print (stream, string, length, force_ellipses, 0, options);
+      }
   }
 
   /* See language.h.  */
index c491a43c04bb6a8819c90c43a65788aa9776216c..60e192bc7f7eff3b3a246abd7e3b51284663b40e 100644 (file)
@@ -172,14 +172,6 @@ extern void ada_value_print (struct value *, struct ui_file *,
 
                                /* Defined in ada-lang.c */
 
-extern void ada_emit_char (int, struct type *, struct ui_file *, int, int);
-
-extern void ada_printchar (int, struct type *, struct ui_file *);
-
-extern void ada_printstr (struct ui_file *, struct type *, const gdb_byte *,
-                         unsigned int, const char *, int,
-                         const struct value_print_options *);
-
 struct value *ada_convert_actual (struct value *actual,
                                  struct type *formal_type0);
 
index 032ffc285875a08ea728da20f75fd0c54e67289a..66b083ef5edc03eb26a488394caafda951d9f347 100644 (file)
@@ -253,35 +253,6 @@ val_print_packed_array_elements (struct type *type, const gdb_byte *valaddr,
     }
 }
 
-/* Print the character C on STREAM as part of the contents of a literal
-   string whose delimiter is QUOTER.  TYPE_LEN is the length in bytes
-   of the character.  */
-
-void
-ada_emit_char (int c, struct type *type, struct ui_file *stream,
-              int quoter, int type_len)
-{
-  /* If this character fits in the normal ASCII range, and is
-     a printable character, then print the character as if it was
-     an ASCII character, even if this is a wide character.
-     The UCHAR_MAX check is necessary because the c_isascii function
-     requires that its argument have a value of an unsigned char,
-     or EOF (EOF is obviously not printable).  */
-  if (c <= UCHAR_MAX && c_isascii (c) && c_isprint (c))
-    {
-      if (c == quoter && c == '"')
-       gdb_printf (stream, "\"\"");
-      else
-       gdb_printf (stream, "%c", c);
-    }
-  else
-    {
-      /* Follow GNAT's lead here and only use 6 digits for
-        wide_wide_character.  */
-      gdb_printf (stream, "[\"%0*x\"]", std::min (6, type_len * 2), c);
-    }
-}
-
 /* Character #I of STRING, given that TYPE_LEN is the size in bytes
    of a character.  */
 
@@ -357,14 +328,6 @@ ada_print_floating (const gdb_byte *valaddr, struct type *type,
     gdb_printf (stream, "%s", &s[skip_count]);
 }
 
-void
-ada_printchar (int c, struct type *type, struct ui_file *stream)
-{
-  gdb_puts ("'", stream);
-  ada_emit_char (c, type, stream, '\'', type->length ());
-  gdb_puts ("'", stream);
-}
-
 /* [From print_type_scalar in typeprint.c].   Print VAL on STREAM in a
    form appropriate for TYPE, if non-NULL.  If TYPE is NULL, print VAL
    like a default signed integer.  */
@@ -433,104 +396,6 @@ ada_print_scalar (struct type *type, LONGEST val, struct ui_file *stream)
     }
 }
 
-/* Print the character string STRING, printing at most LENGTH characters.
-   Printing stops early if the number hits print_max; repeat counts
-   are printed as appropriate.  Print ellipses at the end if we
-   had to stop before printing LENGTH characters, or if FORCE_ELLIPSES.
-   TYPE_LEN is the length (1 or 2) of the character type.  */
-
-static void
-printstr (struct ui_file *stream, struct type *elttype, const gdb_byte *string,
-         unsigned int length, int force_ellipses, int type_len,
-         const struct value_print_options *options)
-{
-  enum bfd_endian byte_order = type_byte_order (elttype);
-  unsigned int i;
-  unsigned int things_printed = 0;
-  int in_quotes = 0;
-  int need_comma = 0;
-
-  if (length == 0)
-    {
-      gdb_puts ("\"\"", stream);
-      return;
-    }
-
-  unsigned int print_max_chars = get_print_max_chars (options);
-  for (i = 0; i < length && things_printed < print_max_chars; i += 1)
-    {
-      /* Position of the character we are examining
-        to see whether it is repeated.  */
-      unsigned int rep1;
-      /* Number of repetitions we have detected so far.  */
-      unsigned int reps;
-
-      QUIT;
-
-      if (need_comma)
-       {
-         gdb_puts (", ", stream);
-         need_comma = 0;
-       }
-
-      rep1 = i + 1;
-      reps = 1;
-      while (rep1 < length
-            && char_at (string, rep1, type_len, byte_order)
-               == char_at (string, i, type_len, byte_order))
-       {
-         rep1 += 1;
-         reps += 1;
-       }
-
-      if (reps > options->repeat_count_threshold)
-       {
-         if (in_quotes)
-           {
-             gdb_puts ("\", ", stream);
-             in_quotes = 0;
-           }
-         gdb_puts ("'", stream);
-         ada_emit_char (char_at (string, i, type_len, byte_order),
-                        elttype, stream, '\'', type_len);
-         gdb_puts ("'", stream);
-         gdb_printf (stream, _(" %p[<repeats %u times>%p]"),
-                     metadata_style.style ().ptr (), reps, nullptr);
-         i = rep1 - 1;
-         things_printed += options->repeat_count_threshold;
-         need_comma = 1;
-       }
-      else
-       {
-         if (!in_quotes)
-           {
-             gdb_puts ("\"", stream);
-             in_quotes = 1;
-           }
-         ada_emit_char (char_at (string, i, type_len, byte_order),
-                        elttype, stream, '"', type_len);
-         things_printed += 1;
-       }
-    }
-
-  /* Terminate the quotes if necessary.  */
-  if (in_quotes)
-    gdb_puts ("\"", stream);
-
-  if (force_ellipses || i < length)
-    gdb_puts ("...", stream);
-}
-
-void
-ada_printstr (struct ui_file *stream, struct type *type,
-             const gdb_byte *string, unsigned int length,
-             const char *encoding, int force_ellipses,
-             const struct value_print_options *options)
-{
-  printstr (stream, type, string, length, force_ellipses, type->length (),
-           options);
-}
-
 static int
 print_variant_part (struct value *value, int field_num,
                    struct value *outer_value,
@@ -705,8 +570,8 @@ ada_val_print_string (struct type *type, const gdb_byte *valaddr,
       len = temp_len;
     }
 
-  printstr (stream, elttype, valaddr + offset_aligned, len, 0,
-           eltlen, options);
+  current_language->printstr (stream, elttype, valaddr + offset_aligned,
+                             len, nullptr, 0, options);
 }
 
 /* Implement Ada value_print'ing for the case where TYPE is a
@@ -801,7 +666,7 @@ ada_value_print_num (struct value *val, struct ui_file *stream, int recurse,
 
              gdb_puts (" ", stream);
              c = unpack_long (type, valaddr);
-             ada_printchar (c, type, stream);
+             current_language->printchar (c, type, stream);
            }
        }
       return;