From 6068e6305ed7d05b4a919c28aa5bcb737e1f163b Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Jun 30 2010 14:11:31 +0000 Subject: - Print 2D C++ vectors as matrices (BZ 562763, sourceware10659, Chris Moller). --- diff --git a/gdb-bz562763-pretty-print-2d-vectors-libstdcxx.patch b/gdb-bz562763-pretty-print-2d-vectors-libstdcxx.patch new file mode 100644 index 0000000..8729a62 --- /dev/null +++ b/gdb-bz562763-pretty-print-2d-vectors-libstdcxx.patch @@ -0,0 +1,43 @@ +2010-06-01 Chris Moller + + * python/libstdcxx/v6/printers.py (StdVectorPrinter): Add + detection for matrices as nested vectors. + +Index: libstdc++-v3/python/libstdcxx/v6/printers.py +=================================================================== +--- ./libstdc++-v3-python-r155978/libstdcxx/v6/printers.py (revision 159937) ++++ ./libstdc++-v3-python-r155978/libstdcxx/v6/printers.py (working copy) +@@ -19,6 +19,9 @@ + import itertools + import re + ++vector_sig = 'std::vector' ++vector_regex = re.compile('^' + vector_sig + '<.*>$') ++ + class StdPointerPrinter: + "Print a smart pointer of some kind" + +@@ -186,7 +189,13 @@ + % (self.typename, int (finish - start), int (end - start))) + + def display_hint(self): +- return 'array' ++ itype0 = self.val.type.template_argument(0) ++ itag = itype0.tag ++ if itag and re.match(vector_regex, itag): ++ rc = 'matrix' ++ else: ++ rc = 'array' ++ return rc + + class StdVectorIteratorPrinter: + "Print std::vector::iterator" +@@ -692,7 +701,7 @@ + pretty_printers_dict[re.compile('^std::set<.*>$')] = lambda val: StdSetPrinter("std::set", val) + pretty_printers_dict[re.compile('^std::stack<.*>$')] = lambda val: StdStackOrQueuePrinter("std::stack", val) + pretty_printers_dict[re.compile('^std::unique_ptr<.*>$')] = UniquePointerPrinter +- pretty_printers_dict[re.compile('^std::vector<.*>$')] = lambda val: StdVectorPrinter("std::vector", val) ++ pretty_printers_dict[vector_regex] = lambda val: StdVectorPrinter(vector_sig, val) + # vector + + # Printer registrations for classes compiled with -D_GLIBCXX_DEBUG. diff --git a/gdb-bz562763-pretty-print-2d-vectors-prereq.patch b/gdb-bz562763-pretty-print-2d-vectors-prereq.patch new file mode 100644 index 0000000..3cc1e17 --- /dev/null +++ b/gdb-bz562763-pretty-print-2d-vectors-prereq.patch @@ -0,0 +1,427 @@ +commit e5ea8d026015c2a0c7774788b425914857de1ffb +Author: pmuldoon +Date: Wed Apr 14 12:02:42 2010 +0000 + + 2010-04-14 Phil Muldoon + + PR python/11381 + + * python/py-prettyprint.c (pretty_print_one_value): Test for + Py_None. + (print_string_repr): Test for Py_None. Set flags accordingly. + Return value depending on return type. + (print_children): Take a value indicating whether data was printed + before this function was called. Alter output accordingly. + (apply_val_pretty_printer): Capture return value from + print_string_repr and pass to print_children. + + 2010-04-14 Phil Muldoon + + * gdb.python/py-prettyprint.py (NoStringContainerPrinter): New printer. + * gdb.python/py-prettyprint.c: Add justchildren struct, typedefs. + * gdb.python/py-prettyprint.exp: New test for to_string returning None. + * gdb.python/py-mi.exp: New test for to_string returning None. + + 2010-04-14 Phil Muldoon + + * gdb.texinfo (Pretty Printing): Document behaviour when to_string + returns None. + +### a/gdb/ChangeLog +### b/gdb/ChangeLog +## -1,3 +1,16 @@ ++2010-04-14 Phil Muldoon ++ ++ PR python/11381 ++ ++ * python/py-prettyprint.c (pretty_print_one_value): Test for ++ Py_None. ++ (print_string_repr): Test for Py_None. Set flags accordingly. ++ Return value depending on return type. ++ (print_children): Take a value indicating whether data was printed ++ before this function was called. Alter output accordingly. ++ (apply_val_pretty_printer): Capture return value from ++ print_string_repr and pass to print_children. ++ + 2010-04-13 Mark Kettenis + + PR corefiles/11481 +### a/gdb/doc/ChangeLog +### b/gdb/doc/ChangeLog +## -1,3 +1,8 @@ ++2010-04-14 Phil Muldoon ++ ++ * gdb.texinfo (Pretty Printing): Document behaviour when to_string ++ returns None. ++ + 2010-04-09 Stan Shebs + + * gdb.texinfo (gdb/mi Tracepoint Commands) <-trace-status>: +Index: gdb-7.1/gdb/doc/gdb.texinfo +=================================================================== +--- gdb-7.1.orig/gdb/doc/gdb.texinfo 2010-06-30 03:22:07.000000000 +0200 ++++ gdb-7.1/gdb/doc/gdb.texinfo 2010-06-30 03:22:20.000000000 +0200 +@@ -20344,6 +20344,9 @@ the resulting value. Again, this may re + pretty-printer. Python scalars (integers, floats, and booleans) and + strings are convertible to @code{gdb.Value}; other types are not. + ++Finally, if this method returns @code{None} then no further operations ++are peformed in this method and nothing is printed. ++ + If the result is not one of these types, an exception is raised. + @end defop + +Index: gdb-7.1/gdb/python/py-prettyprint.c +=================================================================== +--- gdb-7.1.orig/gdb/python/py-prettyprint.c 2010-06-30 03:22:02.000000000 +0200 ++++ gdb-7.1/gdb/python/py-prettyprint.c 2010-06-30 03:23:38.000000000 +0200 +@@ -125,9 +125,12 @@ find_pretty_printer (PyObject *value) + + /* Pretty-print a single value, via the printer object PRINTER. + If the function returns a string, a PyObject containing the string +- is returned. Otherwise, if the function returns a value, +- *OUT_VALUE is set to the value, and NULL is returned. On error, +- *OUT_VALUE is set to NULL, and NULL is returned. */ ++ is returned. If the function returns Py_NONE that means the pretty ++ printer returned the Python None as a value. Otherwise, if the ++ function returns a value, *OUT_VALUE is set to the value, and NULL ++ is returned. On error, *OUT_VALUE is set to NULL, and NULL is ++ returned. */ ++ + static PyObject * + pretty_print_one_value (PyObject *printer, struct value **out_value) + { +@@ -140,7 +143,8 @@ pretty_print_one_value (PyObject *printe + result = PyObject_CallMethodObjArgs (printer, gdbpy_to_string_cst, NULL); + if (result) + { +- if (! gdbpy_is_string (result) && ! gdbpy_is_lazy_string (result)) ++ if (! gdbpy_is_string (result) && ! gdbpy_is_lazy_string (result) ++ && result != Py_None) + { + *out_value = convert_value_from_python (result); + if (PyErr_Occurred ()) +@@ -184,8 +188,11 @@ gdbpy_get_display_hint (PyObject *printe + } + + /* Helper for apply_val_pretty_printer which calls to_string and +- formats the result. */ +-static void ++ formats the result. If the value returnd is Py_None, nothing is ++ printed and the function returns a 1; in all other cases data is ++ printed as given by the pretty printer and the function returns 0. ++*/ ++static int + print_string_repr (PyObject *printer, const char *hint, + struct ui_file *stream, int recurse, + const struct value_print_options *options, +@@ -194,52 +201,58 @@ print_string_repr (PyObject *printer, co + { + struct value *replacement = NULL; + PyObject *py_str = NULL; ++ int is_py_none = 0; + + py_str = pretty_print_one_value (printer, &replacement); + if (py_str) + { +- gdb_byte *output = NULL; +- long length; +- struct type *type; +- char *encoding = NULL; +- PyObject *string = NULL; +- int is_lazy; +- +- is_lazy = gdbpy_is_lazy_string (py_str); +- if (is_lazy) +- output = gdbpy_extract_lazy_string (py_str, &type, &length, &encoding); ++ if (py_str == Py_None) ++ is_py_none = 1; + else + { +- string = python_string_to_target_python_string (py_str); +- if (string) ++ gdb_byte *output = NULL; ++ long length; ++ struct type *type; ++ char *encoding = NULL; ++ PyObject *string = NULL; ++ int is_lazy; ++ ++ is_lazy = gdbpy_is_lazy_string (py_str); ++ if (is_lazy) ++ output = gdbpy_extract_lazy_string (py_str, &type, &length, &encoding); ++ else + { +- output = PyString_AsString (string); +- length = PyString_Size (string); +- type = builtin_type (gdbarch)->builtin_char; ++ string = python_string_to_target_python_string (py_str); ++ if (string) ++ { ++ output = PyString_AsString (string); ++ length = PyString_Size (string); ++ type = builtin_type (gdbarch)->builtin_char; ++ } ++ else ++ gdbpy_print_stack (); ++ ++ } ++ ++ if (output) ++ { ++ if (is_lazy || (hint && !strcmp (hint, "string"))) ++ LA_PRINT_STRING (stream, type, output, length, encoding, ++ 0, options); ++ else ++ fputs_filtered (output, stream); + } + else + gdbpy_print_stack (); + +- } +- +- if (output) +- { +- if (is_lazy || (hint && !strcmp (hint, "string"))) +- LA_PRINT_STRING (stream, type, output, length, encoding, +- 0, options); ++ if (string) ++ Py_DECREF (string); + else +- fputs_filtered (output, stream); +- } +- else +- gdbpy_print_stack (); +- +- if (string) +- Py_DECREF (string); +- else +- xfree (output); ++ xfree (output); + +- xfree (encoding); +- Py_DECREF (py_str); ++ xfree (encoding); ++ Py_DECREF (py_str); ++ } + } + else if (replacement) + { +@@ -250,6 +263,8 @@ print_string_repr (PyObject *printer, co + } + else + gdbpy_print_stack (); ++ ++ return is_py_none; + } + + static void +@@ -328,12 +343,14 @@ push_dummy_python_frame () + } + + /* Helper for apply_val_pretty_printer that formats children of the +- printer, if any exist. */ ++ printer, if any exist. If is_py_none is true, then nothing has ++ been printed by to_string, and format output accordingly. */ + static void + print_children (PyObject *printer, const char *hint, + struct ui_file *stream, int recurse, + const struct value_print_options *options, +- const struct language_defn *language) ++ const struct language_defn *language, ++ int is_py_none) + { + int is_map, is_array, done_flag, pretty; + unsigned int i; +@@ -413,7 +430,13 @@ print_children (PyObject *printer, const + 2. Arrays. Always print a ",". + 3. Other. Always print a ",". */ + if (i == 0) +- fputs_filtered (" = {", stream); ++ { ++ if (is_py_none) ++ fputs_filtered ("{", stream); ++ else ++ fputs_filtered (" = {", stream); ++ } ++ + else if (! is_map || i % 2 == 0) + fputs_filtered (pretty ? "," : ", ", stream); + +@@ -537,7 +560,7 @@ apply_val_pretty_printer (struct type *t + char *hint = NULL; + struct cleanup *cleanups; + int result = 0; +- ++ int is_py_none = 0; + cleanups = ensure_python_env (gdbarch, language); + + /* Instantiate the printer. */ +@@ -562,9 +585,11 @@ apply_val_pretty_printer (struct type *t + make_cleanup (free_current_contents, &hint); + + /* Print the section */ +- print_string_repr (printer, hint, stream, recurse, options, language, +- gdbarch); +- print_children (printer, hint, stream, recurse, options, language); ++ is_py_none = print_string_repr (printer, hint, stream, recurse, ++ options, language, gdbarch); ++ print_children (printer, hint, stream, recurse, options, language, ++ is_py_none); ++ + result = 1; + + +Index: gdb-7.1/gdb/testsuite/gdb.python/py-mi.exp +=================================================================== +--- gdb-7.1.orig/gdb/testsuite/gdb.python/py-mi.exp 2010-01-14 09:03:37.000000000 +0100 ++++ gdb-7.1/gdb/testsuite/gdb.python/py-mi.exp 2010-06-30 03:22:20.000000000 +0200 +@@ -61,6 +61,16 @@ mi_list_varobj_children container { + + mi_delete_varobj container "delete varobj" + ++mi_create_dynamic_varobj nscont nstype \ ++ "create nscont varobj, no pretty-printing" ++ ++mi_list_varobj_children nscont { ++ { nscont.len len 0 int } ++ { nscont.elements elements 1 "int ." } ++} "examine nscont children=0, no pretty-printing" ++ ++mi_delete_varobj nscont "delete varobj" ++ + mi_gdb_test "-enable-pretty-printing" "" + + mi_create_varobj_checked string string_1 \ +@@ -239,4 +249,29 @@ mi_continue_to_line \ + + mi_varobj_update_with_type_change container int 0 "update after type change" + ++ ++mi_continue_to_line \ ++ [gdb_get_line_number {break to inspect struct and union} ${testfile}.c] \ ++ "step to outer breakpoint" ++ ++mi_create_dynamic_varobj nscont nstype \ ++ "create nstype varobj" ++ ++mi_list_varobj_children nscont { ++ { {nscont.\[0\]} {\[0\]} 0 int } ++ { {nscont.\[1\]} {\[1\]} 0 int } ++} "list children after setting update range" ++ ++mi_gdb_test "-var-set-visualizer nscont None" \ ++ "\\^done" \ ++ "clear visualizer" ++ ++mi_gdb_test "-var-update nscont" \ ++ "\\^done,changelist=\\\[\\\]" \ ++ "varobj update after clearing" ++ ++mi_gdb_test "-var-set-visualizer nscont gdb.default_visualizer" \ ++ "\\^done" \ ++ "choose default visualizer" ++ + remote_file host delete ${remote_python_file} +Index: gdb-7.1/gdb/testsuite/gdb.python/py-prettyprint.c +=================================================================== +--- gdb-7.1.orig/gdb/testsuite/gdb.python/py-prettyprint.c 2010-01-14 09:03:37.000000000 +0100 ++++ gdb-7.1/gdb/testsuite/gdb.python/py-prettyprint.c 2010-06-30 03:22:20.000000000 +0200 +@@ -119,6 +119,15 @@ typedef struct string_repr + + /* This lets us avoid malloc. */ + int array[100]; ++int narray[10]; ++ ++struct justchildren ++{ ++ int len; ++ int *elements; ++}; ++ ++typedef struct justchildren nostring_type; + + struct container + { +@@ -196,7 +205,9 @@ main () + const struct string_repr cstring = { { "const string" } }; + /* Clearing by being `static' could invoke an other GDB C++ bug. */ + struct nullstr nullstr; +- ++ nostring_type nstype; ++ nstype.elements = narray; ++ nstype.len = 0; + + init_ss(&ss, 1, 2); + init_ss(ssa+0, 3, 4); +@@ -249,5 +260,9 @@ main () + do_nothing (); + #endif + ++ nstype.elements[0] = 7; ++ nstype.elements[1] = 42; ++ nstype.len = 2; ++ + return 0; /* break to inspect struct and union */ + } +Index: gdb-7.1/gdb/testsuite/gdb.python/py-prettyprint.exp +=================================================================== +--- gdb-7.1.orig/gdb/testsuite/gdb.python/py-prettyprint.exp 2010-06-30 03:22:02.000000000 +0200 ++++ gdb-7.1/gdb/testsuite/gdb.python/py-prettyprint.exp 2010-06-30 03:24:14.000000000 +0200 +@@ -115,6 +115,7 @@ proc run_lang_tests {lang} { + + gdb_test "print nullstr" "RuntimeError: Error reading string from inferior.*" + ++ gdb_test "print nstype" " = {$nl *.0. = 7,$nl *.1. = 42$nl}" + gdb_test "continue" "Program exited normally\." + + remote_file host delete ${remote_python_file} +Index: gdb-7.1/gdb/testsuite/gdb.python/py-prettyprint.py +=================================================================== +--- gdb-7.1.orig/gdb/testsuite/gdb.python/py-prettyprint.py 2010-01-14 09:03:37.000000000 +0100 ++++ gdb-7.1/gdb/testsuite/gdb.python/py-prettyprint.py 2010-06-30 03:22:20.000000000 +0200 +@@ -53,6 +53,33 @@ class ContainerPrinter: + def children(self): + return self._iterator(self.val['elements'], self.val['len']) + ++# Test a printer where to_string is None ++class NoStringContainerPrinter: ++ class _iterator: ++ def __init__ (self, pointer, len): ++ self.start = pointer ++ self.pointer = pointer ++ self.end = pointer + len ++ ++ def __iter__(self): ++ return self ++ ++ def next(self): ++ if self.pointer == self.end: ++ raise StopIteration ++ result = self.pointer ++ self.pointer = self.pointer + 1 ++ return ('[%d]' % int (result - self.start), result.dereference()) ++ ++ def __init__(self, val): ++ self.val = val ++ ++ def to_string(self): ++ return None ++ ++ def children(self): ++ return self._iterator(self.val['elements'], self.val['len']) ++ + class pp_s: + def __init__(self, val): + self.val = val +@@ -190,8 +217,10 @@ def register_pretty_printers (): + # both the C and C++ cases. + pretty_printers_dict[re.compile ('^struct string_repr$')] = string_print + pretty_printers_dict[re.compile ('^struct container$')] = ContainerPrinter ++ pretty_printers_dict[re.compile ('^struct justchildren$')] = NoStringContainerPrinter + pretty_printers_dict[re.compile ('^string_repr$')] = string_print + pretty_printers_dict[re.compile ('^container$')] = ContainerPrinter ++ pretty_printers_dict[re.compile ('^justchildren$')] = NoStringContainerPrinter + + pretty_printers_dict[re.compile ('^struct ns$')] = pp_ns + pretty_printers_dict[re.compile ('^ns$')] = pp_ns diff --git a/gdb-bz562763-pretty-print-2d-vectors.patch b/gdb-bz562763-pretty-print-2d-vectors.patch new file mode 100644 index 0000000..f1a8973 --- /dev/null +++ b/gdb-bz562763-pretty-print-2d-vectors.patch @@ -0,0 +1,404 @@ +2010-05-31 Chris Moller + + * python/py-prettyprint.c (print_children): Add formatting for + matrices. (apply_val_pretty_printer): Detect and deal with matrix + hints. + + +2010-05-31 Chris Moller + + * gdb.python/Makefile.in (EXECUTABLES): Added pr10659. + * gdb.python/pr10659.cc: New file. + * gdb.python/pr10659.exp. New file. + * gdb.python/pr10659.py: New file. + +Index: gdb-7.1/gdb/valprint.h +=================================================================== +--- gdb-7.1.orig/gdb/valprint.h 2010-06-30 14:02:16.000000000 +0200 ++++ gdb-7.1/gdb/valprint.h 2010-06-30 14:35:24.000000000 +0200 +@@ -90,6 +90,9 @@ struct value_print_options + + /* If nonzero, print the value in "summary" form. */ + int summary; ++ ++ /* Affects pretty printing of matrices. */ ++ int prettyprint_matrix; + }; + + /* The global print options set by the user. In general this should +Index: gdb-7.1/gdb/python/py-prettyprint.c +=================================================================== +--- gdb-7.1.orig/gdb/python/py-prettyprint.c 2010-06-30 14:01:40.000000000 +0200 ++++ gdb-7.1/gdb/python/py-prettyprint.c 2010-06-30 14:34:49.000000000 +0200 +@@ -385,7 +385,8 @@ print_children (PyObject *printer, const + + /* Use the prettyprint_arrays option if we are printing an array, + and the pretty option otherwise. */ +- pretty = is_array ? options->prettyprint_arrays : options->pretty; ++ pretty = (is_array || options->prettyprint_matrix) ? ++ options->prettyprint_arrays : options->pretty; + + /* Manufacture a dummy Python frame to work around Python 2.4 bug, + where it insists on having a non-NULL tstate->frame when +@@ -397,6 +398,9 @@ print_children (PyObject *printer, const + goto done; + } + make_cleanup_py_decref (frame); ++ ++ if (options->prettyprint_matrix && recurse == 0) ++ fputs_filtered ("\n", stream); + + done_flag = 0; + for (i = 0; i < options->print_max; ++i) +@@ -431,12 +435,23 @@ print_children (PyObject *printer, const + 3. Other. Always print a ",". */ + if (i == 0) + { +- if (is_py_none) +- fputs_filtered ("{", stream); +- else +- fputs_filtered (" = {", stream); ++ if (options->prettyprint_matrix && recurse == 0) ++ print_spaces_filtered (2 + 2 * recurse, stream); ++ if (is_py_none) ++ { ++ if (options->prettyprint_matrix && strcmp (hint, "array")) ++ { ++ fputs_filtered ("{\n", stream); ++ print_spaces_filtered (4 + 2 * recurse, stream); ++ } ++ else ++ fputs_filtered ("{", stream); ++ } ++ else ++ fputs_filtered (" = {", stream); + } +- ++ else if (options->prettyprint_matrix) ++ print_spaces_filtered (4 + 2 * recurse, stream); + else if (! is_map || i % 2 == 0) + fputs_filtered (pretty ? "," : ", ", stream); + +@@ -465,6 +480,10 @@ print_children (PyObject *printer, const + + if (is_map && i % 2 == 0) + fputs_filtered ("[", stream); ++ else if (options->prettyprint_matrix) ++ { ++ /* Force a do-nothing. */ ++ } + else if (is_array) + { + /* We print the index, not whatever the child method +@@ -539,7 +558,12 @@ print_children (PyObject *printer, const + fputs_filtered ("\n", stream); + print_spaces_filtered (2 * recurse, stream); + } +- fputs_filtered ("}", stream); ++ if (options->prettyprint_matrix) ++ { ++ print_spaces_filtered (4 * recurse, stream); ++ fputs_filtered ("}\n", stream); ++ } ++ else fputs_filtered ("}", stream); + } + + done: +@@ -561,6 +585,7 @@ apply_val_pretty_printer (struct type *t + struct cleanup *cleanups; + int result = 0; + int is_py_none = 0; ++ struct value_print_options *options_copy; + cleanups = ensure_python_env (gdbarch, language); + + /* Instantiate the printer. */ +@@ -582,12 +607,23 @@ apply_val_pretty_printer (struct type *t + + /* If we are printing a map, we want some special formatting. */ + hint = gdbpy_get_display_hint (printer); ++ ++ if (recurse == 0) ++ { ++ options_copy = alloca (sizeof (struct value_print_options)); ++ memcpy (options_copy, options, sizeof (struct value_print_options)); ++ options_copy->prettyprint_matrix = hint && !strcmp (hint, "matrix"); ++ } ++ else options_copy = (struct value_print_options *)options; ++ + make_cleanup (free_current_contents, &hint); + + /* Print the section */ +- is_py_none = print_string_repr (printer, hint, stream, recurse, +- options, language, gdbarch); +- print_children (printer, hint, stream, recurse, options, language, ++ is_py_none = options_copy->prettyprint_matrix ? ++ 1 : print_string_repr (printer, hint, stream, ++ recurse, options_copy, ++ language, gdbarch); ++ print_children (printer, hint, stream, recurse, options_copy, language, + is_py_none); + + result = 1; +Index: gdb-7.1/gdb/testsuite/gdb.python/pr10659.cc +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ gdb-7.1/gdb/testsuite/gdb.python/pr10659.cc 2010-06-30 14:34:49.000000000 +0200 +@@ -0,0 +1,43 @@ ++#include ++#include // /usr/include/c++/4.4.1/bits/vector.tcc ++#include ++ ++using namespace std; ++ ++int use_windows = 9999; ++ ++int ++main(){ ++ vector test1(2,0); ++ test1[0]=8; ++ test1[1]=9; ++ ++ vector< vector > test2(3, vector(2,0)); ++ test2[0][0]=0; ++ test2[0][1]=1; ++ test2[1][0]=2; ++ test2[1][1]=3; ++ test2[2][0]=4; ++ test2[2][1]=5; ++ ++#define NR_ROWS 2 ++#define NR_COLS 3 ++#define NR_PLANES 4 ++ vector rows(NR_ROWS, 0); ++ vector< vector > columns(NR_COLS, rows); ++ vector< vector < vector > > test3(NR_PLANES, columns); ++ ++ cout << "rows.size() = " << rows.size() ++ << ", columns.size() = " << columns.size() ++ << ", test3.size() = " << test3.size() << "\n"; ++ ++ for (int i = 0; i < rows.size(); i++) { ++ for (int j = 0; j < columns.size(); j++) { ++ for (int k = 0; k < test3.size(); k++) { ++ test3[k][j][i] = k * 100 + j * 10 + i; ++ } ++ } ++ } ++ ++ return 0; // break ++} +Index: gdb-7.1/gdb/testsuite/gdb.python/pr10659.exp +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ gdb-7.1/gdb/testsuite/gdb.python/pr10659.exp 2010-06-30 14:34:49.000000000 +0200 +@@ -0,0 +1,82 @@ ++#Copyright 2010 Free Software Foundation, Inc. ++ ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++set nl "\[\r\n\]+" ++ ++set testfile pr10659 ++set srcfile ${testfile}.cc ++if [prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}] { ++ return -1 ++} ++ ++#if { [skip_python_tests] } { continue } ++ ++gdb_test "python execfile(\"$srcdir/$subdir/pr10659.py\")" "" ++gdb_test "python gdb.pretty_printers = \[lookup_function\]" "" ++ ++if ![runto_main] then { ++ fail "Can't run to main" ++ return ++} ++ ++gdb_breakpoint [gdb_get_line_number "break"] ++gdb_continue_to_breakpoint "break" ++ ++gdb_test "p test1" "vector of length 2, capacity 2 =.*" ++ ++gdb_test "p test2" "= $nl {$nl {.*" ++ ++# Complete result is: ++# ++# (gdb) p test2 ++# $2 = ++# { ++# {0 1 } ++# {2 3 } ++# {4 5 } ++# } ++ ++ ++gdb_test "p test3" "= $nl {$nl {$nl {.*" ++ ++# Complete result is: ++# ++# (gdb) p test3 ++# $3 = ++# { ++# { ++# {0 1 } ++# {10 11 } ++# {20 21 } ++# } ++# { ++# {100 101 } ++# {110 111 } ++# {120 121 } ++# } ++# { ++# {200 201 } ++# {210 211 } ++# {220 221 } ++# } ++# { ++# {300 301 } ++# {310 311 } ++# {320 321 } ++# } ++# } ++# ++ ++ +Index: gdb-7.1/gdb/testsuite/gdb.python/pr10659.py +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ gdb-7.1/gdb/testsuite/gdb.python/pr10659.py 2010-06-30 14:34:49.000000000 +0200 +@@ -0,0 +1,109 @@ ++# Copyright (C) 2008, 2009 Free Software Foundation, Inc. ++ ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++import gdb ++import itertools ++import re ++ ++vector_sig = 'std::vector' ++vector_regex = re.compile('^' + vector_sig + '<.*>$') ++ ++class FakeVectorPrinter: ++ "Print a std::vector" ++ ++ class _iterator: ++ def __init__ (self, start, finish): ++ self.item = start ++ self.finish = finish ++ self.count = 0 ++ ++ def __iter__(self): ++ return self ++ ++ def next(self): ++ if self.item == self.finish: ++ raise StopIteration ++ count = self.count ++ self.count = self.count + 1 ++ elt = self.item.dereference() ++ self.item = self.item + 1 ++ return ('[%d]' % count, elt) ++ ++ def __init__(self, typename, val): ++ self.typename = typename ++ self.val = val ++ ++ def children(self): ++ return self._iterator(self.val['_M_impl']['_M_start'], ++ self.val['_M_impl']['_M_finish']) ++ ++ def to_string(self): ++ start = self.val['_M_impl']['_M_start'] ++ finish = self.val['_M_impl']['_M_finish'] ++ end = self.val['_M_impl']['_M_end_of_storage'] ++ return ('std::vector of length %d, capacity %d' ++ % (int (finish - start), int (end - start))) ++ ++ def display_hint(self): ++ itype0 = self.val.type.template_argument(0) ++ itag = itype0.tag ++ if itag and re.match(vector_regex, itag): ++ rc = 'matrix' ++ else: ++ rc = 'array' ++ return rc ++ ++def register_libstdcxx_printers (obj): ++ "Register libstdc++ pretty-printers with objfile Obj." ++ ++ if obj == None: ++ obj = gdb ++ ++ obj.pretty_printers.append (lookup_function) ++ ++def lookup_function (val): ++ "Look-up and return a pretty-printer that can print val." ++ ++ # Get the type. ++ type = val.type; ++ ++ # If it points to a reference, get the reference. ++ if type.code == gdb.TYPE_CODE_REF: ++ type = type.target () ++ ++ # Get the unqualified type, stripped of typedefs. ++ type = type.unqualified ().strip_typedefs () ++ ++ # Get the type name. ++ typename = type.tag ++ if typename == None: ++ return None ++ ++ # Iterate over local dictionary of types to determine ++ # if a printer is registered for that type. Return an ++ # instantiation of the printer if found. ++ for function in fake_pretty_printers_dict: ++ if function.search (typename): ++ return fake_pretty_printers_dict[function] (val) ++ ++ # Cannot find a pretty printer. Return None. ++ return None ++ ++def build_libfakecxx_dictionary (): ++ fake_pretty_printers_dict[vector_regex] = lambda val: FakeVectorPrinter(vector_sig, val) ++ ++fake_pretty_printers_dict = {} ++ ++build_libfakecxx_dictionary () +Index: gdb-7.1/gdb/valprint.c +=================================================================== +--- gdb-7.1.orig/gdb/valprint.c 2010-06-30 13:51:26.000000000 +0200 ++++ gdb-7.1/gdb/valprint.c 2010-06-30 14:35:41.000000000 +0200 +@@ -83,7 +83,8 @@ struct value_print_options user_print_op + 1, /* static_field_print */ + 1, /* pascal_static_field_print */ + 0, /* raw */ +- 0 /* summary */ ++ 0, /* summary */ ++ 0 /* prettyprint_matrix */ + }; + + /* Initialize *OPTS to be a copy of the user print options. */ diff --git a/gdb.spec b/gdb.spec index 182d326..0d15723 100644 --- a/gdb.spec +++ b/gdb.spec @@ -36,7 +36,7 @@ Version: 7.1 # The release always contains a leading reserved number, start it at 1. # `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing. -Release: 27%{?_with_upstream:.upstream}%{dist} +Release: 28%{?_with_upstream:.upstream}%{dist} License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and GFDL and BSD and Public Domain Group: Development/Debuggers @@ -522,6 +522,11 @@ Patch483: gdb-bz602314-ptype-class-typedef-3of3.patch # Fix `set print object on' for some non-dynamic classes (BZ 606660). Patch484: gdb-bz606660-print-object-nonvirtual.patch +# Print 2D C++ vectors as matrices (BZ 562763, sourceware10659, Chris Moller). +Patch485: gdb-bz562763-pretty-print-2d-vectors-prereq.patch +Patch486: gdb-bz562763-pretty-print-2d-vectors.patch +Patch487: gdb-bz562763-pretty-print-2d-vectors-libstdcxx.patch + BuildRequires: ncurses-devel%{?_isa} texinfo gettext flex bison expat-devel%{?_isa} Requires: readline%{?_isa} BuildRequires: readline-devel%{?_isa} @@ -821,6 +826,9 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c %patch482 -p1 %patch483 -p1 %patch484 -p1 +%patch485 -p1 +%patch486 -p1 +%patch487 -p1 %patch415 -p1 %patch393 -p1 @@ -1153,6 +1161,9 @@ fi %endif %changelog +* Wed Jun 30 2010 Jan Kratochvil - 7.1-28.fc13 +- Print 2D C++ vectors as matrices (BZ 562763, sourceware10659, Chris Moller). + * Wed Jun 30 2010 Jan Kratochvil - 7.1-27.fc13 - Fix obstack corruptions on C++ (BZ 606185, Chris Moller, Jan Kratochvil). - Improve support for typedefs in classes (BZ 602314).