126680b8c6426f80d795dc580d1705c3ab392b8a
[platform/upstream/gstreamer.git] / libs / gst / helpers / gst_gdb.py
1 import gdb
2 import sys
3 import re
4
5 from glib_gobject_helper import g_type_to_name, g_type_name_from_instance
6
7 if sys.version_info[0] >= 3:
8     long = int
9
10
11 def is_gst_type(val, klass):
12     def _is_gst_type(type):
13         if str(type) == klass:
14             return True
15
16         while type.code == gdb.TYPE_CODE_TYPEDEF:
17             type = type.target()
18
19         if type.code != gdb.TYPE_CODE_STRUCT:
20             return False
21
22         fields = type.fields()
23         if len(fields) < 1:
24             return False
25
26         first_field = fields[0]
27         return _is_gst_type(first_field.type)
28
29     type = val.type
30     if type.code != gdb.TYPE_CODE_PTR:
31         return False
32     type = type.target()
33     return _is_gst_type(type)
34
35
36 class GstMiniObjectPrettyPrinter:
37     "Prints a GstMiniObject instance pointer"
38
39     def __init__(self, val):
40         self.val = val
41
42     def to_string(self):
43         try:
44             inst = self.val.cast(gdb.lookup_type("GstMiniObject").pointer())
45             gtype = inst["type"]
46             name = g_type_to_name(gtype)
47             return "0x%x [%s]" % (long(self.val), name)
48         except RuntimeError:
49             return "0x%x" % long(self.val)
50
51
52 class GstObjectPrettyPrinter:
53     "Prints a GstObject instance"
54
55     def __init__(self, val):
56         self.val = val
57
58     def to_string(self):
59         try:
60             name = g_type_name_from_instance(self.val)
61             if not name:
62                 name = str(self.val.type.target())
63             if long(self.val) != 0:
64                 inst = self.val.cast(gdb.lookup_type("GstObject").pointer())
65                 inst_name = inst["name"].string()
66                 if inst_name:
67                     name += "|" + inst_name
68             return ("0x%x [%s]") % (long(self.val), name)
69         except RuntimeError:
70             return "0x%x" % long(self.val)
71
72
73 class GstClockTimePrinter:
74     "Prints a GstClockTime / GstClockTimeDiff"
75
76     def __init__(self, val):
77         self.val = val
78
79     def to_string(self):
80         GST_SECOND = 1000000000
81         GST_CLOCK_TIME_NONE = 2**64-1
82         GST_CLOCK_STIME_NONE = -2**63
83         n = int(self.val)
84         prefix = ""
85         invalid = False
86         if str(self.val.type) == "GstClockTimeDiff":
87             if n == GST_CLOCK_STIME_NONE:
88                 invalid = True
89             prefix = "+" if n >= 0 else "-"
90             n = abs(n)
91         else:
92             if n == GST_CLOCK_TIME_NONE:
93                 invalid = True
94
95         if invalid:
96             return str(n) + " [99:99:99.999999999]"
97
98         return str(n) + " [%s%u:%02u:%02u.%09u]" % (
99             prefix,
100             n / (GST_SECOND * 60 * 60),
101             (n / (GST_SECOND * 60)) % 60,
102             (n / GST_SECOND) % 60,
103             n % GST_SECOND)
104
105
106 def gst_pretty_printer_lookup(val):
107     if is_gst_type(val, "GstMiniObject"):
108         return GstMiniObjectPrettyPrinter(val)
109     if is_gst_type(val, "GstObject"):
110         return GstObjectPrettyPrinter(val)
111     if str(val.type) == "GstClockTime" or str(val.type) == "GstClockTimeDiff":
112         return GstClockTimePrinter(val)
113     return None
114
115
116 def register(obj):
117     if obj is None:
118         obj = gdb
119
120     # Make sure this is always used befor the glib lookup function.
121     # Otherwise the gobject pretty printer is used for GstObjects
122     obj.pretty_printers.insert(0, gst_pretty_printer_lookup)