Re: [RFA] print arrays with indexes

Joel Brobecker
2005-09-22T16:47:10Z

[-- Attachment #1: Type: text/plain, Size: 3176 bytes --]

> This sounds good to me too. Perhaps a compromise between what Eli
> suggested and what you have been suggesting would work. How about
> we implement a on/off knob for now. Later on, if we understand better
> in which direction to use the threshold, then we can enhance the knob
> to include "auto", and then have a second knob.
>
> As long as we cross-reference each setting in the help text, I think
> users won't be confused.

No objection to the above, so far... Fingers crossed.

Would you know, it just occured to me that the above is what my last
patch actually implemented :). Assuming this intermediate approach is
ok, I'm resubmitting that patch again.

Note that the patch was first submitted in:

http://sources.redhat.com/ml/gdb-patches/2005-09/msg00047.html

2005-09-22 Joel Brobecker <brobecker@adacore.com>

* language.h (language_defn): New field la_print_array_index.
(LA_PRINT_ARRAY_INDEX): New macro.
(default_print_array_index): Add declaration.
* language.c (default_print_array_index): new function.
(unknown_language): Add value for new field.
(auto_language): Likewise.
(local_language): Likewise.
* c-lang.c (c_language_defn): Likewise.
(cpluc_language_defn): Likewise.
(asm_language_defn): Likewise.
(minimal_language_defn): Likewise.
* f-lang.c (f_language_defn): Likewise.
* jv-lang.c (java_language_defn): Likewise.
* m2-lang.c (m2_language_defn): Likewise.
* objc-lang.c (objc_language_defn): Likewise.
* p-lang.c (pascal_language_defn): Likewise.
* ada-lang.c (ada_print_array_index): New function.
(ada_language_defn): Add value for new field.
* valprint.h (print_array_indexes_p): Add declaration.
(maybe_print_array_index): Add declaration.
(val_print_array_elements): Add new parameter to function profile.
* valprint.c (print_array_indexes): New static variable.
(show_print_array_indexes): New function.
(print_array_indexes_p): New function.
(maybe_print_array_index): New function.
(val_print_array_elements): Add new parameter real_index_offset.
Print the index of each element if required by the user.
(_initialize_valprint): Add new array-indexes "set/show print" command.
* c-valprint.c (c_val_print): Update call to val_print_array_elements.
* p-valprint.c (pascal_val_print): Likewise.
* ada-valprint.c (ada_get_array_low_bound_and_type): New function,
mostly extracted from print_optional_low_bound().
(print_optional_low_bound): Replace extracted code by call to
ada_get_array_low_bound_and_type(). Stop printing the low bound
if indexes will be printed for all elements of the array.
(val_print_packed_array_elements): Print the index of each element
of the array if necessary.
(ada_val_print_1): For non-packed arrays, compute the array low
bound, and pass it to val_print_array_elements().

Tested on x86-linux, no regression. Testcases and documentation to follow
after the review.

Thanks,
--
Joel

[-- Attachment #2: indexes.diff --]
[-- Type: text/plain, Size: 18615 bytes --]

Index: language.h
===================================================================
RCS file: /cvs/src/src/gdb/language.h,v
retrieving revision 1.35
diff -u -p -r1.35 language.h
--- language.h 9 May 2005 21:20:34 -0000 1.35
+++ language.h 7 Sep 2005 20:00:10 -0000
@@ -275,6 +275,12 @@ struct language_defn
void (*la_language_arch_info) (struct gdbarch *,
struct language_arch_info *);

+ /* Print the index of an element of an array. */
+ void (*la_print_array_index) (struct value *index_value,
+ struct ui_file *stream,
+ int format,
+ enum val_prettyprint pretty);
+
/* Add fields above this point, so the magic number is always last. */
/* Magic number for compat checking */

@@ -362,6 +368,9 @@ extern enum language set_language (enum
#define LA_EMIT_CHAR(ch, stream, quoter) \
(current_language->la_emitchar(ch, stream, quoter))

+#define LA_PRINT_ARRAY_INDEX(index_value, stream, format, pretty) \
+ (current_language->la_print_array_index(index_value, stream, format, pretty))
+
/* Test a character to decide whether it can be printed in literal form
or needs to be printed in another representation. For example,
in C the literal form of the character with octal value 141 is 'a'
@@ -457,4 +466,10 @@ extern char *language_class_name_from_ph
/* Splitting strings into words. */
extern char *default_word_break_characters (void);

+/* Print the index of an array element using the C99 syntax. */
+extern void default_print_array_index (struct value *index_value,
+ struct ui_file *stream,
+ int format,
+ enum val_prettyprint pretty);
+
#endif /* defined (LANGUAGE_H) */
Index: language.c
===================================================================
RCS file: /cvs/src/src/gdb/language.c,v
retrieving revision 1.62
diff -u -p -r1.62 language.c
--- language.c 29 Aug 2005 12:57:49 -0000 1.62
+++ language.c 7 Sep 2005 20:00:09 -0000
@@ -1057,6 +1057,17 @@ default_word_break_characters (void)
return " \t\n!@#$%^&*()+=|~`}{[]\"';:?/>.<,-";
}

+/* Print the index of array elements using the C99 syntax. */
+
+void
+default_print_array_index (struct value *index_value, struct ui_file *stream,
+ int format, enum val_prettyprint pretty)
+{
+ fprintf_filtered (stream, "[");
+ LA_VALUE_PRINT (index_value, stream, format, pretty);
+ fprintf_filtered (stream, "] = ");
+}
+
/* Define the language that is no language. */

static int
@@ -1181,6 +1192,7 @@ const struct language_defn unknown_langu
NULL,
default_word_break_characters,
unknown_language_arch_info, /* la_language_arch_info. */
+ default_print_array_index,
LANG_MAGIC
};

@@ -1217,6 +1229,7 @@ const struct language_defn auto_language
NULL,
default_word_break_characters,
unknown_language_arch_info, /* la_language_arch_info. */
+ default_print_array_index,
LANG_MAGIC
};

@@ -1252,6 +1265,7 @@ const struct language_defn local_languag
NULL,
default_word_break_characters,
unknown_language_arch_info, /* la_language_arch_info. */
+ default_print_array_index,
LANG_MAGIC
};
\f
Index: c-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/c-lang.c,v
retrieving revision 1.37
diff -u -p -r1.37 c-lang.c
--- c-lang.c 9 May 2005 21:20:30 -0000 1.37
+++ c-lang.c 7 Sep 2005 19:58:49 -0000
@@ -595,6 +595,7 @@ const struct language_defn c_language_de
NULL,
default_word_break_characters,
c_language_arch_info,
+ default_print_array_index,
LANG_MAGIC
};

@@ -653,6 +654,7 @@ const struct language_defn cplus_languag
&builtin_type_char, /* Type of string elements */
default_word_break_characters,
NULL, /* FIXME: la_language_arch_info. */
+ default_print_array_index,
LANG_MAGIC
};

@@ -688,6 +690,7 @@ const struct language_defn asm_language_
NULL,
default_word_break_characters,
c_language_arch_info, /* FIXME: la_language_arch_info. */
+ default_print_array_index,
LANG_MAGIC
};

@@ -728,6 +731,7 @@ const struct language_defn minimal_langu
NULL,
default_word_break_characters,
c_language_arch_info,
+ default_print_array_index,
LANG_MAGIC
};

Index: f-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/f-lang.c,v
retrieving revision 1.31
diff -u -p -r1.31 f-lang.c
--- f-lang.c 9 May 2005 21:20:30 -0000 1.31
+++ f-lang.c 7 Sep 2005 19:59:30 -0000
@@ -485,6 +485,7 @@ const struct language_defn f_language_de
&builtin_type_f_character, /* Type of string elements */
default_word_break_characters,
NULL, /* FIXME: la_language_arch_info. */
+ default_print_array_index,
LANG_MAGIC
};

Index: jv-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/jv-lang.c,v
retrieving revision 1.42
diff -u -p -r1.42 jv-lang.c
--- jv-lang.c 27 May 2005 04:39:32 -0000 1.42
+++ jv-lang.c 7 Sep 2005 20:00:08 -0000
@@ -1114,6 +1114,7 @@ const struct language_defn java_language
NULL,
default_word_break_characters,
c_language_arch_info,
+ default_print_array_index,
LANG_MAGIC
};

Index: m2-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/m2-lang.c,v
retrieving revision 1.23
diff -u -p -r1.23 m2-lang.c
--- m2-lang.c 9 May 2005 21:20:34 -0000 1.23
+++ m2-lang.c 7 Sep 2005 20:00:14 -0000
@@ -437,6 +437,7 @@ const struct language_defn m2_language_d
&builtin_type_m2_char, /* Type of string elements */
default_word_break_characters,
NULL, /* FIXME: la_language_arch_info. */
+ default_print_array_index,
LANG_MAGIC
};

Index: objc-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/objc-lang.c,v
retrieving revision 1.49
diff -u -p -r1.49 objc-lang.c
--- objc-lang.c 12 Jul 2005 12:11:44 -0000 1.49
+++ objc-lang.c 7 Sep 2005 20:00:33 -0000
@@ -684,6 +684,7 @@ const struct language_defn objc_language
&builtin_type_char, /* Type of string elements */
default_word_break_characters,
NULL, /* FIXME: la_language_arch_info. */
+ default_print_array_index,
LANG_MAGIC
};

Index: p-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/p-lang.c,v
retrieving revision 1.25
diff -u -p -r1.25 p-lang.c
--- p-lang.c 9 May 2005 21:20:34 -0000 1.25
+++ p-lang.c 7 Sep 2005 20:00:36 -0000
@@ -477,6 +477,7 @@ const struct language_defn pascal_langua
&builtin_type_char, /* Type of string elements */
default_word_break_characters,
NULL, /* FIXME: la_language_arch_info. */
+ default_print_array_index,
LANG_MAGIC
};

Index: scm-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/scm-lang.c,v
retrieving revision 1.32
diff -u -p -r1.32 scm-lang.c
--- scm-lang.c 27 May 2005 04:39:32 -0000 1.32
+++ scm-lang.c 7 Sep 2005 20:01:01 -0000
@@ -269,6 +269,7 @@ const struct language_defn scm_language_
NULL,
default_word_break_characters,
c_language_arch_info,
+ default_print_array_index,
LANG_MAGIC
};

Index: ada-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/ada-lang.c,v
retrieving revision 1.78
diff -u -p -r1.78 ada-lang.c
--- ada-lang.c 9 May 2005 21:20:29 -0000 1.78
+++ ada-lang.c 7 Sep 2005 19:58:31 -0000
@@ -303,6 +303,16 @@ ada_get_gdb_completer_word_break_charact
return ada_completer_word_break_characters;
}

+/* Print an array element index using the Ada syntax. */
+
+static void
+ada_print_array_index (struct value *index_value, struct ui_file *stream,
+ int format, enum val_prettyprint pretty)
+{
+ LA_VALUE_PRINT (index_value, stream, format, pretty);
+ fprintf_filtered (stream, " => ");
+}
+
/* Read the string located at ADDR from the inferior and store the
result into BUF. */

@@ -8766,6 +8776,7 @@ const struct language_defn ada_language_
NULL,
ada_get_gdb_completer_word_break_characters,
ada_language_arch_info,
+ ada_print_array_index,
LANG_MAGIC
};

Index: valprint.h
===================================================================
RCS file: /cvs/src/src/gdb/valprint.h,v
retrieving revision 1.10
diff -u -p -r1.10 valprint.h
--- valprint.h 9 May 2005 21:20:35 -0000 1.10
+++ valprint.h 7 Sep 2005 20:01:35 -0000
@@ -50,10 +50,16 @@ extern int output_format;

extern int stop_print_at_null; /* Stop printing at null char? */

+extern int print_array_indexes_p (void);
+
+extern void maybe_print_array_index (struct type *index_type, LONGEST index,
+ struct ui_file *stream, int format,
+ enum val_prettyprint pretty);
+
extern void val_print_array_elements (struct type *, const gdb_byte *,
CORE_ADDR, struct ui_file *, int,
int, int, enum val_prettyprint,
- unsigned int);
+ unsigned int, LONGEST);

extern void val_print_type_code_int (struct type *, const gdb_byte *,
struct ui_file *);
Index: valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/valprint.c,v
retrieving revision 1.54
diff -u -p -r1.54 valprint.c
--- valprint.c 10 Jun 2005 06:07:32 -0000 1.54
+++ valprint.c 7 Sep 2005 20:01:35 -0000
@@ -100,6 +100,17 @@ Default output radix for printing of val
}
int output_format = 0;

+/* By default we print arrays without printing the index of each element in
+ the array. This behavior can be changed by setting PRINT_ARRAY_INDEXES. */
+
+static int print_array_indexes = 0;
+static void
+show_print_array_indexes (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("Printing of array indexes is %s.\n"), value);
+}
+
/* Print repeat counts if there are more than this many repetitions of an
element in an array. Referenced by the low level language dependent
print routines. */
@@ -859,9 +870,41 @@ print_char_chars (struct ui_file *stream
}
}

+/* Return non-zero if the debugger should print the index of each element
+ when printing array values. */
+
+int
+print_array_indexes_p (void)
+{
+ return print_array_indexes;
+}
+
+/* Print on STREAM using the given FORMAT the index for the element
+ at INDEX of an array whose index type is INDEX_TYPE. */
+
+void
+maybe_print_array_index (struct type *index_type, LONGEST index,
+ struct ui_file *stream, int format,
+ enum val_prettyprint pretty)
+{
+ struct value *index_value;
+
+ if (!print_array_indexes)
+ return;
+
+ index_value = value_from_longest (index_type, index);
+
+ LA_PRINT_ARRAY_INDEX (index_value, stream, format, pretty);
+}
+
/* Called by various <lang>_val_print routines to print elements of an
array in the form "<elem1>, <elem2>, <elem3>, ...".

+ Some languages such as Ada allow the user to specify arrays where
+ the index of the first element is not zero. REAL_INDEX_OFFSET is
+ the user-level index of the first element of the array. For many
+ languages such as C or C++, it is always zero.
+
(FIXME?) Assumes array element separator is a comma, which is correct
for all languages currently handled.
(FIXME?) Some languages have a notation for repeated array elements,
@@ -873,11 +916,11 @@ val_print_array_elements (struct type *t
CORE_ADDR address, struct ui_file *stream,
int format, int deref_ref,
int recurse, enum val_prettyprint pretty,
- unsigned int i)
+ unsigned int i, LONGEST real_index_offset)
{
unsigned int things_printed = 0;
unsigned len;
- struct type *elttype;
+ struct type *elttype, *index_type;
unsigned eltlen;
/* Position of the array element we are examining to see
whether it is repeated. */
@@ -888,6 +931,7 @@ val_print_array_elements (struct type *t
elttype = TYPE_TARGET_TYPE (type);
eltlen = TYPE_LENGTH (check_typedef (elttype));
len = TYPE_LENGTH (type) / eltlen;
+ index_type = TYPE_INDEX_TYPE (type);

annotate_array_section_begin (i, elttype);

@@ -906,6 +950,8 @@ val_print_array_elements (struct type *t
}
}
wrap_here (n_spaces (2 + 2 * recurse));
+ maybe_print_array_index (index_type, i + real_index_offset,
+ stream, format, pretty);

rep1 = i + 1;
reps = 1;
@@ -1396,6 +1442,12 @@ Show the default input and output number
Use 'show input-radix' or 'show output-radix' to independently show each."),
&showlist);

+ add_setshow_boolean_cmd ("array-indexes", class_support,
+ &print_array_indexes, _("\
+Set printing of array indexes."), _("\
+Show printing of array indexes"), NULL, NULL, show_print_array_indexes,
+ &setprintlist, &showprintlist);
+
/* Give people the defaults which they are used to. */
prettyprint_structs = 0;
prettyprint_arrays = 0;
Index: c-valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/c-valprint.c,v
retrieving revision 1.37
diff -u -p -r1.37 c-valprint.c
--- c-valprint.c 9 May 2005 21:20:30 -0000 1.37
+++ c-valprint.c 7 Sep 2005 19:58:50 -0000
@@ -133,7 +133,7 @@ c_val_print (struct type *type, const gd
i = 0;
}
val_print_array_elements (type, valaddr + embedded_offset, address, stream,
- format, deref_ref, recurse, pretty, i);
+ format, deref_ref, recurse, pretty, i, 0);
fprintf_filtered (stream, "}");
}
break;
Index: p-valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/p-valprint.c,v
retrieving revision 1.39
diff -u -p -r1.39 p-valprint.c
--- p-valprint.c 9 May 2005 21:20:34 -0000 1.39
+++ p-valprint.c 7 Sep 2005 20:00:37 -0000
@@ -123,7 +123,7 @@ pascal_val_print (struct type *type, con
i = 0;
}
val_print_array_elements (type, valaddr + embedded_offset, address, stream,
- format, deref_ref, recurse, pretty, i);
+ format, deref_ref, recurse, pretty, i, 0);
fprintf_filtered (stream, "}");
}
break;
Index: ada-valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/ada-valprint.c,v
retrieving revision 1.23
diff -u -p -r1.23 ada-valprint.c
--- ada-valprint.c 9 May 2005 21:20:30 -0000 1.23
+++ ada-valprint.c 7 Sep 2005 19:58:33 -0000
@@ -75,6 +75,44 @@ adjust_type_signedness (struct type *typ
TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
}

+/* Assuming TYPE is a simple, non-empty array type, compute the lower
+ bound and the array index type. Save the low bound into LOW_BOUND
+ if not NULL. Save the index type in INDEX_TYPE if not NULL.
+
+ Return 1 if the operation was successful. Return zero otherwise,
+ in which case the value of LOW_BOUND and INDEX_TYPE is undefined. */
+
+static int
+ada_get_array_low_bound_and_type (struct type *type,
+ long *low_bound,
+ struct type **index_type)
+{
+ struct type *index = TYPE_INDEX_TYPE (type);
+ long low = 0;
+
+ if (index == NULL)
+ return 0;
+
+ if (TYPE_CODE (index) != TYPE_CODE_RANGE
+ && TYPE_CODE (index) != TYPE_CODE_ENUM)
+ return 0;
+
+ low = TYPE_LOW_BOUND (index);
+ if (low > TYPE_HIGH_BOUND (index))
+ return 0;
+
+ if (TYPE_CODE (index) == TYPE_CODE_RANGE)
+ index = TYPE_TARGET_TYPE (index);
+
+ if (low_bound)
+ *low_bound = low;
+
+ if (index_type)
+ *index_type = index;
+
+ return 1;
+}
+
/* Assuming TYPE is a simple, non-empty array type, prints its lower bound
on STREAM, if non-standard (i.e., other than 1 for numbers, other
than lower bound of index type for enumerated type). Returns 1
@@ -86,19 +124,10 @@ print_optional_low_bound (struct ui_file
struct type *index_type;
long low_bound;

- index_type = TYPE_INDEX_TYPE (type);
- low_bound = 0;
-
- if (index_type == NULL)
+ if (print_array_indexes_p ())
return 0;
- if (TYPE_CODE (index_type) == TYPE_CODE_RANGE)
- {
- low_bound = TYPE_LOW_BOUND (index_type);
- if (low_bound > TYPE_HIGH_BOUND (index_type))
- return 0;
- index_type = TYPE_TARGET_TYPE (index_type);
- }
- else
+
+ if (!ada_get_array_low_bound_and_type (type, &low_bound, &index_type))
return 0;

switch (TYPE_CODE (index_type))
@@ -137,16 +166,18 @@ val_print_packed_array_elements (struct
unsigned int i;
unsigned int things_printed = 0;
unsigned len;
- struct type *elttype;
+ struct type *elttype, *index_type;
unsigned eltlen;
unsigned long bitsize = TYPE_FIELD_BITSIZE (type, 0);
struct value *mark = value_mark ();
+ LONGEST low = 0;

elttype = TYPE_TARGET_TYPE (type);
eltlen = TYPE_LENGTH (check_typedef (elttype));
+ index_type = TYPE_INDEX_TYPE (type);

{
- LONGEST low, high;
+ LONGEST high;
if (get_discrete_bounds (TYPE_FIELD_TYPE (type, 0), &low, &high) < 0)
len = 1;
else
@@ -174,6 +205,7 @@ val_print_packed_array_elements (struct
}
}
wrap_here (n_spaces (2 + 2 * recurse));
+ maybe_print_array_index (index_type, i + low, stream, format, pretty);

i0 = i;
v0 = ada_value_primitive_packed_val (NULL, valaddr,
@@ -219,6 +251,8 @@ val_print_packed_array_elements (struct
fprintf_filtered (stream, ", ");
}
wrap_here (n_spaces (2 + 2 * recurse));
+ maybe_print_array_index (index_type, j + low,
+ stream, format, pretty);
}
val_print (elttype, value_contents (v0), 0, 0, stream, format,
0, recurse + 1, pretty);
@@ -824,7 +858,11 @@ ada_val_print_1 (struct type *type, cons
}
else
{
+ long low_bound = 0;
+
len = 0;
+ ada_get_array_low_bound_and_type (type, &low_bound, NULL);
+
fprintf_filtered (stream, "(");
print_optional_low_bound (stream, type);
if (TYPE_FIELD_BITSIZE (type, 0) > 0)
@@ -833,7 +871,7 @@ ada_val_print_1 (struct type *type, cons
else
val_print_array_elements (type, valaddr, address, stream,
format, deref_ref, recurse,
- pretty, 0);
+ pretty, 0, low_bound);
fprintf_filtered (stream, ")");
}
gdb_flush (stream);