add private GBuffer type
[glib.git] / glib / glib.py
blob0953aee7cab35d860cc7087e3c22f8ab04504179
1 import gdb
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):
8 if quark == None:
9 return None
10 quark = long(quark)
11 if quark == 0:
12 return None
13 val = read_global_var ("g_quarks")
14 max_q = long(read_global_var ("g_quark_seq_id"))
15 if quark < max_q:
16 return val[quark].string()
17 return None
19 # We override the node printers too, so that node->next is not expanded
20 class GListNodePrinter:
21 "Prints a GList node"
23 def __init__ (self, val):
24 self.val = val
26 def to_string (self):
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):
33 self.val = val
35 def to_string (self):
36 return "{data=%s, next=0x%x}" % (str(self.val["data"]), long(self.val["next"]))
38 class GListPrinter:
39 "Prints a GList"
41 class _iterator:
42 def __init__(self, head, listtype):
43 self.link = head
44 self.listtype = listtype
45 self.count = 0
47 def __iter__(self):
48 return self
50 def next(self):
51 if self.link == 0:
52 raise StopIteration
53 data = self.link['data']
54 self.link = self.link['next']
55 count = self.count
56 self.count = self.count + 1
57 return ('[%d]' % count, data)
59 def __init__ (self, val, listtype):
60 self.val = val
61 self.listtype = listtype
63 def children(self):
64 return self._iterator(self.val, self.listtype)
66 def to_string (self):
67 return "0x%x" % (long(self.val))
69 def display_hint (self):
70 return "array"
72 class GHashPrinter:
73 "Prints a GHashTable"
75 class _iterator:
76 def __init__(self, ht, keys_are_strings):
77 self.ht = ht
78 if ht != 0:
79 self.array = ht["nodes"]
80 self.size = ht["size"]
81 self.pos = 0
82 self.keys_are_strings = keys_are_strings
83 self.value = None
85 def __iter__(self):
86 return self
88 def next(self):
89 if self.ht == 0:
90 raise StopIteration
91 if self.value != None:
92 v = self.value
93 self.value = None
94 return v
95 while long(self.pos) < long(self.size):
96 node = self.array[self.pos]
97 self.pos = self.pos + 1
98 if long (node["key_hash"]) >= 2:
99 key = node["key"]
100 val = node["value"]
102 if self.keys_are_strings:
103 key = key.cast (gdb.lookup_type("char").pointer())
105 # Queue value for next result
106 self.value = ('[%dv]'% (self.pos), val)
108 # Return key
109 return ('[%dk]'% (self.pos), key)
110 raise StopIteration
112 def __init__ (self, val):
113 self.val = val
114 self.keys_are_strings = False
115 try:
116 string_hash = read_global_var ("g_str_hash")
117 except:
118 try:
119 string_hash = read_global_var ("IA__g_str_hash")
120 except:
121 string_hash = None
122 if self.val != 0 and string_hash != None and self.val["hash_func"] == string_hash:
123 self.keys_are_strings = True
125 def children(self):
126 return self._iterator(self.val, self.keys_are_strings)
128 def to_string (self):
129 return "0x%x" % (long(self.val))
131 def display_hint (self):
132 return "map"
134 def pretty_printer_lookup (val):
135 if is_g_type_instance (val):
136 return GTypePrettyPrinter (val)
138 def pretty_printer_lookup (val):
139 # None yet, want things like hash table and list
141 type = val.type.unqualified()
143 # If it points to a reference, get the reference.
144 if type.code == gdb.TYPE_CODE_REF:
145 type = type.target ()
147 if type.code == gdb.TYPE_CODE_PTR:
148 type = type.target().unqualified()
149 t = str(type)
150 if t == "GList":
151 return GListPrinter(val, "GList")
152 if t == "GSList":
153 return GListPrinter(val, "GSList")
154 if t == "GHashTable":
155 return GHashPrinter(val)
156 else:
157 t = str(type)
158 if t == "GList":
159 return GListNodePrinter(val)
160 if t == "GSList *":
161 return GListPrinter(val, "GSList")
162 return None
164 def register (obj):
165 if obj == None:
166 obj = gdb
168 obj.pretty_printers.append(pretty_printer_lookup)
170 class ForeachCommand (gdb.Command):
171 """Foreach on list"""
173 def __init__ (self):
174 super (ForeachCommand, self).__init__ ("gforeach",
175 gdb.COMMAND_DATA,
176 gdb.COMPLETE_SYMBOL)
178 def valid_name (self, name):
179 if not name[0].isalpha():
180 return False
181 return True
183 def parse_args (self, arg):
184 i = arg.find(" ")
185 if i <= 0:
186 raise Exception ("No var specified")
187 var = arg[:i]
188 if not self.valid_name(var):
189 raise Exception ("Invalid variable name")
191 while i < len (arg) and arg[i].isspace():
192 i = i + 1
194 if arg[i:i+2] != "in":
195 raise Exception ("Invalid syntax, missing in")
197 i = i + 2
199 while i < len (arg) and arg[i].isspace():
200 i = i + 1
202 colon = arg.find (":", i)
203 if colon == -1:
204 raise Exception ("Invalid syntax, missing colon")
206 val = arg[i:colon]
208 colon = colon + 1
209 while colon < len (arg) and arg[colon].isspace():
210 colon = colon + 1
212 command = arg[colon:]
214 return (var, val, command)
216 def do_iter(self, arg, item, command):
217 item = item.cast (gdb.lookup_type("void").pointer())
218 item = long(item)
219 to_eval = "set $%s = (void *)0x%x\n"%(arg, item)
220 gdb.execute(to_eval)
221 gdb.execute(command)
223 def slist_iterator (self, arg, container, command):
224 l = container.cast (gdb.lookup_type("GSList").pointer())
225 while long(l) != 0:
226 self.do_iter (arg, l["data"], command)
227 l = l["next"]
229 def list_iterator (self, arg, container, command):
230 l = container.cast (gdb.lookup_type("GList").pointer())
231 while long(l) != 0:
232 self.do_iter (arg, l["data"], command)
233 l = l["next"]
235 def pick_iterator (self, container):
236 t = container.type.unqualified()
237 if t.code == gdb.TYPE_CODE_PTR:
238 t = t.target().unqualified()
239 t = str(t)
240 if t == "GSList":
241 return self.slist_iterator
242 if t == "GList":
243 return self.list_iterator
244 raise Exception("Invalid container type %s"%(str(container.type)))
246 def invoke (self, arg, from_tty):
247 (var, container, command) = self.parse_args(arg)
248 container = gdb.parse_and_eval (container)
249 func = self.pick_iterator(container)
250 func(var, container, command)
252 ForeachCommand ()