X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fp-lang.c;h=64d2e9f9be6ab66b742b7ae692ba8e9b20f971bc;hb=8ea5bce59057ef1906bf1180843c0900b191dcab;hp=0e0de2e05b2db7cac55e69709b6d8ba46c2d3c60;hpb=0fb0cc7590113e9b459dfcc48dc71c9d419d9580;p=binutils-gdb.git diff --git a/gdb/p-lang.c b/gdb/p-lang.c index 0e0de2e05b2..64d2e9f9be6 100644 --- a/gdb/p-lang.c +++ b/gdb/p-lang.c @@ -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 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,10 +97,11 @@ 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. */ @@ -114,8 +115,8 @@ 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; return 2; @@ -126,15 +127,20 @@ is_pascal_string_type (struct type *type,int *length_pos, && strcmp (TYPE_FIELDS (type)[0].name, "Capacity") == 0 && strcmp (TYPE_FIELDS (type)[1].name, "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; return 3; @@ -152,10 +158,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 +179,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 +212,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 +249,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 +259,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 +282,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, " ", reps); i = rep1 - 1; things_printed += options->repeat_count_threshold; @@ -269,8 +290,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 +298,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 +376,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, @@ -433,6 +454,7 @@ const struct language_defn pascal_language_defn = pascal_language_arch_info, default_print_array_index, default_pass_by_reference, + default_get_string, LANG_MAGIC };