2015-04-28 Doug Evans <dje@google.com>
+ PR python/18299
+ * python/lib/gdb/printing.py (register_pretty_printer): Handle
+ name or __name__ attributes. Handle gdb module as first argument.
+
+2015-04-28 Doug Evans <dje@google.com>
+
PR python/18089
* python/py-prettyprint.c (print_children): Verify result of children
iterator. Provide better error message.
if not hasattr(printer, "__call__"):
raise TypeError("printer missing attribute: __call__")
- if obj is None:
+ if hasattr(printer, "name"):
+ name = printer.name
+ else:
+ name = printer.__name__
+ if obj is None or obj is gdb:
if gdb.parameter("verbose"):
gdb.write("Registering global %s pretty-printer ...\n" % name)
obj = gdb
else:
if gdb.parameter("verbose"):
- gdb.write("Registering %s pretty-printer for %s ...\n" %
- (printer.name, obj.filename))
+ gdb.write("Registering %s pretty-printer for %s ...\n" % (
+ name, obj.filename))
+ # Printers implemented as functions are old-style. In order to not risk
+ # breaking anything we do not check __name__ here.
if hasattr(printer, "name"):
if not isinstance(printer.name, basestring):
raise TypeError("printer name is not a string")
2015-04-28 Doug Evans <dje@google.com>
+ * gdb.python/py-pp-maint.py: Move "replace" testing to ...
+ * gdb.python/py-pp-registration.exp: ... here. New file.
+ * gdb.python/py-pp-registration.c: New file.
+ * gdb.python/py-pp-registration.py: New file.
+
+2015-04-28 Doug Evans <dje@google.com>
+
* gdb.python/py-bad-printers.c: New file.
* gdb.python/py-bad-printers.py: New file.
* gdb.python/py-bad-printers.exp: New file.
gdb.printing.register_pretty_printer(gdb, lookup_function_lookup_test)
my_pretty_printer = build_pretty_printer()
gdb.printing.register_pretty_printer(gdb, my_pretty_printer)
-
-# Exercise the "replace" argument to register pretty_printer.
-saw_runtime_error = False
-try:
- gdb.printing.register_pretty_printer(gdb, my_pretty_printer, replace=False)
-except RuntimeError:
- saw_runtime_error = True
- pass
-if not saw_runtime_error:
- raise RuntimeError("Missing RuntimeError from register_pretty_printer")
-gdb.printing.register_pretty_printer(gdb, my_pretty_printer, replace=True)
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2010-2015 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/>. */
+
+#include <string.h>
+
+struct function_lookup_test
+{
+ int x,y;
+};
+
+void
+init_flt (struct function_lookup_test *p, int x, int y)
+{
+ p->x = x;
+ p->y = y;
+}
+
+struct s
+{
+ int a;
+ int *b;
+};
+
+void
+init_s (struct s *s, int a)
+{
+ s->a = a;
+ s->b = &s->a;
+}
+
+int
+main ()
+{
+ struct function_lookup_test flt;
+ struct s s;
+
+ init_flt (&flt, 42, 43);
+ init_s (&s, 1);
+
+ return 0; /* break to inspect */
+}
--- /dev/null
+# Copyright (C) 2010-2015 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/>.
+
+# This file is part of the GDB testsuite. It tests python pretty
+# printer registration.
+
+load_lib gdb-python.exp
+
+standard_testfile
+
+if {[prepare_for_testing $testfile.exp $testfile $srcfile debug]} {
+ return -1
+}
+
+# Skip all tests if Python scripting is not enabled.
+if { [skip_python_tests] } { continue }
+
+set remote_python_file [gdb_remote_download host \
+ ${srcdir}/${subdir}/${testfile}.py]
+
+if ![runto_main ] {
+ fail "Can't run to main"
+ return -1
+}
+
+proc prepare_test { } {
+ global testfile remote_python_file
+
+ # Start with a fresh gdb.
+ clean_restart ${testfile}
+
+ set run_to_here [gdb_get_line_number {break to inspect} ${testfile}.c ]
+ if ![runto ${testfile}.c:$run_to_here message] {
+ return 0
+ }
+
+ gdb_test_no_output "python exec (open ('${remote_python_file}').read ())"
+
+ gdb_test_no_output "py progspace = gdb.current_progspace()"
+ gdb_test_no_output "py my_pretty_printer1 = build_pretty_printer1()"
+ gdb_test_no_output "py my_pretty_printer2 = build_pretty_printer2()"
+
+ return 1
+}
+
+proc test_printers { s_prefix } {
+ global hex
+
+ gdb_test "print flt" " = x=<42> y=<43>" \
+ "print flt"
+ gdb_test "print s" " = ${s_prefix} a=<1> b=<$hex>" \
+ "print s"
+}
+
+# Test registration with verbose off.
+
+with_test_prefix "verbose off" {
+ if ![prepare_test] {
+ return -1
+ }
+
+ gdb_test_no_output "set verbose off"
+
+ gdb_test_no_output "py gdb.printing.register_pretty_printer(gdb, lookup_function_lookup_test)"
+ gdb_test_no_output "py gdb.printing.register_pretty_printer(progspace, my_pretty_printer1)"
+
+ test_printers "s1"
+}
+
+# Test registration with verbose on.
+
+with_test_prefix "verbose on" {
+ if ![prepare_test] {
+ return -1
+ }
+
+ gdb_test_no_output "set verbose on"
+
+ gdb_test "py gdb.printing.register_pretty_printer(gdb, lookup_function_lookup_test)" \
+ "Registering global lookup_function_lookup_test pretty-printer ..."
+ gdb_test "py gdb.printing.register_pretty_printer(progspace, my_pretty_printer1)" \
+ "Registering pp-test pretty-printer for .*/py-pp-registration ..."
+
+ test_printers "s1"
+}
+
+# Exercise the "replace" argument to register_pretty_printer.
+
+with_test_prefix "replace" {
+ if ![prepare_test] {
+ return -1
+ }
+
+ gdb_test_no_output "py gdb.printing.register_pretty_printer(gdb, lookup_function_lookup_test)"
+ gdb_test_no_output "py gdb.printing.register_pretty_printer(progspace, my_pretty_printer1)"
+ gdb_test "py gdb.printing.register_pretty_printer(progspace, my_pretty_printer2, replace=False)" \
+ "RuntimeError: pretty-printer already registered: pp-test\r\nError while executing Python code."
+
+ test_printers "s1"
+
+ gdb_test_no_output "py gdb.printing.register_pretty_printer(progspace, my_pretty_printer2, replace=True)"
+
+ test_printers "s2"
+}
--- /dev/null
+# Copyright (C) 2010-2015 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/>.
+
+# This file is part of the GDB testsuite. It tests python pretty
+# printer registration.
+
+import re
+import gdb.types
+import gdb.printing
+
+
+def lookup_function_lookup_test(val):
+ class PrintFunctionLookup(object):
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ return ("x=<" + str(self.val["x"]) +
+ "> y=<" + str(self.val["y"]) + ">")
+
+ typename = gdb.types.get_basic_type(val.type).tag
+ # Note: typename could be None.
+ if typename == "function_lookup_test":
+ return PrintFunctionLookup(val)
+ return None
+
+
+class pp_s1 (object):
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ a = self.val["a"]
+ b = self.val["b"]
+ return "s1 a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"
+
+
+class pp_s2 (object):
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ a = self.val["a"]
+ b = self.val["b"]
+ return "s2 a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"
+
+
+def build_pretty_printer1():
+ pp = gdb.printing.RegexpCollectionPrettyPrinter("pp-test")
+
+ pp.add_printer('struct s', '^struct s$', pp_s1)
+ pp.add_printer('s', '^s$', pp_s1)
+
+ return pp
+
+
+def build_pretty_printer2():
+ # This intentionally has the same name as build_pretty_printer1.
+ # It is used to test the "replace" functionality of
+ # register_pretty_printer.
+ pp = gdb.printing.RegexpCollectionPrettyPrinter("pp-test")
+
+ pp.add_printer('struct s', '^struct s$', pp_s2)
+ pp.add_printer('s', '^s$', pp_s2)
+
+ return pp
+
+# Note: Registering the printers is done in the .exp file.