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).