def main():
    parser = argparse.ArgumentParser(description='Display and manipulate Exploded Graph dumps.')
    parser.add_argument('filename', type=str, help='the .dot file produced by the Static Analyzer')
    parser.add_argument('-v', '--verbose', action='store_const', dest='loglevel', const=logging.DEBUG, default=logging.WARNING, help='enable info prints')
    parser.add_argument('-d', '--diff', action='store_const', dest='diff', const=True, default=False, help='display differences between states')
    parser.add_argument('-t', '--topology', action='store_const', dest='topology', const=True, default=False, help='only display program points, omit states')
    parser.add_argument('-s', '--single-path', action='store_const', dest='single_path', const=True, default=False, help='only display the leftmost path in the graph (useful for trimmed graphs that still branch too much)')
    parser.add_argument('--to', type=str, default=None, help='only display execution paths from the root to the given comma-separated list of nodes identified by a pointer or a stable ID; compatible with --single-path')
    parser.add_argument('--dark', action='store_const', dest='dark', const=True, default=False, help='dark mode')
    parser.add_argument('--gray', action='store_const', dest='gray', const=True, default=False, help='black-and-white mode')
    parser.add_argument('--dump-dot-only', action='store_const', dest='dump_dot_only', const=True, default=False, help='instead of writing an HTML file and immediately displaying it, dump the rewritten dot file to stdout')
    args = parser.parse_args()
    logging.basicConfig(level=args.loglevel)
    graph = ExplodedGraph()
    with open(args.filename) as fd:
        for raw_line in fd:
            raw_line = raw_line.strip()
            graph.add_raw_line(raw_line)
    trimmers = []
    if (args.to is not None):
        trimmers.append(TargetedTrimmer(TargetedTrimmer.parse_target_nodes(args.to, graph)))
    if args.single_path:
        trimmers.append(SinglePathTrimmer())
    explorer = BasicExplorer()
    visitor = DotDumpVisitor(args.diff, args.dark, args.gray, args.topology, args.dump_dot_only)
    for trimmer in trimmers:
        trimmer.trim(graph)
    explorer.explore(graph, visitor)
def main():
    parser = argparse.ArgumentParser(description='Display and manipulate Exploded Graph dumps.')
    parser.add_argument('filename', type=str, help='the .dot file produced by the Static Analyzer')
    parser.add_argument('-v', '--verbose', action='store_const', dest='loglevel', const=logging.DEBUG, default=logging.WARNING, help='enable info prints')
    parser.add_argument('-d', '--diff', action='store_const', dest='diff', const=True, default=False, help='display differences between states')
    parser.add_argument('-t', '--topology', action='store_const', dest='topology', const=True, default=False, help='only display program points, omit states')
    parser.add_argument('-s', '--single-path', action='store_const', dest='single_path', const=True, default=False, help='only display the leftmost path in the graph (useful for trimmed graphs that still branch too much)')
    parser.add_argument('--to', type=str, default=None, help='only display execution paths from the root to the given comma-separated list of nodes identified by a pointer or a stable ID; compatible with --single-path')
    parser.add_argument('--dark', action='store_const', dest='dark', const=True, default=False, help='dark mode')
    parser.add_argument('--gray', action='store_const', dest='gray', const=True, default=False, help='black-and-white mode')
    parser.add_argument('--dump-dot-only', action='store_const', dest='dump_dot_only', const=True, default=False, help='instead of writing an HTML file and immediately displaying it, dump the rewritten dot file to stdout')
    args = parser.parse_args()
    logging.basicConfig(level=args.loglevel)
    graph = ExplodedGraph()
    with open(args.filename) as fd:
        for raw_line in fd:
            raw_line = raw_line.strip()
            graph.add_raw_line(raw_line)
    trimmers = []
    if (args.to is not None):
        trimmers.append(TargetedTrimmer(TargetedTrimmer.parse_target_nodes(args.to, graph)))
    if args.single_path:
        trimmers.append(SinglePathTrimmer())
    explorer = BasicExplorer()
    visitor = DotDumpVisitor(args.diff, args.dark, args.gray, args.topology, args.dump_dot_only)
    for trimmer in trimmers:
        trimmer.trim(graph)
    explorer.explore(graph, visitor)