Mirror of the gdb mailing list
 help / color / mirror / Atom feed
From: Jim Blandy <jimb@codesourcery.com>
To: Mark Kettenis <mark.kettenis@xs4all.nl>
Cc: eliz@gnu.org,  dewar@adacore.com,  nickrob@snap.net.nz,
		  jan.kratochvil@redhat.com,  Mathieu.Lacage@sophia.inria.fr,
		  gdb@sourceware.org
Subject: Re: [RFC] Signed/unsigned character arrays are not strings
Date: Thu, 01 Mar 2007 00:43:00 -0000	[thread overview]
Message-ID: <m3zm6x7pzx.fsf@codesourcery.com> (raw)
In-Reply-To: <20070228134640.GA11261@caradoc.them.org> (Daniel Jacobowitz's message of "Wed, 28 Feb 2007 08:46:40 -0500")


Daniel Jacobowitz <drow@false.org> writes:
> On Tue, Feb 27, 2007 at 11:11:32PM +0100, Mark Kettenis wrote:
>> Anyway, I'm in favour of restore the traditional gdb behaviour of
>> printing all three as strings.
>
> While I haven't seen responses to some of my arguments in favor of the
> new behavior, it's obvious that I'm in the minority here.  So, the
> behavior ought to change.
>
> I was concerned about Jim's patch, but thinking about it some more, I
> would be happy with it (probably with Paul's suggestion).  That's
> because "typedef char *name" is reasonably common, but "typedef char
> name_unit;" is much less so.  What do those who prefer the old
> behavior think of that?

For whatever it's worth, here's a revised patch that implements Paul's
suggestions and has better comments (more accurately apologetic):

gdb/ChangeLog:
2007-02-27  Jim Blandy  <jimb@codesourcery.com>

	* c-valprint.c (textual_element_type): New function.
	(c_val_print): Use textual_element_type to decide whether to print
	arrays, pointer types, and integer types as strings and characters.
	(c_value_print): Doc fix.

Index: gdb/c-valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/c-valprint.c,v
retrieving revision 1.42
diff -u -r1.42 c-valprint.c
--- gdb/c-valprint.c	26 Jan 2007 20:54:16 -0000	1.42
+++ gdb/c-valprint.c	28 Feb 2007 23:09:29 -0000
@@ -56,6 +56,66 @@
 }
 
 
+/* Apply a heuristic to decide whether an array of TYPE or a pointer
+   to TYPE should be printed as a textual string.  Return non-zero if
+   it should, or zero if it should be treated as an array of /pointer
+   to integers.
+
+   It's a shame that we need to use a heuristic here, but C hasn't
+   historically provided distinct types for bytes and characters; you
+   get 'char', which is guaranteed to occupy a byte.  You can put
+   qualifiers on it, but people use the qualified char types for text
+   too, so the qualifier's presence doesn't really tell you anything.
+
+   What's especially a shame here is that the heuristic is fixed.  The
+   user knows which of their types are textual and which are numeric,
+   but we don't give them a way to tell us, beyond using '/s' every time
+   they print something.  */
+static int
+textual_element_type (struct type *type)
+{
+  /* GDB doesn't use TYPE_CODE_CHAR for the C 'char' types; instead,
+     it uses one-byte TYPE_CODE_INT types, with TYPE_NAMEs like
+     "char", "unsigned char", etc. and appropriate flags.  For various
+     reasons, this works out well in some places.  */
+
+
+  struct type *true_type = check_typedef (type);
+
+  /* TYPE_CODE_CHAR is always textual.  But I don't think it ever
+     occurs in C code.  */
+  if (TYPE_CODE (true_type) == TYPE_CODE_CHAR)
+    return 1;
+
+  /* If a one-byte TYPE_CODE_INT has a TYPE_NAME of "char" or
+     something ending with " char", then we treat it as text;
+     otherwise, we assume it's being used as data.  This makes all our
+     SIMD types like builtin_type_v8_int8 and the <stdint.h> types
+     like uint8_t print numerically, but all 'char' types print
+     textually.  Code which says what it means does well.
+     We also recognize types ending in 'char_t'.  */
+  if (TYPE_CODE (true_type) == TYPE_CODE_INT
+      && TYPE_LENGTH (true_type) == 1)
+    {
+      int name_len;
+      
+      /* All integer types should have names.  */
+      gdb_assert (TYPE_NAME (type));
+
+      name_len = strlen (TYPE_NAME (type));
+
+      if (strcmp (TYPE_NAME (type), "char") == 0
+          || (name_len > 5
+              && strcmp (TYPE_NAME (type) + name_len - 5, " char") == 0)
+          || (name_len >= 6
+              && strcmp (TYPE_NAME (type) + name_len - 6, " char_t") == 0))
+        return 1;
+    }
+
+  return 0;
+}
+
+
 /* Print data of type TYPE located at VALADDR (within GDB), which came from
    the inferior at address ADDRESS, onto stdio stream STREAM according to
    FORMAT (a letter or 0 for natural format).  The data at VALADDR is in
@@ -94,11 +154,9 @@
 	    {
 	      print_spaces_filtered (2 + 2 * recurse, stream);
 	    }
-	  /* For an array of chars, print with string syntax.  */
-	  if (eltlen == 1 &&
-	      ((TYPE_CODE (elttype) == TYPE_CODE_INT && TYPE_NOSIGN (elttype))
-	       || ((current_language->la_language == language_m2)
-		   && (TYPE_CODE (elttype) == TYPE_CODE_CHAR)))
+
+	  /* Print arrays of textual chars with a string syntax.  */
+          if (textual_element_type (TYPE_TARGET_TYPE (type))
 	      && (format == 0 || format == 's'))
 	    {
 	      /* If requested, look for the first null char and only print
@@ -191,12 +249,11 @@
 	      deprecated_print_address_numeric (addr, 1, stream);
 	    }
 
-	  /* For a pointer to char or unsigned char, also print the string
+	  /* For a pointer to a textual type, also print the string
 	     pointed to, unless pointer is null.  */
 	  /* FIXME: need to handle wchar_t here... */
 
-	  if (TYPE_LENGTH (elttype) == 1
-	      && TYPE_CODE (elttype) == TYPE_CODE_INT
+	  if (textual_element_type (TYPE_TARGET_TYPE (type))
 	      && (format == 0 || format == 's')
 	      && addr != 0)
 	    {
@@ -398,7 +455,7 @@
 	     Since we don't know whether the value is really intended to
 	     be used as an integer or a character, print the character
 	     equivalent as well. */
-	  if (TYPE_LENGTH (type) == 1)
+	  if (textual_element_type (type))
 	    {
 	      fputs_filtered (" ", stream);
 	      LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr + embedded_offset),
@@ -500,7 +557,9 @@
       || TYPE_CODE (type) == TYPE_CODE_REF)
     {
       /* Hack:  remove (char *) for char strings.  Their
-         type is indicated by the quoted string anyway. */
+         type is indicated by the quoted string anyway.
+         (Don't use textual_element_type here; quoted strings
+         are always exactly (char *).  */
       if (TYPE_CODE (type) == TYPE_CODE_PTR
 	  && TYPE_NAME (type) == NULL
 	  && TYPE_NAME (TYPE_TARGET_TYPE (type)) != NULL


  reply	other threads:[~2007-03-01  0:43 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-02-24 16:13 Nick Roberts
2007-02-24 20:11 ` Daniel Jacobowitz
2007-02-24 20:53   ` Nick Roberts
2007-02-24 21:07     ` Jan Kratochvil
2007-02-25  8:00       ` Daniel Jacobowitz
2007-02-25 19:54         ` Nick Roberts
2007-02-25 21:07     ` mathieu lacage
2007-02-26  0:45       ` Jan Kratochvil
2007-02-27  7:17         ` Eli Zaretskii
2007-02-27  9:29         ` Daniel Jacobowitz
2007-02-27 12:02           ` Nick Roberts
2007-02-27 17:06             ` Robert Dewar
2007-02-27 18:42               ` Daniel Jacobowitz
2007-02-27 21:53                 ` Eli Zaretskii
2007-02-27 22:12                   ` Daniel Jacobowitz
2007-02-27 22:14                     ` Mark Kettenis
2007-02-28  0:47                       ` Paul Koning
2007-02-28  1:14                       ` Jim Blandy
2007-02-28  1:59                         ` Jim Blandy
2007-02-28  5:26                           ` Nick Roberts
2007-02-28 14:35                       ` Daniel Jacobowitz
2007-03-01  0:43                         ` Jim Blandy [this message]
2007-03-01  0:54                         ` Nick Roberts
2007-02-27 21:47               ` Eli Zaretskii
2007-02-27 22:12             ` Daniel Jacobowitz
2007-04-10 21:59         ` Daniel Jacobowitz
2007-02-28 13:05 pkoning
2007-03-01 11:01 ` Mark Kettenis

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=m3zm6x7pzx.fsf@codesourcery.com \
    --to=jimb@codesourcery.com \
    --cc=Mathieu.Lacage@sophia.inria.fr \
    --cc=dewar@adacore.com \
    --cc=eliz@gnu.org \
    --cc=gdb@sourceware.org \
    --cc=jan.kratochvil@redhat.com \
    --cc=mark.kettenis@xs4all.nl \
    --cc=nickrob@snap.net.nz \
    /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