NoQ created this revision.
NoQ added reviewers: dcoughlin, xazax.hun, a_sidorin, rnkovacs, Szelethus, 
baloghadamsoftware, Charusso.
Herald added subscribers: cfe-commits, dkrupp, donat.nagy, mikhail.ramalho, 
a.sidorin, szepet.
Herald added a project: clang.

Change the default behavior: the tool no longer dumps the rewritten .dot file 
to stdout, but instead it automatically converts it into an .html file (which 
essentially wraps an .svg file) and immediately opens it with the default web 
browser.

This means that the tool should be fairly easy to use:

  $ exploded-graph-rewriter.py /tmp/ExprEngine.dot

The benefits of wrapping the .svg file into an .html file are:

- It'll open in a web browser, which is the intended behavior. An .svg file 
would be open with an image viewer/editor instead.
- It avoids the white background around the otherwise dark svg area in dark 
mode.

I also added more help text so that it was easier to figure out how to use the 
tool (suggestions are welcome!).

The new feature bypasses tests because i don't expect everybody (esp. 
buildbots) to have python-graphviz installed. The LIT substitution is 
specifically tweaked to enforce the old mode.

TODO: Add a `-o` flag to specify the output file.


Repository:
  rC Clang

https://reviews.llvm.org/D65250

Files:
  clang/test/Analysis/exploded-graph-rewriter/lit.local.cfg
  clang/utils/analyzer/exploded-graph-rewriter.py

Index: clang/utils/analyzer/exploded-graph-rewriter.py
===================================================================
--- clang/utils/analyzer/exploded-graph-rewriter.py
+++ clang/utils/analyzer/exploded-graph-rewriter.py
@@ -394,16 +394,25 @@
 # A visitor that dumps the ExplodedGraph into a DOT file with fancy HTML-based
 # syntax highlighing.
 class DotDumpVisitor(object):
-    def __init__(self, do_diffs, dark_mode, gray_mode, topo_mode):
+    def __init__(self, do_diffs, dark_mode, gray_mode,
+                 topo_mode, rewrite_only):
         super(DotDumpVisitor, self).__init__()
         self._do_diffs = do_diffs
         self._dark_mode = dark_mode
         self._gray_mode = gray_mode
         self._topo_mode = topo_mode
+        self._rewrite_only = rewrite_only
+        self._output = []
 
-    @staticmethod
-    def _dump_raw(s):
-        print(s, end='')
+    def _dump_raw(self, s):
+        if self._rewrite_only:
+            print(s, end='')
+        else:
+            self._output.append(s)
+
+    def output(self):
+        assert not self._rewrite_only
+        return ''.join(self._output)
 
     def _dump(self, s):
         s = s.replace('&', '&') \
@@ -812,6 +821,27 @@
     def visit_end_of_graph(self):
         self._dump_raw('}\n')
 
+        if not self._rewrite_only:
+            import graphviz
+            import sys
+            import tempfile
+            svg = graphviz.pipe('dot', 'svg', self.output())
+            fd, filename = tempfile.mkstemp(suffix='.html')
+            with os.fdopen(fd, 'w') as fp:
+                fp.write('<html>')
+                if self._dark_mode:
+                    fp.write('<body bgcolor="#1a1a1a">')
+                else:
+                    fp.write('<body bgcolor="white">')
+                fp.write(svg)
+                fp.write('</body></html>')
+            if sys.platform == 'win32':
+                os.startfile(filename)
+            elif sys.platform == 'darwin':
+                os.system('open "%s"' % filename)
+            else:
+                os.system('xdg-open "%s"' % filename)
+
 
 #===-----------------------------------------------------------------------===#
 # Explorers know how to traverse the ExplodedGraph in a certain order.
@@ -874,8 +904,10 @@
 
 
 def main():
-    parser = argparse.ArgumentParser()
-    parser.add_argument('filename', type=str)
+    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,
@@ -897,6 +929,11 @@
     parser.add_argument('--gray', action='store_const', dest='gray',
                         const=True, default=False,
                         help='black-and-white mode')
+    parser.add_argument('--rewrite-only', action='store_const',
+                        dest='rewrite_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)
 
@@ -907,7 +944,8 @@
             graph.add_raw_line(raw_line)
 
     explorer = SinglePathExplorer() if args.single_path else BasicExplorer()
-    visitor = DotDumpVisitor(args.diff, args.dark, args.gray, args.topology)
+    visitor = DotDumpVisitor(args.diff, args.dark, args.gray, args.topology,
+                             args.rewrite_only)
 
     explorer.explore(graph, visitor)
 
Index: clang/test/Analysis/exploded-graph-rewriter/lit.local.cfg
===================================================================
--- clang/test/Analysis/exploded-graph-rewriter/lit.local.cfg
+++ clang/test/Analysis/exploded-graph-rewriter/lit.local.cfg
@@ -8,7 +8,7 @@
 config.test_format = lit.formats.ShTest(use_lit_shell == "0")
 
 config.substitutions.append(('%exploded_graph_rewriter',
-                             '\'%s\' %s' % (
+                             '\'%s\' %s --rewrite-only' % (
                                  config.python_executable,
                                  lit.util.which('exploded-graph-rewriter.py',
                                                 os.path.join(
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to