4 if sys.version_info[0] >= 3:
7 # This is not quite right, as local vars may override symname
8 def read_global_var (symname):
9 return gdb.selected_frame().read_var(symname)
11 def g_quark_to_string (quark):
18 val = read_global_var ("quarks")
19 max_q = long(read_global_var ("quark_seq_id"))
22 val = read_global_var ("g_quarks")
23 max_q = long(read_global_var ("g_quark_seq_id"))
27 return val[quark].string()
30 # We override the node printers too, so that node->next is not expanded
31 class GListNodePrinter:
34 def __init__ (self, val):
38 return "{data=%s, next=0x%x, prev=0x%x}" % (str(self.val["data"]), long(self.val["next"]), long(self.val["prev"]))
40 class GSListNodePrinter:
41 "Prints a GSList node"
43 def __init__ (self, val):
47 return "{data=%s, next=0x%x}" % (str(self.val["data"]), long(self.val["next"]))
53 def __init__(self, head, listtype):
55 self.listtype = listtype
64 data = self.link['data']
65 self.link = self.link['next']
67 self.count = self.count + 1
68 return ('[%d]' % count, data)
70 def __init__ (self, val, listtype):
72 self.listtype = listtype
75 return self._iterator(self.val, self.listtype)
78 return "0x%x" % (long(self.val))
80 def display_hint (self):
87 def __init__(self, ht, keys_are_strings):
90 self.keys = ht["keys"]
91 self.values = ht["values"]
92 self.hashes = ht["hashes"]
93 self.size = ht["size"]
95 self.keys_are_strings = keys_are_strings
104 if self.value != None:
108 while long(self.pos) < long(self.size):
109 self.pos = self.pos + 1
110 if long (self.hashes[self.pos]) >= 2:
111 key = self.keys[self.pos]
112 val = self.values[self.pos]
114 if self.keys_are_strings:
115 key = key.cast (gdb.lookup_type("char").pointer())
117 # Queue value for next result
118 self.value = ('[%dv]'% (self.pos), val)
121 return ('[%dk]'% (self.pos), key)
124 def __init__ (self, val):
126 self.keys_are_strings = False
128 string_hash = read_global_var ("g_str_hash")
131 if self.val != 0 and string_hash != None and self.val["hash_func"] == string_hash:
132 self.keys_are_strings = True
135 return self._iterator(self.val, self.keys_are_strings)
137 def to_string (self):
138 return "0x%x" % (long(self.val))
140 def display_hint (self):
143 def pretty_printer_lookup (val):
144 # None yet, want things like hash table and list
146 type = val.type.unqualified()
148 # If it points to a reference, get the reference.
149 if type.code == gdb.TYPE_CODE_REF:
150 type = type.target ()
152 if type.code == gdb.TYPE_CODE_PTR:
153 type = type.target().unqualified()
156 return GListPrinter(val, "GList")
158 return GListPrinter(val, "GSList")
159 if t == "GHashTable":
160 return GHashPrinter(val)
164 return GListNodePrinter(val)
166 return GListPrinter(val, "GSList")
173 obj.pretty_printers.append(pretty_printer_lookup)
175 class ForeachCommand (gdb.Command):
176 """Foreach on list"""
179 super (ForeachCommand, self).__init__ ("gforeach",
183 def valid_name (self, name):
184 if not name[0].isalpha():
188 def parse_args (self, arg):
191 raise Exception ("No var specified")
193 if not self.valid_name(var):
194 raise Exception ("Invalid variable name")
196 while i < len (arg) and arg[i].isspace():
199 if arg[i:i+2] != "in":
200 raise Exception ("Invalid syntax, missing in")
204 while i < len (arg) and arg[i].isspace():
207 colon = arg.find (":", i)
209 raise Exception ("Invalid syntax, missing colon")
214 while colon < len (arg) and arg[colon].isspace():
217 command = arg[colon:]
219 return (var, val, command)
221 def do_iter(self, arg, item, command):
222 item = item.cast (gdb.lookup_type("void").pointer())
224 to_eval = "set $%s = (void *)0x%x\n"%(arg, item)
228 def slist_iterator (self, arg, container, command):
229 l = container.cast (gdb.lookup_type("GSList").pointer())
231 self.do_iter (arg, l["data"], command)
234 def list_iterator (self, arg, container, command):
235 l = container.cast (gdb.lookup_type("GList").pointer())
237 self.do_iter (arg, l["data"], command)
240 def pick_iterator (self, container):
241 t = container.type.unqualified()
242 if t.code == gdb.TYPE_CODE_PTR:
243 t = t.target().unqualified()
246 return self.slist_iterator
248 return self.list_iterator
249 raise Exception("Invalid container type %s"%(str(container.type)))
251 def invoke (self, arg, from_tty):
252 (var, container, command) = self.parse_args(arg)
253 container = gdb.parse_and_eval (container)
254 func = self.pick_iterator(container)
255 func(var, container, command)