]> git.saurik.com Git - apple/xnu.git/blob - tools/lldbmacros/core/standard.py
bb96a17cd29e9e8db902a7d94920e59d2b26bf9f
[apple/xnu.git] / tools / lldbmacros / core / standard.py
1 import getopt
2 import os
3 import sys
4 import re
5
6 class ArgumentError(Exception):
7 """ Exception class for raising errors in command arguments. The lldb_command framework will catch this
8 class of exceptions and print suitable error message to user.
9 """
10 def __init__(self, msg):
11 self.error_message = msg
12 def __str__(self):
13 return str(self.error_message)
14
15
16 class RedirectStdStreams(object):
17 def __init__(self, stdout=None, stderr=None):
18 self._stdout = stdout or sys.stdout
19 self._stderr = stderr or sys.stderr
20
21 def __enter__(self):
22 self.old_stdout, self.old_stderr = sys.stdout, sys.stderr
23 self.old_stdout.flush(); self.old_stderr.flush()
24 sys.stdout, sys.stderr = self._stdout, self._stderr
25
26 def __exit__(self, exc_type, exc_value, traceback):
27 self._stdout.flush(); self._stderr.flush()
28 sys.stdout = self.old_stdout
29 sys.stderr = self.old_stderr
30
31 class CommandOutput(object):
32 """
33 An output handler for all commands. Use Output.print to direct all output of macro via the handler.
34 These arguments are passed after a "--". eg
35 (lldb) zprint -- -o /tmp/zprint.out.txt
36
37 Currently this provide capabilities
38 -o path/to/filename
39 The output of this command execution will be saved to file. Parser information or errors will
40 not be sent to file though. eg /tmp/output.txt
41 -s filter_string
42 the "filter_string" param is parsed to python regex expression and each line of output
43 will be printed/saved only if it matches the expression.
44 The command header will not be filtered in any case.
45 """
46 def __init__(self, cmd_name, CommandResult):
47 """ Create a new instance to handle command output.
48 params:
49 CommandResult : SBCommandReturnObject result param from lldb's command invocation.
50 """
51 self.fname=None
52 self.fhandle=None
53 self.FILTER=False
54 self.pluginRequired = False
55 self.pluginName = None
56 self.cmd_name = cmd_name
57 self.resultObj = CommandResult
58 self.immediateOutput = False
59 self.verbose_level = 0
60 self.target_cmd_args = []
61 self.target_cmd_options = {}
62
63 def write(self, s):
64 """ Handler for all commands output. By default just print to stdout """
65 if self.FILTER and not self.reg.search(s):
66 return
67 if self.FILTER:
68 s += "\n"
69
70 if self.fhandle != None:
71 self.fhandle.write(s)
72 else:
73 if self.immediateOutput:
74 sys.__stdout__.write(s)
75 else:
76 res_str = s
77 if s.endswith("\n"):
78 res_str = s[:-1]
79 if self.resultObj and len(res_str) > 0: self.resultObj.AppendMessage(res_str)
80
81 def flush(self):
82 if self.fhandle != None:
83 self.fhandle.flush()
84
85 def __del__(self):
86 """ closes any open files. report on any errors """
87 if self.fhandle != None :
88 self.fhandle.close()
89
90 def setOptions(self, cmdargs, cmdoptions =''):
91 """ parse the arguments passed to the command
92 param :
93 cmdargs => [] of <str> (typically args.split())
94 cmdoptions : str - string of command level options.
95 These should be CAPITAL LETTER options only.
96 """
97 opts=()
98 args = cmdargs
99 cmdoptions = cmdoptions.upper()
100 try:
101 opts,args = getopt.gnu_getopt(args,'hvo:s:p:'+ cmdoptions,[])
102 self.target_cmd_args = args
103 except getopt.GetoptError,err:
104 raise ArgumentError(str(err))
105 #continue with processing
106 for o,a in opts :
107 if o == "-h":
108 # This is misuse of exception but 'self' has no info on doc string.
109 # The caller may handle exception and display appropriate info
110 raise ArgumentError("HELP")
111 if o == "-o" and len(a) > 0:
112 self.fname=os.path.normpath(os.path.expanduser(a.strip()))
113 self.fhandle=open(self.fname,"w")
114 print "saving results in file ",str(a)
115 self.fhandle.write("(lldb)%s %s \n" % (self.cmd_name, " ".join(cmdargs)))
116 elif o == "-s" and len(a) > 0:
117 self.reg = re.compile(a.strip(),re.MULTILINE|re.DOTALL)
118 self.FILTER=True
119 print "showing results for regex:",a.strip()
120 elif o == "-p" and len(a) > 0:
121 self.pluginRequired = True
122 self.pluginName = a.strip()
123 #print "passing output to " + a.strip()
124 elif o == "-v" :
125 self.verbose_level += 1
126 else:
127 o = o.strip()
128 self.target_cmd_options[o] = a
129
130
131
132