xref: /openbsd-src/gnu/llvm/lldb/examples/summaries/cocoa/Logger.py (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1*061da546Spatrickimport sys
2*061da546Spatrickimport os.path
3*061da546Spatrickimport inspect
4*061da546Spatrick
5*061da546Spatrick
6*061da546Spatrickclass NopLogger:
7*061da546Spatrick
8*061da546Spatrick    def __init__(self):
9*061da546Spatrick        pass
10*061da546Spatrick
11*061da546Spatrick    def write(self, data):
12*061da546Spatrick        pass
13*061da546Spatrick
14*061da546Spatrick    def flush(self):
15*061da546Spatrick        pass
16*061da546Spatrick
17*061da546Spatrick    def close(self):
18*061da546Spatrick        pass
19*061da546Spatrick
20*061da546Spatrick
21*061da546Spatrickclass StdoutLogger:
22*061da546Spatrick
23*061da546Spatrick    def __init__(self):
24*061da546Spatrick        pass
25*061da546Spatrick
26*061da546Spatrick    def write(self, data):
27*061da546Spatrick        print(data)
28*061da546Spatrick
29*061da546Spatrick    def flush(self):
30*061da546Spatrick        pass
31*061da546Spatrick
32*061da546Spatrick    def close(self):
33*061da546Spatrick        pass
34*061da546Spatrick
35*061da546Spatrick
36*061da546Spatrickclass FileLogger:
37*061da546Spatrick
38*061da546Spatrick    def __init__(self, name):
39*061da546Spatrick        self.file = None
40*061da546Spatrick        try:
41*061da546Spatrick            name = os.path.abspath(name)
42*061da546Spatrick            self.file = open(name, 'a')
43*061da546Spatrick        except:
44*061da546Spatrick            try:
45*061da546Spatrick                self.file = open('formatters.log', 'a')
46*061da546Spatrick            except:
47*061da546Spatrick                pass
48*061da546Spatrick
49*061da546Spatrick    def write(self, data):
50*061da546Spatrick        if self.file is not None:
51*061da546Spatrick            print(data, file=self.file)
52*061da546Spatrick        else:
53*061da546Spatrick            print(data)
54*061da546Spatrick
55*061da546Spatrick    def flush(self):
56*061da546Spatrick        if self.file is not None:
57*061da546Spatrick            self.file.flush()
58*061da546Spatrick
59*061da546Spatrick    def close(self):
60*061da546Spatrick        if self.file is not None:
61*061da546Spatrick            self.file.close()
62*061da546Spatrick            self.file = None
63*061da546Spatrick
64*061da546Spatrick# to enable logging:
65*061da546Spatrick# define lldb.formatters.Logger._lldb_formatters_debug_level to any number greater than 0
66*061da546Spatrick# if you define it to any value greater than 1, the log will be automatically flushed after each write (slower but should make sure most of the stuff makes it to the log even if we crash)
67*061da546Spatrick# if you define it to any value greater than 2, the calling function's details will automatically be logged (even slower, but provides additional details)
68*061da546Spatrick# if you need the log to go to a file instead of on screen, define
69*061da546Spatrick# lldb.formatters.Logger._lldb_formatters_debug_filename to a valid
70*061da546Spatrick# filename
71*061da546Spatrick
72*061da546Spatrick
73*061da546Spatrickclass Logger:
74*061da546Spatrick
75*061da546Spatrick    def __init__(self, autoflush=False, logcaller=False):
76*061da546Spatrick        global _lldb_formatters_debug_level
77*061da546Spatrick        global _lldb_formatters_debug_filename
78*061da546Spatrick        self.autoflush = autoflush
79*061da546Spatrick        want_log = False
80*061da546Spatrick        try:
81*061da546Spatrick            want_log = (_lldb_formatters_debug_level > 0)
82*061da546Spatrick        except:
83*061da546Spatrick            pass
84*061da546Spatrick        if not (want_log):
85*061da546Spatrick            self.impl = NopLogger()
86*061da546Spatrick            return
87*061da546Spatrick        want_file = False
88*061da546Spatrick        try:
89*061da546Spatrick            want_file = (_lldb_formatters_debug_filename is not None and _lldb_formatters_debug_filename !=
90*061da546Spatrick                         '' and _lldb_formatters_debug_filename != 0)
91*061da546Spatrick        except:
92*061da546Spatrick            pass
93*061da546Spatrick        if want_file:
94*061da546Spatrick            self.impl = FileLogger(_lldb_formatters_debug_filename)
95*061da546Spatrick        else:
96*061da546Spatrick            self.impl = StdoutLogger()
97*061da546Spatrick        try:
98*061da546Spatrick            self.autoflush = (_lldb_formatters_debug_level > 1)
99*061da546Spatrick        except:
100*061da546Spatrick            self.autoflush = autoflush
101*061da546Spatrick        want_caller_info = False
102*061da546Spatrick        try:
103*061da546Spatrick            want_caller_info = (_lldb_formatters_debug_level > 2)
104*061da546Spatrick        except:
105*061da546Spatrick            pass
106*061da546Spatrick        if want_caller_info:
107*061da546Spatrick            self._log_caller()
108*061da546Spatrick
109*061da546Spatrick    def _log_caller(self):
110*061da546Spatrick        caller = inspect.stack()[2]
111*061da546Spatrick        try:
112*061da546Spatrick            if caller is not None and len(caller) > 3:
113*061da546Spatrick                self.write('Logging from function ' + str(caller))
114*061da546Spatrick            else:
115*061da546Spatrick                self.write(
116*061da546Spatrick                    'Caller info not available - Required caller logging not possible')
117*061da546Spatrick        finally:
118*061da546Spatrick            del caller  # needed per Python docs to avoid keeping objects alive longer than we care
119*061da546Spatrick
120*061da546Spatrick    def write(self, data):
121*061da546Spatrick        self.impl.write(data)
122*061da546Spatrick        if self.autoflush:
123*061da546Spatrick            self.flush()
124*061da546Spatrick
125*061da546Spatrick    def __rshift__(self, data):
126*061da546Spatrick        self.write(data)
127*061da546Spatrick
128*061da546Spatrick    def flush(self):
129*061da546Spatrick        self.impl.flush()
130*061da546Spatrick
131*061da546Spatrick    def close(self):
132*061da546Spatrick        self.impl.close()
133