You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
4.6 KiB
151 lines
4.6 KiB
#!/usr/bin/env python
|
|
|
|
from __future__ import print_function
|
|
|
|
"""The clang static analyzer results viewer.
|
|
"""
|
|
|
|
import sys
|
|
import imp
|
|
import os
|
|
import posixpath
|
|
import threading
|
|
import time
|
|
try:
|
|
from urllib.request import urlopen
|
|
except ImportError:
|
|
from urllib2 import urlopen
|
|
import webbrowser
|
|
|
|
# How long to wait for server to start.
|
|
kSleepTimeout = .05
|
|
kMaxSleeps = int(60 / kSleepTimeout)
|
|
|
|
# Default server parameters
|
|
|
|
kDefaultHost = '127.0.0.1'
|
|
kDefaultPort = 8181
|
|
kMaxPortsToTry = 100
|
|
|
|
###
|
|
|
|
|
|
def url_is_up(url):
|
|
try:
|
|
o = urlopen(url)
|
|
except IOError:
|
|
return False
|
|
o.close()
|
|
return True
|
|
|
|
|
|
def start_browser(port, options):
|
|
import webbrowser
|
|
|
|
url = 'http://%s:%d' % (options.host, port)
|
|
|
|
# Wait for server to start...
|
|
if options.debug:
|
|
sys.stderr.write('%s: Waiting for server.' % sys.argv[0])
|
|
sys.stderr.flush()
|
|
for i in range(kMaxSleeps):
|
|
if url_is_up(url):
|
|
break
|
|
if options.debug:
|
|
sys.stderr.write('.')
|
|
sys.stderr.flush()
|
|
time.sleep(kSleepTimeout)
|
|
else:
|
|
print('WARNING: Unable to detect that server started.', file=sys.stderr)
|
|
|
|
if options.debug:
|
|
print('%s: Starting webbrowser...' % sys.argv[0], file=sys.stderr)
|
|
webbrowser.open(url)
|
|
|
|
|
|
def run(port, options, root):
|
|
# Prefer to look relative to the installed binary
|
|
share = os.path.dirname(__file__) + "/../share/scan-view"
|
|
if not os.path.isdir(share):
|
|
# Otherwise look relative to the source
|
|
share = os.path.dirname(__file__) + "/../../scan-view/share"
|
|
sys.path.append(share)
|
|
|
|
import ScanView
|
|
try:
|
|
print('Starting scan-view at: http://%s:%d' % (options.host,
|
|
port))
|
|
print(' Use Ctrl-C to exit.')
|
|
httpd = ScanView.create_server((options.host, port),
|
|
options, root)
|
|
httpd.serve_forever()
|
|
except KeyboardInterrupt:
|
|
pass
|
|
|
|
|
|
def port_is_open(port):
|
|
try:
|
|
import socketserver
|
|
except ImportError:
|
|
import SocketServer as socketserver
|
|
try:
|
|
t = socketserver.TCPServer((kDefaultHost, port), None)
|
|
except:
|
|
return False
|
|
t.server_close()
|
|
return True
|
|
|
|
|
|
def main():
|
|
import argparse
|
|
parser = argparse.ArgumentParser(description="The clang static analyzer "
|
|
"results viewer.")
|
|
parser.add_argument("root", metavar="<results directory>", type=str)
|
|
parser.add_argument(
|
|
'--host', dest="host", default=kDefaultHost, type=str,
|
|
help="Host interface to listen on. (default=%s)" % kDefaultHost)
|
|
parser.add_argument('--port', dest="port", default=None, type=int,
|
|
help="Port to listen on. (default=%s)" % kDefaultPort)
|
|
parser.add_argument("--debug", dest="debug", default=0,
|
|
action="count",
|
|
help="Print additional debugging information.")
|
|
parser.add_argument("--auto-reload", dest="autoReload", default=False,
|
|
action="store_true",
|
|
help="Automatically update module for each request.")
|
|
parser.add_argument("--no-browser", dest="startBrowser", default=True,
|
|
action="store_false",
|
|
help="Don't open a webbrowser on startup.")
|
|
parser.add_argument("--allow-all-hosts", dest="onlyServeLocal",
|
|
default=True, action="store_false",
|
|
help='Allow connections from any host (access '
|
|
'restricted to "127.0.0.1" by default)')
|
|
args = parser.parse_args()
|
|
|
|
# Make sure this directory is in a reasonable state to view.
|
|
if not posixpath.exists(posixpath.join(args.root, 'index.html')):
|
|
parser.error('Invalid directory, analysis results not found!')
|
|
|
|
# Find an open port. We aren't particularly worried about race
|
|
# conditions here. Note that if the user specified a port we only
|
|
# use that one.
|
|
if args.port is not None:
|
|
port = args.port
|
|
else:
|
|
for i in range(kMaxPortsToTry):
|
|
if port_is_open(kDefaultPort + i):
|
|
port = kDefaultPort + i
|
|
break
|
|
else:
|
|
parser.error('Unable to find usable port in [%d,%d)' %
|
|
(kDefaultPort, kDefaultPort+kMaxPortsToTry))
|
|
|
|
# Kick off thread to wait for server and start web browser, if
|
|
# requested.
|
|
if args.startBrowser:
|
|
threading.Thread(target=start_browser, args=(port, args)).start()
|
|
|
|
run(port, args, args.root)
|
|
|
|
if __name__ == '__main__':
|
|
main()
|