blob: 1b6e8ba90dfac4b550b976263fc3c422aa5194d3 [file] [log] [blame]
Pirama Arumuga Nainar4940bb52016-03-17 10:49:45 -07001#!/usr/bin/env python
2
3"""The clang static analyzer results viewer.
4"""
5
6import sys
7import imp
8import os
9import posixpath
10import thread
11import time
12import urllib
13import webbrowser
14
15# How long to wait for server to start.
16kSleepTimeout = .05
17kMaxSleeps = int(60 / kSleepTimeout)
18
19# Default server parameters
20
21kDefaultHost = '127.0.0.1'
22kDefaultPort = 8181
23kMaxPortsToTry = 100
24
25###
26
27
28def url_is_up(url):
29 try:
30 o = urllib.urlopen(url)
31 except IOError:
32 return False
33 o.close()
34 return True
35
36
37def start_browser(port, options):
38 import urllib
39 import webbrowser
40
41 url = 'http://%s:%d' % (options.host, port)
42
43 # Wait for server to start...
44 if options.debug:
45 sys.stderr.write('%s: Waiting for server.' % sys.argv[0])
46 sys.stderr.flush()
47 for i in range(kMaxSleeps):
48 if url_is_up(url):
49 break
50 if options.debug:
51 sys.stderr.write('.')
52 sys.stderr.flush()
53 time.sleep(kSleepTimeout)
54 else:
55 print >> sys.stderr, 'WARNING: Unable to detect that server started.'
56
57 if options.debug:
58 print >> sys.stderr, '%s: Starting webbrowser...' % sys.argv[0]
59 webbrowser.open(url)
60
61
62def run(port, options, root):
63 # Prefer to look relative to the installed binary
64 share = os.path.dirname(__file__) + "/../share/scan-view"
65 if not os.path.isdir(share):
66 # Otherwise look relative to the source
67 share = os.path.dirname(__file__) + "/../../scan-view/share"
68 sys.path.append(share)
69
70 import ScanView
71 try:
72 print 'Starting scan-view at: http://%s:%d' % (options.host,
73 port)
74 print ' Use Ctrl-C to exit.'
75 httpd = ScanView.create_server((options.host, port),
76 options, root)
77 httpd.serve_forever()
78 except KeyboardInterrupt:
79 pass
80
81
82def port_is_open(port):
83 import SocketServer
84 try:
85 t = SocketServer.TCPServer((kDefaultHost, port), None)
86 except:
87 return False
88 t.server_close()
89 return True
90
91
92def main():
93 import argparse
94 parser = argparse.ArgumentParser(description="The clang static analyzer "
95 "results viewer.")
96 parser.add_argument("root", metavar="<results directory>", type=str)
97 parser.add_argument(
98 '--host', dest="host", default=kDefaultHost, type=str,
99 help="Host interface to listen on. (default=%s)" % kDefaultHost)
100 parser.add_argument('--port', dest="port", default=None, type=int,
101 help="Port to listen on. (default=%s)" % kDefaultPort)
102 parser.add_argument("--debug", dest="debug", default=0,
103 action="count",
104 help="Print additional debugging information.")
105 parser.add_argument("--auto-reload", dest="autoReload", default=False,
106 action="store_true",
107 help="Automatically update module for each request.")
108 parser.add_argument("--no-browser", dest="startBrowser", default=True,
109 action="store_false",
110 help="Don't open a webbrowser on startup.")
111 parser.add_argument("--allow-all-hosts", dest="onlyServeLocal",
112 default=True, action="store_false",
113 help='Allow connections from any host (access '
114 'restricted to "127.0.0.1" by default)')
115 args = parser.parse_args()
116
117 # Make sure this directory is in a reasonable state to view.
118 if not posixpath.exists(posixpath.join(args.root, 'index.html')):
119 parser.error('Invalid directory, analysis results not found!')
120
121 # Find an open port. We aren't particularly worried about race
122 # conditions here. Note that if the user specified a port we only
123 # use that one.
124 if args.port is not None:
125 port = args.port
126 else:
127 for i in range(kMaxPortsToTry):
128 if port_is_open(kDefaultPort + i):
129 port = kDefaultPort + i
130 break
131 else:
132 parser.error('Unable to find usable port in [%d,%d)' %
133 (kDefaultPort, kDefaultPort+kMaxPortsToTry))
134
135 # Kick off thread to wait for server and start web browser, if
136 # requested.
137 if args.startBrowser:
138 t = thread.start_new_thread(start_browser, (port, args))
139
140 run(port, args, args.root)
141
142if __name__ == '__main__':
143 main()