1*d8b80295SApple OSS Distributionsimport getopt 2*d8b80295SApple OSS Distributionsimport os 3*d8b80295SApple OSS Distributionsimport string 4*d8b80295SApple OSS Distributionsimport sys 5*d8b80295SApple OSS Distributionsimport re 6*d8b80295SApple OSS Distributions 7*d8b80295SApple OSS Distributionsfrom lldb import SBValue 8*d8b80295SApple OSS Distributionsfrom core import value as cvalue 9*d8b80295SApple OSS Distributionsfrom .configuration import config 10*d8b80295SApple OSS Distributions 11*d8b80295SApple OSS Distributionsclass ArgumentError(Exception): 12*d8b80295SApple OSS Distributions """ Exception class for raising errors in command arguments. The lldb_command framework will catch this 13*d8b80295SApple OSS Distributions class of exceptions and print suitable error message to user. 14*d8b80295SApple OSS Distributions """ 15*d8b80295SApple OSS Distributions def __init__(self, msg): 16*d8b80295SApple OSS Distributions self.error_message = msg 17*d8b80295SApple OSS Distributions def __str__(self): 18*d8b80295SApple OSS Distributions return str(self.error_message) 19*d8b80295SApple OSS Distributions 20*d8b80295SApple OSS Distributions 21*d8b80295SApple OSS Distributionsclass RedirectStdStreams(object): 22*d8b80295SApple OSS Distributions def __init__(self, stdout=None, stderr=None): 23*d8b80295SApple OSS Distributions self._stdout = stdout or sys.stdout 24*d8b80295SApple OSS Distributions self._stderr = stderr or sys.stderr 25*d8b80295SApple OSS Distributions 26*d8b80295SApple OSS Distributions def __enter__(self): 27*d8b80295SApple OSS Distributions self.old_stdout, self.old_stderr = sys.stdout, sys.stderr 28*d8b80295SApple OSS Distributions self.old_stdout.flush(); self.old_stderr.flush() 29*d8b80295SApple OSS Distributions sys.stdout, sys.stderr = self._stdout, self._stderr 30*d8b80295SApple OSS Distributions 31*d8b80295SApple OSS Distributions def __exit__(self, exc_type, exc_value, traceback): 32*d8b80295SApple OSS Distributions self._stdout.flush(); self._stderr.flush() 33*d8b80295SApple OSS Distributions sys.stdout = self.old_stdout 34*d8b80295SApple OSS Distributions sys.stderr = self.old_stderr 35*d8b80295SApple OSS Distributions 36*d8b80295SApple OSS Distributionsclass IndentScope(object): 37*d8b80295SApple OSS Distributions def __init__(self, O): 38*d8b80295SApple OSS Distributions self._O = O 39*d8b80295SApple OSS Distributions 40*d8b80295SApple OSS Distributions def __enter__(self): 41*d8b80295SApple OSS Distributions self._O._indent += ' ' 42*d8b80295SApple OSS Distributions 43*d8b80295SApple OSS Distributions def __exit__(self, exc_type, exc_value, traceback): 44*d8b80295SApple OSS Distributions self._O._indent = self._O._indent[:-4] 45*d8b80295SApple OSS Distributions 46*d8b80295SApple OSS Distributionsclass HeaderScope(object): 47*d8b80295SApple OSS Distributions def __init__(self, O, hdr, indent = False): 48*d8b80295SApple OSS Distributions self._O = O 49*d8b80295SApple OSS Distributions self._header = hdr 50*d8b80295SApple OSS Distributions self._indent = indent 51*d8b80295SApple OSS Distributions 52*d8b80295SApple OSS Distributions def __enter__(self): 53*d8b80295SApple OSS Distributions self._oldHeader = self._O._header 54*d8b80295SApple OSS Distributions self._oldLastHeader = self._O._lastHeader 55*d8b80295SApple OSS Distributions self._O._header = self._header 56*d8b80295SApple OSS Distributions self._O._lastHeader = None 57*d8b80295SApple OSS Distributions if self._indent: 58*d8b80295SApple OSS Distributions self._O._indent += ' ' 59*d8b80295SApple OSS Distributions 60*d8b80295SApple OSS Distributions def __exit__(self, exc_type, exc_value, traceback): 61*d8b80295SApple OSS Distributions self._O._header = self._oldHeader 62*d8b80295SApple OSS Distributions self._O._lastHeader = self._oldLastHeader 63*d8b80295SApple OSS Distributions if self._indent: 64*d8b80295SApple OSS Distributions self._O._indent = self._O._indent[:-4] 65*d8b80295SApple OSS Distributions 66*d8b80295SApple OSS Distributionsclass VT(object): 67*d8b80295SApple OSS Distributions Black = "\033[38;5;0m" 68*d8b80295SApple OSS Distributions DarkRed = "\033[38;5;1m" 69*d8b80295SApple OSS Distributions DarkGreen = "\033[38;5;2m" 70*d8b80295SApple OSS Distributions Brown = "\033[38;5;3m" 71*d8b80295SApple OSS Distributions DarkBlue = "\033[38;5;4m" 72*d8b80295SApple OSS Distributions DarkMagenta = "\033[38;5;5m" 73*d8b80295SApple OSS Distributions DarkCyan = "\033[38;5;6m" 74*d8b80295SApple OSS Distributions Grey = "\033[38;5;7m" 75*d8b80295SApple OSS Distributions 76*d8b80295SApple OSS Distributions DarkGrey = "\033[38;5;8m" 77*d8b80295SApple OSS Distributions Red = "\033[38;5;9m" 78*d8b80295SApple OSS Distributions Green = "\033[38;5;10m" 79*d8b80295SApple OSS Distributions Yellow = "\033[38;5;11m" 80*d8b80295SApple OSS Distributions Blue = "\033[38;5;12m" 81*d8b80295SApple OSS Distributions Magenta = "\033[38;5;13m" 82*d8b80295SApple OSS Distributions Cyan = "\033[38;5;14m" 83*d8b80295SApple OSS Distributions White = "\033[38;5;15m" 84*d8b80295SApple OSS Distributions 85*d8b80295SApple OSS Distributions Default = "\033[39m" 86*d8b80295SApple OSS Distributions 87*d8b80295SApple OSS Distributions Bold = "\033[1m" 88*d8b80295SApple OSS Distributions EndBold = "\033[22m" 89*d8b80295SApple OSS Distributions 90*d8b80295SApple OSS Distributions Oblique = "\033[3m" 91*d8b80295SApple OSS Distributions EndOblique = "\033[23m" 92*d8b80295SApple OSS Distributions 93*d8b80295SApple OSS Distributions Underline = "\033[4m" 94*d8b80295SApple OSS Distributions EndUnderline = "\033[24m" 95*d8b80295SApple OSS Distributions 96*d8b80295SApple OSS Distributions Reset = "\033[0m" 97*d8b80295SApple OSS Distributions 98*d8b80295SApple OSS Distributionsclass NOVT(object): 99*d8b80295SApple OSS Distributions def __getattribute__(self, *args): 100*d8b80295SApple OSS Distributions return "" 101*d8b80295SApple OSS Distributions 102*d8b80295SApple OSS Distributionsclass SBValueFormatter(string.Formatter): 103*d8b80295SApple OSS Distributions """ 104*d8b80295SApple OSS Distributions Formatter that treats SBValues specially 105*d8b80295SApple OSS Distributions 106*d8b80295SApple OSS Distributions It adds the following magical syntax for fields: 107*d8b80295SApple OSS Distributions 108*d8b80295SApple OSS Distributions - {$value->path.to[10].field} will follow a given expression path, 109*d8b80295SApple OSS Distributions and compute the resulting SBValue. This works with cvalues too. 110*d8b80295SApple OSS Distributions 111*d8b80295SApple OSS Distributions - {&value->path.to[10].field} will return the load address 112*d8b80295SApple OSS Distributions of the specified value path. This works with cvalue too. 113*d8b80295SApple OSS Distributions 114*d8b80295SApple OSS Distributions 115*d8b80295SApple OSS Distributions The format spec can now take a multi-char conversion, 116*d8b80295SApple OSS Distributions {field|<multi-char-conversion>!conv:spec}, 117*d8b80295SApple OSS Distributions where <multi-char-conversion> is one of: 118*d8b80295SApple OSS Distributions 119*d8b80295SApple OSS Distributions - `c_str` which will attempt to read the value as a C string using 120*d8b80295SApple OSS Distributions xGetValueAsCString() 121*d8b80295SApple OSS Distributions 122*d8b80295SApple OSS Distributions - `human_size` will convert sizes into a human readable representation. 123*d8b80295SApple OSS Distributions 124*d8b80295SApple OSS Distributions - a conversion registered with the SBValueFormatter.converter 125*d8b80295SApple OSS Distributions decorator, 126*d8b80295SApple OSS Distributions 127*d8b80295SApple OSS Distributions - a `key.method` specification where the key is one of the positional 128*d8b80295SApple OSS Distributions or named arguments to the format. 129*d8b80295SApple OSS Distributions 130*d8b80295SApple OSS Distributions 131*d8b80295SApple OSS Distributions When the value of a given field is an SBValue (because &/$ was used, 132*d8b80295SApple OSS Distributions or the field was already an SBValue -- but not a cvalue), in the absence 133*d8b80295SApple OSS Distributions of a explicit conversion, the SBValue will be converted to a scalar 134*d8b80295SApple OSS Distributions using xGetValueAsScalar() 135*d8b80295SApple OSS Distributions """ 136*d8b80295SApple OSS Distributions 137*d8b80295SApple OSS Distributions _KEY_RE = re.compile(r"[.-\[]") 138*d8b80295SApple OSS Distributions 139*d8b80295SApple OSS Distributions _CONVERTERS = {} 140*d8b80295SApple OSS Distributions 141*d8b80295SApple OSS Distributions @classmethod 142*d8b80295SApple OSS Distributions def converter(cls, name, raw=False): 143*d8b80295SApple OSS Distributions def register(fn): 144*d8b80295SApple OSS Distributions cls._CONVERTERS[name] = (fn, raw) 145*d8b80295SApple OSS Distributions 146*d8b80295SApple OSS Distributions return register 147*d8b80295SApple OSS Distributions 148*d8b80295SApple OSS Distributions def format(self, format_string, *args, **kwargs): 149*d8b80295SApple OSS Distributions return self.vformat(self, format_string, args, kwargs) 150*d8b80295SApple OSS Distributions 151*d8b80295SApple OSS Distributions def _raise_switch_manual_to_automatic(self): 152*d8b80295SApple OSS Distributions raise ValueError('cannot switch from manual field ' 153*d8b80295SApple OSS Distributions 'specification to automatic field ' 154*d8b80295SApple OSS Distributions 'numbering') 155*d8b80295SApple OSS Distributions 156*d8b80295SApple OSS Distributions def vformat(self, format_string, args, kwargs): 157*d8b80295SApple OSS Distributions result = [] 158*d8b80295SApple OSS Distributions auto_idx = 0 159*d8b80295SApple OSS Distributions 160*d8b80295SApple OSS Distributions # 161*d8b80295SApple OSS Distributions # Python 2.7 doesn't support empty field names in Formatter, 162*d8b80295SApple OSS Distributions # so we need to implement vformat. Because we avoid certain 163*d8b80295SApple OSS Distributions # features such as "unused fields accounting" we actually 164*d8b80295SApple OSS Distributions # are faster than the core library Formatter this way which 165*d8b80295SApple OSS Distributions # adds up quickly for our macros, so it's worth keeping 166*d8b80295SApple OSS Distributions # this implementation even on Python 3. 167*d8b80295SApple OSS Distributions # 168*d8b80295SApple OSS Distributions for text, field_name, format_spec, conv in \ 169*d8b80295SApple OSS Distributions self.parse(format_string): 170*d8b80295SApple OSS Distributions 171*d8b80295SApple OSS Distributions if text: 172*d8b80295SApple OSS Distributions result.append(text) 173*d8b80295SApple OSS Distributions 174*d8b80295SApple OSS Distributions if field_name is None: 175*d8b80295SApple OSS Distributions continue 176*d8b80295SApple OSS Distributions 177*d8b80295SApple OSS Distributions field_name, _, transform = field_name.partition('|') 178*d8b80295SApple OSS Distributions 179*d8b80295SApple OSS Distributions if field_name == '': 180*d8b80295SApple OSS Distributions # 181*d8b80295SApple OSS Distributions # Handle auto-numbering like python 3 182*d8b80295SApple OSS Distributions # 183*d8b80295SApple OSS Distributions if auto_idx is None: 184*d8b80295SApple OSS Distributions self._raise_switch_manual_to_automatic() 185*d8b80295SApple OSS Distributions field_name = str(auto_idx) 186*d8b80295SApple OSS Distributions auto_idx += 1 187*d8b80295SApple OSS Distributions 188*d8b80295SApple OSS Distributions elif field_name.isdigit(): 189*d8b80295SApple OSS Distributions # 190*d8b80295SApple OSS Distributions # numeric key 191*d8b80295SApple OSS Distributions # 192*d8b80295SApple OSS Distributions if auto_idx: 193*d8b80295SApple OSS Distributions self._raise_switch_manual_to_automatic() 194*d8b80295SApple OSS Distributions auto_idx = None 195*d8b80295SApple OSS Distributions 196*d8b80295SApple OSS Distributions try: 197*d8b80295SApple OSS Distributions if field_name[0] in '&$': 198*d8b80295SApple OSS Distributions # 199*d8b80295SApple OSS Distributions # Our magic sigils 200*d8b80295SApple OSS Distributions # 201*d8b80295SApple OSS Distributions obj, auto_idx = self.get_value_field( 202*d8b80295SApple OSS Distributions field_name, args, kwargs, auto_idx) 203*d8b80295SApple OSS Distributions 204*d8b80295SApple OSS Distributions else: 205*d8b80295SApple OSS Distributions # 206*d8b80295SApple OSS Distributions # Fallback typical case 207*d8b80295SApple OSS Distributions # 208*d8b80295SApple OSS Distributions obj, _ = self.get_field(field_name, args, kwargs) 209*d8b80295SApple OSS Distributions except: 210*d8b80295SApple OSS Distributions if config['debug']: raise 211*d8b80295SApple OSS Distributions result.extend(( 212*d8b80295SApple OSS Distributions VT.Red, 213*d8b80295SApple OSS Distributions "<FAIL {}>".format(field_name), 214*d8b80295SApple OSS Distributions VT.Reset 215*d8b80295SApple OSS Distributions )) 216*d8b80295SApple OSS Distributions continue 217*d8b80295SApple OSS Distributions 218*d8b80295SApple OSS Distributions # do any conv on the resulting object 219*d8b80295SApple OSS Distributions try: 220*d8b80295SApple OSS Distributions obj = self.convert_field(obj, conv, transform, args, kwargs) 221*d8b80295SApple OSS Distributions except: 222*d8b80295SApple OSS Distributions if config['debug']: raise 223*d8b80295SApple OSS Distributions result.extend(( 224*d8b80295SApple OSS Distributions VT.Red, 225*d8b80295SApple OSS Distributions "<CONV {}>".format(field_name), 226*d8b80295SApple OSS Distributions VT.Reset 227*d8b80295SApple OSS Distributions )) 228*d8b80295SApple OSS Distributions continue 229*d8b80295SApple OSS Distributions 230*d8b80295SApple OSS Distributions result.append(self.format_field(obj, format_spec)) 231*d8b80295SApple OSS Distributions 232*d8b80295SApple OSS Distributions return ''.join(result) 233*d8b80295SApple OSS Distributions 234*d8b80295SApple OSS Distributions def get_value_field(self, name, args, kwargs, auto_idx): 235*d8b80295SApple OSS Distributions match = self._KEY_RE.search(name) 236*d8b80295SApple OSS Distributions index = match.start() if match else len(name) 237*d8b80295SApple OSS Distributions key = name[1:index] 238*d8b80295SApple OSS Distributions path = name[index:] 239*d8b80295SApple OSS Distributions 240*d8b80295SApple OSS Distributions if key == '': 241*d8b80295SApple OSS Distributions raise ValueError("Key part of '{}' can't be empty".format(name)) 242*d8b80295SApple OSS Distributions 243*d8b80295SApple OSS Distributions if key.isdigit(): 244*d8b80295SApple OSS Distributions key = int(key) 245*d8b80295SApple OSS Distributions if auto_idx: 246*d8b80295SApple OSS Distributions self._raise_switch_manual_to_automatic() 247*d8b80295SApple OSS Distributions auto_idx = None 248*d8b80295SApple OSS Distributions 249*d8b80295SApple OSS Distributions obj = self.get_value(key, args, kwargs) 250*d8b80295SApple OSS Distributions if isinstance(obj, cvalue): 251*d8b80295SApple OSS Distributions obj = obj.GetSBValue() 252*d8b80295SApple OSS Distributions 253*d8b80295SApple OSS Distributions if name[0] == '&': 254*d8b80295SApple OSS Distributions if len(path): 255*d8b80295SApple OSS Distributions return obj.xGetLoadAddressByPath(path), auto_idx 256*d8b80295SApple OSS Distributions return obj.GetLoadAddress(), auto_idx 257*d8b80295SApple OSS Distributions 258*d8b80295SApple OSS Distributions if len(path): 259*d8b80295SApple OSS Distributions obj = obj.GetValueForExpressionPath(path) 260*d8b80295SApple OSS Distributions return obj, auto_idx 261*d8b80295SApple OSS Distributions 262*d8b80295SApple OSS Distributions def convert_field(self, obj, conv, transform='', args=None, kwargs=None): 263*d8b80295SApple OSS Distributions is_sbval = isinstance(obj, SBValue) 264*d8b80295SApple OSS Distributions 265*d8b80295SApple OSS Distributions if transform != '': 266*d8b80295SApple OSS Distributions fn, raw = self._CONVERTERS.get(transform, (None, False)) 267*d8b80295SApple OSS Distributions if not raw and is_sbval: 268*d8b80295SApple OSS Distributions obj = obj.xGetValueAsScalar() 269*d8b80295SApple OSS Distributions 270*d8b80295SApple OSS Distributions if fn: 271*d8b80295SApple OSS Distributions obj = fn(obj) 272*d8b80295SApple OSS Distributions else: 273*d8b80295SApple OSS Distributions objname, _, method = transform.partition('.') 274*d8b80295SApple OSS Distributions field, _ = self.get_field(objname, args, kwargs) 275*d8b80295SApple OSS Distributions obj = getattr(field, method)(obj) 276*d8b80295SApple OSS Distributions 277*d8b80295SApple OSS Distributions is_sbval = False 278*d8b80295SApple OSS Distributions 279*d8b80295SApple OSS Distributions if conv is None: 280*d8b80295SApple OSS Distributions return obj.xGetValueAsScalar() if is_sbval else obj 281*d8b80295SApple OSS Distributions 282*d8b80295SApple OSS Distributions return super(SBValueFormatter, self).convert_field(obj, conv) 283*d8b80295SApple OSS Distributions 284*d8b80295SApple OSS Distributions@SBValueFormatter.converter("c_str", raw=True) 285*d8b80295SApple OSS Distributionsdef __sbval_to_cstr(v): 286*d8b80295SApple OSS Distributions return v.xGetValueAsCString() if isinstance(v, SBValue) else str(v) 287*d8b80295SApple OSS Distributions 288*d8b80295SApple OSS Distributions@SBValueFormatter.converter("human_size") 289*d8b80295SApple OSS Distributionsdef __human_size(v): 290*d8b80295SApple OSS Distributions n = v.xGetValueAsCString() if isinstance(v, SBValue) else int(v) 291*d8b80295SApple OSS Distributions order = ((n//10) | 1).bit_length() // 10 292*d8b80295SApple OSS Distributions return "{:.1f}{}".format(n / (1024 ** order), "BKMGTPE"[order]) 293*d8b80295SApple OSS Distributions 294*d8b80295SApple OSS Distributions 295*d8b80295SApple OSS Distributions_xnu_core_default_formatter = SBValueFormatter() 296*d8b80295SApple OSS Distributions 297*d8b80295SApple OSS Distributionsdef xnu_format(fmt, *args, **kwargs): 298*d8b80295SApple OSS Distributions """ Conveniency function to call SBValueFormatter().format """ 299*d8b80295SApple OSS Distributions return _xnu_core_default_formatter.vformat(fmt, args, kwargs) 300*d8b80295SApple OSS Distributions 301*d8b80295SApple OSS Distributionsdef xnu_vformat(fmt, args, kwargs): 302*d8b80295SApple OSS Distributions """ Conveniency function to call SBValueFormatter().vformat """ 303*d8b80295SApple OSS Distributions return _xnu_core_default_formatter.vformat(fmt, args, kwargs) 304*d8b80295SApple OSS Distributions 305*d8b80295SApple OSS Distributions 306*d8b80295SApple OSS Distributionsclass CommandOutput(object): 307*d8b80295SApple OSS Distributions """ 308*d8b80295SApple OSS Distributions An output handler for all commands. Use Output.print to direct all output of macro via the handler. 309*d8b80295SApple OSS Distributions These arguments are passed after a "--". eg 310*d8b80295SApple OSS Distributions (lldb) zprint -- -o /tmp/zprint.out.txt 311*d8b80295SApple OSS Distributions 312*d8b80295SApple OSS Distributions Currently this provide capabilities 313*d8b80295SApple OSS Distributions -h show help 314*d8b80295SApple OSS Distributions -o path/to/filename 315*d8b80295SApple OSS Distributions The output of this command execution will be saved to file. Parser information or errors will 316*d8b80295SApple OSS Distributions not be sent to file though. eg /tmp/output.txt 317*d8b80295SApple OSS Distributions -s filter_string 318*d8b80295SApple OSS Distributions the "filter_string" param is parsed to python regex expression and each line of output 319*d8b80295SApple OSS Distributions will be printed/saved only if it matches the expression. 320*d8b80295SApple OSS Distributions The command header will not be filtered in any case. 321*d8b80295SApple OSS Distributions -p <plugin_name> 322*d8b80295SApple OSS Distributions Send the output of the command to plugin. 323*d8b80295SApple OSS Distributions -v ... 324*d8b80295SApple OSS Distributions Up verbosity 325*d8b80295SApple OSS Distributions -c <always|never|auto> 326*d8b80295SApple OSS Distributions configure color 327*d8b80295SApple OSS Distributions """ 328*d8b80295SApple OSS Distributions def __init__(self, cmd_name, CommandResult=None, fhandle=None): 329*d8b80295SApple OSS Distributions """ Create a new instance to handle command output. 330*d8b80295SApple OSS Distributions params: 331*d8b80295SApple OSS Distributions CommandResult : SBCommandReturnObject result param from lldb's command invocation. 332*d8b80295SApple OSS Distributions """ 333*d8b80295SApple OSS Distributions self.fname=None 334*d8b80295SApple OSS Distributions self.fhandle=fhandle 335*d8b80295SApple OSS Distributions self.FILTER=False 336*d8b80295SApple OSS Distributions self.pluginRequired = False 337*d8b80295SApple OSS Distributions self.pluginName = None 338*d8b80295SApple OSS Distributions self.cmd_name = cmd_name 339*d8b80295SApple OSS Distributions self.resultObj = CommandResult 340*d8b80295SApple OSS Distributions self.verbose_level = 0 341*d8b80295SApple OSS Distributions self.target_cmd_args = [] 342*d8b80295SApple OSS Distributions self.target_cmd_options = {} 343*d8b80295SApple OSS Distributions self._indent = '' 344*d8b80295SApple OSS Distributions self._buffer = '' 345*d8b80295SApple OSS Distributions 346*d8b80295SApple OSS Distributions self._header = None 347*d8b80295SApple OSS Distributions self._lastHeader = None 348*d8b80295SApple OSS Distributions self._line = 0 349*d8b80295SApple OSS Distributions 350*d8b80295SApple OSS Distributions self.color = None 351*d8b80295SApple OSS Distributions self.isatty = os.isatty(sys.__stdout__.fileno()) 352*d8b80295SApple OSS Distributions self.VT = VT if self._doColor() else NOVT() 353*d8b80295SApple OSS Distributions 354*d8b80295SApple OSS Distributions 355*d8b80295SApple OSS Distributions def _doColor(self): 356*d8b80295SApple OSS Distributions if self.color is True: 357*d8b80295SApple OSS Distributions return True; 358*d8b80295SApple OSS Distributions return self.color is None and self.isatty 359*d8b80295SApple OSS Distributions 360*d8b80295SApple OSS Distributions def _needsHeader(self): 361*d8b80295SApple OSS Distributions if self._header is None: 362*d8b80295SApple OSS Distributions return False 363*d8b80295SApple OSS Distributions if self._lastHeader is None: 364*d8b80295SApple OSS Distributions return True 365*d8b80295SApple OSS Distributions if not self.isatty: 366*d8b80295SApple OSS Distributions return False 367*d8b80295SApple OSS Distributions return self._line - self._lastHeader > 40 368*d8b80295SApple OSS Distributions 369*d8b80295SApple OSS Distributions def indent(self): 370*d8b80295SApple OSS Distributions return IndentScope(self) 371*d8b80295SApple OSS Distributions 372*d8b80295SApple OSS Distributions def table(self, header, indent = False): 373*d8b80295SApple OSS Distributions return HeaderScope(self, header, indent) 374*d8b80295SApple OSS Distributions 375*d8b80295SApple OSS Distributions def format(self, s, *args, **kwargs): 376*d8b80295SApple OSS Distributions kwargs['VT'] = self.VT 377*d8b80295SApple OSS Distributions return xnu_vformat(s, args, kwargs) 378*d8b80295SApple OSS Distributions 379*d8b80295SApple OSS Distributions def error(self, s, *args, **kwargs): 380*d8b80295SApple OSS Distributions print(self.format("{cmd.cmd_name}: {VT.Red}"+s+"{VT.Default}", cmd=self, *args, **kwargs)) 381*d8b80295SApple OSS Distributions 382*d8b80295SApple OSS Distributions def write(self, s): 383*d8b80295SApple OSS Distributions """ Handler for all commands output. By default just print to stdout """ 384*d8b80295SApple OSS Distributions 385*d8b80295SApple OSS Distributions o = self.fhandle or self.resultObj 386*d8b80295SApple OSS Distributions 387*d8b80295SApple OSS Distributions for l in (self._buffer + s).splitlines(True): 388*d8b80295SApple OSS Distributions if l[-1] != '\n': 389*d8b80295SApple OSS Distributions self._buffer = l 390*d8b80295SApple OSS Distributions return 391*d8b80295SApple OSS Distributions 392*d8b80295SApple OSS Distributions if self.FILTER: 393*d8b80295SApple OSS Distributions if not self.reg.search(l): 394*d8b80295SApple OSS Distributions continue 395*d8b80295SApple OSS Distributions l = self.reg.sub(self.VT.Underline + r"\g<0>" + self.VT.EndUnderline, l); 396*d8b80295SApple OSS Distributions 397*d8b80295SApple OSS Distributions if len(l) == 1: 398*d8b80295SApple OSS Distributions o.write(l) 399*d8b80295SApple OSS Distributions self._line += 1 400*d8b80295SApple OSS Distributions continue 401*d8b80295SApple OSS Distributions 402*d8b80295SApple OSS Distributions if len(l) > 1 and self._needsHeader(): 403*d8b80295SApple OSS Distributions for h in self._header.splitlines(): 404*d8b80295SApple OSS Distributions o.write(self.format("{}{VT.Bold}{:s}{VT.EndBold}\n", self._indent, h)) 405*d8b80295SApple OSS Distributions self._lastHeader = self._line 406*d8b80295SApple OSS Distributions 407*d8b80295SApple OSS Distributions o.write(self._indent + l) 408*d8b80295SApple OSS Distributions self._line += 1 409*d8b80295SApple OSS Distributions 410*d8b80295SApple OSS Distributions self._buffer = '' 411*d8b80295SApple OSS Distributions 412*d8b80295SApple OSS Distributions def flush(self): 413*d8b80295SApple OSS Distributions if self.fhandle != None: 414*d8b80295SApple OSS Distributions self.fhandle.flush() 415*d8b80295SApple OSS Distributions 416*d8b80295SApple OSS Distributions def __del__(self): 417*d8b80295SApple OSS Distributions """ closes any open files. report on any errors """ 418*d8b80295SApple OSS Distributions if self.fhandle != None and self.fname != None: 419*d8b80295SApple OSS Distributions self.fhandle.close() 420*d8b80295SApple OSS Distributions 421*d8b80295SApple OSS Distributions def setOptions(self, cmdargs, cmdoptions =''): 422*d8b80295SApple OSS Distributions """ parse the arguments passed to the command 423*d8b80295SApple OSS Distributions param : 424*d8b80295SApple OSS Distributions cmdargs => [] of <str> (typically args.split()) 425*d8b80295SApple OSS Distributions cmdoptions : str - string of command level options. 426*d8b80295SApple OSS Distributions These should be CAPITAL LETTER options only. 427*d8b80295SApple OSS Distributions """ 428*d8b80295SApple OSS Distributions opts=() 429*d8b80295SApple OSS Distributions args = cmdargs 430*d8b80295SApple OSS Distributions cmdoptions = cmdoptions.upper() 431*d8b80295SApple OSS Distributions try: 432*d8b80295SApple OSS Distributions opts,args = getopt.gnu_getopt(args,'hvo:s:p:c:'+ cmdoptions,[]) 433*d8b80295SApple OSS Distributions self.target_cmd_args = args 434*d8b80295SApple OSS Distributions except getopt.GetoptError as err: 435*d8b80295SApple OSS Distributions raise ArgumentError(str(err)) 436*d8b80295SApple OSS Distributions #continue with processing 437*d8b80295SApple OSS Distributions for o,a in opts : 438*d8b80295SApple OSS Distributions if o == "-h": 439*d8b80295SApple OSS Distributions # This is misuse of exception but 'self' has no info on doc string. 440*d8b80295SApple OSS Distributions # The caller may handle exception and display appropriate info 441*d8b80295SApple OSS Distributions raise ArgumentError("HELP") 442*d8b80295SApple OSS Distributions if o == "-o" and len(a) > 0: 443*d8b80295SApple OSS Distributions self.fname=os.path.normpath(os.path.expanduser(a.strip())) 444*d8b80295SApple OSS Distributions self.fhandle=open(self.fname,"w") 445*d8b80295SApple OSS Distributions print("saving results in file ",str(a)) 446*d8b80295SApple OSS Distributions self.fhandle.write("(lldb)%s %s \n" % (self.cmd_name, " ".join(cmdargs))) 447*d8b80295SApple OSS Distributions self.isatty = os.isatty(self.fhandle.fileno()) 448*d8b80295SApple OSS Distributions elif o == "-s" and len(a) > 0: 449*d8b80295SApple OSS Distributions self.reg = re.compile(a.strip(),re.MULTILINE|re.DOTALL) 450*d8b80295SApple OSS Distributions self.FILTER=True 451*d8b80295SApple OSS Distributions print("showing results for regex:",a.strip()) 452*d8b80295SApple OSS Distributions elif o == "-p" and len(a) > 0: 453*d8b80295SApple OSS Distributions self.pluginRequired = True 454*d8b80295SApple OSS Distributions self.pluginName = a.strip() 455*d8b80295SApple OSS Distributions #print "passing output to " + a.strip() 456*d8b80295SApple OSS Distributions elif o == "-v": 457*d8b80295SApple OSS Distributions self.verbose_level += 1 458*d8b80295SApple OSS Distributions elif o == "-c": 459*d8b80295SApple OSS Distributions if a in ["always", '1']: 460*d8b80295SApple OSS Distributions self.color = True 461*d8b80295SApple OSS Distributions elif a in ["never", '0']: 462*d8b80295SApple OSS Distributions self.color = False 463*d8b80295SApple OSS Distributions else: 464*d8b80295SApple OSS Distributions self.color = None 465*d8b80295SApple OSS Distributions self.VT = VT if self._doColor() else NOVT() 466*d8b80295SApple OSS Distributions else: 467*d8b80295SApple OSS Distributions o = o.strip() 468*d8b80295SApple OSS Distributions self.target_cmd_options[o] = a 469*d8b80295SApple OSS Distributions 470*d8b80295SApple OSS Distributions 471