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):
13 val = read_global_var ("g_quarks")
14 max_q = long(read_global_var ("g_quark_seq_id"))
16 return val[quark].string()
19 # We override the node printers too, so that node->next is not expanded
20 class GListNodePrinter:
23 def __init__ (self, val):
27 return "{data=%s, next=0x%x, prev=0x%x}" % (str(self.val["data"]), long(self.val["next"]), long(self.val["prev"]))
29 class GSListNodePrinter:
30 "Prints a GSList node"
32 def __init__ (self, val):
36 return "{data=%s, next=0x%x}" % (str(self.val["data"]), long(self.val["next"]))
42 def __init__(self, head, listtype):
44 self.listtype = listtype
53 data = self.link['data']
54 self.link = self.link['next']
56 self.count = self.count + 1
57 return ('[%d]' % count, data)
59 def __init__ (self, val, listtype):
61 self.listtype = listtype
64 return self._iterator(self.val, self.listtype)
67 return "0x%x" % (long(self.val))
69 def display_hint (self):
76 def __init__(self, ht, keys_are_strings):
79 self.keys = ht["keys"]
80 self.values = ht["values"]
81 self.hashes = ht["hashes"]
82 self.size = ht["size"]
84 self.keys_are_strings = keys_are_strings
93 if self.value != None:
97 while long(self.pos) < long(self.size):
98 self.pos = self.pos + 1
99 if long (self.hashes[self.pos]) >= 2:
100 key = self.keys[self.pos]
101 val = self.values[self.pos]
103 if self.keys_are_strings:
104 key = key.cast (gdb.lookup_type("char").pointer())
106 # Queue value for next result
107 self.value = ('[%dv]'% (self.pos), val)
110 return ('[%dk]'% (self.pos), key)
113 def __init__ (self, val):
115 self.keys_are_strings = False
117 string_hash = read_global_var ("g_str_hash")
120 if self.val != 0 and string_hash != None and self.val["hash_func"] == string_hash:
121 self.keys_are_strings = True
124 return self._iterator(self.val, self.keys_are_strings)
126 def to_string (self):
127 return "0x%x" % (long(self.val))
129 def display_hint (self):
132 def pretty_printer_lookup (val):
133 if is_g_type_instance (val):
134 return GTypePrettyPrinter (val)
136 def pretty_printer_lookup (val):
137 # None yet, want things like hash table and list
139 type = val.type.unqualified()
141 # If it points to a reference, get the reference.
142 if type.code == gdb.TYPE_CODE_REF:
143 type = type.target ()
145 if type.code == gdb.TYPE_CODE_PTR:
146 type = type.target().unqualified()
149 return GListPrinter(val, "GList")
151 return GListPrinter(val, "GSList")
152 if t == "GHashTable":
153 return GHashPrinter(val)
157 return GListNodePrinter(val)
159 return GListPrinter(val, "GSList")
166 obj.pretty_printers.append(pretty_printer_lookup)
168 class ForeachCommand (gdb.Command):
169 """Foreach on list"""
172 super (ForeachCommand, self).__init__ ("gforeach",
176 def valid_name (self, name):
177 if not name[0].isalpha():
181 def parse_args (self, arg):
184 raise Exception ("No var specified")
186 if not self.valid_name(var):
187 raise Exception ("Invalid variable name")
189 while i < len (arg) and arg[i].isspace():
192 if arg[i:i+2] != "in":
193 raise Exception ("Invalid syntax, missing in")
197 while i < len (arg) and arg[i].isspace():
200 colon = arg.find (":", i)
202 raise Exception ("Invalid syntax, missing colon")
207 while colon < len (arg) and arg[colon].isspace():
210 command = arg[colon:]
212 return (var, val, command)
214 def do_iter(self, arg, item, command):
215 item = item.cast (gdb.lookup_type("void").pointer())
217 to_eval = "set $%s = (void *)0x%x\n"%(arg, item)
221 def slist_iterator (self, arg, container, command):
222 l = container.cast (gdb.lookup_type("GSList").pointer())
224 self.do_iter (arg, l["data"], command)
227 def list_iterator (self, arg, container, command):
228 l = container.cast (gdb.lookup_type("GList").pointer())
230 self.do_iter (arg, l["data"], command)
233 def pick_iterator (self, container):
234 t = container.type.unqualified()
235 if t.code == gdb.TYPE_CODE_PTR:
236 t = t.target().unqualified()
239 return self.slist_iterator
241 return self.list_iterator
242 raise Exception("Invalid container type %s"%(str(container.type)))
244 def invoke (self, arg, from_tty):
245 (var, container, command) = self.parse_args(arg)
246 container = gdb.parse_and_eval (container)
247 func = self.pick_iterator(container)
248 func(var, container, command)