0

I'm able to get the value using ptr.dereference, however I have no idea how to increment the pointer to get the next value. Assume I'm using a 16bit signed array. How do I get the first 5 values?

class MyArrayPrinter:
    "Print a MyArray"

    def __init__ (self, val):
        self.val = val

    def to_string (self):
        return "Array of"

    def children(self):
        ptr = self.val['array']
        #yield ('0', ptr.address[1].dereference())
        yield ('5', 47)

    def display_hint (self):
        return 'array'
Eric Stotch
  • 141
  • 4
  • 19
  • Is this for the same `struct MyArray` as in your other question? What should the values `'5'` and `47` do? – ssbssa Oct 31 '20 at 11:23
  • @ssbssa: Yes, same as other. The values mean nothing, I was using it as a test so the array isn't empty – Eric Stotch Oct 31 '20 at 16:13

1 Answers1

2

For this simple array class, taken from your other question:

template<class T>
struct MyArray
{
    int pos;
    T array[10];
    MyArray() : pos(0) {}
    void push(T val) {
        if (pos >= 10)
            return;
        array[pos++] = val;
    }
};

I would implement the pretty printer like this:

class MyArrayPrinter:
    "Print a MyArray"

    class _iterator:
        def __init__ (self, start, finish):
            self.item = start
            self.finish = finish
            self.count = 0

        def __iter__ (self):
            return self

        def __next__ (self):
            count = self.count
            self.count = self.count + 1
            if self.item == self.finish:
                raise StopIteration
            elt = self.item.dereference()
            self.item = self.item + 1
            return ('[%d]' % count, elt)

        def next (self):
            return self.__next__()

    def __init__ (self, val):
        self.val = val

    def children (self):
        start = self.val['array'][0].address
        return self._iterator(start, start + self.val['pos'])

    def to_string (self):
        len = self.val['pos']
        return '%s of length %d' % (self.val.type, len)

    def display_hint (self):
        return 'array'

pp = gdb.printing.RegexpCollectionPrettyPrinter("mine")
pp.add_printer('MyArray', '^MyArray<.*>$', MyArrayPrinter)
gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)

Which would look like this:

(gdb) p arr
$1 = MyArray<MyString> of length 2 = {"My test string", "has two"}
(gdb) p arr2
$2 = MyArray<MoreComplex*> of length 1 = {0x22fe00}
ssbssa
  • 1,261
  • 1
  • 13
  • 21
  • tyvm. Just wondering, is there a reason you did `'[%d]' % count`? `str(count)` appears to work the same and I'm wondering if you noticed a difference or if one way is more proper – Eric Stotch Oct 31 '20 at 18:59
  • 1
    To be honest, I'm not sure about that either, but that's how it's also done in [libstdc++](https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libstdc%2B%2B-v3/python/libstdcxx/v6/printers.py;h=c0f061f79c1f03715d10091f8b2955d86bca9ad2;hb=HEAD#l438), so I just did it the same way. – ssbssa Oct 31 '20 at 19:05