Я пишу симпатичный принтер 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())