2011-01-05 Michael Snyder <msnyder@vmware.com>
[deliverable/binutils-gdb.git] / gdb / p-lang.c
index 4ba61362bb4a038a4e9c57b105677d4faeb1a905..79a3338d334826c275ede1eee6be3a4a808b336d 100644 (file)
@@ -1,6 +1,6 @@
 /* Pascal language support routines for GDB, the GNU debugger.
 
-   Copyright (C) 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009
+   Copyright (C) 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -86,7 +86,7 @@ pascal_main_name (void)
 }
 
 /* Determines if type TYPE is a pascal string type.
-   Returns 1 if the type is a known pascal type
+   Returns a positive value if the type is a known pascal string type.
    This function is used by p-valprint.c code to allow better string display.
    If it is a pascal string type, then it also sets info needed
    to get the length and the data of the string
@@ -97,16 +97,19 @@ pascal_main_name (void)
    but this does not happen for Free Pascal nor for GPC.  */
 int
 is_pascal_string_type (struct type *type,int *length_pos,
-                       int *length_size, int *string_pos, int *char_size,
+                       int *length_size, int *string_pos,
+                      struct type **char_type,
                       char **arrayname)
 {
-  if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+  if (type != NULL && TYPE_CODE (type) == TYPE_CODE_STRUCT)
     {
       /* Old Borland type pascal strings from Free Pascal Compiler.  */
       /* Two fields: length and st.  */
-      if (TYPE_NFIELDS (type) == 2 
-          && strcmp (TYPE_FIELDS (type)[0].name, "length") == 0 
-          && strcmp (TYPE_FIELDS (type)[1].name, "st") == 0)
+      if (TYPE_NFIELDS (type) == 2
+         && TYPE_FIELD_NAME (type, 0)
+         && strcmp (TYPE_FIELD_NAME (type, 0), "length") == 0 
+         && TYPE_FIELD_NAME (type, 1)
+         && strcmp (TYPE_FIELD_NAME (type, 1), "st") == 0)
         {
           if (length_pos)
            *length_pos = TYPE_FIELD_BITPOS (type, 0) / TARGET_CHAR_BIT;
@@ -114,29 +117,36 @@ is_pascal_string_type (struct type *type,int *length_pos,
            *length_size = TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0));
           if (string_pos)
            *string_pos = TYPE_FIELD_BITPOS (type, 1) / TARGET_CHAR_BIT;
-          if (char_size)
-           *char_size = 1;
+          if (char_type)
+           *char_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 1));
          if (arrayname)
-           *arrayname = TYPE_FIELDS (type)[1].name;
+           *arrayname = TYPE_FIELD_NAME (type, 1);
          return 2;
         };
       /* GNU pascal strings.  */
       /* Three fields: Capacity, length and schema$ or _p_schema.  */
       if (TYPE_NFIELDS (type) == 3
-          && strcmp (TYPE_FIELDS (type)[0].name, "Capacity") == 0
-          && strcmp (TYPE_FIELDS (type)[1].name, "length") == 0)
+         && TYPE_FIELD_NAME (type, 0)
+         && strcmp (TYPE_FIELD_NAME (type, 0), "Capacity") == 0
+         && TYPE_FIELD_NAME (type, 1)
+         && strcmp (TYPE_FIELD_NAME (type, 1), "length") == 0)
         {
-          if (length_pos)
+         if (length_pos)
            *length_pos = TYPE_FIELD_BITPOS (type, 1) / TARGET_CHAR_BIT;
-          if (length_size)
+         if (length_size)
            *length_size = TYPE_LENGTH (TYPE_FIELD_TYPE (type, 1));
-          if (string_pos)
+         if (string_pos)
            *string_pos = TYPE_FIELD_BITPOS (type, 2) / TARGET_CHAR_BIT;
           /* FIXME: how can I detect wide chars in GPC ?? */
-          if (char_size)
-           *char_size = 1;
+          if (char_type)
+           {
+             *char_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 2));
+
+             if (TYPE_CODE (*char_type) == TYPE_CODE_ARRAY)
+               *char_type = TYPE_TARGET_TYPE (*char_type);
+           }
          if (arrayname)
-           *arrayname = TYPE_FIELDS (type)[2].name;
+           *arrayname = TYPE_FIELD_NAME (type, 2);
          return 3;
         };
     }
@@ -152,10 +162,7 @@ static void pascal_one_char (int, struct ui_file *, int *);
 static void
 pascal_one_char (int c, struct ui_file *stream, int *in_quotes)
 {
-
-  c &= 0xFF;                   /* Avoid sign bit follies */
-
-  if ((c == '\'') || (PRINT_LITERAL_FORM (c)))
+  if (c == '\'' || ((unsigned int) c <= 0xff && (PRINT_LITERAL_FORM (c))))
     {
       if (!(*in_quotes))
        fputs_filtered ("'", stream);
@@ -176,25 +183,28 @@ pascal_one_char (int c, struct ui_file *stream, int *in_quotes)
     }
 }
 
-static void pascal_emit_char (int c, struct ui_file *stream, int quoter);
+static void pascal_emit_char (int c, struct type *type,
+                             struct ui_file *stream, int quoter);
 
 /* Print the character C on STREAM as part of the contents of a literal
    string whose delimiter is QUOTER.  Note that that format for printing
    characters and strings is language specific. */
 
 static void
-pascal_emit_char (int c, struct ui_file *stream, int quoter)
+pascal_emit_char (int c, struct type *type, struct ui_file *stream, int quoter)
 {
   int in_quotes = 0;
+
   pascal_one_char (c, stream, &in_quotes);
   if (in_quotes)
     fputs_filtered ("'", stream);
 }
 
 void
-pascal_printchar (int c, struct ui_file *stream)
+pascal_printchar (int c, struct type *type, struct ui_file *stream)
 {
   int in_quotes = 0;
+
   pascal_one_char (c, stream, &in_quotes);
   if (in_quotes)
     fputs_filtered ("'", stream);
@@ -206,19 +216,28 @@ pascal_printchar (int c, struct ui_file *stream)
    had to stop before printing LENGTH characters, or if FORCE_ELLIPSES.  */
 
 void
-pascal_printstr (struct ui_file *stream, const gdb_byte *string,
-                unsigned int length, int width, int force_ellipses,
+pascal_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)
 {
+  enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
   unsigned int i;
   unsigned int things_printed = 0;
   int in_quotes = 0;
   int need_comma = 0;
+  int width;
+
+  /* Preserve TYPE's original type, just set its LENGTH.  */
+  check_typedef (type);
+  width = TYPE_LENGTH (type);
 
   /* If the string was not truncated due to `set print elements', and
      the last byte of it is a null, we don't print that, in traditional C
      style.  */
-  if ((!force_ellipses) && length > 0 && string[length - 1] == '\0')
+  if ((!force_ellipses) && length > 0
+       && extract_unsigned_integer (string + (length - 1) * width, width,
+                                    byte_order) == 0)
     length--;
 
   if (length == 0)
@@ -234,6 +253,7 @@ pascal_printstr (struct ui_file *stream, const gdb_byte *string,
       unsigned int rep1;
       /* Number of repetitions we have detected so far.  */
       unsigned int reps;
+      unsigned long int current_char;
 
       QUIT;
 
@@ -243,9 +263,14 @@ pascal_printstr (struct ui_file *stream, const gdb_byte *string,
          need_comma = 0;
        }
 
+      current_char = extract_unsigned_integer (string + i * width, width,
+                                              byte_order);
+
       rep1 = i + 1;
       reps = 1;
-      while (rep1 < length && string[rep1] == string[i])
+      while (rep1 < length 
+            && extract_unsigned_integer (string + rep1 * width, width,
+                                         byte_order) == current_char)
        {
          ++rep1;
          ++reps;
@@ -261,7 +286,7 @@ pascal_printstr (struct ui_file *stream, const gdb_byte *string,
                fputs_filtered ("', ", stream);
              in_quotes = 0;
            }
-         pascal_printchar (string[i], stream);
+         pascal_printchar (current_char, type, stream);
          fprintf_filtered (stream, " <repeats %u times>", reps);
          i = rep1 - 1;
          things_printed += options->repeat_count_threshold;
@@ -269,8 +294,7 @@ pascal_printstr (struct ui_file *stream, const gdb_byte *string,
        }
       else
        {
-         int c = string[i];
-         if ((!in_quotes) && (PRINT_LITERAL_FORM (c)))
+         if ((!in_quotes) && (PRINT_LITERAL_FORM (current_char)))
            {
              if (options->inspect_it)
                fputs_filtered ("\\'", stream);
@@ -278,7 +302,7 @@ pascal_printstr (struct ui_file *stream, const gdb_byte *string,
                fputs_filtered ("'", stream);
              in_quotes = 1;
            }
-         pascal_one_char (c, stream, &in_quotes);
+         pascal_one_char (current_char, stream, &in_quotes);
          ++things_printed;
        }
     }
@@ -356,6 +380,7 @@ pascal_language_arch_info (struct gdbarch *gdbarch,
                           struct language_arch_info *lai)
 {
   const struct builtin_type *builtin = builtin_type (gdbarch);
+
   lai->string_char_type = builtin->builtin_char;
   lai->primitive_type_vector
     = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_pascal_primitive_types + 1,
This page took 0.027207 seconds and 4 git commands to generate.