From 7782bdde3062e15ccbdc5f617aa3a8f096b6751b Mon Sep 17 00:00:00 2001 From: Liu Liu Date: Fri, 11 Oct 2019 12:36:45 -0700 Subject: [PATCH] Make chisel compatible with Python 3 (#266) * Make chisel compatible with Python 3 Xcode 11 shipped with Python 3 now. Unfortunately, chisel was written in Python 2 style and will fail load for lldb. This PR fixed the Python 3 compatibility issues. * Addressed comment. Updated with file output. * Properly resolve the conflict. * Import from future on print. * Address @lsavino comment. --- commands/FBAccessibilityCommands.py | 8 ++--- commands/FBAutoLayoutCommands.py | 2 +- commands/FBClassDump.py | 20 ++++++------ commands/FBComponentCommands.py | 8 ++--- commands/FBDebugCommands.py | 47 ++++++++++++++------------- commands/FBFindCommands.py | 2 +- commands/FBFlickerCommands.py | 18 +++++------ commands/FBInvocationCommands.py | 20 ++++++------ commands/FBPrintCommands.py | 49 +++++++++++++++-------------- commands/FBVisualizationCommands.py | 20 ++++++------ commands/FBXCTestCommands.py | 14 ++++----- fblldb.py | 4 +-- fblldbbase.py | 10 +++--- 13 files changed, 113 insertions(+), 109 deletions(-) diff --git a/commands/FBAccessibilityCommands.py b/commands/FBAccessibilityCommands.py index e078666..f0f2760 100644 --- a/commands/FBAccessibilityCommands.py +++ b/commands/FBAccessibilityCommands.py @@ -126,7 +126,7 @@ def printAccessibilityHierarchy(view, indent = 0): #if we don't have any accessibility string - we should have some children if int(a11yLabel.GetValue(), 16) == 0: - print indentString + ('{} {}'.format(classDesc, view)) + print(indentString + ('{} {}'.format(classDesc, view))) #We call private method that gives back all visible accessibility children for view a11yElements = accessibilityElements(view) accessibilityElementsCount = int(fb.evaluateExpression('(int)[%s count]' % a11yElements)) @@ -134,7 +134,7 @@ def printAccessibilityHierarchy(view, indent = 0): subview = fb.evaluateObjectExpression('[%s objectAtIndex:%i]' % (a11yElements, index)) printAccessibilityHierarchy(subview, indent + 1) else: - print indentString + ('({} {}) {}'.format(classDesc, view, a11yLabel.GetObjectDescription())) + print(indentString + ('({} {}) {}'.format(classDesc, view, a11yLabel.GetObjectDescription()))) def printAccessibilityIdentifiersHierarchy(view, indent = 0): a11yIdentifier = accessibilityIdentifier(view) @@ -143,7 +143,7 @@ def printAccessibilityIdentifiersHierarchy(view, indent = 0): #if we don't have any accessibility identifier - we should have some children if int(a11yIdentifier.GetValue(), 16) == 0: - print indentString + ('{} {}'.format(classDesc, view)) + print(indentString + ('{} {}'.format(classDesc, view))) #We call private method that gives back all visible accessibility children for view a11yElements = accessibilityElements(view) accessibilityElementsCount = int(fb.evaluateExpression('(int)[%s count]' % a11yElements)) @@ -151,4 +151,4 @@ def printAccessibilityIdentifiersHierarchy(view, indent = 0): subview = fb.evaluateObjectExpression('[%s objectAtIndex:%i]' % (a11yElements, index)) printAccessibilityIdentifiersHierarchy(subview, indent + 1) else: - print indentString + ('({} {}) {}'.format(classDesc, view, a11yIdentifier.GetObjectDescription())) + print(indentString + ('({} {}) {}'.format(classDesc, view, a11yIdentifier.GetObjectDescription()))) diff --git a/commands/FBAutoLayoutCommands.py b/commands/FBAutoLayoutCommands.py index 89f1b9a..f7254a9 100644 --- a/commands/FBAutoLayoutCommands.py +++ b/commands/FBAutoLayoutCommands.py @@ -31,7 +31,7 @@ def run(self, arguments, options): view = fb.evaluateInputExpression(arguments[0]) opt = fb.evaluateBooleanExpression('[UIView instancesRespondToSelector:@selector(_autolayoutTraceRecursively:)]') traceCall = '_autolayoutTraceRecursively:1' if opt else '_autolayoutTrace' - print fb.describeObject('[{} {}]'.format(view, traceCall)) + print(fb.describeObject('[{} {}]'.format(view, traceCall))) def setBorderOnAmbiguousViewRecursive(view, width, color): diff --git a/commands/FBClassDump.py b/commands/FBClassDump.py index a066707..68639ad 100644 --- a/commands/FBClassDump.py +++ b/commands/FBClassDump.py @@ -39,17 +39,17 @@ def run(self, arguments, options): cls = getClassFromArgument(arguments[0], options.clsname) if options.clsmethod: - print 'Class Methods:' + print('Class Methods:') printClassMethods(cls, options.showaddr) if options.insmethod: - print '\nInstance Methods:' + print('\nInstance Methods:') printInstanceMethods(cls, options.showaddr) if not options.clsmethod and not options.insmethod: - print 'Class Methods:' + print('Class Methods:') printClassMethods(cls, options.showaddr) - print '\nInstance Methods:' + print('\nInstance Methods:') printInstanceMethods(cls, options.showaddr) @@ -147,7 +147,7 @@ def run(self, arguments, options): signature = json['signature'] if not signature: - print 'Imp: ' + hex(json['invoke']) + print('Imp: ' + hex(json['invoke'])) return sigStr = '{} ^('.format(decode(signature[0])) @@ -155,7 +155,7 @@ def run(self, arguments, options): sigStr += ', '.join([decode(m) for m in signature[2:]]) sigStr += ');' - print 'Imp: ' + hex(json['invoke']) + ' Signature: ' + sigStr + print('Imp: ' + hex(json['invoke']) + ' Signature: ' + sigStr) # helpers def isClassObject(arg): @@ -178,13 +178,13 @@ def getClassFromArgument(arg, is_classname): def printInstanceMethods(cls, showaddr=False, prefix='-'): methods = getMethods(cls) if not methods: - print "No methods were found" + print("No methods were found") for m in methods: if showaddr: - print prefix + ' ' + m.prettyPrintString() + ' ' + str(m.imp) + print(prefix + ' ' + m.prettyPrintString() + ' ' + str(m.imp)) else: - print prefix + ' ' + m.prettyPrintString() + print(prefix + ' ' + m.prettyPrintString()) def printClassMethods(cls, showaddr=False): printInstanceMethods(runtimeHelpers.object_getClass(cls), showaddr, '+') @@ -192,7 +192,7 @@ def printClassMethods(cls, showaddr=False): def printProperties(cls, showvalue=False): props = getProperties(cls) for p in props: - print p.prettyPrintString() + print(p.prettyPrintString()) def decode(code): encodeMap = { diff --git a/commands/FBComponentCommands.py b/commands/FBComponentCommands.py index 89eb1b7..dce4a10 100644 --- a/commands/FBComponentCommands.py +++ b/commands/FBComponentCommands.py @@ -35,12 +35,12 @@ def options(self): def run(self, arguments, options): if options.set: fb.evaluateEffect('[CKComponentDebugController setDebugMode:YES]') - print 'Debug mode for ComponentKit has been set.' + print('Debug mode for ComponentKit has been set.') elif options.unset: fb.evaluateEffect('[CKComponentDebugController setDebugMode:NO]') - print 'Debug mode for ComponentKit has been unset.' + print('Debug mode for ComponentKit has been unset.') else: - print 'No option for ComponentKit Debug mode specified.' + print('No option for ComponentKit Debug mode specified.') class FBComponentsPrintCommand(fb.FBCommand): def name(self): @@ -67,7 +67,7 @@ def run(self, arguments, options): # assume it's a CKComponent view = fb.evaluateExpression('((CKComponent *)%s).viewContext.view' % view) - print fb.describeObject('[CKComponentHierarchyDebugHelper componentHierarchyDescriptionForView:(UIView *)' + view + ' searchUpwards:' + upwards + ' showViews:' + showViews + ']') + print(fb.describeObject('[CKComponentHierarchyDebugHelper componentHierarchyDescriptionForView:(UIView *)' + view + ' searchUpwards:' + upwards + ' showViews:' + showViews + ']')) class FBComponentsReflowCommand(fb.FBCommand): def name(self): diff --git a/commands/FBDebugCommands.py b/commands/FBDebugCommands.py index a1a6e48..290f328 100644 --- a/commands/FBDebugCommands.py +++ b/commands/FBDebugCommands.py @@ -5,6 +5,9 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. +# Can be removed when Python 2 support is removed. +from __future__ import print_function + import lldb import fblldbbase as fb import fblldbobjcruntimehelpers as objc @@ -58,9 +61,9 @@ def run(self, arguments, options): watchpoint = lldb.debugger.GetSelectedTarget().WatchAddress(objectAddress + ivarOffset, ivarSize, False, True, error) if error.Success(): - print 'Remember to delete the watchpoint using: watchpoint delete {}'.format(watchpoint.GetID()) + print('Remember to delete the watchpoint using: watchpoint delete {}'.format(watchpoint.GetID())) else: - print 'Could not create the watchpoint: {}'.format(error.GetCString()) + print('Could not create the watchpoint: {}'.format(error.GetCString())) class FBFrameworkAddressBreakpointCommand(fb.FBCommand): def name(self): @@ -108,12 +111,12 @@ def run(self, arguments, options): match = methodPattern.match(expression) if not match: - print 'Failed to parse expression. Do you even Objective-C?!' + print('Failed to parse expression. Do you even Objective-C?!') return expressionForSelf = objc.functionPreambleExpressionForSelf() if not expressionForSelf: - print 'Your architecture, {}, is truly fantastic. However, I don\'t currently support it.'.format(arch) + print('Your architecture, {}, is truly fantastic. However, I don\'t currently support it.'.format(arch)) return methodTypeCharacter = match.group('scope') @@ -139,7 +142,7 @@ def run(self, arguments, options): targetClass = fb.evaluateObjectExpression('[{} class]'.format(targetObject), False) if not targetClass or int(targetClass, 0) == 0: - print 'Couldn\'t find a class from the expression "{}". Did you typo?'.format(classNameOrExpression) + print('Couldn\'t find a class from the expression "{}". Did you typo?'.format(classNameOrExpression)) return if methodIsClassMethod: @@ -155,7 +158,7 @@ def run(self, arguments, options): nextClass = objc.class_getSuperclass(nextClass) if not found: - print 'There doesn\'t seem to be an implementation of {} in the class hierarchy. Made a boo boo with the selector name?'.format(selector) + print('There doesn\'t seem to be an implementation of {} in the class hierarchy. Made a boo boo with the selector name?'.format(selector)) return breakpointClassName = objc.class_getName(nextClass) @@ -167,7 +170,7 @@ def run(self, arguments, options): else: breakpointCondition = '(void*){} == {}'.format(expressionForSelf, targetObject) - print 'Setting a breakpoint at {} with condition {}'.format(breakpointFullName, breakpointCondition) + print('Setting a breakpoint at {} with condition {}'.format(breakpointFullName, breakpointCondition)) if category: lldb.debugger.HandleCommand('breakpoint set --skip-prologue false --fullname "{}" --condition "{}"'.format(breakpointFullName, breakpointCondition)) @@ -205,11 +208,11 @@ def switchBreakpointState(expression,on): target = lldb.debugger.GetSelectedTarget() for breakpoint in target.breakpoint_iter(): if breakpoint.IsEnabled() != on and (expression_pattern.search(str(breakpoint))): - print str(breakpoint) + print(str(breakpoint)) breakpoint.SetEnabled(on) for location in breakpoint: if location.IsEnabled() != on and (expression_pattern.search(str(location)) or expression == hex(location.GetAddress()) ): - print str(location) + print(str(location)) location.SetEnabled(on) class FBMethodBreakpointEnableCommand(fb.FBCommand): @@ -330,7 +333,7 @@ def run(self, arguments, options): return if len(arguments) == 0 or not arguments[0].strip(): - print 'Usage: findinstances []; Run `help findinstances`' + print('Usage: findinstances []; Run `help findinstances`') return query = arguments[0] @@ -348,7 +351,7 @@ def loadChiselIfNecessary(self): path = self.chiselLibraryPath() if not os.path.exists(path): - print 'Chisel library missing: ' + path + print('Chisel library missing: ' + path) return False module = fb.evaluateExpressionValue('(void*)dlopen("{}", 2)'.format(path)) @@ -361,17 +364,17 @@ def loadChiselIfNecessary(self): error = fb.evaluateExpressionValue('(char*)dlerror()') if errno == 50: # KERN_CODESIGN_ERROR from - print 'Error loading Chisel: Code signing failure; Must re-run codesign' + print('Error loading Chisel: Code signing failure; Must re-run codesign') elif error.unsigned != 0: - print 'Error loading Chisel: ' + error.summary + print('Error loading Chisel: ' + error.summary) elif errno != 0: error = fb.evaluateExpressionValue('(char*)strerror({})'.format(errno)) if error.unsigned != 0: - print 'Error loading Chisel: ' + error.summary + print('Error loading Chisel: ' + error.summary) else: - print 'Error loading Chisel (errno {})'.format(errno) + print('Error loading Chisel (errno {})'.format(errno)) else: - print 'Unknown error loading Chisel' + print('Unknown error loading Chisel') return False @@ -428,9 +431,9 @@ def isHeap(addr): allocations = (addr for addr in pointers if isHeap(addr)) for addr in allocations: - print >>self.result, '0x{addr:x} {path}'.format(addr=addr, path=pointers[addr]) + print('0x{addr:x} {path}'.format(addr=addr, path=pointers[addr]), file=self.result) if not allocations: - print >>self.result, "No heap addresses found" + print("No heap addresses found", file=self.result) class FBSequenceCommand(fb.FBCommand): @@ -453,17 +456,17 @@ def run(self, arguments, options): # Complete one command before running the next one in the sequence. Disable # async to do this. Also, save the current async value to restore it later. - async = lldb.debugger.GetAsync() + asyncFlag = lldb.debugger.GetAsync() lldb.debugger.SetAsync(False) for command in commands[:-1]: success = self.run_command(interpreter, command) if not success: - lldb.debugger.SetAsync(async) + lldb.debugger.SetAsync(asyncFlag) return # Restore original async value. - lldb.debugger.SetAsync(async) + lldb.debugger.SetAsync(asyncFlag) # If the last command is `continue`, call Continue() on the process # instead. This is done because HandleCommand('continue') has strange @@ -478,7 +481,7 @@ def run_command(self, interpreter, command): ret = lldb.SBCommandReturnObject() interpreter.HandleCommand(command, ret) if ret.GetOutput(): - print >>self.result, ret.GetOutput().strip() + print(ret.GetOutput().strip(), file=self.result) if ret.Succeeded(): return True diff --git a/commands/FBFindCommands.py b/commands/FBFindCommands.py index 9c4d9a7..0467157 100644 --- a/commands/FBFindCommands.py +++ b/commands/FBFindCommands.py @@ -120,6 +120,6 @@ def run(self, arguments, options): @staticmethod def taplog_callback(frame, bp_loc, internal_dict): parameterExpr = objc.functionPreambleExpressionForObjectParameterAtIndex(0) - print fb.describeObject('[[[%s allTouches] anyObject] view]' % (parameterExpr)) + print(fb.describeObject('[[[%s allTouches] anyObject] view]' % (parameterExpr))) # We don't want to proceed event (click on button for example), so we just skip it lldb.debugger.HandleCommand('thread return') diff --git a/commands/FBFlickerCommands.py b/commands/FBFlickerCommands.py index c275f36..77e53b6 100644 --- a/commands/FBFlickerCommands.py +++ b/commands/FBFlickerCommands.py @@ -51,7 +51,7 @@ def args(self): return [ fb.FBCommandArgument(arg='view', type='UIView*', help='The view to border.') ] def run(self, arguments, options): - print '\nUse the following and (q) to quit.\n(w) move to superview\n(s) move to first subview\n(a) move to previous sibling\n(d) move to next sibling\n(p) print the hierarchy\n' + print('\nUse the following and (q) to quit.\n(w) move to superview\n(s) move to first subview\n(a) move to previous sibling\n(d) move to next sibling\n(p) print the hierarchy\n') object = fb.evaluateInputExpression(arguments[0]) walker = FlickerWalker(object) @@ -78,29 +78,29 @@ def inputCallback(self, input): cmd = 'echo %s | tr -d "\n" | pbcopy' % oldView os.system(cmd) - print '\nI hope ' + oldView + ' was what you were looking for. I put it on your clipboard.' + print('\nI hope ' + oldView + ' was what you were looking for. I put it on your clipboard.') viewHelpers.unmaskView(oldView) self.keepRunning = False elif input == 'w': v = superviewOfView(self.currentView) if not v: - print 'There is no superview. Where are you trying to go?!' + print('There is no superview. Where are you trying to go?!') self.setCurrentView(v, oldView) elif input == 's': v = firstSubviewOfView(self.currentView) if not v: - print '\nThe view has no subviews.\n' + print('\nThe view has no subviews.\n') self.setCurrentView(v, oldView) elif input == 'd': v = nthSiblingOfView(self.currentView, -1) if v == oldView: - print '\nThere are no sibling views to this view.\n' + print('\nThere are no sibling views to this view.\n') self.setCurrentView(v, oldView) elif input == 'a': v = nthSiblingOfView(self.currentView, 1) if v == oldView: - print '\nThere are no sibling views to this view.\n' + print('\nThere are no sibling views to this view.\n') self.setCurrentView(v, oldView) elif input == 'p': recursionName = 'recursiveDescription' @@ -109,9 +109,9 @@ def inputCallback(self, input): if isMac: recursionName = '_subtreeDescription' - print fb.describeObject('[(id){} {}]'.format(oldView, recursionName)) + print(fb.describeObject('[(id){} {}]'.format(oldView, recursionName))) else: - print '\nI really have no idea what you meant by \'' + input + '\'... =\\\n' + print('\nI really have no idea what you meant by \'' + input + '\'... =\\\n') def setCurrentView(self, view, oldView=None): if view: @@ -119,7 +119,7 @@ def setCurrentView(self, view, oldView=None): if oldView: viewHelpers.unmaskView(oldView) viewHelpers.maskView(self.currentView, 'red', '0.4') - print fb.describeObject(view) + print(fb.describeObject(view)) def superviewOfView(view): superview = fb.evaluateObjectExpression('[' + view + ' superview]') diff --git a/commands/FBInvocationCommands.py b/commands/FBInvocationCommands.py index 21d0177..b31d699 100644 --- a/commands/FBInvocationCommands.py +++ b/commands/FBInvocationCommands.py @@ -31,7 +31,7 @@ def run(self, arguments, options): target = lldb.debugger.GetSelectedTarget() if not re.match(r'.*i386.*', target.GetTriple()): - print 'Only x86 is currently supported (32-bit iOS Simulator or Mac OS X).' + print('Only x86 is currently supported (32-bit iOS Simulator or Mac OS X).') return thread = target.GetProcess().GetSelectedThread() @@ -39,13 +39,13 @@ def run(self, arguments, options): if options.all: for frame in thread: printInvocationForFrame(frame) - print '---------------------------------' + print('---------------------------------') else: frame = thread.GetSelectedFrame() printInvocationForFrame(frame) def printInvocationForFrame(frame): - print frame + print(frame) symbolName = frame.GetSymbol().GetName() if not re.match(r'[-+]\s*\[.*\]', symbolName): @@ -58,7 +58,7 @@ def printInvocationForFrame(frame): signatureValue = fb.evaluateExpressionValue('(id)' + commandForSignature) if signatureValue.GetError() is not None and str(signatureValue.GetError()) != 'success': - print "My sincerest apologies. I couldn't find a method signature for the selector." + print("My sincerest apologies. I couldn't find a method signature for the selector.") return signature = signatureValue.GetValue() @@ -70,7 +70,7 @@ def printInvocationForFrame(frame): if invocation: prettyPrintInvocation(frame, invocation) else: - print frame + print(frame) def stackStartAddressInSelectedFrame(frame): # Determine if the %ebp register has already had the stack register pushed into it (always the first instruction) @@ -102,11 +102,11 @@ def prettyPrintInvocation(frame, invocation): description = fb.evaluateExpressionValue('(id)' + invocation).GetObjectDescription() argDescriptions = description.splitlines(True)[4:] - print 'NSInvocation: ' + invocation - print 'self: ' + fb.evaluateExpression('(id)' + object) + print('NSInvocation: ' + invocation) + print('self: ' + fb.evaluateExpression('(id)' + object)) if len(argDescriptions) > 0: - print '\n' + str(len(argDescriptions)) + ' Arguments:' if len(argDescriptions) > 1 else '\nArgument:' + print('\n' + str(len(argDescriptions)) + ' Arguments:' if len(argDescriptions) > 1 else '\nArgument:') index = 2 for argDescription in argDescriptions: @@ -120,11 +120,11 @@ def prettyPrintInvocation(frame, invocation): readableString = argumentAsString(frame, address, encoding) if readableString: - print readableString + print(readableString) else: if encoding[0] == '{': encoding = encoding[1:] - print (hex(address) + ', address of ' + encoding + ' ' + description).strip() + print((hex(address) + ', address of ' + encoding + ' ' + description).strip()) index += 1 diff --git a/commands/FBPrintCommands.py b/commands/FBPrintCommands.py index 7630dce..3849672 100755 --- a/commands/FBPrintCommands.py +++ b/commands/FBPrintCommands.py @@ -77,9 +77,9 @@ def run(self, arguments, options): view = arguments[0] description = viewHelpers.upwardsRecursiveDescription(view, maxDepth) if description: - print description + print(description) else: - print 'Failed to walk view hierarchy. Make sure you pass a view, not any other kind of object or expression.' + print('Failed to walk view hierarchy. Make sure you pass a view, not any other kind of object or expression.') else: printingMethod = 'recursiveDescription' if isMac: @@ -99,7 +99,8 @@ def run(self, arguments, options): toRemove = ";.*(?:\n|$)" description = re.sub(toRemove, r'>\n', description) - print description + print(description) + class FBPrintViewControllerHierarchyCommand(fb.FBCommand): def name(self): @@ -116,14 +117,14 @@ def run(self, arguments, options): if arguments[0] == '__keyWindow_rootVC_dynamic__': if fb.evaluateBooleanExpression('[UIViewController respondsToSelector:@selector(_printHierarchy)]'): - print fb.describeObject('[UIViewController _printHierarchy]') + print(fb.describeObject('[UIViewController _printHierarchy]')) return arguments[0] = '(id)[(id)[[UIApplication sharedApplication] keyWindow] rootViewController]' if isMac: arguments[0] = '(id)[[[[NSApplication sharedApplication] windows] objectAtIndex:0] contentViewController]' - print vcHelpers.viewControllerRecursiveDescription(arguments[0]) + print(vcHelpers.viewControllerRecursiveDescription(arguments[0])) class FBPrintIsExecutingInAnimationBlockCommand(fb.FBCommand): @@ -140,7 +141,7 @@ def run(self, arguments, options): def _printIterative(initialValue, generator): indent = 0 for currentValue in generator(initialValue): - print ' | ' * indent + currentValue + print(' | ' * indent + currentValue) indent += 1 @@ -184,7 +185,7 @@ def run(self, arguments, options): responderClass = 'NSResponder' if not fb.evaluateBooleanExpression('(BOOL)[(id)' + startResponder + ' isKindOfClass:[' + responderClass + ' class]]'): - print 'Whoa, ' + startResponder + ' is not a ' + responderClass + '. =(' + print('Whoa, ' + startResponder + ' is not a ' + responderClass + '. =(') return _printIterative(startResponder, _responderChain) @@ -235,11 +236,11 @@ def run(self, arguments, options): tableView = tableViewInHierarchy() if tableView: viewValue = fb.evaluateExpressionValue(tableView) - print viewValue.GetObjectDescription() + print(viewValue.GetObjectDescription()) cmd = 'echo %s | tr -d "\n" | pbcopy' % tableView os.system(cmd) else: - print 'Sorry, chump. I couldn\'t find a table-view. :\'(' + print('Sorry, chump. I couldn\'t find a table-view. :\'(') class FBPrintOnscreenTableViewCells(fb.FBCommand): def name(self): @@ -250,7 +251,7 @@ def description(self): def run(self, arguments, options): tableView = tableViewInHierarchy() - print fb.evaluateExpressionValue('(id)[(id)' + tableView + ' visibleCells]').GetObjectDescription() + print(fb.evaluateExpressionValue('(id)[(id)' + tableView + ' visibleCells]').GetObjectDescription()) class FBPrintInternals(fb.FBCommand): @@ -274,7 +275,7 @@ def run(self, arguments, options): if fb.evaluateBooleanExpression('[{} respondsToSelector:@selector(_ivarDescription)]'.format(object)): command = 'po [{} _ivarDescription]'.format(object) else: - print 'Sorry, but it seems Apple dumped the _ivarDescription method' + print('Sorry, but it seems Apple dumped the _ivarDescription method') return else: objectClass = fb.evaluateExpressionValue('(id)[(id)(' + object + ') class]').GetObjectDescription() @@ -305,7 +306,7 @@ def run(self, arguments, options): ivarTypeEncodingFirstChar = fb.evaluateExpression(ivarTypeCommand) result = fb.evaluateExpressionValue('(({} *)({}))->{}'.format(objectClass, object, ivarName)) - print result.GetObjectDescription() if '@' in ivarTypeEncodingFirstChar else result + print(result.GetObjectDescription() if '@' in ivarTypeEncodingFirstChar else result) class FBPrintKeyPath(fb.FBCommand): def name(self): @@ -326,7 +327,7 @@ def run(self, arguments, options): else: objectToMessage, keypath = command.split('.', 1) object = fb.evaluateObjectExpression(objectToMessage) - print fb.describeObject('[{} valueForKeyPath:@"{}"]'.format(object, keypath)) + print(fb.describeObject('[{} valueForKeyPath:@"{}"]'.format(object, keypath))) class FBPrintApplicationDocumentsPath(fb.FBCommand): @@ -349,7 +350,7 @@ def run(self, arguments, options): pathString = '{}'.format(path).split('"')[1] cmd = 'echo {} | tr -d "\n" | pbcopy'.format(pathString) os.system(cmd) - print pathString + print(pathString) if options.open: os.system('open '+ pathString) @@ -371,7 +372,7 @@ def run(self, arguments, options): pathString = '{}'.format(path).split('"')[1] cmd = 'echo {} | tr -d "\n" | pbcopy'.format(pathString) os.system(cmd) - print pathString + print(pathString) if options.open: os.system('open '+ pathString) @@ -444,7 +445,7 @@ def run(self, arguments, option): elif encoding_text == 'utf32l': enc = 0x9c000100 - print fb.describeObject('[[NSString alloc] initWithData:{} encoding:{}]'.format(arguments[0], enc)) + print(fb.describeObject('[[NSString alloc] initWithData:{} encoding:{}]'.format(arguments[0], enc))) class FBPrintTargetActions(fb.FBCommand): @@ -469,7 +470,7 @@ def run(self, arguments, options): targetDescription = fb.evaluateExpressionValue('(id){target}'.format(target=target)).GetObjectDescription() actionsDescription = fb.evaluateExpressionValue('(id)[{actions} componentsJoinedByString:@", "]'.format(actions=actions)).GetObjectDescription() - print '{target}: {actions}'.format(target=targetDescription, actions=actionsDescription) + print('{target}: {actions}'.format(target=targetDescription, actions=actionsDescription)) class FBPrintJSON(fb.FBCommand): @@ -493,7 +494,7 @@ def run(self, arguments, options): jsonData = fb.evaluateObjectExpression('[NSJSONSerialization dataWithJSONObject:(id){} options:{} error:nil]'.format(objectToPrint, pretty)) jsonString = fb.evaluateExpressionValue('(NSString*)[[NSString alloc] initWithData:(id){} encoding:4]'.format(jsonData)).GetObjectDescription() - print jsonString + print(jsonString) class FBPrintSwiftJSON(fb.FBCommand): @@ -516,7 +517,7 @@ def run(self, arguments, options): jsonData = fb.evaluateObjectExpression('[NSJSONSerialization dataWithJSONObject:(NSObject*){} options:{} error:nil]'.format(objectToPrint, pretty)) jsonString = fb.evaluateExpressionValue('(NSString*)[[NSString alloc] initWithData:(NSObject*){} encoding:4]'.format(jsonData)).GetObjectDescription() - print jsonString + print(jsonString) class FBPrintAsCurl(fb.FBCommand): def name(self): @@ -560,15 +561,15 @@ def run(self, arguments, options): if fb.evaluateIntegerExpression('[{} respondsToSelector:@selector(base64EncodedStringWithOptions:)]'.format(HTTPData)): dataAsString = fb.evaluateExpressionValue('(id)[(id){} base64EncodedStringWithOptions:0]'.format(HTTPData)).GetObjectDescription() else : - print 'This version of OS doesn\'t supports base64 data encoding' + print('This version of OS doesn\'t supports base64 data encoding') return False elif not runtimeHelpers.isIOSDevice(): dataFile = self.generateTmpFilePath() if not fb.evaluateBooleanExpression('(BOOL)[{} writeToFile:@"{}" atomically:NO]'.format(HTTPData, dataFile)): - print 'Can\'t write data to file {}'.format(dataFile) + print('Can\'t write data to file {}'.format(dataFile)) return False else: - print 'HTTPBody data for iOS Device is supported only with "--embed-data" flag' + print('HTTPBody data for iOS Device is supported only with "--embed-data" flag') return False commandString = '' @@ -582,7 +583,7 @@ def run(self, arguments, options): commandString += ' --data-binary @"{}"'.format(dataFile) commandString += ' "{}"'.format(URL) - print commandString + print(commandString) class FBPrintToClipboard(fb.FBCommand): def name(self): @@ -599,7 +600,7 @@ def run(self, arguments, options): process = subprocess.Popen( 'pbcopy', env={'LANG': 'en_US.UTF-8'}, stdin=subprocess.PIPE) process.communicate(lldbOutput.encode('utf-8')) - print "Object copied to clipboard" + print("Object copied to clipboard") class FBPrintObjectInObjc(fb.FBCommand): def name(self): diff --git a/commands/FBVisualizationCommands.py b/commands/FBVisualizationCommands.py index 35fed39..0621760 100755 --- a/commands/FBVisualizationCommands.py +++ b/commands/FBVisualizationCommands.py @@ -41,7 +41,7 @@ def _showImage(commandForImage): length = int(imageBytesLength) if not (address or length): - print 'Could not get image data.' + print('Could not get image data.') return process = lldb.debugger.GetSelectedTarget().GetProcess() @@ -49,7 +49,7 @@ def _showImage(commandForImage): mem = process.ReadMemory(address, length, error) if error is not None and str(error) != 'success': - print error + print(error) else: imgFile = open(imagePath, 'wb') imgFile.write(mem) @@ -62,7 +62,7 @@ def _colorIsCGColorRef(color): result = fb.evaluateExpressionValue('(unsigned long)CFGetTypeID({color}) == (unsigned long)CGColorGetTypeID()'.format(color=color)) if result.GetError() is not None and str(result.GetError()) != 'success': - print "got error: {}".format(result) + print("got error: {}".format(result)) return False else: isCFColor = result.GetValueAsUnsigned() != 0 @@ -87,8 +87,8 @@ def _showColor(color): result = fb.evaluateExpressionValue('(UIImage *)UIGraphicsGetImageFromCurrentImageContext()') if result.GetError() is not None and str(result.GetError()) != 'success': - print "got error {}".format(result) - print result.GetError() + print("got error {}".format(result)) + print(result.GetError()) else: image = result.GetValue() _showImage(image) @@ -102,7 +102,7 @@ def _showLayer(layer): width = float(fb.evaluateExpression('(CGFloat)(' + size + '.width)')) height = float(fb.evaluateExpression('(CGFloat)(' + size + '.height)')) if width == 0.0 or height == 0.0: - print 'Nothing to see here - the size of this element is {} x {}.'.format(width, height) + print('Nothing to see here - the size of this element is {} x {}.'.format(width, height)) return fb.evaluateEffect('UIGraphicsBeginImageContextWithOptions(' + size + ', NO, 0.0)') @@ -110,7 +110,7 @@ def _showLayer(layer): result = fb.evaluateExpressionValue('(UIImage *)UIGraphicsGetImageFromCurrentImageContext()') if result.GetError() is not None and str(result.GetError()) != 'success': - print result.GetError() + print(result.GetError()) else: image = result.GetValue() _showImage(image) @@ -157,11 +157,11 @@ def _visualize(target): if _dataIsImage(target): _showImage('(id)[UIImage imageWithData:' + target + ']') elif _dataIsString(target): - print fb.describeObject('[[NSString alloc] initWithData:' + target + ' encoding:4]') + print(fb.describeObject('[[NSString alloc] initWithData:' + target + ' encoding:4]')) else: - print 'Data isn\'t an image and isn\'t a string.' + print('Data isn\'t an image and isn\'t a string.') else: - print '{} isn\'t supported. You can visualize UIImage, CGImageRef, UIView, CALayer, NSData, UIColor, CIColor, or CGColorRef.'.format(objectHelpers.className(target)) + print('{} isn\'t supported. You can visualize UIImage, CGImageRef, UIView, CALayer, NSData, UIColor, CIColor, or CGColorRef.'.format(objectHelpers.className(target))) class FBVisualizeCommand(fb.FBCommand): def name(self): diff --git a/commands/FBXCTestCommands.py b/commands/FBXCTestCommands.py index 281fc83..966ca31 100644 --- a/commands/FBXCTestCommands.py +++ b/commands/FBXCTestCommands.py @@ -39,13 +39,13 @@ def run(self, arguments, options): element = 'XCUIApplication()' if language == lldb.eLanguageTypeSwift else '(XCUIApplication *)[[XCUIApplication alloc] init]' if language == lldb.eLanguageTypeSwift: - print fb.evaluateExpressionValue("{}.debugDescription".format(element), language=language) \ + print(fb.evaluateExpressionValue("{}.debugDescription".format(element), language=language) \ .GetObjectDescription() \ .replace("\\n", "\n") \ .replace("\\'", "'") \ - .strip(' "\n\t') + .strip(' "\n\t')) else: - print fb.evaluateExpressionValue("[{} debugDescription]".format(element)).GetObjectDescription() + print(fb.evaluateExpressionValue("[{} debugDescription]".format(element)).GetObjectDescription()) class FBXCPrintTree(fb.FBCommand): @@ -83,7 +83,7 @@ def run(self, arguments, options): # Print tree for snapshot element snapshot_object = XCElementSnapshot(snapshot, language=language) - print snapshot_object.tree().hierarchy_text(pointer=options.pointer, trait=options.trait, frame=options.frame) + print(snapshot_object.tree().hierarchy_text(pointer=options.pointer, trait=options.trait, frame=options.frame)) class FBXCPrintObject(fb.FBCommand): @@ -114,7 +114,7 @@ def run(self, arguments, options): # Print details of snapshot element snapshot_object = XCElementSnapshot(snapshot, language=language) - print snapshot_object.detail_summary() + print(snapshot_object.detail_summary()) class FBXCNoId(fb.FBCommand): @@ -155,9 +155,9 @@ def run(self, arguments, options): snapshot_object = XCElementSnapshot(snapshot, language=language) elements = snapshot_object.find_missing_identifiers(status_bar=options.status_bar) if elements is not None: - print elements.hierarchy_text(pointer=options.pointer, trait=options.trait, frame=options.frame) + print(elements.hierarchy_text(pointer=options.pointer, trait=options.trait, frame=options.frame)) else: - print "Couldn't found elements without identifier" + print("Couldn't found elements without identifier") def take_snapshot(element): diff --git a/fblldb.py b/fblldb.py index d59fe2d..7539af5 100755 --- a/fblldb.py +++ b/fblldb.py @@ -94,8 +94,8 @@ def validateArgsForCommand(args, command): for defaultArg in defaultArgsToAppend: if not defaultArg: arg = command.args()[index] - print 'Whoops! You are missing the <' + arg.argName + '> argument.' - print '\nUsage: ' + usageForCommand(command) + print('Whoops! You are missing the <' + arg.argName + '> argument.') + print('\nUsage: ' + usageForCommand(command)) return index += 1 diff --git a/fblldbbase.py b/fblldbbase.py index 04ef37e..4839e27 100755 --- a/fblldbbase.py +++ b/fblldbbase.py @@ -82,7 +82,7 @@ def evaluateExpressionValue(expression, printErrors=True, language=lldb.eLanguag error = value.GetError() if printErrors and not isSuccess(error): - print error + print(error) return value @@ -98,7 +98,7 @@ def evaluateInputExpression(expression, printErrors=True): error = value.GetError() if printErrors and error.Fail(): - print error + print(error) return value.GetValue() @@ -135,7 +135,7 @@ def evaluateCStringExpression(expression, printErrors=True): return ret else: if printErrors: - print error + print(error) return None @@ -172,14 +172,14 @@ def evaluate(expr): command = "({" + RETURN_MACRO + '\n' + expr + "})" ret = evaluateExpressionValue(command, printErrors=True) if not ret.GetError().Success(): - print ret.GetError() + print(ret.GetError()) return None else: process = lldb.debugger.GetSelectedTarget().GetProcess() error = lldb.SBError() ret = process.ReadCStringFromMemory(int(ret.GetValue(), 16), 2**20, error) if not error.Success(): - print error + print(error) return None else: ret = json.loads(ret)