@@ -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,8 @@ class ada_language : public language_defn
void printchar (int ch, struct type *chtype,
struct ui_file *stream) const override
{
- ada_printchar (ch, chtype, stream);
+ ada_wchar_printer printer (chtype, '\'');
+ printer.print (ch, stream);
}
/* See language.h. */
@@ -13913,8 +13965,10 @@ class ada_language : public language_defn
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. */
@@ -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);
@@ -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
@@ -800,7 +665,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;