diff options
author | Denis Ovsienko <denis@ovsienko.info> | 2022-06-02 13:50:32 +0100 |
---|---|---|
committer | Denis Ovsienko <denis@ovsienko.info> | 2022-06-02 13:50:32 +0100 |
commit | 2c1c9cc7c7b05c736bd6e951b0bfdbce1394cb4c (patch) | |
tree | bdb0b3a767de8980ee1ee8c856c60567bd06e96e | |
parent | 4c1e516dd2971810918babcd871e428db53383e4 (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-x | testprogs/visopts.py | 69 |
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"><<</button> @@ -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()) |