aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Ovsienko <denis@ovsienko.info>2022-06-02 13:50:32 +0100
committerDenis Ovsienko <denis@ovsienko.info>2022-06-02 13:50:32 +0100
commit2c1c9cc7c7b05c736bd6e951b0bfdbce1394cb4c (patch)
treebdb0b3a767de8980ee1ee8c856c60567bd06e96e
parent4c1e516dd2971810918babcd871e428db53383e4 (diff)
Convert visopts.py to Python 3. [skip ci]
In Python 3 "print" is a function, not a keyword; rearrange some imports clauses; redo the BPF expression escaping; for clarity use the full syntax within the string template; fix and improve the dot subprocess management; use modern HTTP server props. This revision has been tested to work with Python 3.8, it should work with earlier Python 3 versions as well.
-rwxr-xr-xtestprogs/visopts.py69
1 files changed, 40 insertions, 29 deletions
diff --git a/testprogs/visopts.py b/testprogs/visopts.py
index 80c14639..bcc34af8 100755
--- a/testprogs/visopts.py
+++ b/testprogs/visopts.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
"""
This program parses the output from pcap_compile() to visualize the CFG after
@@ -37,13 +37,11 @@ Note:
import sys, os
import string
-import subprocess
-import json
html_template = string.Template("""
<html>
<head>
- <title>BPF compiler optimization phases for $expr </title>
+ <title>BPF compiler optimization phases for "${expr_html}"</title>
<style type="text/css">
.hc {
/* half width container */
@@ -56,10 +54,10 @@ html_template = string.Template("""
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"/></script>
<!--script type="text/javascript" src="./jquery.min.js"/></script-->
<script type="text/javascript">
- var expr = '$expr';
+ var expr = '${expr_json}';
var exprid = 1;
- var gcount = $gcount;
- var logs = JSON.parse('$logs');
+ var gcount = ${gcount};
+ var logs = JSON.parse('${logs}');
logs[gcount] = "";
var leftsvg = null;
@@ -196,7 +194,7 @@ html_template = string.Template("""
</head>
<body style="width: 96%">
<div>
- <h1>$expr</h1>
+ <h1>${expr_html}</h1>
<div style="text-align: center;">
<button id="backward" type="button">&lt;&lt;</button>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -226,14 +224,29 @@ html_template = string.Template("""
""")
def write_html(expr, gcount, logs):
- logs = map(lambda s: s.strip().replace("\n", "<br/>"), logs)
+ import html
+ import json
- global html_template
- html = html_template.safe_substitute(expr=expr.encode("string-escape"), gcount=gcount, logs=json.dumps(logs).encode("string-escape"))
- with file("expr1.html", "wt") as f:
- f.write(html)
+ # In the Python 2.7 version this used to be str.encode('string-escape'),
+ # which was a normal string, but in Python 3 the "string_escape" encoding
+ # no longer exists and even with the "unicode_escape" encoding encode()
+ # always returns a binary string. So let's just escape the single quotes
+ # here and hope the result is a valid JavaScript string literal.
+ def encode(s):
+ return s.replace("'", "\'")
+
+ mapping = {
+ 'expr_html': html.escape(expr),
+ 'expr_json': encode(expr),
+ 'gcount': gcount,
+ 'logs': encode(json.dumps([s.strip().replace("\n", "<br/>") for s in logs])),
+ }
+ with open("expr1.html", "wt") as f:
+ f.write(html_template.safe_substitute(mapping))
def render_on_html(infile):
+ import subprocess
+
expr = None
gid = 1
log = ""
@@ -257,14 +270,16 @@ def render_on_html(infile):
if indot == 2:
try:
- p = subprocess.Popen(['dot', '-Tsvg'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+ svg=subprocess.check_output(['dot', '-Tsvg'], input=dot, universal_newlines=True)
except OSError as ose:
- print "Failed to run 'dot':", ose
- print "(Is Graphviz installed?)"
- exit(1)
+ print("Failed to run 'dot':", ose)
+ print("(Is Graphviz installed?)")
+ return False
+ except subprocess.CalledProcessError as cpe:
+ print("Got an error from the 'dot' process: ", cpe)
+ return False
- svg = p.communicate(dot)[0]
- with file("expr1_g%03d.svg" % (gid), "wt") as f:
+ with open("expr1_g%03d.svg" % gid, "wt") as f:
f.write(svg)
logs.append(log)
@@ -283,14 +298,10 @@ def render_on_html(infile):
return True
def run_httpd():
- import SimpleHTTPServer
- import SocketServer
+ import http.server
- class MySocketServer(SocketServer.TCPServer):
- allow_reuse_address = True
- Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
- httpd = MySocketServer(("localhost", 0), Handler)
- print "open this link: http://localhost:%d/expr1.html" % (httpd.server_address[1])
+ httpd = http.server.HTTPServer(("localhost", 0), http.server.SimpleHTTPRequestHandler)
+ print("open this link: http://localhost:%d/expr1.html" % httpd.server_port)
try:
httpd.serve_forever()
except KeyboardInterrupt as e:
@@ -302,8 +313,8 @@ def main():
import shutil
os.chdir(tempfile.mkdtemp(prefix="visopts-"))
atexit.register(shutil.rmtree, os.getcwd())
- print "generated files under directory: %s" % os.getcwd()
- print " the directory will be removed when this program has finished."
+ print("generated files under directory: %s" % os.getcwd())
+ print(" the directory will be removed when this program has finished.")
if not render_on_html(sys.stdin):
return 1
@@ -312,6 +323,6 @@ def main():
if __name__ == "__main__":
if '-h' in sys.argv or '--help' in sys.argv:
- print __doc__
+ print(__doc__)
exit(0)
exit(main())