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
)