Как передать тип данных в общем связанном списке в команду печати GDB? - PullRequest
0 голосов
/ 04 декабря 2018

Я пишу симпатичный принтер GDB на Python для этой структуры данных связанного списка:

struct listNode {
    void                 *data;         /* node's data                       */
    struct listNode      *next;         /* next node in list                 */
};


struct xlist {
    struct listNode      *head;         /* head of the list                  */
    struct listNode     **tail;         /* addr of last node's 'next' ptr    */
    struct listIterator  *iNext;        /* iterator chain for list_destroy() */
    ListDelF              fDel;         /* function to delete node data      */
    int                   count;        /* number of nodes in list           */
};

typedef struct xlist * List;

Поле данных является недействительным *, поскольку оно является универсальным, поэтому при необходимости оно приводится к соответствующему типу указателя,Ниже приведен мой симпатичный принтер, который прекрасно работает в жестком коде для определенного типа (print_field_t), но я ищу способ передать желаемый тип в качестве аргумента принтеру.Насколько я могу судить, это не поддерживается API, но есть ли способ сделать это или эквивалент?

#!/usr/bin/env python3
import gdb.printing
import gdb

class ListPrinter(object):
    '''Print a List object'''

    class _iterator:
        def __init__(self, current):
            self.current = current
            self.count = 0
            self.end = False

        def __iter__(self):
            return self

        def __next__(self):
            if self.end:
                raise StopIteration

            type = gdb.lookup_type('print_field_t').pointer()
            value = self.current['data'].cast(type).dereference()

            self.current = self.current['next']
            self.count += 1
            if self.current == 0:
                self.end = True
            return (str(self.count), value)

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

    def to_string(self):
        return 'List({}):'.format(self.val['count'])

    def children(self):
        return self._iterator(self.val['head'])

    def display_hint(self):
        return 'array'

def build_pretty_printer():
    pp = gdb.printing.RegexpCollectionPrettyPrinter('List')
    pp.add_printer('List Printer', '^List$', ListPrinter)
    return pp

gdb.printing.register_pretty_printer(gdb.current_objfile(), build_pretty_printer())
...