Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Tom Tromey <tromey@redhat.com>
To: Joel Brobecker <brobecker@adacore.com>
Cc: Thiago Jung Bauermann <bauerman@br.ibm.com>,
	        gdb-patches ml <gdb-patches@sourceware.org>
Subject: Re: [rfc] expose gdb values to python
Date: Sun, 05 Oct 2008 00:00:00 -0000	[thread overview]
Message-ID: <m3bpxzewvb.fsf@fleche.redhat.com> (raw)
In-Reply-To: <20081004222055.GA7541@caradoc.them.org> (Daniel Jacobowitz's message of "Sat\, 4 Oct 2008 18\:20\:55 -0400")

>>>>> "Daniel" == Daniel Jacobowitz <drow@false.org> writes:

Daniel> WDYT about making this work anyway - and using a documented namespace
Daniel> for any methods we add?  Then the common case will be able to use the
Daniel> attributes safely.

In practice, I don't mind how it works now.  I wrote a few
pretty-printers (appended for your viewing pleasure) and I found that
the array syntax is not a real impediment.  If anything, the
dereference method is more of a pain.

FYI -- on the current python branch, Value already has a few more
methods: address, cast, and type.

I guess I wouldn't mind a mangling scheme if it were unobtrusive enough.

Tom

# Pretty-printers for libstc++.

def printstdlist(val):
    "Print a std::list"
    itype = val.type().template_argument(0)
    nodetype = gdb.Type('std::_List_node<%s>' % itype).pointer()
    head = val['_M_impl']['_M_node']
    base = head['_M_next']
    head = head.address()
    max = gdb.get_parameter('print elements')
    n = 0
    result = []
    while base != head and (max == 0 or n < max):
        elt = base.cast(nodetype).dereference()
        datum = elt['_M_data']
        result.append ('[%d] = %s' % (n, str (datum)))
        n = n + 1
        base = elt['_M_next']
    if len (result) == 0:
        result.append('<<empty list>>')
    return "\n".join(result)

def printstdvector(val):
    "Print a std::vector"
    start = val['_M_impl']['_M_start']
    finish = val['_M_impl']['_M_finish']
    end = val['_M_impl']['_M_end_of_storage']
    max = gdb.get_parameter('print elements')
    result = []
    result.append('std::vector of length %d, capacity %d'
                  % (int (finish - start), int (end - start)))
    i = 0
    while start < finish and (max == 0 or i < max):
        result.append('[%d] = %s' % (i, str(start.dereference())))
        start = start + 1
        i = i + 1
    return "\n".join(result)

def printstdstack(val):
    "Print a std::stack or std::queue"
    # Maybe we should print stack and queue in opposite orders?
    cur = val['c']['_M_impl']['_M_start']['_M_cur']
    finish = val['c']['_M_impl']['_M_finish']['_M_cur']
    i = 0
    max = gdb.get_parameter('print elements')
    result = ['std::stack or std::queue of size %d' % int (finish -cur)]
    while cur != finish and (max == 0 or i < max):
        result.append('[%d] = %s' % (i, str (cur.dereference())))
        cur = cur + 1
        i = i + 1
    return "\n".join(result)

def rbtree_to_list(val):
    "Turn an rbtree into a size and a list of elements."
    maxprint = gdb.get_parameter('print elements')
    size = val['_M_t']['_M_impl']['_M_node_count']
    if maxprint == 0 or maxprint > size:
        maxprint = size
    node = val['_M_t']['_M_impl']['_M_header']['_M_left']
    i = 0
    result = []
    while i < maxprint:
        result.append(node)
        if node.dereference()['_M_right']:
            node = node.dereference()['_M_right']
            while node.dereference()['_M_left']:
                node = node.dereference()['_M_left']
        else:
            parent = node.dereference()['_M_parent']
            while node == parent.dereference()['_M_right']:
                node = parent
                parent = parent.dereference()['_M_parent']
            if node.dereference()['_M_right'] != parent:
                node = parent
        i = i + 1
    return (size, result)

def printstdmap(val):
    "Print a std::map"
    keytype = val.type().template_argument(0)
    valuetype = val.type().template_argument(1)
    nodetype = gdb.Type('std::_Rb_tree_node< std::pair< const %s, %s > >' % (keytype, valuetype))
    nodetype = nodetype.pointer()
    (size, nodes) = rbtree_to_list (val)
    result = ['std::map with %d elements' % int (size)]
    for node in nodes:
        pair = node.cast(nodetype).dereference()['_M_value_field']
        result.append('[%s] = %s' % (str (pair['first']), str (pair['second'])))
    return "\n".join(result)

def printstdset(val):
    "Print a std::set"
    keytype = val.type().template_argument(0)
    nodetype = gdb.Type("std::_Rb_tree_node< %s >" % keytype).pointer()
    (size, nodes) = rbtree_to_list (val)
    result = ['std::set with %d elements' % int (size)]
    for node in nodes:
        elt = node.cast(nodetype).dereference()['_M_value_field']
        result.append('  %s' % str (elt))
    return "\n".join(result)

def printstdstring(val):
    "Print a std::string"
    return val['_M_dataplus']['_M_p']

gdb.pretty_printers['^std::list<.*>$'] = printstdlist
gdb.pretty_printers['^std::vector<.*>$'] = printstdvector
gdb.pretty_printers['^std::map<.*>$'] = printstdmap
gdb.pretty_printers['^std::set<.*>$'] = printstdset
gdb.pretty_printers['^std::basic_string<char.*>$'] = printstdstring
gdb.pretty_printers['^std::stack<.*>$'] = printstdstack
gdb.pretty_printers['^std::queue<.*>$'] = printstdstack


  reply	other threads:[~2008-10-05  0:00 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-09-12  6:05 Thiago Jung Bauermann
2008-09-20 21:29 ` Tom Tromey
2008-09-21  4:27   ` Daniel Jacobowitz
2008-09-25  4:33     ` Thiago Jung Bauermann
2008-09-25 11:47       ` Daniel Jacobowitz
2008-09-26  2:00         ` Thiago Jung Bauermann
2008-09-26  9:30           ` Eli Zaretskii
2008-09-28  1:19             ` Thiago Jung Bauermann
2008-09-28 18:19               ` Eli Zaretskii
2008-09-29 16:16                 ` Thiago Jung Bauermann
2008-09-29 17:00                   ` Daniel Jacobowitz
2008-09-30  4:07                     ` Thiago Jung Bauermann
2008-09-30 12:41                       ` Daniel Jacobowitz
2008-10-01  3:18                         ` Thiago Jung Bauermann
2008-10-01 11:40                           ` Daniel Jacobowitz
2008-09-29 18:52                   ` Eli Zaretskii
2008-09-26 20:57           ` Daniel Jacobowitz
2008-10-01  5:39           ` Joel Brobecker
2008-10-04 22:14             ` Thiago Jung Bauermann
2008-09-25  4:49   ` Thiago Jung Bauermann
2008-09-26 23:08     ` Tom Tromey
2008-10-01  5:48   ` Joel Brobecker
2008-10-01 15:12     ` Tom Tromey
2008-10-01 16:04       ` Joel Brobecker
2008-10-04 22:21       ` Daniel Jacobowitz
2008-10-05  0:00         ` Tom Tromey [this message]
2008-10-06 18:49           ` Joel Brobecker
2008-10-06 21:15           ` Daniel Jacobowitz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m3bpxzewvb.fsf@fleche.redhat.com \
    --to=tromey@redhat.com \
    --cc=bauerman@br.ibm.com \
    --cc=brobecker@adacore.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox