1import getopt
2import os
3import sys
4import re
5
6class 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
16class 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
31class 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, 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.resultObj = CommandResult
57        self.immediateOutput = False
58        self.verbose_level = 0
59        self.target_cmd_args = []
60        self.target_cmd_options = {}
61
62    def write(self, s):
63        """ Handler for all commands output. By default just print to stdout """
64        if self.FILTER and not self.reg.search(s): return
65        if self.FILTER : s+="\n"
66        if self.fhandle != None: self.fhandle.write(s)
67        else:
68            if self.immediateOutput:
69                sys.__stdout__.write(s)
70            else:
71                res_str = s
72                if s.endswith("\n"):
73                    res_str = s[:-1]
74                if self.resultObj and len(res_str) > 0: self.resultObj.AppendMessage(res_str)
75
76    def flush(self):
77        if self.fhandle != None:
78            self.fhandle.flush()
79
80    def __del__(self):
81        """ closes any open files. report on any errors """
82        if self.fhandle != None :
83            self.fhandle.close()
84
85    def setOptions(self,cmdargs, cmdoptions =''):
86        """ parse the arguments passed to the command
87            param :
88                cmdargs => [] of <str> (typically args.split())
89                cmdoptions : str - string of command level options.
90                             These should be CAPITAL LETTER options only.
91        """
92        opts=()
93        args = cmdargs
94        cmdoptions = cmdoptions.upper()
95        try:
96            opts,args = getopt.gnu_getopt(args,'hvo:s:p:'+ cmdoptions,[])
97            self.target_cmd_args = args
98        except getopt.GetoptError,err:
99            raise ArgumentError(str(err))
100        #continue with processing
101        for o,a in opts :
102            if o == "-h":
103                # This is misuse of exception but 'self' has no info on doc string.
104                # The caller may handle exception and display appropriate info
105                raise ArgumentError("HELP")
106            if o == "-o" and len(a) > 0:
107                self.fname=os.path.normpath(os.path.expanduser(a.strip()))
108                self.fhandle=open(self.fname,"w")
109                print "saving results in file ",str(a)
110                self.fhandle.write("(lldb)%s \n" % " ".join(cmdargs))
111            elif o == "-s" and len(a) > 0:
112                self.reg = re.compile(a.strip(),re.MULTILINE|re.DOTALL)
113                self.FILTER=True
114                print "showing results for regex:",a.strip()
115            elif o == "-p" and len(a) > 0:
116                self.pluginRequired = True
117                self.pluginName = a.strip()
118                #print "passing output to " + a.strip()
119            elif o == "-v" :
120                self.verbose_level += 1
121            else:
122                o = o.strip()
123                self.target_cmd_options[o] = a
124
125
126
127
128