- Print 2D C++ vectors as matrices (BZ 562763, sourceware10659, Chris
Moller).
This commit is contained in:
parent
61b288432e
commit
6068e6305e
|
@ -0,0 +1,43 @@
|
|||
2010-06-01 Chris Moller <cmoller@redhat.com>
|
||||
|
||||
* 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<bool>
|
||||
|
||||
# Printer registrations for classes compiled with -D_GLIBCXX_DEBUG.
|
|
@ -0,0 +1,427 @@
|
|||
commit e5ea8d026015c2a0c7774788b425914857de1ffb
|
||||
Author: pmuldoon <pmuldoon>
|
||||
Date: Wed Apr 14 12:02:42 2010 +0000
|
||||
|
||||
2010-04-14 Phil Muldoon <pmuldoon@redhat.com>
|
||||
|
||||
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 <pmuldoon@redhat.com>
|
||||
|
||||
* 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 <pmuldoon@redhat.com>
|
||||
|
||||
* 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 <pmuldoon@redhat.com>
|
||||
+
|
||||
+ 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 <kettenis@gnu.org>
|
||||
|
||||
PR corefiles/11481
|
||||
### a/gdb/doc/ChangeLog
|
||||
### b/gdb/doc/ChangeLog
|
||||
## -1,3 +1,8 @@
|
||||
+2010-04-14 Phil Muldoon <pmuldoon@redhat.com>
|
||||
+
|
||||
+ * gdb.texinfo (Pretty Printing): Document behaviour when to_string
|
||||
+ returns None.
|
||||
+
|
||||
2010-04-09 Stan Shebs <stan@codesourcery.com>
|
||||
|
||||
* 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
|
|
@ -0,0 +1,404 @@
|
|||
2010-05-31 Chris Moller <cmoller@redhat.com>
|
||||
|
||||
* 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 <cmoller@redhat.com>
|
||||
|
||||
* 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 <list>
|
||||
+#include <vector> // /usr/include/c++/4.4.1/bits/vector.tcc
|
||||
+#include <iostream>
|
||||
+
|
||||
+using namespace std;
|
||||
+
|
||||
+int use_windows = 9999;
|
||||
+
|
||||
+int
|
||||
+main(){
|
||||
+ vector<int> test1(2,0);
|
||||
+ test1[0]=8;
|
||||
+ test1[1]=9;
|
||||
+
|
||||
+ vector< vector<int> > test2(3, vector<int>(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<int> rows(NR_ROWS, 0);
|
||||
+ vector< vector<int> > columns(NR_COLS, rows);
|
||||
+ vector< vector < vector<int> > > 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 <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+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 <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+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. */
|
13
gdb.spec
13
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 <jan.kratochvil@redhat.com> - 7.1-28.fc13
|
||||
- Print 2D C++ vectors as matrices (BZ 562763, sourceware10659, Chris Moller).
|
||||
|
||||
* Wed Jun 30 2010 Jan Kratochvil <jan.kratochvil@redhat.com> - 7.1-27.fc13
|
||||
- Fix obstack corruptions on C++ (BZ 606185, Chris Moller, Jan Kratochvil).
|
||||
- Improve support for typedefs in classes (BZ 602314).
|
||||
|
|
Loading…
Reference in New Issue