From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16506 invoked by alias); 6 Sep 2005 20:20:30 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 16476 invoked by uid 22791); 6 Sep 2005 20:20:21 -0000 Received: from nile.gnat.com (HELO nile.gnat.com) (205.232.38.5) by sourceware.org (qpsmtpd/0.30-dev) with ESMTP; Tue, 06 Sep 2005 20:20:21 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-nile.gnat.com (Postfix) with ESMTP id D7B9748CDA8 for ; Tue, 6 Sep 2005 16:20:19 -0400 (EDT) Received: from nile.gnat.com ([127.0.0.1]) by localhost (nile.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 15732-01-7 for ; Tue, 6 Sep 2005 16:20:19 -0400 (EDT) Received: from takamaka.act-europe.fr (S0106000f3d96cb6d.vc.shawcable.net [24.81.152.226]) by nile.gnat.com (Postfix) with ESMTP id 3278648CD97 for ; Tue, 6 Sep 2005 16:20:19 -0400 (EDT) Received: by takamaka.act-europe.fr (Postfix, from userid 507) id 38BBE47E74; Tue, 6 Sep 2005 13:20:18 -0700 (PDT) Date: Tue, 06 Sep 2005 20:20:00 -0000 From: Joel Brobecker To: gdb-patches@sources.redhat.com Subject: [RFC/RFA] print arrays with indexes Message-ID: <20050906202018.GC1153@adacore.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="4Ckj6UjgE2iN1+kY" Content-Disposition: inline User-Agent: Mutt/1.4i X-SW-Source: 2005-09/txt/msg00033.txt.bz2 --4Ckj6UjgE2iN1+kY Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 2864 Hello, This is a suggestion to enhance GDB when printing arrays. The idea is that the default and currently only way for GDB to print arrays is to print them as a sequence of elements, separated by a coma, like this: (gdb) p array $1 = {1, 2, 3, 4} The idea is that, for large arrays, it's sometimes convenient to print them in a form where the index of each element is printed prior to the array element itself. In Ada, the notation for doing is => So, the idea would be for GDB to print the above array as: (gdb) p array $2 = {0 => 1, 1 => 2, 2 => 3, 3 => 4} For my personal usage, I find this to be very convenient when dealing with super large arrays such as the regnum-to-regname arrays that we frequently have in GDB. I'm always concerned about being off by one when counting. Having the index simplifies the process a little bit. So, the suggestion is to have the feature being controled by a set/show command; I suggest: (gdb) set/show print array-indexes With a default of "off", to preserve the current behavior. For the moment, the patch I am submitting here is using the Ada notation, because C/C++/ObjC don't provide this way of "qualifying" each element. Not sure about Fortran or Pascal. We can certainly make this a language method, with a default method. Testcase and documentation will come shortly after we've agreed on the principle and the design. 2005-09-06 Joel Brobecker * valprint.c (print_array_indexes): New 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 print-array-indexes set/show command. * valprint.h (print_array_indexes_p): Add declaration. (maybe_print_array_index): Likewise. (val_print_array_elements): Update parameter list. * 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. Opinions? -- Joel --4Ckj6UjgE2iN1+kY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="indexes.diff" Content-length: 9749 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 6 Sep 2005 20:18:00 -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,42 @@ 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_VALUE_PRINT (index_value, stream, format, pretty); + fprintf_filtered (stream, " => "); +} + /* Called by various _val_print routines to print elements of an array in the form ", , , ...". + 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 +917,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 +932,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 +951,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 +1443,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: 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 6 Sep 2005 20:18:00 -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: 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 6 Sep 2005 20:18:00 -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: 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 6 Sep 2005 20:18:00 -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); --4Ckj6UjgE2iN1+kY--