ee681d3
2010-05-31  Chris Moller  <cmoller@redhat.com>
ee681d3
ee681d3
	* python/py-prettyprint.c (print_children): Add formatting for
ee681d3
	matrices. (apply_val_pretty_printer): Detect and deal with matrix
ee681d3
	hints. 
ee681d3
ee681d3
ee681d3
2010-05-31  Chris Moller  <cmoller@redhat.com>
ee681d3
ee681d3
	* gdb.python/Makefile.in (EXECUTABLES):  Added pr10659.
ee681d3
	* gdb.python/pr10659.cc:  New file.
ee681d3
	* gdb.python/pr10659.exp.  New file.
ee681d3
	* gdb.python/pr10659.py: New file.
ee681d3
Jan Kratochvil 3080c0e
Index: gdb-7.2.50.20110218/gdb/valprint.h
ee681d3
===================================================================
Jan Kratochvil 3080c0e
--- gdb-7.2.50.20110218.orig/gdb/valprint.h	2011-02-14 12:35:45.000000000 +0100
Jan Kratochvil 3080c0e
+++ gdb-7.2.50.20110218/gdb/valprint.h	2011-02-18 10:44:32.000000000 +0100
ee681d3
@@ -90,6 +90,9 @@ struct value_print_options
ee681d3
 
ee681d3
   /* If nonzero, print the value in "summary" form.  */
ee681d3
   int summary;
ee681d3
+
ee681d3
+  /* Affects pretty printing of matrices.  */
ee681d3
+  int prettyprint_matrix;
ee681d3
 };
ee681d3
 
ee681d3
 /* The global print options set by the user.  In general this should
Jan Kratochvil 3080c0e
Index: gdb-7.2.50.20110218/gdb/python/py-prettyprint.c
ee681d3
===================================================================
Jan Kratochvil 3080c0e
--- gdb-7.2.50.20110218.orig/gdb/python/py-prettyprint.c	2011-02-14 12:10:53.000000000 +0100
Jan Kratochvil 3080c0e
+++ gdb-7.2.50.20110218/gdb/python/py-prettyprint.c	2011-02-18 10:45:02.000000000 +0100
Jan Kratochvil cb641a7
@@ -501,7 +501,7 @@ print_children (PyObject *printer, const
ee681d3
 
ee681d3
   /* Use the prettyprint_arrays option if we are printing an array,
ee681d3
      and the pretty option otherwise.  */
Jan Kratochvil cb641a7
-  if (is_array)
Jan Kratochvil cb641a7
+  if (is_array || options->prettyprint_matrix)
Jan Kratochvil cb641a7
     pretty = options->prettyprint_arrays;
Jan Kratochvil cb641a7
   else
Jan Kratochvil cb641a7
     {
Jan Kratochvil cb641a7
@@ -521,6 +521,9 @@ print_children (PyObject *printer, const
ee681d3
       goto done;
ee681d3
     }
ee681d3
   make_cleanup_py_decref (frame);
ee681d3
+  
ee681d3
+  if (options->prettyprint_matrix && recurse == 0)
ee681d3
+    fputs_filtered ("\n", stream);
ee681d3
 
ee681d3
   done_flag = 0;
ee681d3
   for (i = 0; i < options->print_max; ++i)
Jan Kratochvil cb641a7
@@ -555,12 +558,23 @@ print_children (PyObject *printer, const
ee681d3
 	 3. Other.  Always print a ",".  */
ee681d3
       if (i == 0)
ee681d3
 	{
ee681d3
-         if (is_py_none)
ee681d3
-           fputs_filtered ("{", stream);
ee681d3
-         else
ee681d3
-           fputs_filtered (" = {", stream);
ee681d3
+	  if (options->prettyprint_matrix && recurse == 0)
ee681d3
+	    print_spaces_filtered (2 + 2 * recurse, stream);
ee681d3
+	  if (is_py_none)
ee681d3
+	    {
ee681d3
+	      if (options->prettyprint_matrix && strcmp (hint, "array"))
ee681d3
+		{
ee681d3
+		  fputs_filtered ("{\n", stream);
ee681d3
+		  print_spaces_filtered (4 + 2 * recurse, stream);
ee681d3
+		}
ee681d3
+	      else
ee681d3
+		fputs_filtered ("{", stream);
ee681d3
+	    }
ee681d3
+	  else
ee681d3
+	    fputs_filtered (" = {", stream);
ee681d3
        }
ee681d3
-
ee681d3
+      else if (options->prettyprint_matrix)
ee681d3
+	print_spaces_filtered (4 + 2 * recurse, stream);
ee681d3
       else if (! is_map || i % 2 == 0)
ee681d3
 	fputs_filtered (pretty ? "," : ", ", stream);
ee681d3
 
Jan Kratochvil cb641a7
@@ -589,6 +603,10 @@ print_children (PyObject *printer, const
ee681d3
 
ee681d3
       if (is_map && i % 2 == 0)
ee681d3
 	fputs_filtered ("[", stream);
ee681d3
+      else if (options->prettyprint_matrix)
ee681d3
+	{
ee681d3
+	  /* Force a do-nothing.  */
ee681d3
+	}
ee681d3
       else if (is_array)
ee681d3
 	{
ee681d3
 	  /* We print the index, not whatever the child method
Jan Kratochvil cb641a7
@@ -667,7 +685,12 @@ print_children (PyObject *printer, const
ee681d3
 	  fputs_filtered ("\n", stream);
ee681d3
 	  print_spaces_filtered (2 * recurse, stream);
ee681d3
 	}
ee681d3
-      fputs_filtered ("}", stream);
ee681d3
+      if (options->prettyprint_matrix)
ee681d3
+      {
ee681d3
+	print_spaces_filtered (4 * recurse, stream);
ee681d3
+	fputs_filtered ("}\n", stream);
ee681d3
+      }
ee681d3
+      else fputs_filtered ("}", stream);
ee681d3
     }
ee681d3
 
ee681d3
  done:
Jan Kratochvil 3080c0e
@@ -689,6 +712,7 @@ apply_val_pretty_printer (struct type *t
Jan Kratochvil 3080c0e
   char *hint = NULL;
ee681d3
   struct cleanup *cleanups;
ee681d3
   int result = 0;
ee681d3
+  struct value_print_options *options_copy;
Jan Kratochvil 3080c0e
   enum string_repr_result print_result;
ee681d3
 
Jan Kratochvil 3080c0e
   /* No pretty-printer support for unavailable values.  */
Jan Kratochvil 3080c0e
@@ -726,9 +750,21 @@ apply_val_pretty_printer (struct type *t
ee681d3
 
ee681d3
   /* If we are printing a map, we want some special formatting.  */
ee681d3
   hint = gdbpy_get_display_hint (printer);
ee681d3
+  
ee681d3
+  if (recurse == 0)
ee681d3
+    {
ee681d3
+      options_copy = alloca (sizeof (struct value_print_options));
ee681d3
+      memcpy (options_copy, options, sizeof (struct value_print_options));
ee681d3
+      options_copy->prettyprint_matrix = hint && !strcmp (hint, "matrix");
ee681d3
+    }
ee681d3
+  else options_copy = (struct value_print_options *)options;
ee681d3
+
ee681d3
   make_cleanup (free_current_contents, &hint);
ee681d3
 
ee681d3
   /* Print the section */
Jan Kratochvil e00e5ea
+  if (options_copy->prettyprint_matrix)
Jan Kratochvil e00e5ea
+    print_result = string_repr_none;
Jan Kratochvil e00e5ea
+else /* Red Hat 2D matrix patch */
Jan Kratochvil e00e5ea
   print_result = print_string_repr (printer, hint, stream, recurse,
Jan Kratochvil e00e5ea
 				    options, language, gdbarch);
Jan Kratochvil e00e5ea
   if (print_result != string_repr_error)
Jan Kratochvil 3080c0e
Index: gdb-7.2.50.20110218/gdb/testsuite/gdb.python/pr10659.cc
ee681d3
===================================================================
ee681d3
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
Jan Kratochvil 3080c0e
+++ gdb-7.2.50.20110218/gdb/testsuite/gdb.python/pr10659.cc	2011-02-18 10:44:32.000000000 +0100
ee681d3
@@ -0,0 +1,43 @@
ee681d3
+#include <list>
ee681d3
+#include <vector>  // /usr/include/c++/4.4.1/bits/vector.tcc
ee681d3
+#include <iostream>
ee681d3
+
ee681d3
+using namespace std;
ee681d3
+
ee681d3
+int use_windows = 9999;
ee681d3
+
ee681d3
+int
ee681d3
+main(){
ee681d3
+  vector<int> test1(2,0);
ee681d3
+  test1[0]=8;
ee681d3
+  test1[1]=9;
ee681d3
+  
ee681d3
+  vector< vector<int> > test2(3, vector<int>(2,0));
ee681d3
+  test2[0][0]=0;
ee681d3
+  test2[0][1]=1;
ee681d3
+  test2[1][0]=2;
ee681d3
+  test2[1][1]=3;
ee681d3
+  test2[2][0]=4;
ee681d3
+  test2[2][1]=5;
ee681d3
+
ee681d3
+#define NR_ROWS    2
ee681d3
+#define NR_COLS    3
ee681d3
+#define NR_PLANES  4
ee681d3
+  vector<int> rows(NR_ROWS, 0);
ee681d3
+  vector< vector<int> > columns(NR_COLS, rows);
ee681d3
+  vector< vector < vector<int> > > test3(NR_PLANES, columns);
ee681d3
+
ee681d3
+  cout << "rows.size() = " << rows.size()
ee681d3
+       << ", columns.size() = " << columns.size()
ee681d3
+       << ", test3.size() = " << test3.size() << "\n";
ee681d3
+
ee681d3
+  for (int i = 0; i < rows.size(); i++) {
ee681d3
+    for (int j = 0; j < columns.size(); j++) {
ee681d3
+      for (int k = 0; k < test3.size(); k++) {
ee681d3
+	test3[k][j][i] = k * 100 + j * 10 + i;
ee681d3
+      }
ee681d3
+    }
ee681d3
+  }
ee681d3
+  
ee681d3
+  return 0;  // break
ee681d3
+}
Jan Kratochvil 3080c0e
Index: gdb-7.2.50.20110218/gdb/testsuite/gdb.python/pr10659.exp
ee681d3
===================================================================
ee681d3
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
Jan Kratochvil 3080c0e
+++ gdb-7.2.50.20110218/gdb/testsuite/gdb.python/pr10659.exp	2011-02-18 10:44:32.000000000 +0100
ee681d3
@@ -0,0 +1,82 @@
ee681d3
+#Copyright 2010 Free Software Foundation, Inc.
ee681d3
+
ee681d3
+# This program is free software; you can redistribute it and/or modify
ee681d3
+# it under the terms of the GNU General Public License as published by
ee681d3
+# the Free Software Foundation; either version 3 of the License, or
ee681d3
+# (at your option) any later version.
ee681d3
+#
ee681d3
+# This program is distributed in the hope that it will be useful,
ee681d3
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
ee681d3
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
ee681d3
+# GNU General Public License for more details.
ee681d3
+#
ee681d3
+# You should have received a copy of the GNU General Public License
ee681d3
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
ee681d3
+
ee681d3
+set nl             "\[\r\n\]+"
ee681d3
+
ee681d3
+set testfile pr10659
ee681d3
+set srcfile ${testfile}.cc
ee681d3
+if [prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}] {
ee681d3
+    return -1
ee681d3
+}
ee681d3
+
ee681d3
+#if { [skip_python_tests] } { continue }
ee681d3
+
ee681d3
+gdb_test "python execfile(\"$srcdir/$subdir/pr10659.py\")" ""
ee681d3
+gdb_test "python gdb.pretty_printers = \[lookup_function\]" ""
ee681d3
+
ee681d3
+if ![runto_main] then {
ee681d3
+    fail "Can't run to main"
ee681d3
+    return
ee681d3
+}
ee681d3
+
ee681d3
+gdb_breakpoint [gdb_get_line_number "break"]
ee681d3
+gdb_continue_to_breakpoint "break"
ee681d3
+
ee681d3
+gdb_test "p test1" "vector of length 2, capacity 2 =.*"
ee681d3
+
ee681d3
+gdb_test "p test2" "= $nl  {$nl    {.*"
ee681d3
+
ee681d3
+# Complete result is:
ee681d3
+#
ee681d3
+# (gdb) p test2
ee681d3
+# $2 =
ee681d3
+#   {
ee681d3
+#     {0      1    }
ee681d3
+#     {2      3    }
ee681d3
+#     {4      5    }
ee681d3
+#  }
ee681d3
+
ee681d3
+
ee681d3
+gdb_test "p test3" "= $nl  {$nl    {$nl      {.*"
ee681d3
+
ee681d3
+# Complete result is:
ee681d3
+#
ee681d3
+# (gdb) p test3
ee681d3
+# $3 =
ee681d3
+#   {
ee681d3
+#     {
ee681d3
+#       {0        1        }
ee681d3
+#       {10        11        }
ee681d3
+#       {20        21        }
ee681d3
+#     }
ee681d3
+#     {
ee681d3
+#       {100        101        }
ee681d3
+#       {110        111        }
ee681d3
+#       {120        121        }
ee681d3
+#     }
ee681d3
+#     {
ee681d3
+#       {200        201        }
ee681d3
+#       {210        211        }
ee681d3
+#       {220        221        }
ee681d3
+#     }
ee681d3
+#     {
ee681d3
+#       {300        301        }
ee681d3
+#       {310        311        }
ee681d3
+#       {320        321        }
ee681d3
+#     }
ee681d3
+#  }
ee681d3
+# 
ee681d3
+
ee681d3
+
Jan Kratochvil 3080c0e
Index: gdb-7.2.50.20110218/gdb/testsuite/gdb.python/pr10659.py
ee681d3
===================================================================
ee681d3
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
Jan Kratochvil 3080c0e
+++ gdb-7.2.50.20110218/gdb/testsuite/gdb.python/pr10659.py	2011-02-18 10:44:32.000000000 +0100
ee681d3
@@ -0,0 +1,109 @@
ee681d3
+# Copyright (C) 2008, 2009 Free Software Foundation, Inc.
ee681d3
+
ee681d3
+# This program is free software; you can redistribute it and/or modify
ee681d3
+# it under the terms of the GNU General Public License as published by
ee681d3
+# the Free Software Foundation; either version 3 of the License, or
ee681d3
+# (at your option) any later version.
ee681d3
+#
ee681d3
+# This program is distributed in the hope that it will be useful,
ee681d3
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
ee681d3
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
ee681d3
+# GNU General Public License for more details.
ee681d3
+#
ee681d3
+# You should have received a copy of the GNU General Public License
ee681d3
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
ee681d3
+
ee681d3
+import gdb
ee681d3
+import itertools
ee681d3
+import re
ee681d3
+
ee681d3
+vector_sig = 'std::vector'
ee681d3
+vector_regex = re.compile('^' + vector_sig + '<.*>$')
ee681d3
+
ee681d3
+class FakeVectorPrinter:
ee681d3
+    "Print a std::vector"
ee681d3
+
ee681d3
+    class _iterator:
ee681d3
+        def __init__ (self, start, finish):
ee681d3
+            self.item = start
ee681d3
+            self.finish = finish
ee681d3
+            self.count = 0
ee681d3
+
ee681d3
+        def __iter__(self):
ee681d3
+            return self
ee681d3
+
ee681d3
+        def next(self):
ee681d3
+            if self.item == self.finish:
ee681d3
+                raise StopIteration
ee681d3
+            count = self.count
ee681d3
+            self.count = self.count + 1
ee681d3
+            elt = self.item.dereference()
ee681d3
+            self.item = self.item + 1
ee681d3
+            return ('[%d]' % count, elt)
ee681d3
+
ee681d3
+    def __init__(self, typename, val):
ee681d3
+        self.typename = typename
ee681d3
+        self.val = val
ee681d3
+
ee681d3
+    def children(self):
ee681d3
+        return self._iterator(self.val['_M_impl']['_M_start'],
ee681d3
+                              self.val['_M_impl']['_M_finish'])
ee681d3
+
ee681d3
+    def to_string(self):
ee681d3
+        start = self.val['_M_impl']['_M_start']
ee681d3
+        finish = self.val['_M_impl']['_M_finish']
ee681d3
+        end = self.val['_M_impl']['_M_end_of_storage']
ee681d3
+        return ('std::vector of length %d, capacity %d'
ee681d3
+                % (int (finish - start), int (end - start)))
ee681d3
+
ee681d3
+    def display_hint(self):
ee681d3
+        itype0  = self.val.type.template_argument(0)
ee681d3
+        itag = itype0.tag
ee681d3
+        if itag and re.match(vector_regex, itag):
ee681d3
+            rc = 'matrix'
ee681d3
+        else:
ee681d3
+            rc = 'array'
ee681d3
+        return rc
ee681d3
+
ee681d3
+def register_libstdcxx_printers (obj):
ee681d3
+    "Register libstdc++ pretty-printers with objfile Obj."
ee681d3
+
ee681d3
+    if obj == None:
ee681d3
+        obj = gdb
ee681d3
+
ee681d3
+    obj.pretty_printers.append (lookup_function)
ee681d3
+
ee681d3
+def lookup_function (val):
ee681d3
+    "Look-up and return a pretty-printer that can print val."
ee681d3
+
ee681d3
+    # Get the type.
ee681d3
+    type = val.type;
ee681d3
+
ee681d3
+    # If it points to a reference, get the reference.
ee681d3
+    if type.code == gdb.TYPE_CODE_REF:
ee681d3
+        type = type.target ()
ee681d3
+
ee681d3
+    # Get the unqualified type, stripped of typedefs.
ee681d3
+    type = type.unqualified ().strip_typedefs ()
ee681d3
+
ee681d3
+    # Get the type name.    
ee681d3
+    typename = type.tag
ee681d3
+    if typename == None:
ee681d3
+        return None
ee681d3
+
ee681d3
+    # Iterate over local dictionary of types to determine
ee681d3
+    # if a printer is registered for that type.  Return an
ee681d3
+    # instantiation of the printer if found.
ee681d3
+    for function in fake_pretty_printers_dict:
ee681d3
+        if function.search (typename):
ee681d3
+            return fake_pretty_printers_dict[function] (val)
ee681d3
+        
ee681d3
+    # Cannot find a pretty printer.  Return None.
ee681d3
+    return None
ee681d3
+
ee681d3
+def build_libfakecxx_dictionary ():
ee681d3
+    fake_pretty_printers_dict[vector_regex] = lambda val: FakeVectorPrinter(vector_sig, val)
ee681d3
+
ee681d3
+fake_pretty_printers_dict = {}
ee681d3
+
ee681d3
+build_libfakecxx_dictionary ()
Jan Kratochvil 3080c0e
Index: gdb-7.2.50.20110218/gdb/valprint.c
ee681d3
===================================================================
Jan Kratochvil 3080c0e
--- gdb-7.2.50.20110218.orig/gdb/valprint.c	2011-02-18 10:44:16.000000000 +0100
Jan Kratochvil 3080c0e
+++ gdb-7.2.50.20110218/gdb/valprint.c	2011-02-18 10:44:32.000000000 +0100
Jan Kratochvil e00e5ea
@@ -85,7 +85,8 @@ struct value_print_options user_print_op
ee681d3
   1,				/* static_field_print */
ee681d3
   1,				/* pascal_static_field_print */
ee681d3
   0,				/* raw */
ee681d3
-  0				/* summary */
ee681d3
+  0,				/* summary */
ee681d3
+  0				/* prettyprint_matrix */
ee681d3
 };
ee681d3
 
ee681d3
 /* Initialize *OPTS to be a copy of the user print options.  */