[v3,6/8] Rewrite Modula-2 character printer

Message ID 20251228-string-printing-2-v3-6-ec5cc9dd0c71@tromey.com
State New
Headers
Series Refactor character printing |

Commit Message

Tom Tromey Dec. 28, 2025, 8:13 p.m. UTC
  This adds a Modula-2-specific subclass of wchar_printer and arranges
to use it.
---
 gdb/m2-lang.c | 145 ++++++++++++----------------------------------------------
 gdb/m2-lang.h |   5 --
 2 files changed, 29 insertions(+), 121 deletions(-)
  

Patch

diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c
index a06dd489c71700d0ae1c3a04d7a5586ae3d4923f..22fa510d948bc7a508aec7289b339089c147218c 100644
--- a/gdb/m2-lang.c
+++ b/gdb/m2-lang.c
@@ -29,6 +29,7 @@ 
 #include "valprint.h"
 #include "gdbarch.h"
 #include "m2-exp.h"
+#include "char-print.h"
 
 /* A helper function for UNOP_HIGH.  */
 
@@ -139,15 +140,38 @@  m2_language::language_arch_info (struct gdbarch *gdbarch,
   lai->set_bool_type (builtin->builtin_bool, "BOOLEAN");
 }
 
+class m2_wchar_printer : public wchar_printer
+{
+public:
+
+  using wchar_printer::wchar_printer;
+
+protected:
+
+  bool printable (gdb_wchar_t w) const override
+  {
+    /* Historically the Modula-2 code in gdb handled \e as well.  */
+    return (w == LCST ('\033')
+	    || wchar_printer::printable (w));
+  }
+
+  void print_char (gdb_wchar_t w) override
+  {
+    if (w == LCST ('\033'))
+      m_file.write (LCST ("\\e"));
+    else
+      wchar_printer::print_char (w);
+  }
+};
+
 /* See language.h.  */
 
 void
 m2_language::printchar (int c, struct type *type,
 			struct ui_file *stream) const
 {
-  gdb_puts ("'", stream);
-  emitchar (c, type, stream, '\'');
-  gdb_puts ("'", stream);
+  m2_wchar_printer printer (type, '\'');
+  printer.print (c, stream);
 }
 
 /* See language.h.  */
@@ -158,119 +182,8 @@  m2_language::printstr (struct ui_file *stream, struct type *elttype,
 			const char *encoding, int force_ellipses,
 			const struct value_print_options *options) const
 {
-  unsigned int i;
-  unsigned int things_printed = 0;
-  int in_quotes = 0;
-  int need_comma = 0;
-
-  if (length == 0)
-    {
-      gdb_puts ("\"\"");
-      return;
-    }
-
-  unsigned int print_max_chars = get_print_max_chars (options);
-  for (i = 0; i < length && things_printed < print_max_chars; ++i)
-    {
-      /* 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 && string[rep1] == string[i])
-	{
-	  ++rep1;
-	  ++reps;
-	}
-
-      if (reps > options->repeat_count_threshold)
-	{
-	  if (in_quotes)
-	    {
-	      gdb_puts ("\", ", stream);
-	      in_quotes = 0;
-	    }
-	  printchar (string[i], elttype, stream);
-	  gdb_printf (stream, " <repeats %u times>", reps);
-	  i = rep1 - 1;
-	  things_printed += options->repeat_count_threshold;
-	  need_comma = 1;
-	}
-      else
-	{
-	  if (!in_quotes)
-	    {
-	      gdb_puts ("\"", stream);
-	      in_quotes = 1;
-	    }
-	  emitchar (string[i], elttype, stream, '"');
-	  ++things_printed;
-	}
-    }
-
-  /* Terminate the quotes if necessary.  */
-  if (in_quotes)
-    gdb_puts ("\"", stream);
-
-  if (force_ellipses || i < length)
-    gdb_puts ("...", stream);
-}
-
-/* See language.h.  */
-
-void
-m2_language::emitchar (int ch, struct type *chtype,
-		       struct ui_file *stream, int quoter) const
-{
-  ch &= 0xFF;			/* Avoid sign bit follies.  */
-
-  if (PRINT_LITERAL_FORM (ch))
-    {
-      if (ch == '\\' || ch == quoter)
-	gdb_puts ("\\", stream);
-      gdb_printf (stream, "%c", ch);
-    }
-  else
-    {
-      switch (ch)
-	{
-	case '\n':
-	  gdb_puts ("\\n", stream);
-	  break;
-	case '\b':
-	  gdb_puts ("\\b", stream);
-	  break;
-	case '\t':
-	  gdb_puts ("\\t", stream);
-	  break;
-	case '\f':
-	  gdb_puts ("\\f", stream);
-	  break;
-	case '\r':
-	  gdb_puts ("\\r", stream);
-	  break;
-	case '\033':
-	  gdb_puts ("\\e", stream);
-	  break;
-	case '\007':
-	  gdb_puts ("\\a", stream);
-	  break;
-	default:
-	  gdb_printf (stream, "\\%.3o", (unsigned int) ch);
-	  break;
-	}
-    }
+  m2_wchar_printer printer (elttype, '"', encoding);
+  printer.print (stream, string, length, force_ellipses, 0, options);
 }
 
 /* Called during architecture gdbarch initialisation to create language
diff --git a/gdb/m2-lang.h b/gdb/m2-lang.h
index 86421a69af23f1b0885534800a9d7f5ae0701b46..ae3a345466d508f92b04570e57283dd5b7020068 100644
--- a/gdb/m2-lang.h
+++ b/gdb/m2-lang.h
@@ -92,11 +92,6 @@  class m2_language : public language_defn
 
   /* See language.h.  */
 
-  void emitchar (int ch, struct type *chtype,
-		 struct ui_file *stream, int quoter) const;
-
-  /* See language.h.  */
-
   void printchar (int ch, struct type *chtype,
 		  struct ui_file *stream) const override;