def _pretty_variable(var): """Return a pretty printed string for a Variable.""" lines = [] single_value = len(var.bindings) == 1 var_desc = "v%d" % var.id if not single_value: # Write a description of the variable (for single value variables this # will be written along with the value later on). lines.append(var_desc) var_prefix = " " else: var_prefix = var_desc + " = " for value in var.bindings: data = utils.maybe_truncate(value.data) binding = "%s %s" % (var_prefix, data) if len(value.origins) == 1: # Single origin. Use the binding as a prefix when writing the orign. prefix = binding + ", " else: # Multiple origins, write the binding on its own line, then indent all # of the origins. lines.append(binding) prefix = " " for origin in value.origins: src = utils.pretty_dnf([[str(v) for v in source_set] for source_set in origin.source_sets]) lines.append("%s%s @%d" %(prefix, src, origin.where.id)) return "\n".join(lines)
def _pretty_variable(var): """Return a pretty printed string for a Variable.""" lines = [] single_value = len(var.bindings) == 1 if not single_value: # Write a description of the variable (for single value variables this # will be written along with the value later on). lines.append("$%d %s" % (var.id, var.name)) for value in var.bindings: data = utils.maybe_truncate(value.data) if single_value: binding = "%s, %s = %s" % (value, var.name, data) else: binding = " #%d %s" % (value.data.id, data) if len(value.origins) == 1: # Single origin. Use the binding as a prefix when writing the orign. prefix = binding + ", " else: # Multiple origins, write the binding on its own line, then indent all # of the origins. lines.append(binding) prefix = " " for origin in value.origins: src = utils.pretty_dnf([[str(v) for v in source_set] for source_set in origin.source_sets]) lines.append("%s%s @%d" %(prefix, src, origin.where.id)) return "\n".join(lines)
def program_to_pseudocode(program): """Generate a pseudocode (CFG nodes + assignments) version of a program. For debugging only. Args: program: An instance of cfg.Program Returns: A string, the "pseudocode" of this program. """ s = StringIO.StringIO() seen = set() for node in utils.order_nodes(program.cfg_nodes): seen.add(node) s.write("<%d>%s\n" % (node.id, node.name)) for value in node.values: s.write(" %s\n" % pretty_assignment(value)) overwritten = False for cfg_node, source_sets in value.origins: if node != cfg_node: overwritten = True continue if source_sets == [set()]: pass # don't print trivially true source_sets else: src = utils.pretty_dnf([[pretty_assignment(v, short=True) for v in source_set] for source_set in source_sets]) s.write(" from: %s\n" % src) if overwritten: s.write(" (also set to this value in other nodes)\n") for out in node.outgoing: s.write(" jump to <%d>%s\n" % (out.id, out.name)) # "stray" nodes are nodes that are unreachable in the CFG. stray_nodes = set(program.cfg_nodes) - seen if stray_nodes: s.write("Stray nodes:\n") for node in stray_nodes: s.write("<%d>%s\n" % (node.id, node.name)) return s.getvalue()
def test_pretty_dnf(self): dnf = [["a", "b"], "c", ["d", "e", "f"]] self.assertEqual(utils.pretty_dnf(dnf), "(a & b) | c | (d & e & f)")
def testPrettyDNF(self): dnf = [["a", "b"], "c", ["d", "e", "f"]] self.assertEquals(utils.pretty_dnf(dnf), "(a & b) | c | (d & e & f)")