diff options
author | Tom Tromey <tromey@redhat.com> | 2009-05-28 01:05:14 +0000 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2009-05-28 01:05:14 +0000 |
commit | a6bac58e84001d33b9540e208e9ca6d6ab265bf3 (patch) | |
tree | 6dc1ea1483f42b9b0995046c029dad43ad45e05c /gdb/testsuite/gdb.python | |
parent | 42ae523077b469c09e83845d30ee137a844aacb8 (diff) | |
download | gdb-a6bac58e84001d33b9540e208e9ca6d6ab265bf3.zip gdb-a6bac58e84001d33b9540e208e9ca6d6ab265bf3.tar.gz gdb-a6bac58e84001d33b9540e208e9ca6d6ab265bf3.tar.bz2 |
gdb
2009-05-27 Tom Tromey <tromey@redhat.com>
Thiago Jung Bauermann <bauerman@br.ibm.com>
Phil Muldoon <pmuldoon@redhat.com>
Paul Pluzhnikov <ppluzhnikov@google.com>
Vladimir Prus <vladimir@codesourcery.com>
* python/python-value.c (value_object_to_value): New function.
* python/python-internal.h: Include frameobject.h.
(gdbpy_children_cst, gdbpy_to_string_cst, gdbpy_display_hint_cst):
Declare.
(value_object_to_value): Declare.
* printcmd.c (struct format_data) <raw>: New field.
(last_format): Default to 0.
(decode_format): Initialize val.raw. Handle /r flag.
(print_command_1): Initialize fmt.raw and opts.raw.
(output_command): Likewise.
(x_command): Fix initialization of fmt.format. Initialize
fmt.raw.
(display_command): Initialize fmt.raw.
(do_one_display): Set opts.raw.
* python/python.c (gdbpy_to_string_cst, gdbpy_children_cst,
gdbpy_display_hint_cst): New globals.
(_initialize_python): Initialize them. Set gdb.pretty_printers.
* cp-valprint.c: Include python.h.
(cp_print_value): Call apply_val_pretty_printer.
* python/python.h (apply_val_pretty_printer): Declare.
* stack.c (print_this_frame_argument_p): Remove.
(print_frame_args): Compute summary flag. Don't use
print_this_frame_argument_p.
* valprint.c: Include python.h.
(user_print_options): Initialize new fields.
(scalar_type_p): New function.
(val_print): Handle 'raw' and 'summary' modes. Call
apply_val_pretty_printer.
(value_print): Handle 'raw' mode.
* valprint.h (struct value_print_options) <raw, summary>: New
fields.
* Makefile.in (SUBDIR_PYTHON_OBS): Add python-prettyprint.o
(SUBDIR_PYTHON_SRCS): Add python-prettyprint.c.
(python-prettyprint.o): New target.
* python/python-prettyprint.c: New file.
gdb/doc
2009-05-27 Tom Tromey <tromey@redhat.com>
Thiago Jung Bauermann <bauerman@br.ibm.com>
Phil Muldoon <pmuldoon@redhat.com>
* gdb.texinfo (Objfiles In Python): Reference pretty printing.
(Pretty Printing): New node.
(Selecting Pretty-Printers): Likewise.
(Python API): Update.
(Output Formats): Document /r format.
gdb/testsuite
2009-05-27 Tom Tromey <tromey@redhat.com>
Thiago Jung Bauermann <bauerman@br.ibm.com>
Phil Muldoon <pmuldoon@redhat.com>
Paul Pluzhnikov <ppluzhnikov@google.com>
* gdb.python/python-prettyprint.exp: New file.
* gdb.python/python-prettyprint.c: New file.
* gdb.python/python-prettyprint.py: New file.
* gdb.base/display.exp: print/r is now valid.
Diffstat (limited to 'gdb/testsuite/gdb.python')
-rw-r--r-- | gdb/testsuite/gdb.python/python-prettyprint.c | 191 | ||||
-rw-r--r-- | gdb/testsuite/gdb.python/python-prettyprint.exp | 92 | ||||
-rw-r--r-- | gdb/testsuite/gdb.python/python-prettyprint.py | 151 |
3 files changed, 434 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.python/python-prettyprint.c b/gdb/testsuite/gdb.python/python-prettyprint.c new file mode 100644 index 0000000..399be23 --- /dev/null +++ b/gdb/testsuite/gdb.python/python-prettyprint.c @@ -0,0 +1,191 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 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/>. */ + +struct s +{ + int a; + int *b; +}; + +struct ss +{ + struct s a; + struct s b; +}; + +#ifdef __cplusplus +struct S : public s { + int zs; +}; + +struct SS { + int zss; + S s; +}; + +struct SSS +{ + SSS (int x, const S& r); + int a; + const S &b; +}; +SSS::SSS (int x, const S& r) : a(x), b(r) { } + +class VirtualTest +{ + private: + int value; + + public: + VirtualTest () + { + value = 1; + } +}; + +class Vbase1 : public virtual VirtualTest { }; +class Vbase2 : public virtual VirtualTest { }; +class Vbase3 : public virtual VirtualTest { }; + +class Derived : public Vbase1, public Vbase2, public Vbase3 +{ + private: + int value; + + public: + Derived () + { + value = 2; + } +}; + +#endif + +typedef struct string_repr +{ + struct whybother + { + const char *contents; + } whybother; +} string; + +/* This lets us avoid malloc. */ +int array[100]; + +struct container +{ + string name; + int len; + int *elements; +}; + +typedef struct container zzz_type; + +string +make_string (const char *s) +{ + string result; + result.whybother.contents = s; + return result; +} + +zzz_type +make_container (const char *s) +{ + zzz_type result; + + result.name = make_string (s); + result.len = 0; + result.elements = 0; + + return result; +} + +void +add_item (zzz_type *c, int val) +{ + if (c->len == 0) + c->elements = array; + c->elements[c->len] = val; + ++c->len; +} + +void init_s(struct s *s, int a) +{ + s->a = a; + s->b = &s->a; +} + +void init_ss(struct ss *s, int a, int b) +{ + init_s(&s->a, a); + init_s(&s->b, b); +} + +void do_nothing(void) +{ + int c; + + c = 23; /* Another MI breakpoint */ +} + +int +main () +{ + struct ss ss; + struct ss ssa[2]; + string x = make_string ("this is x"); + zzz_type c = make_container ("container"); + const struct string_repr cstring = { { "const string" } }; + + init_ss(&ss, 1, 2); + init_ss(ssa+0, 3, 4); + init_ss(ssa+1, 5, 6); + +#ifdef __cplusplus + S cps; + + cps.zs = 7; + init_s(&cps, 8); + + SS cpss; + cpss.zss = 9; + init_s(&cpss.s, 10); + + SS cpssa[2]; + cpssa[0].zss = 11; + init_s(&cpssa[0].s, 12); + cpssa[1].zss = 13; + init_s(&cpssa[1].s, 14); + + SSS sss(15, cps); + + SSS& ref (sss); + + Derived derived; + +#endif + + add_item (&c, 23); /* MI breakpoint here */ + add_item (&c, 72); + +#ifdef MI + do_nothing (); +#endif + + return 0; /* break to inspect struct and union */ +} diff --git a/gdb/testsuite/gdb.python/python-prettyprint.exp b/gdb/testsuite/gdb.python/python-prettyprint.exp new file mode 100644 index 0000000..f83b1cd --- /dev/null +++ b/gdb/testsuite/gdb.python/python-prettyprint.exp @@ -0,0 +1,92 @@ +# 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/>. + +# This file is part of the GDB testsuite. It tests Python-based +# pretty-printing for the CLI. + +if $tracelevel then { + strace $tracelevel +} + +set testfile "python-prettyprint" +set srcfile ${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} + +# Start with a fresh gdb. +gdb_exit +gdb_start +gdb_test_multiple "python print 'hello, world!'" "verify python support" { + -re "not supported.*$gdb_prompt $" { + unsupported "python support is disabled" + return -1 + } + -re "$gdb_prompt $" {} +} + +proc run_lang_tests {lang} { + global srcdir subdir srcfile binfile testfile hex + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "debug $lang"] != "" } { + untested "Couldn't compile ${srcfile} in $lang mode" + return -1 + } + + set nl "\[\r\n\]+" + + # Start with a fresh gdb. + gdb_exit + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + gdb_load ${binfile} + + + if ![runto_main ] then { + perror "couldn't run to breakpoint" + return + } + + gdb_test "set print pretty on" "" + + gdb_test "b [gdb_get_line_number {break to inspect} ${testfile}.c ]" \ + ".*Breakpoint.*" + gdb_test "continue" ".*Breakpoint.*" + + gdb_test "python execfile ('${srcdir}/${subdir}/${testfile}.py')" "" + + gdb_test "print ss" " = a=< a=<1> b=<$hex>> b=< a=<2> b=<$hex>>" + gdb_test "print ssa\[1\]" " = a=< a=<5> b=<$hex>> b=< a=<6> b=<$hex>>" + gdb_test "print ssa" " = {a=< a=<3> b=<$hex>> b=< a=<4> b=<$hex>>, a=< a=<5> b=<$hex>> b=< a=<6> b=<$hex>>}" + + if {$lang == "c++"} { + gdb_test "print cps" "= a=<8> b=<$hex>" + gdb_test "print cpss" " = {$nl *zss = 9, *$nl *s = a=<10> b=<$hex>$nl}" + gdb_test "print cpssa\[0\]" " = {$nl *zss = 11, *$nl *s = a=<12> b=<$hex>$nl}" + gdb_test "print cpssa\[1\]" " = {$nl *zss = 13, *$nl *s = a=<14> b=<$hex>$nl}" + gdb_test "print cpssa" " = {{$nl *zss = 11, *$nl *s = a=<12> b=<$hex>$nl *}, {$nl *zss = 13, *$nl *s = a=<14> b=<$hex>$nl *}}" + gdb_test "print sss" "= a=<15> b=< a=<8> b=<$hex>>" + gdb_test "print ref" "= a=<15> b=< a=<8> b=<$hex>>" + gdb_test "print derived" \ + " = \{.*<Vbase1> = pp class name: Vbase1.*<Vbase2> = \{.*<VirtualTest> = pp value variable is: 1,.*members of Vbase2:.*_vptr.Vbase2 = $hex.*<Vbase3> = \{.*members of Vbase3.*members of Derived:.*value = 2.*" + } + + gdb_test "print x" " = $hex \"this is x\"" + gdb_test "print cstring" " = $hex \"const string\"" + + gdb_test "print c" " = container $hex \"container\" with 2 elements = {$nl *.0. = 23,$nl *.1. = 72$nl}" + + gdb_test "continue" "Program exited normally\." +} + +run_lang_tests "c" +run_lang_tests "c++" diff --git a/gdb/testsuite/gdb.python/python-prettyprint.py b/gdb/testsuite/gdb.python/python-prettyprint.py new file mode 100644 index 0000000..493cf29 --- /dev/null +++ b/gdb/testsuite/gdb.python/python-prettyprint.py @@ -0,0 +1,151 @@ +# 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/>. + +# This file is part of the GDB testsuite. It tests python pretty +# printers. + +import re + +# Test returning a Value from a printer. +class string_print: + def __init__(self, val): + self.val = val + + def to_string(self): + return self.val['whybother']['contents'] + +# Test a class-based printer. +class ContainerPrinter: + 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 'container %s with %d elements' % (self.val['name'], self.val['len']) + + def children(self): + return self._iterator(self.val['elements'], self.val['len']) + +class pp_s: + def __init__(self, val): + self.val = val + + def to_string(self): + a = self.val["a"] + b = self.val["b"] + if a.address != b: + raise Exception("&a(%s) != b(%s)" % (str(a.address), str(b))) + return " a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">" + +class pp_ss: + def __init__(self, val): + self.val = val + + def to_string(self): + return "a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">" + +class pp_sss: + def __init__(self, val): + self.val = val + + def to_string(self): + return "a=<" + str(self.val['a']) + "> b=<" + str(self.val["b"]) + ">" + +class pp_multiple_virtual: + def __init__ (self, val): + self.val = val + + def to_string (self): + return "pp value variable is: " + str (self.val['value']) + +class pp_vbase1: + def __init__ (self, val): + self.val = val + + def to_string (self): + return "pp class name: " + self.val.type.tag + +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.match (typename): + return pretty_printers_dict[function] (val) + + # Cannot find a pretty printer. Return None. + + return None + + +def register_pretty_printers (): + pretty_printers_dict[re.compile ('^struct s$')] = pp_s + pretty_printers_dict[re.compile ('^s$')] = pp_s + pretty_printers_dict[re.compile ('^S$')] = pp_s + + pretty_printers_dict[re.compile ('^struct ss$')] = pp_ss + pretty_printers_dict[re.compile ('^ss$')] = pp_ss + pretty_printers_dict[re.compile ('^const S &$')] = pp_s + pretty_printers_dict[re.compile ('^SSS$')] = pp_sss + + pretty_printers_dict[re.compile ('^VirtualTest$')] = pp_multiple_virtual + pretty_printers_dict[re.compile ('^Vbase1$')] = pp_vbase1 + + # Note that we purposely omit the typedef names here. + # Printer lookup is based on canonical name. + # However, we do need both tagged and untagged variants, to handle + # 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 ('^string_repr$')] = string_print + pretty_printers_dict[re.compile ('^container$')] = ContainerPrinter + +pretty_printers_dict = {} + +register_pretty_printers () +gdb.pretty_printers.append (lookup_function) |