# Path: core.py
# class BBlock:
#     def __init__(self, addr):
#         self.addr = addr
#         self.items = []
#         self.props = {}
# 
#     def add(self, s):
#         self.items.append(s)
# 
#     def __getitem__(self, i):
#         return self.items[i]
# 
#     def def_addrs(self, regs_only=True):
#         """Return all variable definitions for this basic block,
#         as set of (var, inst_addr) pairs. Note that this includes
#         multiple entries for the same var, if it is redefined
#         multiple times within the basic block.
#         """
#         defs = set()
#         for i in self.items:
#             inst_defs = i.defs(regs_only)
#             for d in inst_defs:
#                 defs.add((d, i.addr))
#         return defs
# 
#     def defs(self, regs_only=True):
#         """Return set of all variables defined in this basic block."""
#         defs = set()
#         for i in self.items:
#             defs |= i.defs(regs_only)
#         return defs
# 
#     def uses(self):
#         """Return set of all variables used in this basic block."""
#         uses = set()
#         for i in self.items:
#             uses |= i.uses()
#         return uses
# 
#     def __repr__(self):
#         return "%s(%s)" % (self.__class__.__name__, self.addr)
# 
#     def write(self, stream, indent, s):
#         for l in str(s).splitlines():
#             stream.write("  " * indent)
#             stream.write(l + "\n")
# 
#     def dump(self, stream, indent=0, printer=str):
#         for s in self.items:
#             out = printer(s)
#             if out is not None:
#                 self.write(stream, indent, out)
# 
# Path: decomp.py
# class IfElse(RecursiveBlock):
#     def __init__(self, header, t_block, f_block, true_cond):
#         super().__init__(header.addr)
#         self.header = header
#         self.branches = [(true_cond, t_block), (None, f_block)]
# 
#     def subblocks(self):
#         return [x[1] for x in self.branches if x[1]]
# 
#     def recursive_union(self, func):
#         res = set()
#         for cond, subb in self.branches:
#             if cond:
#                 res |= func(cond)
#             if subb:
#                 res |= func(subb)
#         return res
# 
#     def swap_branches(self):
#         # Swap If/Else branches, negating condition
#         assert len(self.branches) == 2
#         assert self.branches[1][1] is not None
#         [(true_cond, t_block), (dummy, f_block)] = self.branches
#         self.branches = [(true_cond.neg(), f_block), (None, t_block)]
# 
#     def __repr__(self):
#         return "%s(%r)" % (self.__class__.__name__, self.branches)
# 
#     def dump(self, stream, indent=0, printer=str):
#         self.write(stream, indent, "if %s {" % self.branches[0][0])
#         self.branches[0][1].dump(stream, indent + 1, printer)
# 
#         for cond, block in self.branches[1:-1]:
#             self.write(stream, indent, "} else if %s {" % cond)
#             block.dump(stream, indent + 1, printer)
# 
#         assert self.branches[-1][0] is None
#         if self.branches[-1][1] is not None:
#             self.write(stream, indent, "} else {")
#             self.branches[-1][1].dump(stream, indent + 1, printer)
#         self.write(stream, indent, "}")
# 
# class While(RecursiveBlock):
#     def __init__(self, addr, b, cond):
#         super().__init__(addr)
#         self.cond = cond
#         self.items = [b]
# 
#     def subblocks(self):
#         return self.items
# 
#     def __repr__(self):
#         return "%s(%s)" % (self.__class__.__name__, self.items[0])
# 
#     def dump(self, stream, indent=0, printer=str):
#         self.write(stream, indent, "while %s {" % self.cond)
#         for b in self.items:
#             b.dump(stream, indent + 1, printer)
#         self.write(stream, indent, "}")


import sys
import re
from core import BBlock
from decomp import IfElse, While
        header = "digraph"
        edge = "->"
    else:
        header = "graph"
        edge = "--"

    out.write("%s G {\n" % header)
    out.write("node [shape=box]\n")
    if is_cfg:
        entries = graph.entries()
        if entries and (len(entries) > 1 or entries[0] != ".ENTRY"):
            for e in sorted(entries):
                out.write('"%s" %s "%s"\n' % ("ENTRY", edge, e))

    block_end_map = {}

    for addr, info in graph.iter_sorted_nodes():
        obj = info.get("val")
        if obj is not None:
            typ = type(obj).__name__
            label = "%s: %s" % (addr, typ)
        else:
            label = addr
        if "postno" in info:
            label += "(#%s)" % info["postno"]
        if info.get("postno_exit"):
            label += "(e#%s)" % info["postno_exit"]
        if "idom" in info:
            label += "\nidom: %s" % info["idom"]


# Path: core.py
# class BBlock:
#     def __init__(self, addr):
#         self.addr = addr
#         self.items = []
#         self.props = {}
# 
#     def add(self, s):
#         self.items.append(s)
# 
#     def __getitem__(self, i):
#         return self.items[i]
# 
#     def def_addrs(self, regs_only=True):
#         """Return all variable definitions for this basic block,
#         as set of (var, inst_addr) pairs. Note that this includes
#         multiple entries for the same var, if it is redefined
#         multiple times within the basic block.
#         """
#         defs = set()
#         for i in self.items:
#             inst_defs = i.defs(regs_only)
#             for d in inst_defs:
#                 defs.add((d, i.addr))
#         return defs
# 
#     def defs(self, regs_only=True):
#         """Return set of all variables defined in this basic block."""
#         defs = set()
#         for i in self.items:
#             defs |= i.defs(regs_only)
#         return defs
# 
#     def uses(self):
#         """Return set of all variables used in this basic block."""
#         uses = set()
#         for i in self.items:
#             uses |= i.uses()
#         return uses
# 
#     def __repr__(self):
#         return "%s(%s)" % (self.__class__.__name__, self.addr)
# 
#     def write(self, stream, indent, s):
#         for l in str(s).splitlines():
#             stream.write("  " * indent)
#             stream.write(l + "\n")
# 
#     def dump(self, stream, indent=0, printer=str):
#         for s in self.items:
#             out = printer(s)
#             if out is not None:
#                 self.write(stream, indent, out)
# 
# Path: decomp.py
# class IfElse(RecursiveBlock):
#     def __init__(self, header, t_block, f_block, true_cond):
#         super().__init__(header.addr)
#         self.header = header
#         self.branches = [(true_cond, t_block), (None, f_block)]
# 
#     def subblocks(self):
#         return [x[1] for x in self.branches if x[1]]
# 
#     def recursive_union(self, func):
#         res = set()
#         for cond, subb in self.branches:
#             if cond:
#                 res |= func(cond)
#             if subb:
#                 res |= func(subb)
#         return res
# 
#     def swap_branches(self):
#         # Swap If/Else branches, negating condition
#         assert len(self.branches) == 2
#         assert self.branches[1][1] is not None
#         [(true_cond, t_block), (dummy, f_block)] = self.branches
#         self.branches = [(true_cond.neg(), f_block), (None, t_block)]
# 
#     def __repr__(self):
#         return "%s(%r)" % (self.__class__.__name__, self.branches)
# 
#     def dump(self, stream, indent=0, printer=str):
#         self.write(stream, indent, "if %s {" % self.branches[0][0])
#         self.branches[0][1].dump(stream, indent + 1, printer)
# 
#         for cond, block in self.branches[1:-1]:
#             self.write(stream, indent, "} else if %s {" % cond)
#             block.dump(stream, indent + 1, printer)
# 
#         assert self.branches[-1][0] is None
#         if self.branches[-1][1] is not None:
#             self.write(stream, indent, "} else {")
#             self.branches[-1][1].dump(stream, indent + 1, printer)
#         self.write(stream, indent, "}")
# 
# class While(RecursiveBlock):
#     def __init__(self, addr, b, cond):
#         super().__init__(addr)
#         self.cond = cond
#         self.items = [b]
# 
#     def subblocks(self):
#         return self.items
# 
#     def __repr__(self):
#         return "%s(%s)" % (self.__class__.__name__, self.items[0])
# 
#     def dump(self, stream, indent=0, printer=str):
#         self.write(stream, indent, "while %s {" % self.cond)
#         for b in self.items:
#             b.dump(stream, indent + 1, printer)
#         self.write(stream, indent, "}")


# Path: dot.py
import sys
import re
from core import BBlock
from decomp import IfElse, While

        header = "digraph"
        edge = "->"
    else:
        header = "graph"
        edge = "--"

    out.write("%s G {\n" % header)
    out.write("node [shape=box]\n")
    if is_cfg:
        entries = graph.entries()
        if entries and (len(entries) > 1 or entries[0] != ".ENTRY"):
            for e in sorted(entries):
                out.write('"%s" %s "%s"\n' % ("ENTRY", edge, e))

    block_end_map = {}

    for addr, info in graph.iter_sorted_nodes():
        obj = info.get("val")
        if obj is not None:
            typ = type(obj).__name__
            label = "%s: %s" % (addr, typ)
        else:
            label = addr
        if "postno" in info:
            label += "(#%s)" % info["postno"]
        if info.get("postno_exit"):
            label += "(e#%s)" % info["postno_exit"]
        if "idom" in info:
            label += "\nidom: %s" % info["idom"]


        if type(obj) is BBlock: