1from __future__ import print_function
2import sys
3import os.path
4import inspect
5
6class NopLogger:
7	def __init__(self):
8		pass
9
10	def write(self,data):
11		pass
12
13	def flush(self):
14		pass
15
16	def close(self):
17		pass
18
19
20class StdoutLogger:
21	def __init__(self):
22		pass
23
24	def write(self,data):
25		print(data)
26
27	def flush(self):
28		pass
29
30	def close(self):
31		pass
32
33class FileLogger:
34	def __init__(self, name):
35		self.file = None
36		try:
37			name = os.path.abspath(name)
38			self.file = open(name,'a')
39		except:
40			try:
41				self.file = open('formatters.log','a')
42			except:
43				pass
44
45	def write(self,data):
46		if self.file != None:
47			print(data,file=self.file)
48		else:
49			print(data)
50
51	def flush(self):
52		if self.file != None:
53			self.file.flush()
54
55	def close(self):
56		if self.file != None:
57			self.file.close()
58			self.file = None
59
60# to enable logging:
61# define lldb.formatters.Logger._lldb_formatters_debug_level to any number greater than 0
62# 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)
63# 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)
64# if you need the log to go to a file instead of on screen, define lldb.formatters.Logger._lldb_formatters_debug_filename to a valid filename
65class Logger:
66	def __init__(self,autoflush=False,logcaller=False):
67		global _lldb_formatters_debug_level
68		global _lldb_formatters_debug_filename
69		self.autoflush = autoflush
70		want_log = False
71		try:
72			want_log = (_lldb_formatters_debug_level > 0)
73		except:
74			pass
75		if not (want_log):
76			self.impl = NopLogger()
77			return
78		want_file = False
79		try:
80			want_file = (_lldb_formatters_debug_filename != None and _lldb_formatters_debug_filename != '' and _lldb_formatters_debug_filename != 0)
81		except:
82			pass
83		if want_file:
84			self.impl = FileLogger(_lldb_formatters_debug_filename)
85		else:
86			self.impl = StdoutLogger()
87		try:
88			self.autoflush = (_lldb_formatters_debug_level > 1)
89		except:
90			self.autoflush = autoflush
91		want_caller_info = False
92		try:
93			want_caller_info = (_lldb_formatters_debug_level > 2)
94		except:
95			pass
96		if want_caller_info:
97			self._log_caller()
98
99	def _log_caller(self):
100		caller = inspect.stack()[2]
101		try:
102			if caller != None and len(caller) > 3:
103				self.write('Logging from function ' + str(caller))
104			else:
105				self.write('Caller info not available - Required caller logging not possible')
106		finally:
107			del caller # needed per Python docs to avoid keeping objects alive longer than we care
108
109	def write(self,data):
110		self.impl.write(data)
111		if self.autoflush:
112			self.flush()
113
114	def __rshift__(self,data):
115		self.write(data)
116
117	def flush(self):
118		self.impl.flush()
119
120	def close(self):
121		self.impl.close()
122
123