public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  archer-tromey-python: Rewrite pretty-printers registration method to use a list over a dictionary.
@ 2009-02-24 11:22 pmuldoon
  0 siblings, 0 replies; only message in thread
From: pmuldoon @ 2009-02-24 11:22 UTC (permalink / raw)
  To: archer-commits

The branch, archer-tromey-python has been updated
       via  9f534e722211caffa7caef5cd11c5da2ac24f6c4 (commit)
      from  6b43f0eaec652104bcbf802d7a86869d956ce4e4 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 9f534e722211caffa7caef5cd11c5da2ac24f6c4
Author: Phil Muldoon <pmuldoon@redhat.com>
Date:   Tue Feb 24 11:19:18 2009 +0000

    Rewrite pretty-printers registration method to use a list over a dictionary.
    
    Update all the pretty-printer in-tree dependencies to this new method.
    
    Update and add documentation
    
    Add new method to python-type.c called strip_typedefs.
    
    Documentation ChangeLog:
    
    2009-02-24  Phil Muldoon  <pmuldoon@redhat.com>
    
    	* gdb.texinfo (Types From Inferior): Add strip_typedef entry.
    	(Pretty Printing): Update explanation for printer selection,
    	update example, and add a note on lookup function.
    
    Testsuite ChangeLog:
    
    2009-02-24  Phil Muldoon  <pmuldoon@redhat.com>
    
    	* gdb.python/python-prettyprint.py: Move printer registration to
    	register_pretty_printers. Register lookup_function with
    	gdb.pretty_printers list.
    	(lookup_function): New    Function.
    	(register_pretty_printers): New Function.
    
    GDB ChangeLog:
    
    2009-02-24  Phil Muldoon  <pmuldoon@redhat.com>
    
    	* varobj.c (struct varobj): Delete constructor member.
    	(instantiate_pretty_printer): Do not instantiate from stored
    	varobj constructor, but from constructor passed as an argument.
    	(install_new_value): Check varobj->pretty_printer existence for
    	changeable state.
    	(install_new_value): Do not lazily instantiate pretty-printer.
    	(install_visualizer): Remove constructor -> instantiate
    	pretty-printer logic.
    	(install_default_visualizer): Check value over type. Add None
    	check for pretty printer. Pass instantiation of pretty-printer to
    	install-visualizer.
    	(varobj_set_visualizer): Add None check. Remove constructor logic and
    	only deal with instantiations.
    	(new_variable): Remove constructor member initialization.
    	(free_variable): Remove constructor member python decref.
    	(c_value_of_variable): Check pretty-printer over constructor.
    	* python/python.c (search_pp_list): Rename from
    	search_pp_dictionary. Rewrite to iterate a list.
    	(find_pretty_printer): Take a value instead of a type, and
    	similarly pass a value to search_pp_list. Convert all dictionary
    	checks to list checks. Do not extract type information from value.
    	(print_children): Add an  iterator error check, and print
    	out exception if one occurs.
    	(apply_val_pretty_printer): Adapt to find_pretty_printer list
    	searching behaviour, and account for None and NULL returns.
    	(gdbpy_get_varobj_pretty_printer): Receive a value, and similarly
    	pass a value to find_pretty_printer.
    	(gdbpy_default_visualizer): Do not instantiate constructor. Return
    	a pretty printer from find_pretty_printer based on value.
    	(_initialize_python): Convert gdb.pretty_printer to a list.
    	(get_type): Delete
    	(apply_varobj_pretty_printer): Delete extra value argument.
    	* python/python-type.c (typy_strip_typedefs): New function
    	Declare in type_object_methods[].
    	* python/python-objfile.c (objfpy_new): Create an new list instead
    	of a dictionary.
    	(objfile_to_objfile_object): Likewise.
    	(objfpy_set_printers): Check for a list, instead of a dictionary.
    	* python/python-internal.h: Change gdbpy_get_varobj_pretty_printer
    	declaration to take a value.
    	(apply_varobj_pretty_printer): Remove value argument.
    	* python/lib/gdb/libstdcxx/v6/printers.py
    	(Tr1HashtableIterator.__init__): Use _M_element_count.
    	(lookup_function): New function.
    	(build_libstdcxx_dictionary): Register with compiled reg-ex as a
    	key. Make dictionary private.

-----------------------------------------------------------------------

Summary of changes:
 gdb/doc/gdb.texinfo                            |   69 +++++---
 gdb/python/lib/gdb/libstdcxx/v6/printers.py    |  103 +++++++----
 gdb/python/python-internal.h                   |    6 +-
 gdb/python/python-objfile.c                    |   12 +-
 gdb/python/python-type.c                       |   13 ++-
 gdb/python/python.c                            |  233 +++++++++++-------------
 gdb/testsuite/gdb.python/python-prettyprint.py |   76 ++++++--
 gdb/varobj.c                                   |  108 ++++++-----
 8 files changed, 354 insertions(+), 266 deletions(-)

First 500 lines of diff:
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 91114a1..d607daa 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -18548,6 +18548,11 @@ target's @code{char} type will be an 8-bit byte.  However, on some
 unusual platforms, this type may have a different size.
 @end defmethod
 
+@defmethod Type strip_typedefs
+Return a new @code{gdb.Type} that represents the real type,
+after removing all layers of typedefs.
+@end defmethod
+
 @defmethod Type tag
 Return the tag name for this type.  The tag name is the name after
 @code{struct}, @code{union}, or @code{enum} in C; not all languages
@@ -18808,30 +18813,27 @@ convertible to @code{gdb.Value}, an exception is raised.
 
 @subsubsection Selecting Pretty-Printers
 
-The Python dictionary @code{gdb.pretty_printers} maps regular
-expressions (strings) onto constructors.  Each @code{gdb.Objfile} also
-contains a @code{pretty_printers} attribute.  A constructor, in this
-context, is a function which takes a single @code{gdb.Value} argument
-and returns a a pretty-printer conforming to the interface definition
-above.
+The Python list @code{gdb.pretty_printers} contains an array of
+functions that have been registered via addition as a pretty-printer.
+Each function will be called with a @code{gdb.Value} to be
+pretty-printed.  Each @code{gdb.Objfile} also contains a
+@code{pretty_printers} attribute.  A function on one of these lists
+takes a single @code{gdb.Value} argument and returns a pretty-printer
+object conforming to the interface definition above.  If this function
+cannot create a pretty-printer for the value, it should return
+@code{None}.
 
-When printing a value, @value{GDBN} first computes the value's
-canonical type by following typedefs, following a reference type to
-its referenced type, and removing qualifiers, such as @code{const} or
-@code{volatile}.
-
-Then, @value{GDBN} tests each regular expression against this type name.
 @value{GDBN} first checks the @code{pretty_printers} attribute of each
-@code{gdb.Objfile}; after these have been exhausted it tries the
-global @code{gdb.pretty_printers}.
-
-If a regular expression matches, then the corresponding pretty-printer
-is invoked with a @code{gdb.Value} representing the value to be
-printed.
+@code{gdb.Objfile} and iteratively calls each function in the list for
+that @code{gdb.Objfile} until it receives a pretty-printer object.
+After these @code{gdb.Objfile} have been exhausted, it tries the
+global @code{gdb.pretty-printers} list, again calling each function
+until an object is returned.
 
 The order in which the objfiles are searched is not specified.
-Similarly, the order in which the regular expressions in a given
-dictionary are tried is not specified.
+Functions are always invoked from the head of the
+@code{gdb.pretty-printers} list, and iterated over sequentially until
+the end of the list, or a printer object is returned.
 
 Here is an example showing how a @code{std::string} printer might be
 written:
@@ -18840,13 +18842,34 @@ written:
 class StdStringPrinter:
     "Print a std::string"
 
-    def __init__(self, val):
+    def __init__ (self, val):
         self.val = val
 
-    def to_string(self):
+    def to_string (self):
         return self.val['_M_dataplus']['_M_p']
 @end smallexample
 
+And here is an example showing how a lookup function for
+the printer example above might be written. 
+
+@smallexample
+def str_lookup_function (val):
+
+    lookup_tag = val.type ().tag ()
+    regex = re.compile ("^std::basic_string<char,.*>$")
+    if lookup_tag == None:
+        return None
+    if regex.match (lookup_tag):
+        return StdStringPrinter (val)
+    
+    return None
+@end smallexample
+
+The example lookup function extracts the value's type, and attempts to
+match it to a type that it can pretty-print.  If it is a type the
+printer can pretty-print, it will return a printer object.  If not, it
+returns: @code{None}.
+
 We recommend that you put your core pretty-printers into a versioned
 python package, and then restrict your auto-loaded code to idempotent
 behavior -- for example, just @code{import}s of your printer modules,
@@ -18859,7 +18882,7 @@ For example, in addition to the above, this code might appear in
 
 @smallexample
 def register_printers (objfile):
-    objfile.pretty_printers['^std::basic_string<char.*>$'] = StdStringPrinter
+    objfile.pretty_printers.add (str_lookup_function)
 @end smallexample
 
 And then the corresponding contents of the auto-load file would be:
diff --git a/gdb/python/lib/gdb/libstdcxx/v6/printers.py b/gdb/python/lib/gdb/libstdcxx/v6/printers.py
index e7b3495..7a77ad4 100644
--- a/gdb/python/lib/gdb/libstdcxx/v6/printers.py
+++ b/gdb/python/lib/gdb/libstdcxx/v6/printers.py
@@ -1,6 +1,6 @@
 # Pretty-printers for libstc++.
 
-# Copyright (C) 2008 Free Software Foundation, Inc.
+# 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
@@ -17,6 +17,7 @@
 
 import gdb
 import itertools
+import re
 
 class StdPointerPrinter:
     "Print a smart pointer of some kind"
@@ -557,56 +558,90 @@ class Tr1UnorderedMapPrinter:
     def display_hint (self):
         return 'map'
 
-def register_libstdcxx_printers(obj):
+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 pretty_printers_dict:
+        if function.search (typename):
+            return pretty_printers_dict[function] (val)
+        
+    # Cannot find a pretty printer.  Return None.
+    return None
+
+def build_libstdcxx_dictionary ():
     # libstdc++ objects requiring pretty-printing.
     # In order from:
     # http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01847.html
-    obj.pretty_printers['^std::basic_string<char,.*>$'] = lambda val: StdStringPrinter(None, val)
-    obj.pretty_printers['^std::basic_string<wchar_t,.*>$'] = lambda val: StdStringPrinter(target_wide_charset, val)
-    obj.pretty_printers['^std::basic_string<char16_t,.*>$'] = lambda val: StdStringPrinter('UTF-16', val)
-    obj.pretty_printers['^std::basic_string<char32_t,.*>$'] = lambda val: StdStringPrinter('UTF-32', val)
-    obj.pretty_printers['^std::bitset<.*>$'] = StdBitsetPrinter
-    obj.pretty_printers['^std::deque<.*>$'] = StdDequePrinter
-    obj.pretty_printers['^std::list<.*>$'] = StdListPrinter
-    obj.pretty_printers['^std::map<.*>$'] = lambda val: StdMapPrinter("std::map", val)
-    obj.pretty_printers['^std::multimap<.*>$'] = lambda val: StdMapPrinter("std::multimap", val)
-    obj.pretty_printers['^std::multiset<.*>$'] = lambda val: StdSetPrinter("std::multiset", val)
-    obj.pretty_printers['^std::priority_queue<.*>$'] = lambda val: StdStackOrQueuePrinter("std::priority_queue", val)
-    obj.pretty_printers['^std::queue<.*>$'] = lambda val: StdStackOrQueuePrinter("std::queue", val)
-    obj.pretty_printers['^std::set<.*>$'] = lambda val: StdSetPrinter("std::set", val)
-    obj.pretty_printers['^std::stack<.*>$'] = lambda val: StdStackOrQueuePrinter("std::stack", val)
-    obj.pretty_printers['^std::vector<.*>$'] = StdVectorPrinter
+    pretty_printers_dict[re.compile('^std::basic_string<char,.*>$')] = lambda val: StdStringPrinter(None, val)
+    pretty_printers_dict[re.compile('^std::basic_string<wchar_t,.*>$')] = lambda val: StdStringPrinter(target_wide_charset, val)
+    pretty_printers_dict[re.compile('^std::basic_string<char16_t,.*>$')] = lambda val: StdStringPrinter('UTF-16', val)
+    pretty_printers_dict[re.compile('^std::basic_string<char32_t,.*>$')] = lambda val: StdStringPrinter('UTF-32', val)
+    pretty_printers_dict[re.compile('^std::bitset<.*>$')] = StdBitsetPrinter
+    pretty_printers_dict[re.compile('^std::deque<.*>$')] = StdDequePrinter
+    pretty_printers_dict[re.compile('^std::list<.*>$')] = StdListPrinter
+    pretty_printers_dict[re.compile('^std::map<.*>$')] = lambda val: StdMapPrinter("std::map", val)
+    pretty_printers_dict[re.compile('^std::multimap<.*>$')] = lambda val: StdMapPrinter("std::multimap", val)
+    pretty_printers_dict[re.compile('^std::multiset<.*>$')] = lambda val: StdSetPrinter("std::multiset", val)
+    pretty_printers_dict[re.compile('^std::priority_queue<.*>$')] = lambda val: StdStackOrQueuePrinter("std::priority_queue", val)
+    pretty_printers_dict[re.compile('^std::queue<.*>$')] = lambda val: StdStackOrQueuePrinter("std::queue", val)
+    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::vector<.*>$')] = StdVectorPrinter
     # vector<bool>
 
     # C++0x stuff.
     # array - the default seems reasonable
     # smart_ptr?  seems to only be in boost right now
-    obj.pretty_printers['^std::tr1::shared_ptr<.*>$'] = lambda val: StdPointerPrinter ('std::shared_ptr', val)
-    obj.pretty_printers['^std::tr1::weak_ptr<.*>$'] = lambda val: StdPointerPrinter ('std::weak_ptr', val)
-    obj.pretty_printers['^std::tr1::unique_ptr<.*>$'] = UniquePointerPrinter
-    obj.pretty_printers['^std::tr1::unordered_map<.*>$'] = lambda val: Tr1UnorderedMapPrinter ('std::tr1::unordered_map', val)
-    obj.pretty_printers['^std::tr1::unordered_set<.*>$'] = lambda val: Tr1UnorderedSetPrinter ('std::tr1::unordered_set', val)
-    obj.pretty_printers['^std::tr1::unordered_multimap<.*>$'] = lambda val: Tr1UnorderedMapPrinter ('std::tr1::unordered_multimap', val)
-    obj.pretty_printers['^std::tr1::unordered_multiset<.*>$'] = lambda val: Tr1UnorderedSetPrinter ('std::tr1::unordered_multiset', val)
+    pretty_printers_dict[re.compile('^std::tr1::shared_ptr<.*>$')] = lambda val: StdPointerPrinter ('std::shared_ptr', val)
+    pretty_printers_dict[re.compile('^std::tr1::weak_ptr<.*>$')] = lambda val: StdPointerPrinter ('std::weak_ptr', val)
+    pretty_printers_dict[re.compile('^std::tr1::unique_ptr<.*>$')] = UniquePointerPrinter
+    pretty_printers_dict[re.compile('^std::tr1::unordered_map<.*>$')] = lambda val: Tr1UnorderedMapPrinter ('std::tr1::unordered_map', val)
+    pretty_printers_dict[re.compile('^std::tr1::unordered_set<.*>$')] = lambda val: Tr1UnorderedSetPrinter ('std::tr1::unordered_set', val)
+    pretty_printers_dict[re.compile('^std::tr1::unordered_multimap<.*>$')] = lambda val: Tr1UnorderedMapPrinter ('std::tr1::unordered_multimap', val)
+    pretty_printers_dict[re.compile('^std::tr1::unordered_multiset<.*>$')] = lambda val: Tr1UnorderedSetPrinter ('std::tr1::unordered_multiset', val)
 
     # Extensions.
-    obj.pretty_printers['^__gnu_cxx::slist<.*>$'] = StdSlistPrinter
+    pretty_printers_dict[re.compile('^__gnu_cxx::slist<.*>$')] = StdSlistPrinter
 
     if True:
         # These shouldn't be necessary, if GDB "print *i" worked.
         # But it often doesn't, so here they are.
-        obj.pretty_printers['^std::_List_iterator<.*>$'] = lambda val: StdListIteratorPrinter(val)
-        obj.pretty_printers['^std::_List_const_iterator<.*>$'] = lambda val: StdListIteratorPrinter(val)
-        obj.pretty_printers['^std::_Rb_tree_iterator<.*>$'] = lambda val: StdRbtreeIteratorPrinter(val)
-        obj.pretty_printers['^std::_Rb_tree_const_iterator<.*>$'] = lambda val: StdRbtreeIteratorPrinter(val)
-        obj.pretty_printers['^std::_Deque_iterator<.*>$'] = lambda val: StdDequeIteratorPrinter(val)
-        obj.pretty_printers['^std::_Deque_const_iterator<.*>$'] = lambda val: StdDequeIteratorPrinter(val)
-        obj.pretty_printers['^__gnu_cxx::__normal_iterator<.*>$'] = lambda val: StdVectorIteratorPrinter(val)
-        obj.pretty_printers['^__gnu_cxx::_Slist_iterator<.*>$'] = lambda val: StdSlistIteratorPrinter(val)
-
+        pretty_printers_dict[re.compile('^std::_List_iterator<.*>$')] = lambda val: StdListIteratorPrinter(val)
+        pretty_printers_dict[re.compile('^std::_List_const_iterator<.*>$')] = lambda val: StdListIteratorPrinter(val)
+        pretty_printers_dict[re.compile('^std::_Rb_tree_iterator<.*>$')] = lambda val: StdRbtreeIteratorPrinter(val)
+        pretty_printers_dict[re.compile('^std::_Rb_tree_const_iterator<.*>$')] = lambda val: StdRbtreeIteratorPrinter(val)
+        pretty_printers_dict[re.compile('^std::_Deque_iterator<.*>$')] = lambda val: StdDequeIteratorPrinter(val)
+        pretty_printers_dict[re.compile('^std::_Deque_const_iterator<.*>$')] = lambda val: StdDequeIteratorPrinter(val)
+        pretty_printers_dict[re.compile('^__gnu_cxx::__normal_iterator<.*>$')] = lambda val: StdVectorIteratorPrinter(val)
+        pretty_printers_dict[re.compile('^__gnu_cxx::_Slist_iterator<.*>$')] = lambda val: StdSlistIteratorPrinter(val)
+
+pretty_printers_dict = {}
+
+build_libstdcxx_dictionary ()
 register_libstdcxx_printers (gdb.current_objfile())
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 0608330..12422af 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -161,10 +161,10 @@ int gdbpy_is_value_object (PyObject *obj);
 
 /* Note that these are declared here, and not in python.h with the
    other pretty-printer functions, because they refer to PyObject.  */
-char *apply_varobj_pretty_printer (PyObject *print_obj, struct value *value,
+char *apply_varobj_pretty_printer (PyObject *print_obj,
 				   struct value **replacement);
-PyObject *gdbpy_get_varobj_pretty_printer (struct type *type);
-PyObject *gdbpy_instantiate_printer (PyObject *cons, struct value *value);
+PyObject *gdbpy_get_varobj_pretty_printer (struct value *value);
+PyObject *gdbpy_instantiate_printer (PyObject *cons, PyObject *value);
 char *gdbpy_get_display_hint (PyObject *printer);
 
 extern PyObject *gdbpy_children_cst;
diff --git a/gdb/python/python-objfile.c b/gdb/python/python-objfile.c
index a225409..e97d3a2 100644
--- a/gdb/python/python-objfile.c
+++ b/gdb/python/python-objfile.c
@@ -1,6 +1,6 @@
 /* Python interface to objfiles.
 
-   Copyright (C) 2008 Free Software Foundation, Inc.
+   Copyright (C) 2008, 2009 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -29,7 +29,7 @@ typedef struct
   /* The corresponding objfile.  */
   struct objfile *objfile;
 
-  /* The pretty-printer dictionary.  */
+  /* The pretty-printer list of functions.  */
   PyObject *printers;
 } objfile_object;
 
@@ -66,7 +66,7 @@ objfpy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
     {
       self->objfile = NULL;
 
-      self->printers = PyDict_New ();
+      self->printers = PyList_New (0);
       if (!self->printers)
 	{
 	  Py_DECREF (self);
@@ -95,10 +95,10 @@ objfpy_set_printers (PyObject *o, PyObject *value, void *ignore)
       return -1;
     }
 
-  if (! PyDict_Check (value))
+  if (! PyList_Check (value))
     {
       PyErr_SetString (PyExc_TypeError,
-		       "the pretty_printers attribute must be a dictionary");
+		       "the pretty_printers attribute must be a list");
       return -1;
     }
 
@@ -139,7 +139,7 @@ objfile_to_objfile_object (struct objfile *objfile)
 
 	  object->objfile = objfile;
 
-	  object->printers = PyDict_New ();
+	  object->printers = PyList_New (0);
 	  if (!object->printers)
 	    {
 	      Py_DECREF (object);
diff --git a/gdb/python/python-type.c b/gdb/python/python-type.c
index 5aa82f6..d336456 100644
--- a/gdb/python/python-type.c
+++ b/gdb/python/python-type.c
@@ -1,6 +1,6 @@
 /* Python interface to types.
 
-   Copyright (C) 2008 Free Software Foundation, Inc.
+   Copyright (C) 2008, 2009 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -233,6 +233,15 @@ typy_tag (PyObject *self, PyObject *args)
   return PyString_FromString (TYPE_TAG_NAME (type));
 }
 
+/* Return the type, stripped of typedefs. */
+static PyObject *
+typy_strip_typedefs (PyObject *self, PyObject *args)
+{
+  struct type *type = ((type_object *) self)->type;
+
+  return type_to_type_object (check_typedef (type));
+}
+
 /* Return a Type object which represents a pointer to SELF.  */
 static PyObject *
 typy_pointer (PyObject *self, PyObject *args)
@@ -710,6 +719,8 @@ Each field is a dictionary." },
     "Return the size of this type, in bytes" },
   { "tag", typy_tag, METH_NOARGS,
     "Return the tag name for this type, or None." },
+  { "strip_typedefs", typy_strip_typedefs, METH_NOARGS,
+    "Return a type stripped of typedefs"},
   { "target", typy_target, METH_NOARGS,
     "Return the target type of this type" },
   { "template_argument", typy_template_argument, METH_VARARGS,
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 2ec509d..4d104c2 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -1055,75 +1055,48 @@ gdbpy_objfiles (PyObject *unused1, PyObject *unused2)
 
 \f
 
-/* Return a string representing TYPE.  */
-static char *
-get_type (struct type *type)
-{
-  struct cleanup *old_chain;
-  struct ui_file *stb;
-  char *thetype;
-  long length;
-
-  stb = mem_fileopen ();
-  old_chain = make_cleanup_ui_file_delete (stb);
-
-  CHECK_TYPEDEF (type);
-
-  type_print (type, "", stb, -1);
-
-  thetype = ui_file_xstrdup (stb, &length);
-  do_cleanups (old_chain);
-  return thetype;
-}
-
 /* Helper function for find_pretty_printer which iterates over a
-   dictionary and tries to find a match.  */
+   list, calls each function and inspects output.  */
 static PyObject *
-search_pp_dictionary (PyObject *dict, char *type_name)
+search_pp_list (PyObject *list, PyObject *value)
 {
-  Py_ssize_t iter;
-  PyObject *key, *func, *found = NULL;
-
-  /* See if the type matches a pretty-printer regexp.  */
-  iter = 0;
-  while (! found && PyDict_Next (dict, &iter, &key, &func))
+  Py_ssize_t pp_list_size, list_index;
+  PyObject *function, *printer = NULL;
+  
+  pp_list_size = PyList_Size (list);
+  for (list_index = 0; list_index < pp_list_size; list_index++)
     {
-      char *rx_str;
+      function = PyList_GetItem (list, list_index);
+      if (! function)
+	return NULL;
 
-      if (! PyString_Check (key))
-	continue;
-      rx_str = PyString_AsString (key);
-      if (re_comp (rx_str) == NULL && re_exec (type_name) == 1)
-	found = func;
+      /* gdbpy_instantiate_printer can return three possible return
+	 values:  NULL on error;  Py_None if the pretty-printer
+	 in the list cannot print the value; or a printer instance if
+	 the printer can print the value.  */
+      printer = gdbpy_instantiate_printer (function, value);
+      if (! printer)
+	return NULL;
+      else if (printer != Py_None)
+	return printer;
+
+      Py_DECREF (printer);
     }
 
-  return found;
+  Py_RETURN_NONE;
 }
 
 /* Find the pretty-printing constructor function for TYPE.  If no
    pretty-printer exists, return NULL.  If one exists, return a new
    reference.  */
 static PyObject *
-find_pretty_printer (struct type *type)
+find_pretty_printer (PyObject *value)
 {
-  PyObject *dict, *found = NULL;
-  char *type_name = NULL;
+  PyObject *pp_list = NULL;
+  PyObject *function = NULL;
   struct objfile *obj;
   volatile struct gdb_exception except;
 
-  /* Get the name of the type.  */
-  TRY_CATCH (except, RETURN_MASK_ALL)
-    {
-      /* If we have a reference, use the referenced type.  */
-      if (TYPE_CODE (type) == TYPE_CODE_REF)
-	type = TYPE_TARGET_TYPE (type);
-      /* Strip off any qualifiers from the type.  */
-      type = make_cv_type (0, 0, type, NULL);
-      type_name = get_type (type);
-    }
-  if (except.reason < 0)
-    return NULL;
-
   /* Look at the pretty-printer dictionary for each objfile.  */
   ALL_OBJFILES (obj)
   {
@@ -1131,34 +1104,43 @@ find_pretty_printer (struct type *type)
     if (!objf)
       continue;
 
-    dict = objfpy_get_printers (objf, NULL);
-    found = search_pp_dictionary (dict, type_name);
-    if (found)
-      goto done;
+    pp_list = objfpy_get_printers (objf, NULL);
+    function = search_pp_list (pp_list, value);
 
-    Py_DECREF (dict);
+    /* If there is an error in any objfile list, abort the search and
+       exit.  */
+    if (! function)
+      {
+	Py_XDECREF (pp_list);
+	return NULL;
+      }
+
+    if (function != Py_None)
+      goto done;
+    
+    /* In this loop, if function is not an instantiation of a
+    pretty-printer, and it is not null, then it is a return of
+    Py_RETURN_NONE, which must be decremented.  */
+    Py_DECREF (function);
+    Py_XDECREF (pp_list);
   }
 
+  pp_list = NULL;
   /* Fetch the global pretty printer dictionary.  */
-  dict = NULL;
   if (! PyObject_HasAttrString (gdb_module, "pretty_printers"))


hooks/post-receive
--
Repository for Project Archer.


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2009-02-24 11:22 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-02-24 11:22 [SCM] archer-tromey-python: Rewrite pretty-printers registration method to use a list over a dictionary pmuldoon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).