Initial class construction
This commit is contained in:
261
Git/usr/share/glib-2.0/gdb/glib_gdb.py
Normal file
261
Git/usr/share/glib-2.0/gdb/glib_gdb.py
Normal file
@ -0,0 +1,261 @@
|
||||
import gdb
|
||||
import sys
|
||||
|
||||
if sys.version_info[0] >= 3:
|
||||
long = int
|
||||
|
||||
# This is not quite right, as local vars may override symname
|
||||
def read_global_var (symname):
|
||||
return gdb.selected_frame().read_var(symname)
|
||||
|
||||
def g_quark_to_string (quark):
|
||||
if quark == None:
|
||||
return None
|
||||
quark = long(quark)
|
||||
if quark == 0:
|
||||
return None
|
||||
try:
|
||||
val = read_global_var ("quarks")
|
||||
max_q = long(read_global_var ("quark_seq_id"))
|
||||
except:
|
||||
try:
|
||||
val = read_global_var ("g_quarks")
|
||||
max_q = long(read_global_var ("g_quark_seq_id"))
|
||||
except:
|
||||
return None;
|
||||
if quark < max_q:
|
||||
return val[quark].string()
|
||||
return None
|
||||
|
||||
# We override the node printers too, so that node->next is not expanded
|
||||
class GListNodePrinter:
|
||||
"Prints a GList node"
|
||||
|
||||
def __init__ (self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string (self):
|
||||
return "{data=%s, next=0x%x, prev=0x%x}" % (str(self.val["data"]), long(self.val["next"]), long(self.val["prev"]))
|
||||
|
||||
class GSListNodePrinter:
|
||||
"Prints a GSList node"
|
||||
|
||||
def __init__ (self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string (self):
|
||||
return "{data=%s, next=0x%x}" % (str(self.val["data"]), long(self.val["next"]))
|
||||
|
||||
class GListPrinter:
|
||||
"Prints a GList"
|
||||
|
||||
class _iterator:
|
||||
def __init__(self, head, listtype):
|
||||
self.link = head
|
||||
self.listtype = listtype
|
||||
self.count = 0
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def next(self):
|
||||
if self.link == 0:
|
||||
raise StopIteration
|
||||
data = self.link['data']
|
||||
self.link = self.link['next']
|
||||
count = self.count
|
||||
self.count = self.count + 1
|
||||
return ('[%d]' % count, data)
|
||||
|
||||
__next__ = next
|
||||
|
||||
def __init__ (self, val, listtype):
|
||||
self.val = val
|
||||
self.listtype = listtype
|
||||
|
||||
def children(self):
|
||||
return self._iterator(self.val, self.listtype)
|
||||
|
||||
def to_string (self):
|
||||
return "0x%x" % (long(self.val))
|
||||
|
||||
def display_hint (self):
|
||||
return "array"
|
||||
|
||||
class GHashPrinter:
|
||||
"Prints a GHashTable"
|
||||
|
||||
class _iterator:
|
||||
def __init__(self, ht, keys_are_strings):
|
||||
self.ht = ht
|
||||
if ht != 0:
|
||||
self.keys = ht["keys"]
|
||||
self.values = ht["values"]
|
||||
self.hashes = ht["hashes"]
|
||||
self.size = ht["size"]
|
||||
self.pos = 0
|
||||
self.keys_are_strings = keys_are_strings
|
||||
self.value = None
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def next(self):
|
||||
if self.ht == 0:
|
||||
raise StopIteration
|
||||
if self.value != None:
|
||||
v = self.value
|
||||
self.value = None
|
||||
return v
|
||||
while long(self.pos) < long(self.size):
|
||||
self.pos = self.pos + 1
|
||||
if long (self.hashes[self.pos]) >= 2:
|
||||
key = self.keys[self.pos]
|
||||
val = self.values[self.pos]
|
||||
|
||||
if self.keys_are_strings:
|
||||
key = key.cast (gdb.lookup_type("char").pointer())
|
||||
|
||||
# Queue value for next result
|
||||
self.value = ('[%dv]'% (self.pos), val)
|
||||
|
||||
# Return key
|
||||
return ('[%dk]'% (self.pos), key)
|
||||
raise StopIteration
|
||||
|
||||
__next__ = next
|
||||
|
||||
def __init__ (self, val):
|
||||
self.val = val
|
||||
self.keys_are_strings = False
|
||||
try:
|
||||
string_hash = read_global_var ("g_str_hash")
|
||||
except:
|
||||
string_hash = None
|
||||
if self.val != 0 and string_hash != None and self.val["hash_func"] == string_hash:
|
||||
self.keys_are_strings = True
|
||||
|
||||
def children(self):
|
||||
return self._iterator(self.val, self.keys_are_strings)
|
||||
|
||||
def to_string (self):
|
||||
return "0x%x" % (long(self.val))
|
||||
|
||||
def display_hint (self):
|
||||
return "map"
|
||||
|
||||
def pretty_printer_lookup (val):
|
||||
# None yet, want things like hash table and list
|
||||
|
||||
type = val.type.unqualified()
|
||||
|
||||
# If it points to a reference, get the reference.
|
||||
if type.code == gdb.TYPE_CODE_REF:
|
||||
type = type.target ()
|
||||
|
||||
if type.code == gdb.TYPE_CODE_PTR:
|
||||
type = type.target().unqualified()
|
||||
t = str(type)
|
||||
if t == "GList":
|
||||
return GListPrinter(val, "GList")
|
||||
if t == "GSList":
|
||||
return GListPrinter(val, "GSList")
|
||||
if t == "GHashTable":
|
||||
return GHashPrinter(val)
|
||||
else:
|
||||
t = str(type)
|
||||
if t == "GList":
|
||||
return GListNodePrinter(val)
|
||||
if t == "GSList *":
|
||||
return GListPrinter(val, "GSList")
|
||||
return None
|
||||
|
||||
def register (obj):
|
||||
if obj == None:
|
||||
obj = gdb
|
||||
|
||||
obj.pretty_printers.append(pretty_printer_lookup)
|
||||
|
||||
class ForeachCommand (gdb.Command):
|
||||
"""Foreach on list"""
|
||||
|
||||
def __init__ (self):
|
||||
super (ForeachCommand, self).__init__ ("gforeach",
|
||||
gdb.COMMAND_DATA,
|
||||
gdb.COMPLETE_SYMBOL)
|
||||
|
||||
def valid_name (self, name):
|
||||
if not name[0].isalpha():
|
||||
return False
|
||||
return True
|
||||
|
||||
def parse_args (self, arg):
|
||||
i = arg.find(" ")
|
||||
if i <= 0:
|
||||
raise Exception ("No var specified")
|
||||
var = arg[:i]
|
||||
if not self.valid_name(var):
|
||||
raise Exception ("Invalid variable name")
|
||||
|
||||
while i < len (arg) and arg[i].isspace():
|
||||
i = i + 1
|
||||
|
||||
if arg[i:i+2] != "in":
|
||||
raise Exception ("Invalid syntax, missing in")
|
||||
|
||||
i = i + 2
|
||||
|
||||
while i < len (arg) and arg[i].isspace():
|
||||
i = i + 1
|
||||
|
||||
colon = arg.find (":", i)
|
||||
if colon == -1:
|
||||
raise Exception ("Invalid syntax, missing colon")
|
||||
|
||||
val = arg[i:colon]
|
||||
|
||||
colon = colon + 1
|
||||
while colon < len (arg) and arg[colon].isspace():
|
||||
colon = colon + 1
|
||||
|
||||
command = arg[colon:]
|
||||
|
||||
return (var, val, command)
|
||||
|
||||
def do_iter(self, arg, item, command):
|
||||
item = item.cast (gdb.lookup_type("void").pointer())
|
||||
item = long(item)
|
||||
to_eval = "set $%s = (void *)0x%x\n"%(arg, item)
|
||||
gdb.execute(to_eval)
|
||||
gdb.execute(command)
|
||||
|
||||
def slist_iterator (self, arg, container, command):
|
||||
l = container.cast (gdb.lookup_type("GSList").pointer())
|
||||
while long(l) != 0:
|
||||
self.do_iter (arg, l["data"], command)
|
||||
l = l["next"]
|
||||
|
||||
def list_iterator (self, arg, container, command):
|
||||
l = container.cast (gdb.lookup_type("GList").pointer())
|
||||
while long(l) != 0:
|
||||
self.do_iter (arg, l["data"], command)
|
||||
l = l["next"]
|
||||
|
||||
def pick_iterator (self, container):
|
||||
t = container.type.unqualified()
|
||||
if t.code == gdb.TYPE_CODE_PTR:
|
||||
t = t.target().unqualified()
|
||||
t = str(t)
|
||||
if t == "GSList":
|
||||
return self.slist_iterator
|
||||
if t == "GList":
|
||||
return self.list_iterator
|
||||
raise Exception("Invalid container type %s"%(str(container.type)))
|
||||
|
||||
def invoke (self, arg, from_tty):
|
||||
(var, container, command) = self.parse_args(arg)
|
||||
container = gdb.parse_and_eval (container)
|
||||
func = self.pick_iterator(container)
|
||||
func(var, container, command)
|
||||
|
||||
ForeachCommand ()
|
295
Git/usr/share/glib-2.0/gdb/gobject_gdb.py
Normal file
295
Git/usr/share/glib-2.0/gdb/gobject_gdb.py
Normal file
@ -0,0 +1,295 @@
|
||||
import os.path
|
||||
import gdb
|
||||
import glib_gdb
|
||||
import sys
|
||||
|
||||
if sys.version_info[0] >= 3:
|
||||
long = int
|
||||
else:
|
||||
import itertools
|
||||
map = itertools.imap
|
||||
|
||||
# FrameDecorator is new in gdb 7.7, so we adapt to its absence.
|
||||
try:
|
||||
import gdb.FrameDecorator
|
||||
HAVE_GDB_FRAMEDECORATOR = True
|
||||
FrameDecorator = gdb.FrameDecorator.FrameDecorator
|
||||
except ImportError:
|
||||
HAVE_GDB_FRAMEDECORATOR = False
|
||||
|
||||
# This is not quite right, as local vars may override symname
|
||||
def read_global_var (symname):
|
||||
return gdb.selected_frame().read_var(symname)
|
||||
|
||||
def g_type_to_name (gtype):
|
||||
def lookup_fundamental_type (typenode):
|
||||
if typenode == 0:
|
||||
return None
|
||||
val = read_global_var ("static_fundamental_type_nodes")
|
||||
if val == None:
|
||||
return None
|
||||
return val[typenode >> 2].address()
|
||||
|
||||
gtype = long(gtype)
|
||||
typenode = gtype - gtype % 4
|
||||
if typenode > (255 << 2):
|
||||
typenode = gdb.Value(typenode).cast (gdb.lookup_type("TypeNode").pointer())
|
||||
else:
|
||||
typenode = lookup_fundamental_type (typenode)
|
||||
if typenode != None:
|
||||
return glib_gdb.g_quark_to_string (typenode["qname"])
|
||||
return None
|
||||
|
||||
def is_g_type_instance (val):
|
||||
def is_g_type_instance_helper (type):
|
||||
if str(type) == "GTypeInstance":
|
||||
return True
|
||||
|
||||
while type.code == gdb.TYPE_CODE_TYPEDEF:
|
||||
type = type.target()
|
||||
|
||||
if type.code != gdb.TYPE_CODE_STRUCT:
|
||||
return False
|
||||
|
||||
fields = type.fields()
|
||||
if len (fields) < 1:
|
||||
return False
|
||||
|
||||
first_field = fields[0]
|
||||
return is_g_type_instance_helper(first_field.type)
|
||||
|
||||
type = val.type
|
||||
if type.code != gdb.TYPE_CODE_PTR:
|
||||
return False
|
||||
type = type.target()
|
||||
return is_g_type_instance_helper (type)
|
||||
|
||||
def g_type_name_from_instance (instance):
|
||||
if long(instance) != 0:
|
||||
try:
|
||||
inst = instance.cast (gdb.lookup_type("GTypeInstance").pointer())
|
||||
klass = inst["g_class"]
|
||||
gtype = klass["g_type"]
|
||||
name = g_type_to_name (gtype)
|
||||
return name
|
||||
except RuntimeError:
|
||||
pass
|
||||
return None
|
||||
|
||||
class GTypePrettyPrinter:
|
||||
"Prints a GType instance pointer"
|
||||
|
||||
def __init__ (self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string (self):
|
||||
name = g_type_name_from_instance (self.val)
|
||||
if name:
|
||||
return ("0x%x [%s]")% (long(self.val), name)
|
||||
return ("0x%x") % (long(self.val))
|
||||
|
||||
def pretty_printer_lookup (val):
|
||||
if is_g_type_instance (val):
|
||||
return GTypePrettyPrinter (val)
|
||||
|
||||
return None
|
||||
|
||||
def get_signal_name (id):
|
||||
if id == None:
|
||||
return None
|
||||
id = long(id)
|
||||
if id == 0:
|
||||
return None
|
||||
val = read_global_var ("g_signal_nodes")
|
||||
max_s = read_global_var ("g_n_signal_nodes")
|
||||
max_s = long(max_s)
|
||||
if id < max_s:
|
||||
return val[id]["name"].string()
|
||||
return None
|
||||
|
||||
def frame_name(frame):
|
||||
return str(frame.function())
|
||||
|
||||
def frame_var(frame, var):
|
||||
return frame.inferior_frame().read_var(var)
|
||||
|
||||
|
||||
class SignalFrame(FrameDecorator):
|
||||
def __init__ (self, frames):
|
||||
FrameDecorator.__init__(self, frames[-1])
|
||||
self.frame = frames[-1]
|
||||
self.frames = frames
|
||||
|
||||
def name (self):
|
||||
return "signal-emission"
|
||||
|
||||
def read_var (self, frame, name, array = None):
|
||||
try:
|
||||
v = frame_var (frame, name)
|
||||
if v == None or v.is_optimized_out:
|
||||
return None
|
||||
if array != None:
|
||||
array.append (v)
|
||||
return v
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
def read_object (self, frame, name, array = None):
|
||||
try:
|
||||
v = frame_var (frame, name)
|
||||
if v == None or v.is_optimized_out:
|
||||
return None
|
||||
v = v.cast (gdb.lookup_type("GObject").pointer())
|
||||
# Ensure this is a somewhat correct object pointer
|
||||
if v != None and g_type_name_from_instance (v):
|
||||
if array != None:
|
||||
array.append (v)
|
||||
return v
|
||||
return None
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
def append (self, array, obj):
|
||||
if obj != None:
|
||||
array.append (obj)
|
||||
|
||||
def or_join_array (self, array):
|
||||
if len(array) == 0:
|
||||
return "???"
|
||||
else:
|
||||
return ' or '.join(set(map(str, array)))
|
||||
|
||||
def get_detailed_signal_from_frame(self, frame, signal):
|
||||
detail = self.read_var (frame, "detail")
|
||||
detail = glib_gdb.g_quark_to_string (detail)
|
||||
if detail is not None:
|
||||
return signal + ":" + detail
|
||||
else:
|
||||
return detail
|
||||
|
||||
def function (self):
|
||||
instances = []
|
||||
signals = []
|
||||
|
||||
for frame in self.frames:
|
||||
name = frame_name(frame)
|
||||
if name == "signal_emit_unlocked_R":
|
||||
self.read_object (frame, "instance", instances)
|
||||
node = self.read_var (frame, "node")
|
||||
if node:
|
||||
signal = node["name"].string()
|
||||
signal = self.get_detailed_signal_from_frame(frame, signal)
|
||||
self.append(signals, signal)
|
||||
|
||||
if name == "g_signal_emitv":
|
||||
instance_and_params = self.read_var (frame, "instance_and_params")
|
||||
if instance_and_params:
|
||||
instance = instance_and_params[0]["v_pointer"].cast (gdb.Type("GObject").pointer())
|
||||
self.append (instances, instance)
|
||||
id = self.read_var (frame, "signal_id")
|
||||
signal = get_signal_name (id)
|
||||
if signal:
|
||||
signal = self.get_detailed_signal_from_frame(frame, signal)
|
||||
self.append (signals, signal)
|
||||
|
||||
if name == "g_signal_emit_valist" or name == "g_signal_emit":
|
||||
self.read_object (frame, "instance", instances)
|
||||
id = self.read_var (frame, "signal_id")
|
||||
signal = get_signal_name (id)
|
||||
if signal:
|
||||
signal = self.get_detailed_signal_from_frame(frame, signal)
|
||||
self.append (signals, signal)
|
||||
|
||||
if name == "g_signal_emit_by_name":
|
||||
self.read_object (frame, "instance", instances)
|
||||
self.read_var (frame, "detailed_signal", signals)
|
||||
break
|
||||
|
||||
instance = self.or_join_array (instances)
|
||||
signal = self.or_join_array (signals)
|
||||
|
||||
return "<emit signal %s on instance %s>" % (signal, instance)
|
||||
|
||||
def elided (self):
|
||||
return self.frames[0:-1]
|
||||
|
||||
def describe (self, stream, full):
|
||||
stream.write (" " + self.function () + "\n")
|
||||
|
||||
class GFrameDecorator:
|
||||
def __init__ (self, iter):
|
||||
self.queue = []
|
||||
self.iter = iter
|
||||
|
||||
def __iter__ (self):
|
||||
return self
|
||||
|
||||
def fill (self):
|
||||
while len(self.queue) <= 8:
|
||||
try:
|
||||
f = next(self.iter)
|
||||
self.queue.append (f)
|
||||
except StopIteration:
|
||||
return
|
||||
|
||||
def find_signal_emission (self):
|
||||
for i in range (min (len(self.queue), 3)):
|
||||
if frame_name(self.queue[i]) == "signal_emit_unlocked_R":
|
||||
return i
|
||||
return -1
|
||||
|
||||
def next (self):
|
||||
# Ensure we have enough frames for a full signal emission
|
||||
self.fill()
|
||||
|
||||
# Are we at the end?
|
||||
if len(self.queue) == 0:
|
||||
raise StopIteration
|
||||
|
||||
emission = self.find_signal_emission ()
|
||||
if emission > 0:
|
||||
start = emission
|
||||
while True:
|
||||
if start == 0:
|
||||
break
|
||||
prev_name = frame_name(self.queue[start-1])
|
||||
if prev_name.find("_marshal_") >= 0 or prev_name == "g_closure_invoke":
|
||||
start = start - 1
|
||||
else:
|
||||
break
|
||||
end = emission + 1
|
||||
while end < len(self.queue):
|
||||
if frame_name(self.queue[end]) in ["g_signal_emitv",
|
||||
"g_signal_emit_valist",
|
||||
"g_signal_emit",
|
||||
"g_signal_emit_by_name",
|
||||
"_g_closure_invoke_va"]:
|
||||
end = end + 1
|
||||
else:
|
||||
break
|
||||
|
||||
signal_frames = self.queue[start:end]
|
||||
new_frames = [SignalFrame(signal_frames)]
|
||||
self.queue[start:end] = new_frames
|
||||
|
||||
return self.queue.pop(0)
|
||||
|
||||
def __next__ (self):
|
||||
return self.next()
|
||||
|
||||
class GFrameFilter(object):
|
||||
name = 'glib'
|
||||
enabled = True
|
||||
priority = 100
|
||||
|
||||
def filter(self, iterator):
|
||||
return GFrameDecorator(iterator)
|
||||
|
||||
def register (obj):
|
||||
if obj == None:
|
||||
obj = gdb
|
||||
|
||||
if HAVE_GDB_FRAMEDECORATOR:
|
||||
filter = GFrameFilter()
|
||||
obj.frame_filters[filter.name] = filter
|
||||
obj.pretty_printers.append(pretty_printer_lookup)
|
74
Git/usr/share/glib-2.0/schemas/gschema.dtd
Normal file
74
Git/usr/share/glib-2.0/schemas/gschema.dtd
Normal file
@ -0,0 +1,74 @@
|
||||
<!ELEMENT schemalist (schema|enum|flags)* >
|
||||
<!ATTLIST schemalist gettext-domain CDATA #IMPLIED >
|
||||
|
||||
<!ELEMENT schema (key|child|override)* >
|
||||
<!ATTLIST schema id CDATA #REQUIRED
|
||||
path CDATA #IMPLIED
|
||||
gettext-domain CDATA #IMPLIED
|
||||
extends CDATA #IMPLIED
|
||||
list-of CDATA #IMPLIED >
|
||||
|
||||
<!-- enumerated and flags types -->
|
||||
<!-- each value element maps a nick to a numeric value -->
|
||||
<!ELEMENT enum (value*) >
|
||||
<!ATTLIST enum id CDATA #REQUIRED >
|
||||
|
||||
<!ELEMENT flags (value*) >
|
||||
<!ATTLIST flags id CDATA #REQUIRED >
|
||||
|
||||
<!ELEMENT value EMPTY >
|
||||
<!-- nick must be at least 2 characters long -->
|
||||
<!-- value must be parsable as a 32-bit integer -->
|
||||
<!ATTLIST value nick CDATA #REQUIRED
|
||||
value CDATA #REQUIRED >
|
||||
|
||||
<!ELEMENT key (default|summary?|description?|range?|choices?|aliases?)* >
|
||||
<!-- name can only contain lowercase letters, numbers and '-' -->
|
||||
<!-- type must be a GVariant type string -->
|
||||
<!-- enum must be the id of an enum type that has been defined earlier -->
|
||||
<!-- flags must be the id of a flags type that has been defined earlier -->
|
||||
<!-- exactly one of type, enum or flags must be given -->
|
||||
<!ATTLIST key name CDATA #REQUIRED
|
||||
type CDATA #IMPLIED
|
||||
enum CDATA #IMPLIED
|
||||
flags CDATA #IMPLIED >
|
||||
|
||||
<!-- the default value is specified a a serialized GVariant,
|
||||
i.e. you have to include the quotes when specifying a string -->
|
||||
<!ELEMENT default (#PCDATA) >
|
||||
<!-- the presence of the l10n attribute marks a default value for
|
||||
translation, its value is the gettext category to use -->
|
||||
<!-- if context is present, it specifies msgctxt to use -->
|
||||
<!ATTLIST default l10n (messages|time) #IMPLIED
|
||||
context CDATA #IMPLIED >
|
||||
|
||||
<!ELEMENT summary (#PCDATA) >
|
||||
<!ELEMENT description (#PCDATA) >
|
||||
|
||||
<!-- range is only allowed for keys with numeric type -->
|
||||
<!ELEMENT range EMPTY >
|
||||
<!-- min and max must be parseable as values of the key type and
|
||||
min must be less than or equal to max -->
|
||||
<!ATTLIST range min CDATA #REQUIRED
|
||||
max CDATA #REQUIRED >
|
||||
|
||||
<!-- choices is only allowed for keys with string or string array type -->
|
||||
<!ELEMENT choices (choice+) >
|
||||
<!-- each choice element specifies one possible value -->
|
||||
<!ELEMENT choice EMPTY >
|
||||
<!ATTLIST choice value CDATA #REQUIRED >
|
||||
|
||||
<!-- aliases is only allowed for keys with enumerated type or with choices -->
|
||||
<!ELEMENT aliases (alias+) >
|
||||
<!-- each alias element specifies an alias for one of the possible values -->
|
||||
<!ELEMENT alias EMPTY >
|
||||
<!ATTLIST alias value CDATA #REQUIRED >
|
||||
|
||||
<!ELEMENT child EMPTY >
|
||||
<!ATTLIST child name CDATA #REQUIRED
|
||||
schema CDATA #REQUIRED >
|
||||
|
||||
<!ELEMENT override (#PCDATA) >
|
||||
<!ATTLIST override name CDATA #REQUIRED
|
||||
l10n CDATA #IMPLIED
|
||||
context CDATA #IMPLIED >
|
Reference in New Issue
Block a user