scan-view 4.6 KB

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