Add tests for GTimer and GTimeVal
[platform/upstream/glib.git] / glib / glib.py
1 import gdb
2 import sys
3
4 if sys.version_info[0] >= 3:
5     long = int
6
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)
10
11 def g_quark_to_string (quark):
12     if quark == None:
13         return None
14     quark = long(quark)
15     if quark == 0:
16         return None
17     try:
18         val = read_global_var ("quarks")
19         max_q = long(read_global_var ("quark_seq_id"))
20     except:
21         try:
22             val = read_global_var ("g_quarks")
23             max_q = long(read_global_var ("g_quark_seq_id"))
24         except:
25             return None;
26     if quark < max_q:
27         return val[quark].string()
28     return None
29
30 # We override the node printers too, so that node->next is not expanded
31 class GListNodePrinter:
32     "Prints a GList node"
33
34     def __init__ (self, val):
35         self.val = val
36
37     def to_string (self):
38         return "{data=%s, next=0x%x, prev=0x%x}" % (str(self.val["data"]), long(self.val["next"]), long(self.val["prev"]))
39
40 class GSListNodePrinter:
41     "Prints a GSList node"
42
43     def __init__ (self, val):
44         self.val = val
45
46     def to_string (self):
47         return "{data=%s, next=0x%x}" % (str(self.val["data"]), long(self.val["next"]))
48
49 class GListPrinter:
50     "Prints a GList"
51
52     class _iterator:
53         def __init__(self, head, listtype):
54             self.link = head
55             self.listtype = listtype
56             self.count = 0
57
58         def __iter__(self):
59             return self
60
61         def next(self):
62             if self.link == 0:
63                 raise StopIteration
64             data = self.link['data']
65             self.link = self.link['next']
66             count = self.count
67             self.count = self.count + 1
68             return ('[%d]' % count, data)
69
70     def __init__ (self, val, listtype):
71         self.val = val
72         self.listtype = listtype
73
74     def children(self):
75         return self._iterator(self.val, self.listtype)
76
77     def to_string (self):
78         return  "0x%x" % (long(self.val))
79
80     def display_hint (self):
81         return "array"
82
83 class GHashPrinter:
84     "Prints a GHashTable"
85
86     class _iterator:
87         def __init__(self, ht, keys_are_strings):
88             self.ht = ht
89             if ht != 0:
90                 self.keys = ht["keys"]
91                 self.values = ht["values"]
92                 self.hashes = ht["hashes"]
93                 self.size = ht["size"]
94             self.pos = 0
95             self.keys_are_strings = keys_are_strings
96             self.value = None
97
98         def __iter__(self):
99             return self
100
101         def next(self):
102             if self.ht == 0:
103                 raise StopIteration
104             if self.value != None:
105                 v = self.value
106                 self.value = None
107                 return v
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]
113
114                     if self.keys_are_strings:
115                         key = key.cast (gdb.lookup_type("char").pointer())
116
117                     # Queue value for next result
118                     self.value = ('[%dv]'% (self.pos), val)
119
120                     # Return key
121                     return ('[%dk]'% (self.pos), key)
122             raise StopIteration
123
124     def __init__ (self, val):
125         self.val = val
126         self.keys_are_strings = False
127         try:
128             string_hash = read_global_var ("g_str_hash")
129         except:
130             string_hash = None
131         if self.val != 0 and string_hash != None and self.val["hash_func"] == string_hash:
132             self.keys_are_strings = True
133
134     def children(self):
135         return self._iterator(self.val, self.keys_are_strings)
136
137     def to_string (self):
138         return  "0x%x" % (long(self.val))
139
140     def display_hint (self):
141         return "map"
142
143 def pretty_printer_lookup (val):
144     # None yet, want things like hash table and list
145
146     type = val.type.unqualified()
147
148     # If it points to a reference, get the reference.
149     if type.code == gdb.TYPE_CODE_REF:
150         type = type.target ()
151
152     if type.code == gdb.TYPE_CODE_PTR:
153         type = type.target().unqualified()
154         t = str(type)
155         if t == "GList":
156             return GListPrinter(val, "GList")
157         if t == "GSList":
158             return GListPrinter(val, "GSList")
159         if t == "GHashTable":
160             return GHashPrinter(val)
161     else:
162         t = str(type)
163         if t == "GList":
164             return GListNodePrinter(val)
165         if t == "GSList *":
166             return GListPrinter(val, "GSList")
167     return None
168
169 def register (obj):
170     if obj == None:
171         obj = gdb
172
173     obj.pretty_printers.append(pretty_printer_lookup)
174
175 class ForeachCommand (gdb.Command):
176     """Foreach on list"""
177
178     def __init__ (self):
179         super (ForeachCommand, self).__init__ ("gforeach",
180                                                gdb.COMMAND_DATA,
181                                                gdb.COMPLETE_SYMBOL)
182
183     def valid_name (self, name):
184         if not name[0].isalpha():
185             return False
186         return True
187
188     def parse_args (self, arg):
189         i = arg.find(" ")
190         if i <= 0:
191             raise Exception ("No var specified")
192         var = arg[:i]
193         if not self.valid_name(var):
194             raise Exception ("Invalid variable name")
195
196         while i < len (arg) and arg[i].isspace():
197             i = i + 1
198
199         if arg[i:i+2] != "in":
200             raise Exception ("Invalid syntax, missing in")
201
202         i = i + 2
203
204         while i < len (arg) and arg[i].isspace():
205             i = i + 1
206
207         colon = arg.find (":", i)
208         if colon == -1:
209             raise Exception ("Invalid syntax, missing colon")
210
211         val = arg[i:colon]
212
213         colon = colon + 1
214         while colon < len (arg) and arg[colon].isspace():
215             colon = colon + 1
216
217         command = arg[colon:]
218
219         return (var, val, command)
220
221     def do_iter(self, arg, item, command):
222         item = item.cast (gdb.lookup_type("void").pointer())
223         item = long(item)
224         to_eval = "set $%s = (void *)0x%x\n"%(arg, item)
225         gdb.execute(to_eval)
226         gdb.execute(command)
227
228     def slist_iterator (self, arg, container, command):
229         l = container.cast (gdb.lookup_type("GSList").pointer())
230         while long(l) != 0:
231             self.do_iter (arg, l["data"], command)
232             l = l["next"]
233
234     def list_iterator (self, arg, container, command):
235         l = container.cast (gdb.lookup_type("GList").pointer())
236         while long(l) != 0:
237             self.do_iter (arg, l["data"], command)
238             l = l["next"]
239
240     def pick_iterator (self, container):
241         t = container.type.unqualified()
242         if t.code == gdb.TYPE_CODE_PTR:
243             t = t.target().unqualified()
244             t = str(t)
245             if t == "GSList":
246                 return self.slist_iterator
247             if t == "GList":
248                 return self.list_iterator
249         raise Exception("Invalid container type %s"%(str(container.type)))
250
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)
256
257 ForeachCommand ()