3 # This is not quite right, as local vars may override symname
4 def read_global_var (symname):
5 return gdb.selected_frame().read_var(symname)
7 def g_quark_to_string (quark):
14 val = read_global_var ("quarks")
15 max_q = long(read_global_var ("quark_seq_id"))
18 val = read_global_var ("g_quarks")
19 max_q = long(read_global_var ("g_quark_seq_id"))
23 return val[quark].string()
26 # We override the node printers too, so that node->next is not expanded
27 class GListNodePrinter:
30 def __init__ (self, val):
34 return "{data=%s, next=0x%x, prev=0x%x}" % (str(self.val["data"]), long(self.val["next"]), long(self.val["prev"]))
36 class GSListNodePrinter:
37 "Prints a GSList node"
39 def __init__ (self, val):
43 return "{data=%s, next=0x%x}" % (str(self.val["data"]), long(self.val["next"]))
49 def __init__(self, head, listtype):
51 self.listtype = listtype
60 data = self.link['data']
61 self.link = self.link['next']
63 self.count = self.count + 1
64 return ('[%d]' % count, data)
66 def __init__ (self, val, listtype):
68 self.listtype = listtype
71 return self._iterator(self.val, self.listtype)
74 return "0x%x" % (long(self.val))
76 def display_hint (self):
83 def __init__(self, ht, keys_are_strings):
86 self.keys = ht["keys"]
87 self.values = ht["values"]
88 self.hashes = ht["hashes"]
89 self.size = ht["size"]
91 self.keys_are_strings = keys_are_strings
100 if self.value != None:
104 while long(self.pos) < long(self.size):
105 self.pos = self.pos + 1
106 if long (self.hashes[self.pos]) >= 2:
107 key = self.keys[self.pos]
108 val = self.values[self.pos]
110 if self.keys_are_strings:
111 key = key.cast (gdb.lookup_type("char").pointer())
113 # Queue value for next result
114 self.value = ('[%dv]'% (self.pos), val)
117 return ('[%dk]'% (self.pos), key)
120 def __init__ (self, val):
122 self.keys_are_strings = False
124 string_hash = read_global_var ("g_str_hash")
127 if self.val != 0 and string_hash != None and self.val["hash_func"] == string_hash:
128 self.keys_are_strings = True
131 return self._iterator(self.val, self.keys_are_strings)
133 def to_string (self):
134 return "0x%x" % (long(self.val))
136 def display_hint (self):
139 def pretty_printer_lookup (val):
140 # None yet, want things like hash table and list
142 type = val.type.unqualified()
144 # If it points to a reference, get the reference.
145 if type.code == gdb.TYPE_CODE_REF:
146 type = type.target ()
148 if type.code == gdb.TYPE_CODE_PTR:
149 type = type.target().unqualified()
152 return GListPrinter(val, "GList")
154 return GListPrinter(val, "GSList")
155 if t == "GHashTable":
156 return GHashPrinter(val)
160 return GListNodePrinter(val)
162 return GListPrinter(val, "GSList")
169 obj.pretty_printers.append(pretty_printer_lookup)
171 class ForeachCommand (gdb.Command):
172 """Foreach on list"""
175 super (ForeachCommand, self).__init__ ("gforeach",
179 def valid_name (self, name):
180 if not name[0].isalpha():
184 def parse_args (self, arg):
187 raise Exception ("No var specified")
189 if not self.valid_name(var):
190 raise Exception ("Invalid variable name")
192 while i < len (arg) and arg[i].isspace():
195 if arg[i:i+2] != "in":
196 raise Exception ("Invalid syntax, missing in")
200 while i < len (arg) and arg[i].isspace():
203 colon = arg.find (":", i)
205 raise Exception ("Invalid syntax, missing colon")
210 while colon < len (arg) and arg[colon].isspace():
213 command = arg[colon:]
215 return (var, val, command)
217 def do_iter(self, arg, item, command):
218 item = item.cast (gdb.lookup_type("void").pointer())
220 to_eval = "set $%s = (void *)0x%x\n"%(arg, item)
224 def slist_iterator (self, arg, container, command):
225 l = container.cast (gdb.lookup_type("GSList").pointer())
227 self.do_iter (arg, l["data"], command)
230 def list_iterator (self, arg, container, command):
231 l = container.cast (gdb.lookup_type("GList").pointer())
233 self.do_iter (arg, l["data"], command)
236 def pick_iterator (self, container):
237 t = container.type.unqualified()
238 if t.code == gdb.TYPE_CODE_PTR:
239 t = t.target().unqualified()
242 return self.slist_iterator
244 return self.list_iterator
245 raise Exception("Invalid container type %s"%(str(container.type)))
247 def invoke (self, arg, from_tty):
248 (var, container, command) = self.parse_args(arg)
249 container = gdb.parse_and_eval (container)
250 func = self.pick_iterator(container)
251 func(var, container, command)