public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Tom Tromey <tom@tromey.com>
To: gdb-patches@sourceware.org
Cc: Tom Tromey <tom@tromey.com>
Subject: [PATCH 11/18] Add an emitter callback to generic_printstr and generic_emit_char
Date: Wed, 16 Feb 2022 06:55:11 -0700	[thread overview]
Message-ID: <20220216135518.3162480-12-tom@tromey.com> (raw)
In-Reply-To: <20220216135518.3162480-1-tom@tromey.com>

This adds an emitter callback to generic_printstr and
generic_emit_char, passing it through to print_wchar.  print_wchar is
modified to call it, if possible.  This will be used to let languages
override the way that escape sequences are emitted.  Nothing uses this
yet, that comes later in the series.
---
 gdb/valprint.c | 41 ++++++++++++++++++++++++++++-------------
 gdb/valprint.h | 30 ++++++++++++++++++++++++++++--
 2 files changed, 56 insertions(+), 15 deletions(-)

diff --git a/gdb/valprint.c b/gdb/valprint.c
index 00c0cd2c72a..c0e5e678005 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -2201,12 +2201,19 @@ print_wchar (gdb_wint_t w, const gdb_byte *orig,
 	     int orig_len, int width,
 	     enum bfd_endian byte_order,
 	     struct obstack *output,
-	     int quoter, bool *need_escapep)
+	     int quoter, bool *need_escapep,
+	     emit_char_ftype emitter)
 {
   bool need_escape = *need_escapep;
 
   *need_escapep = false;
 
+  obstack_wide_file file (output);
+  if (emitter != nullptr
+      && emitter (&file, w, gdb::make_array_view (orig, orig_len),
+		  width, byte_order, quoter))
+    return;
+
   switch (w)
     {
       case LCST ('\a'):
@@ -2246,7 +2253,6 @@ print_wchar (gdb_wint_t w, const gdb_byte *orig,
 	  else
 	    {
 	      int i;
-	      obstack_wide_file file (output);
 
 	      for (i = 0; i + width <= orig_len; i += width)
 		{
@@ -2281,7 +2287,8 @@ print_wchar (gdb_wint_t w, const gdb_byte *orig,
 
 void
 generic_emit_char (int c, struct type *type, struct ui_file *stream,
-		   int quoter, const char *encoding)
+		   int quoter, const char *encoding,
+		   emit_char_ftype emitter)
 {
   enum bfd_endian byte_order
     = type_byte_order (type);
@@ -2330,14 +2337,16 @@ generic_emit_char (int c, struct type *type, struct ui_file *stream,
 	      for (i = 0; i < num_chars; ++i)
 		print_wchar (chars[i], buf, buflen,
 			     TYPE_LENGTH (type), byte_order,
-			     &wchar_buf, quoter, &need_escape);
+			     &wchar_buf, quoter, &need_escape,
+			     emitter);
 	    }
 	}
 
       /* This handles the NUM_CHARS == 0 case as well.  */
       if (print_escape)
 	print_wchar (gdb_WEOF, buf, buflen, TYPE_LENGTH (type),
-		     byte_order, &wchar_buf, quoter, &need_escape);
+		     byte_order, &wchar_buf, quoter, &need_escape,
+		     emitter);
     }
 
   /* The output in the host encoding.  */
@@ -2445,7 +2454,8 @@ print_converted_chars_to_obstack (struct obstack *obstack,
 				  const std::vector<converted_character> &chars,
 				  int quote_char, int width,
 				  enum bfd_endian byte_order,
-				  const struct value_print_options *options)
+				  const struct value_print_options *options,
+				  emit_char_ftype emitter)
 {
   unsigned int idx;
   const converted_character *elem;
@@ -2486,10 +2496,12 @@ print_converted_chars_to_obstack (struct obstack *obstack,
 	      {
 		if (elem->result == wchar_iterate_ok)
 		  print_wchar (elem->chars[0], elem->buf, elem->buflen, width,
-			       byte_order, obstack, quote_char, &need_escape);
+			       byte_order, obstack, quote_char, &need_escape,
+			       emitter);
 		else
 		  print_wchar (gdb_WEOF, elem->buf, elem->buflen, width,
-			       byte_order, obstack, quote_char, &need_escape);
+			       byte_order, obstack, quote_char, &need_escape,
+			       emitter);
 	      }
 	  }
 	  break;
@@ -2514,10 +2526,12 @@ print_converted_chars_to_obstack (struct obstack *obstack,
 	    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);
+			   byte_order, obstack, quote_char, &need_escape,
+			   emitter);
 	    else
 	      print_wchar (gdb_WEOF, elem->buf, elem->buflen, width,
-			   byte_order, obstack, quote_char, &need_escape);
+			   byte_order, obstack, quote_char, &need_escape,
+			   emitter);
 	    obstack_grow_wstr (obstack, LCST ("'"));
 	    std::string s = string_printf (_(" <repeats %u times>"),
 					   elem->repeat_count);
@@ -2543,7 +2557,7 @@ print_converted_chars_to_obstack (struct obstack *obstack,
 	  /* 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, 0, &need_escape, emitter);
 	  obstack_grow_wstr (obstack, LCST (">"));
 
 	  /* We do not attempt to output anything after this.  */
@@ -2602,7 +2616,8 @@ generic_printstr (struct ui_file *stream, struct type *type,
 		  const gdb_byte *string, unsigned int length, 
 		  const char *encoding, int force_ellipses,
 		  int quote_char, int c_style_terminator,
-		  const struct value_print_options *options)
+		  const struct value_print_options *options,
+		  emit_char_ftype emitter)
 {
   enum bfd_endian byte_order = type_byte_order (type);
   unsigned int i;
@@ -2678,7 +2693,7 @@ generic_printstr (struct ui_file *stream, struct type *type,
 
   /* Print the output string to the obstack.  */
   print_converted_chars_to_obstack (&wchar_buf, converted_chars, quote_char,
-				    width, byte_order, options);
+				    width, byte_order, options, emitter);
 
   if (force_ellipses || !finished)
     obstack_grow_wstr (&wchar_buf, LCST ("..."));
diff --git a/gdb/valprint.h b/gdb/valprint.h
index 0586836f9e6..64fea1ccb4a 100644
--- a/gdb/valprint.h
+++ b/gdb/valprint.h
@@ -233,14 +233,40 @@ extern void generic_value_print (struct value *val, struct ui_file *stream,
 				 const struct value_print_options *options,
 				 const struct generic_val_print_decorations *d);
 
+/* A callback that can be used to print a representation of a wide
+   character to a stream.
+   
+   If the character can be represented by this callback, it will
+   return true.  A false return indicates that the default behavior
+   should be taken -- for printable characters, the default is to emit
+   it verbatim; for non-printable characters, C-style escapes are
+   used.  Normally a callback should always return false for
+   printable, non-control characters.
+
+   STREAM is the stream to write to.
+   W is the character.  It might be gdb_WEOF, meaning an unconvertible
+   sequence.
+   ORIG is the original (target) bytes corresponding to W.
+   WIDTH is the width of a base character in the encoding.
+   BYTE_ORDER is the character type's byte order.
+   QUOTER is the quote character used -- this is a host character.  */
+typedef gdb::function_view<bool (ui_file *stream,
+				 gdb_wint_t w,
+				 gdb::array_view<const gdb_byte> orig,
+				 int width,
+				 enum bfd_endian byte_order,
+				 int quoter)> emit_char_ftype;
+
 extern void generic_emit_char (int c, struct type *type, struct ui_file *stream,
-			       int quoter, const char *encoding);
+			       int quoter, const char *encoding,
+			       emit_char_ftype emitter = nullptr);
 
 extern void generic_printstr (struct ui_file *stream, struct type *type, 
 			      const gdb_byte *string, unsigned int length, 
 			      const char *encoding, int force_ellipses,
 			      int quote_char, int c_style_terminator,
-			      const struct value_print_options *options);
+			      const struct value_print_options *options,
+			      emit_char_ftype emitter = nullptr);
 
 /* Run the "output" command.  ARGS and FROM_TTY are the usual
    arguments passed to all command implementations, except ARGS is
-- 
2.31.1


  parent reply	other threads:[~2022-02-16 13:55 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-16 13:55 [PATCH 00/18] Refactor character printing Tom Tromey
2022-02-16 13:55 ` [PATCH 01/18] Fix latent quote char bug in generic_printstr Tom Tromey
2022-02-16 15:38   ` Andrew Burgess
2022-02-16 13:55 ` [PATCH 02/18] Boolify need_escape in generic_emit_char Tom Tromey
2022-02-16 15:39   ` Andrew Burgess
2022-02-16 13:55 ` [PATCH 03/18] Remove c_emit_char Tom Tromey
2022-02-16 15:40   ` Andrew Burgess
2022-02-16 13:55 ` [PATCH 04/18] Remove c_printstr Tom Tromey
2022-02-16 15:46   ` Andrew Burgess
2022-02-16 13:55 ` [PATCH 05/18] Don't use wchar_printable in print_wchar Tom Tromey
2022-02-16 15:52   ` Andrew Burgess
2022-02-16 13:55 ` [PATCH 06/18] Fix a latent bug " Tom Tromey
2022-02-16 16:02   ` Andrew Burgess
2022-02-17 22:02     ` Tom Tromey
2022-02-16 13:55 ` [PATCH 07/18] Remove language_defn::emitchar Tom Tromey
2022-02-16 16:12   ` Andrew Burgess
2022-02-17 22:02     ` Tom Tromey
2022-02-16 13:55 ` [PATCH 08/18] Add gdb_iswcntrl Tom Tromey
2022-02-16 16:13   ` Andrew Burgess
2022-02-16 13:55 ` [PATCH 09/18] Include \0 in printable wide characters Tom Tromey
2022-02-16 17:19   ` Andrew Burgess
2022-02-16 13:55 ` [PATCH 10/18] Use a ui_file in print_wchar Tom Tromey
2022-02-16 17:25   ` Andrew Burgess
2022-02-16 13:55 ` Tom Tromey [this message]
2022-02-16 17:47   ` [PATCH 11/18] Add an emitter callback to generic_printstr and generic_emit_char Andrew Burgess
2022-02-16 20:40     ` Tom Tromey
2022-02-16 21:00       ` Tom Tromey
2022-02-16 13:55 ` [PATCH 12/18] Add a default encoding to generic_emit_char and generic_printstr Tom Tromey
2022-02-16 13:55 ` [PATCH 13/18] Change generic_emit_char to print the quotes Tom Tromey
2022-02-16 13:55 ` [PATCH 14/18] Use generic_emit_char in Rust Tom Tromey
2022-02-16 13:55 ` [PATCH 15/18] Use generic_emit_char in Ada Tom Tromey
2022-02-16 13:55 ` [PATCH 16/18] Use generic_emit_char in Modula-2 Tom Tromey
2022-02-16 13:55 ` [PATCH 17/18] Use generic_emit_char in Pascal Tom Tromey
2022-02-16 13:55 ` [PATCH 18/18] Simplify Fortran string printing Tom Tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220216135518.3162480-12-tom@tromey.com \
    --to=tom@tromey.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).