4 if sys.version_info[0] >= 3:
8 # This is not quite right, as local vars may override symname
9 def read_global_var(symname):
10 return gdb.selected_frame().read_var(symname)
13 def g_quark_to_string(quark):
20 val = read_global_var("quarks")
21 max_q = long(read_global_var("quark_seq_id"))
24 val = read_global_var("g_quarks")
25 max_q = long(read_global_var("g_quark_seq_id"))
29 return val[quark].string()
33 # We override the node printers too, so that node->next is not expanded
34 class GListNodePrinter:
37 def __init__(self, val):
41 return "{data=%s, next=0x%x, prev=0x%x}" % (
42 str(self.val["data"]),
43 long(self.val["next"]),
44 long(self.val["prev"]),
48 class GSListNodePrinter:
49 "Prints a GSList node"
51 def __init__(self, val):
55 return "{data=%s, next=0x%x}" % (str(self.val["data"]), long(self.val["next"]))
62 def __init__(self, head, listtype):
64 self.listtype = listtype
73 data = self.link["data"]
74 self.link = self.link["next"]
76 self.count = self.count + 1
77 return ("[%d]" % count, data)
81 def __init__(self, val, listtype):
83 self.listtype = listtype
86 return self._iterator(self.val, self.listtype)
89 return "0x%x" % (long(self.val))
91 def display_hint(self):
100 def __init__(self, ptr, big_items):
101 self._big_items = big_items
102 self._gpointer_type = gdb.lookup_type("gpointer")
104 self._gpointer_type if self._big_items else gdb.lookup_type("guint")
107 self._items = ptr.cast(item_type.pointer())
109 def __getitem__(self, item):
110 item = self._items[item]
112 if not self._big_items:
113 item = item.cast(self._gpointer_type)
117 def __init__(self, ht, keys_are_strings):
120 self.keys = self._pointer_array(ht["keys"], ht["have_big_keys"])
121 self.values = self._pointer_array(ht["values"], ht["have_big_values"])
122 self.hashes = ht["hashes"]
123 self.size = ht["size"]
125 self.keys_are_strings = keys_are_strings
134 if self.value is not None:
138 while long(self.pos) < long(self.size):
139 if long(self.hashes[self.pos]) >= 2:
140 key = self.keys[self.pos]
141 val = self.values[self.pos]
143 if self.keys_are_strings:
144 key = key.cast(gdb.lookup_type("char").pointer())
146 # Queue value for next result
147 self.value = ("[%dv]" % (self.pos), val)
149 # Increment pos and return key
150 key = ("[%dk]" % (self.pos), key)
159 def __init__(self, val):
161 self.keys_are_strings = False
163 string_hash = read_global_var("g_str_hash")
168 and string_hash is not None
169 and self.val["hash_func"] == string_hash
171 self.keys_are_strings = True
174 return self._iterator(self.val, self.keys_are_strings)
177 return "0x%x" % (long(self.val))
179 def display_hint(self):
183 def pretty_printer_lookup(val):
184 # None yet, want things like hash table and list
186 type = val.type.unqualified()
188 # If it points to a reference, get the reference.
189 if type.code == gdb.TYPE_CODE_REF:
192 if type.code == gdb.TYPE_CODE_PTR:
193 type = type.target().unqualified()
196 return GListPrinter(val, "GList")
198 return GListPrinter(val, "GSList")
199 if t == "GHashTable":
200 return GHashPrinter(val)
204 return GListNodePrinter(val)
206 return GListPrinter(val, "GSList")
214 obj.pretty_printers.append(pretty_printer_lookup)
217 class ForeachCommand(gdb.Command):
218 """Foreach on list"""
221 super(ForeachCommand, self).__init__(
222 "gforeach", gdb.COMMAND_DATA, gdb.COMPLETE_SYMBOL
225 def valid_name(self, name):
226 if not name[0].isalpha():
230 def parse_args(self, arg):
233 raise Exception("No var specified")
235 if not self.valid_name(var):
236 raise Exception("Invalid variable name")
238 while i < len(arg) and arg[i].isspace():
241 if arg[i : i + 2] != "in":
242 raise Exception("Invalid syntax, missing in")
246 while i < len(arg) and arg[i].isspace():
249 colon = arg.find(":", i)
251 raise Exception("Invalid syntax, missing colon")
256 while colon < len(arg) and arg[colon].isspace():
259 command = arg[colon:]
261 return (var, val, command)
263 def do_iter(self, arg, item, command):
264 item = item.cast(gdb.lookup_type("void").pointer())
266 to_eval = "set $%s = (void *)0x%x\n" % (arg, item)
270 def slist_iterator(self, arg, container, command):
271 list_element = container.cast(gdb.lookup_type("GSList").pointer())
272 while long(list_element) != 0:
273 self.do_iter(arg, list_element["data"], command)
274 list_element = list_element["next"]
276 def list_iterator(self, arg, container, command):
277 list_element = container.cast(gdb.lookup_type("GList").pointer())
278 while long(list_element) != 0:
279 self.do_iter(arg, list_element["data"], command)
280 list_element = list_element["next"]
282 def pick_iterator(self, container):
283 t = container.type.unqualified()
284 if t.code == gdb.TYPE_CODE_PTR:
285 t = t.target().unqualified()
288 return self.slist_iterator
290 return self.list_iterator
291 raise Exception("Invalid container type %s" % (str(container.type)))
293 def invoke(self, arg, from_tty):
294 (var, container, command) = self.parse_args(arg)
295 container = gdb.parse_and_eval(container)
296 func = self.pick_iterator(container)
297 func(var, container, command)