def addNodeRecursive(self, node, prefix=None): nodeName = node.__class__.__name__ if prefix is not None: nodeName = prefix + nodeName treeNode = QTreeWidgetItem([nodeName, self.__getNodePosition(node)]) if self.__parentStack[-1] is None: self.addTopLevelItem(treeNode) else: self.__parentStack[-1].addChild(treeNode) for fieldName in node._fields: fieldValue = getattr(node, fieldName) if isinstance(fieldValue, ast.AST): if fieldValue._fields: self.__parentStack.append(treeNode) self.addNodeRecursive(fieldValue, fieldName + ': ') self.__parentStack.pop(-1) else: treeNode.addChild( QTreeWidgetItem( [fieldName + ': ' + fieldValue.__class__.__name__, self.__getNodePosition(fieldValue)])) elif self.__isScalar(fieldValue): treeNode.addChild( QTreeWidgetItem([fieldName + ': ' + repr(fieldValue), ''])) elif isinstance(fieldValue, list): listLength = len(fieldValue) txt = str(listLength) + ' item' if listLength != 1: txt += 's' listNode = QTreeWidgetItem([fieldName + ': [...]', txt]) treeNode.addChild(listNode) self.expandItem(listNode) self.__parentStack.append(listNode) for index, listItem in enumerate(fieldValue): prefix = '[' + str(index) + ']: ' if self.__isScalar(listItem): treeNode.addChild( QTreeWidgetItem([prefix + repr(listItem), ''])) else: self.addNodeRecursive(listItem, prefix) self.__parentStack.pop(-1) else: logging.error('AST node is not recognized. Skipping...') self.expandItem(treeNode)
def __populate(self, disassembly): """Populates disassembly""" currentTopLevel = None emptyCount = 0 for line in disassembly.splitlines(): if line.lower().startswith('disassembly of'): line = line.strip() emptyCount = 0 # Two options: # Disassembly of <code object optToString at 0x7f63b7bf9920, file "...", line 45>: # Disassembly of optToString: if line.endswith(':'): line = line[:-1] if '<' in line and '>' in line: # First option begin = line.find('code object ') + len('code object ') end = line.find(' at 0x') name = line[begin:end] begin = line.find(', line ') + len(', line ') lineNo = line[begin:-1] currentTopLevel = QTreeWidgetItem( [name + ' (' + lineNo + ')']) else: # Second option currentTopLevel = QTreeWidgetItem([line.split()[-1]]) self.__table.addTopLevelItem(currentTopLevel) continue if currentTopLevel is None: continue if not line.strip(): emptyCount += 1 continue # Here: not an empty line and there is a parent # so parse and add as a child while emptyCount > 0: currentTopLevel.addChild(QTreeWidgetItem([])) emptyCount -= 1 # Line numbers may occupy more than 3 positions so the first # part is taken with a good margin parts = line.split() if '>>' in parts: jump = '>>' parts.remove('>>') else: jump = '' if '-->' in parts: parts.remove('-->') if parts[0].isdigit() and parts[1].isdigit(): # Line number and address lineNo = parts.pop(0) else: # Only adderess lineNo = '' address = parts.pop(0) instruction = parts.pop(0) if parts: argument = parts.pop(0) else: argument = '' if parts: interpretation = ' '.join(parts) else: interpretation = '' currentTopLevel.addChild( QTreeWidgetItem([ lineNo, jump, address, instruction, argument, interpretation ])) self.__table.expandItem(currentTopLevel)