--- tools/clang/tools/scan-view/bin/scan-view.orig 2016-10-12 02:17:08 UTC +++ tools/clang/tools/scan-view/bin/scan-view @@ -0,0 +1,143 @@ +#!/usr/bin/env python + +"""The clang static analyzer results viewer. +""" + +import sys +import imp +import os +import posixpath +import thread +import time +import urllib +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 = urllib.urlopen(url) + except IOError: + return False + o.close() + return True + + +def start_browser(port, options): + import urllib + 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 >> sys.stderr, 'WARNING: Unable to detect that server started.' + + if options.debug: + print >> sys.stderr, '%s: Starting webbrowser...' % sys.argv[0] + 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): + import 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="", 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: + t = thread.start_new_thread(start_browser, (port, args)) + + run(port, args, args.root) + +if __name__ == '__main__': + main()