Author: jroelofs Date: Fri Nov 13 13:56:07 2015 New Revision: 253068 URL: http://llvm.org/viewvc/llvm-project?rev=253068&view=rev Log: [scan-build] Move non user-facing utilities to share
Added: cfe/trunk/tools/scan-view/share/Reporter.py - copied unchanged from r253045, cfe/trunk/tools/scan-view/Reporter.py cfe/trunk/tools/scan-view/share/ScanView.py - copied unchanged from r253045, cfe/trunk/tools/scan-view/ScanView.py cfe/trunk/tools/scan-view/share/startfile.py - copied unchanged from r253045, cfe/trunk/tools/scan-view/startfile.py Removed: cfe/trunk/tools/scan-view/Reporter.py cfe/trunk/tools/scan-view/ScanView.py cfe/trunk/tools/scan-view/startfile.py Modified: cfe/trunk/tools/scan-build/CMakeLists.txt cfe/trunk/tools/scan-build/scan-build cfe/trunk/tools/scan-view/CMakeLists.txt cfe/trunk/tools/scan-view/Makefile cfe/trunk/tools/scan-view/scan-view Modified: cfe/trunk/tools/scan-build/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-build/CMakeLists.txt?rev=253068&r1=253067&r2=253068&view=diff ============================================================================== --- cfe/trunk/tools/scan-build/CMakeLists.txt (original) +++ cfe/trunk/tools/scan-build/CMakeLists.txt Fri Nov 13 13:56:07 2015 @@ -64,15 +64,15 @@ if(CLANG_INSTALL_SCANBUILD) endforeach() foreach(ShareFile ${ShareFiles}) - add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/share/scan-view/${ShareFile} + add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/share/scan-build/${ShareFile} COMMAND ${CMAKE_COMMAND} -E make_directory - ${CMAKE_BINARY_DIR}/share/scan-view + ${CMAKE_BINARY_DIR}/share/scan-build COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/share/${ShareFile} - ${CMAKE_BINARY_DIR}/share/scan-view/ + ${CMAKE_BINARY_DIR}/share/scan-build/ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/share/${ShareFile}) - list(APPEND Depends ${CMAKE_BINARY_DIR}/share/scan-view/${ShareFile}) - install(FILES share/${ShareFile} DESTINATION share/scan-view) + list(APPEND Depends ${CMAKE_BINARY_DIR}/share/scan-build/${ShareFile}) + install(FILES share/${ShareFile} DESTINATION share/scan-build) endforeach() add_custom_target(scan-build ALL DEPENDS ${Depends}) Modified: cfe/trunk/tools/scan-build/scan-build URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-build/scan-build?rev=253068&r1=253067&r2=253068&view=diff ============================================================================== --- cfe/trunk/tools/scan-build/scan-build (original) +++ cfe/trunk/tools/scan-build/scan-build Fri Nov 13 13:56:07 2015 @@ -462,7 +462,7 @@ sub CopyFiles { my $Dir = shift; - my $JS = Cwd::realpath("$RealBin/sorttable.js"); + my $JS = Cwd::realpath("$RealBin/../share/scan-build/sorttable.js"); DieDiag("Cannot find 'sorttable.js'.\n") if (! -r $JS); @@ -472,7 +472,7 @@ sub CopyFiles { DieDiag("Could not copy 'sorttable.js' to '$Dir'.\n") if (! -r "$Dir/sorttable.js"); - my $CSS = Cwd::realpath("$RealBin/scanview.css"); + my $CSS = Cwd::realpath("$RealBin/../share/scan-build/scanview.css"); DieDiag("Cannot find 'scanview.css'.\n") if (! -r $CSS); Modified: cfe/trunk/tools/scan-view/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-view/CMakeLists.txt?rev=253068&r1=253067&r2=253068&view=diff ============================================================================== --- cfe/trunk/tools/scan-view/CMakeLists.txt (original) +++ cfe/trunk/tools/scan-view/CMakeLists.txt Fri Nov 13 13:56:07 2015 @@ -1,12 +1,12 @@ option(CLANG_INSTALL_SCANVIEW "Install the scan-view tool" ON) set(BinFiles - Reporter.py - ScanView.py - scan-view - startfile.py) + scan-view) set(ShareFiles + ScanView.py + Reporter.py + startfile.py FileRadar.scpt GetRadarVersion.scpt bugcatcher.ico) Modified: cfe/trunk/tools/scan-view/Makefile URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-view/Makefile?rev=253068&r1=253067&r2=253068&view=diff ============================================================================== --- cfe/trunk/tools/scan-view/Makefile (original) +++ cfe/trunk/tools/scan-view/Makefile Fri Nov 13 13:56:07 2015 @@ -15,10 +15,10 @@ include $(CLANG_LEVEL)/Makefile CLANG_INSTALL_SCANVIEW ?= 1 ifeq ($(CLANG_INSTALL_SCANVIEW), 1) - InstallTargets := $(ToolDir)/Reporter.py \ - $(ToolDir)/ScanView.py \ - $(ToolDir)/scan-view \ - $(ToolDir)/startfile.py \ + InstallTargets := $(ToolDir)/scan-view \ + $(ShareDir)/scan-view/Reporter.py \ + $(ShareDir)/scan-view/ScanView.py \ + $(ShareDir)/scan-view/startfile.py \ $(ShareDir)/scan-view/FileRadar.scpt \ $(ShareDir)/scan-view/GetRadarVersion.scpt \ $(ShareDir)/scan-view/bugcatcher.ico Removed: cfe/trunk/tools/scan-view/Reporter.py URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-view/Reporter.py?rev=253067&view=auto ============================================================================== --- cfe/trunk/tools/scan-view/Reporter.py (original) +++ cfe/trunk/tools/scan-view/Reporter.py (removed) @@ -1,248 +0,0 @@ -"""Methods for reporting bugs.""" - -import subprocess, sys, os - -__all__ = ['ReportFailure', 'BugReport', 'getReporters'] - -# - -class ReportFailure(Exception): - """Generic exception for failures in bug reporting.""" - def __init__(self, value): - self.value = value - -# Collect information about a bug. - -class BugReport: - def __init__(self, title, description, files): - self.title = title - self.description = description - self.files = files - -# Reporter interfaces. - -import os - -import email, mimetypes, smtplib -from email import encoders -from email.message import Message -from email.mime.base import MIMEBase -from email.mime.multipart import MIMEMultipart -from email.mime.text import MIMEText - -#===------------------------------------------------------------------------===# -# ReporterParameter -#===------------------------------------------------------------------------===# - -class ReporterParameter: - def __init__(self, n): - self.name = n - def getName(self): - return self.name - def getValue(self,r,bugtype,getConfigOption): - return getConfigOption(r.getName(),self.getName()) - def saveConfigValue(self): - return True - -class TextParameter (ReporterParameter): - def getHTML(self,r,bugtype,getConfigOption): - return """\ -<tr> -<td class="form_clabel">%s:</td> -<td class="form_value"><input type="text" name="%s_%s" value="%s"></td> -</tr>"""%(self.getName(),r.getName(),self.getName(),self.getValue(r,bugtype,getConfigOption)) - -class SelectionParameter (ReporterParameter): - def __init__(self, n, values): - ReporterParameter.__init__(self,n) - self.values = values - - def getHTML(self,r,bugtype,getConfigOption): - default = self.getValue(r,bugtype,getConfigOption) - return """\ -<tr> -<td class="form_clabel">%s:</td><td class="form_value"><select name="%s_%s"> -%s -</select></td>"""%(self.getName(),r.getName(),self.getName(),'\n'.join(["""\ -<option value="%s"%s>%s</option>"""%(o[0], - o[0] == default and ' selected="selected"' or '', - o[1]) for o in self.values])) - -#===------------------------------------------------------------------------===# -# Reporters -#===------------------------------------------------------------------------===# - -class EmailReporter: - def getName(self): - return 'Email' - - def getParameters(self): - return map(lambda x:TextParameter(x),['To', 'From', 'SMTP Server', 'SMTP Port']) - - # Lifted from python email module examples. - def attachFile(self, outer, path): - # Guess the content type based on the file's extension. Encoding - # will be ignored, although we should check for simple things like - # gzip'd or compressed files. - ctype, encoding = mimetypes.guess_type(path) - if ctype is None or encoding is not None: - # No guess could be made, or the file is encoded (compressed), so - # use a generic bag-of-bits type. - ctype = 'application/octet-stream' - maintype, subtype = ctype.split('/', 1) - if maintype == 'text': - fp = open(path) - # Note: we should handle calculating the charset - msg = MIMEText(fp.read(), _subtype=subtype) - fp.close() - else: - fp = open(path, 'rb') - msg = MIMEBase(maintype, subtype) - msg.set_payload(fp.read()) - fp.close() - # Encode the payload using Base64 - encoders.encode_base64(msg) - # Set the filename parameter - msg.add_header('Content-Disposition', 'attachment', filename=os.path.basename(path)) - outer.attach(msg) - - def fileReport(self, report, parameters): - mainMsg = """\ -BUG REPORT ---- -Title: %s -Description: %s -"""%(report.title, report.description) - - if not parameters.get('To'): - raise ReportFailure('No "To" address specified.') - if not parameters.get('From'): - raise ReportFailure('No "From" address specified.') - - msg = MIMEMultipart() - msg['Subject'] = 'BUG REPORT: %s'%(report.title) - # FIXME: Get config parameters - msg['To'] = parameters.get('To') - msg['From'] = parameters.get('From') - msg.preamble = mainMsg - - msg.attach(MIMEText(mainMsg, _subtype='text/plain')) - for file in report.files: - self.attachFile(msg, file) - - try: - s = smtplib.SMTP(host=parameters.get('SMTP Server'), - port=parameters.get('SMTP Port')) - s.sendmail(msg['From'], msg['To'], msg.as_string()) - s.close() - except: - raise ReportFailure('Unable to send message via SMTP.') - - return "Message sent!" - -class BugzillaReporter: - def getName(self): - return 'Bugzilla' - - def getParameters(self): - return map(lambda x:TextParameter(x),['URL','Product']) - - def fileReport(self, report, parameters): - raise NotImplementedError - - -class RadarClassificationParameter(SelectionParameter): - def __init__(self): - SelectionParameter.__init__(self,"Classification", - [['1', 'Security'], ['2', 'Crash/Hang/Data Loss'], - ['3', 'Performance'], ['4', 'UI/Usability'], - ['6', 'Serious Bug'], ['7', 'Other']]) - - def saveConfigValue(self): - return False - - def getValue(self,r,bugtype,getConfigOption): - if bugtype.find("leak") != -1: - return '3' - elif bugtype.find("dereference") != -1: - return '2' - elif bugtype.find("missing ivar release") != -1: - return '3' - else: - return '7' - -class RadarReporter: - @staticmethod - def isAvailable(): - # FIXME: Find this .scpt better - path = os.path.join(os.path.dirname(__file__),'../share/scan-view/GetRadarVersion.scpt') - try: - p = subprocess.Popen(['osascript',path], - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - except: - return False - data,err = p.communicate() - res = p.wait() - # FIXME: Check version? Check for no errors? - return res == 0 - - def getName(self): - return 'Radar' - - def getParameters(self): - return [ TextParameter('Component'), TextParameter('Component Version'), - RadarClassificationParameter() ] - - def fileReport(self, report, parameters): - component = parameters.get('Component', '') - componentVersion = parameters.get('Component Version', '') - classification = parameters.get('Classification', '') - personID = "" - diagnosis = "" - config = "" - - if not component.strip(): - component = 'Bugs found by clang Analyzer' - if not componentVersion.strip(): - componentVersion = 'X' - - script = os.path.join(os.path.dirname(__file__),'../share/scan-view/FileRadar.scpt') - args = ['osascript', script, component, componentVersion, classification, personID, report.title, - report.description, diagnosis, config] + map(os.path.abspath, report.files) -# print >>sys.stderr, args - try: - p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - except: - raise ReportFailure("Unable to file radar (AppleScript failure).") - data, err = p.communicate() - res = p.wait() - - if res: - raise ReportFailure("Unable to file radar (AppleScript failure).") - - try: - values = eval(data) - except: - raise ReportFailure("Unable to process radar results.") - - # We expect (int: bugID, str: message) - if len(values) != 2 or not isinstance(values[0], int): - raise ReportFailure("Unable to process radar results.") - - bugID,message = values - bugID = int(bugID) - - if not bugID: - raise ReportFailure(message) - - return "Filed: <a href=\"rdar://%d/\">%d</a>"%(bugID,bugID) - -### - -def getReporters(): - reporters = [] - if RadarReporter.isAvailable(): - reporters.append(RadarReporter()) - reporters.append(EmailReporter()) - return reporters - Removed: cfe/trunk/tools/scan-view/ScanView.py URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-view/ScanView.py?rev=253067&view=auto ============================================================================== --- cfe/trunk/tools/scan-view/ScanView.py (original) +++ cfe/trunk/tools/scan-view/ScanView.py (removed) @@ -1,767 +0,0 @@ -import BaseHTTPServer -import SimpleHTTPServer -import os -import sys -import urllib, urlparse -import posixpath -import StringIO -import re -import shutil -import threading -import time -import socket -import itertools - -import Reporter -import ConfigParser - -### -# Various patterns matched or replaced by server. - -kReportFileRE = re.compile('(.*/)?report-(.*)\\.html') - -kBugKeyValueRE = re.compile('<!-- BUG([^ ]*) (.*) -->') - -# <!-- REPORTPROBLEM file="crashes/clang_crash_ndSGF9.mi" stderr="crashes/clang_crash_ndSGF9.mi.stderr.txt" info="crashes/clang_crash_ndSGF9.mi.info" --> - -kReportCrashEntryRE = re.compile('<!-- REPORTPROBLEM (.*?)-->') -kReportCrashEntryKeyValueRE = re.compile(' ?([^=]+)="(.*?)"') - -kReportReplacements = [] - -# Add custom javascript. -kReportReplacements.append((re.compile('<!-- SUMMARYENDHEAD -->'), """\ -<script language="javascript" type="text/javascript"> -function load(url) { - if (window.XMLHttpRequest) { - req = new XMLHttpRequest(); - } else if (window.ActiveXObject) { - req = new ActiveXObject("Microsoft.XMLHTTP"); - } - if (req != undefined) { - req.open("GET", url, true); - req.send(""); - } -} -</script>""")) - -# Insert additional columns. -kReportReplacements.append((re.compile('<!-- REPORTBUGCOL -->'), - '<td></td><td></td>')) - -# Insert report bug and open file links. -kReportReplacements.append((re.compile('<!-- REPORTBUG id="report-(.*)\\.html" -->'), - ('<td class="Button"><a href="report/\\1">Report Bug</a></td>' + - '<td class="Button"><a href="javascript:load(\'open/\\1\')">Open File</a></td>'))) - -kReportReplacements.append((re.compile('<!-- REPORTHEADER -->'), - '<h3><a href="/">Summary</a> > Report %(report)s</h3>')) - -kReportReplacements.append((re.compile('<!-- REPORTSUMMARYEXTRA -->'), - '<td class="Button"><a href="report/%(report)s">Report Bug</a></td>')) - -# Insert report crashes link. - -# Disabled for the time being until we decide exactly when this should -# be enabled. Also the radar reporter needs to be fixed to report -# multiple files. - -#kReportReplacements.append((re.compile('<!-- REPORTCRASHES -->'), -# '<br>These files will automatically be attached to ' + -# 'reports filed here: <a href="report_crashes">Report Crashes</a>.')) - -### -# Other simple parameters - -kShare = posixpath.join(posixpath.dirname(__file__), '../share/scan-view') -kConfigPath = os.path.expanduser('~/.scanview.cfg') - -### - -__version__ = "0.1" - -__all__ = ["create_server"] - -class ReporterThread(threading.Thread): - def __init__(self, report, reporter, parameters, server): - threading.Thread.__init__(self) - self.report = report - self.server = server - self.reporter = reporter - self.parameters = parameters - self.success = False - self.status = None - - def run(self): - result = None - try: - if self.server.options.debug: - print >>sys.stderr, "%s: SERVER: submitting bug."%(sys.argv[0],) - self.status = self.reporter.fileReport(self.report, self.parameters) - self.success = True - time.sleep(3) - if self.server.options.debug: - print >>sys.stderr, "%s: SERVER: submission complete."%(sys.argv[0],) - except Reporter.ReportFailure,e: - self.status = e.value - except Exception,e: - s = StringIO.StringIO() - import traceback - print >>s,'<b>Unhandled Exception</b><br><pre>' - traceback.print_exc(e,file=s) - print >>s,'</pre>' - self.status = s.getvalue() - -class ScanViewServer(BaseHTTPServer.HTTPServer): - def __init__(self, address, handler, root, reporters, options): - BaseHTTPServer.HTTPServer.__init__(self, address, handler) - self.root = root - self.reporters = reporters - self.options = options - self.halted = False - self.config = None - self.load_config() - - def load_config(self): - self.config = ConfigParser.RawConfigParser() - - # Add defaults - self.config.add_section('ScanView') - for r in self.reporters: - self.config.add_section(r.getName()) - for p in r.getParameters(): - if p.saveConfigValue(): - self.config.set(r.getName(), p.getName(), '') - - # Ignore parse errors - try: - self.config.read([kConfigPath]) - except: - pass - - # Save on exit - import atexit - atexit.register(lambda: self.save_config()) - - def save_config(self): - # Ignore errors (only called on exit). - try: - f = open(kConfigPath,'w') - self.config.write(f) - f.close() - except: - pass - - def halt(self): - self.halted = True - if self.options.debug: - print >>sys.stderr, "%s: SERVER: halting." % (sys.argv[0],) - - def serve_forever(self): - while not self.halted: - if self.options.debug > 1: - print >>sys.stderr, "%s: SERVER: waiting..." % (sys.argv[0],) - try: - self.handle_request() - except OSError,e: - print 'OSError',e.errno - - def finish_request(self, request, client_address): - if self.options.autoReload: - import ScanView - self.RequestHandlerClass = reload(ScanView).ScanViewRequestHandler - BaseHTTPServer.HTTPServer.finish_request(self, request, client_address) - - def handle_error(self, request, client_address): - # Ignore socket errors - info = sys.exc_info() - if info and isinstance(info[1], socket.error): - if self.options.debug > 1: - print >>sys.stderr, "%s: SERVER: ignored socket error." % (sys.argv[0],) - return - BaseHTTPServer.HTTPServer.handle_error(self, request, client_address) - -# Borrowed from Quixote, with simplifications. -def parse_query(qs, fields=None): - if fields is None: - fields = {} - for chunk in filter(None, qs.split('&')): - if '=' not in chunk: - name = chunk - value = '' - else: - name, value = chunk.split('=', 1) - name = urllib.unquote(name.replace('+', ' ')) - value = urllib.unquote(value.replace('+', ' ')) - item = fields.get(name) - if item is None: - fields[name] = [value] - else: - item.append(value) - return fields - -class ScanViewRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): - server_version = "ScanViewServer/" + __version__ - dynamic_mtime = time.time() - - def do_HEAD(self): - try: - SimpleHTTPServer.SimpleHTTPRequestHandler.do_HEAD(self) - except Exception,e: - self.handle_exception(e) - - def do_GET(self): - try: - SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self) - except Exception,e: - self.handle_exception(e) - - def do_POST(self): - """Serve a POST request.""" - try: - length = self.headers.getheader('content-length') or "0" - try: - length = int(length) - except: - length = 0 - content = self.rfile.read(length) - fields = parse_query(content) - f = self.send_head(fields) - if f: - self.copyfile(f, self.wfile) - f.close() - except Exception,e: - self.handle_exception(e) - - def log_message(self, format, *args): - if self.server.options.debug: - sys.stderr.write("%s: SERVER: %s - - [%s] %s\n" % - (sys.argv[0], - self.address_string(), - self.log_date_time_string(), - format%args)) - - def load_report(self, report): - path = os.path.join(self.server.root, 'report-%s.html'%report) - data = open(path).read() - keys = {} - for item in kBugKeyValueRE.finditer(data): - k,v = item.groups() - keys[k] = v - return keys - - def load_crashes(self): - path = posixpath.join(self.server.root, 'index.html') - data = open(path).read() - problems = [] - for item in kReportCrashEntryRE.finditer(data): - fieldData = item.group(1) - fields = dict([i.groups() for i in - kReportCrashEntryKeyValueRE.finditer(fieldData)]) - problems.append(fields) - return problems - - def handle_exception(self, exc): - import traceback - s = StringIO.StringIO() - print >>s, "INTERNAL ERROR\n" - traceback.print_exc(exc, s) - f = self.send_string(s.getvalue(), 'text/plain') - if f: - self.copyfile(f, self.wfile) - f.close() - - def get_scalar_field(self, name): - if name in self.fields: - return self.fields[name][0] - else: - return None - - def submit_bug(self, c): - title = self.get_scalar_field('title') - description = self.get_scalar_field('description') - report = self.get_scalar_field('report') - reporterIndex = self.get_scalar_field('reporter') - files = [] - for fileID in self.fields.get('files',[]): - try: - i = int(fileID) - except: - i = None - if i is None or i<0 or i>=len(c.files): - return (False, 'Invalid file ID') - files.append(c.files[i]) - - if not title: - return (False, "Missing title.") - if not description: - return (False, "Missing description.") - try: - reporterIndex = int(reporterIndex) - except: - return (False, "Invalid report method.") - - # Get the reporter and parameters. - reporter = self.server.reporters[reporterIndex] - parameters = {} - for o in reporter.getParameters(): - name = '%s_%s'%(reporter.getName(),o.getName()) - if name not in self.fields: - return (False, - 'Missing field "%s" for %s report method.'%(name, - reporter.getName())) - parameters[o.getName()] = self.get_scalar_field(name) - - # Update config defaults. - if report != 'None': - self.server.config.set('ScanView', 'reporter', reporterIndex) - for o in reporter.getParameters(): - if o.saveConfigValue(): - name = o.getName() - self.server.config.set(reporter.getName(), name, parameters[name]) - - # Create the report. - bug = Reporter.BugReport(title, description, files) - - # Kick off a reporting thread. - t = ReporterThread(bug, reporter, parameters, self.server) - t.start() - - # Wait for thread to die... - while t.isAlive(): - time.sleep(.25) - submitStatus = t.status - - return (t.success, t.status) - - def send_report_submit(self): - report = self.get_scalar_field('report') - c = self.get_report_context(report) - if c.reportSource is None: - reportingFor = "Report Crashes > " - fileBug = """\ -<a href="/report_crashes">File Bug</a> > """%locals() - else: - reportingFor = '<a href="/%s">Report %s</a> > ' % (c.reportSource, - report) - fileBug = '<a href="/report/%s">File Bug</a> > ' % report - title = self.get_scalar_field('title') - description = self.get_scalar_field('description') - - res,message = self.submit_bug(c) - - if res: - statusClass = 'SubmitOk' - statusName = 'Succeeded' - else: - statusClass = 'SubmitFail' - statusName = 'Failed' - - result = """ -<head> - <title>Bug Submission</title> - <link rel="stylesheet" type="text/css" href="/scanview.css" /> -</head> -<body> -<h3> -<a href="/">Summary</a> > -%(reportingFor)s -%(fileBug)s -Submit</h3> -<form name="form" action=""> -<table class="form"> -<tr><td> -<table class="form_group"> -<tr> - <td class="form_clabel">Title:</td> - <td class="form_value"> - <input type="text" name="title" size="50" value="%(title)s" disabled> - </td> -</tr> -<tr> - <td class="form_label">Description:</td> - <td class="form_value"> -<textarea rows="10" cols="80" name="description" disabled> -%(description)s -</textarea> - </td> -</table> -</td></tr> -</table> -</form> -<h1 class="%(statusClass)s">Submission %(statusName)s</h1> -%(message)s -<p> -<hr> -<a href="/">Return to Summary</a> -</body> -</html>"""%locals() - return self.send_string(result) - - def send_open_report(self, report): - try: - keys = self.load_report(report) - except IOError: - return self.send_error(400, 'Invalid report.') - - file = keys.get('FILE') - if not file or not posixpath.exists(file): - return self.send_error(400, 'File does not exist: "%s"' % file) - - import startfile - if self.server.options.debug: - print >>sys.stderr, '%s: SERVER: opening "%s"'%(sys.argv[0], - file) - - status = startfile.open(file) - if status: - res = 'Opened: "%s"' % file - else: - res = 'Open failed: "%s"' % file - - return self.send_string(res, 'text/plain') - - def get_report_context(self, report): - class Context: - pass - if report is None or report == 'None': - data = self.load_crashes() - # Don't allow empty reports. - if not data: - raise ValueError, 'No crashes detected!' - c = Context() - c.title = 'clang static analyzer failures' - - stderrSummary = "" - for item in data: - if 'stderr' in item: - path = posixpath.join(self.server.root, item['stderr']) - if os.path.exists(path): - lns = itertools.islice(open(path), 0, 10) - stderrSummary += '%s\n--\n%s' % (item.get('src', - '<unknown>'), - ''.join(lns)) - - c.description = """\ -The clang static analyzer failed on these inputs: -%s - -STDERR Summary --------------- -%s -""" % ('\n'.join([item.get('src','<unknown>') for item in data]), - stderrSummary) - c.reportSource = None - c.navMarkup = "Report Crashes > " - c.files = [] - for item in data: - c.files.append(item.get('src','')) - c.files.append(posixpath.join(self.server.root, - item.get('file',''))) - c.files.append(posixpath.join(self.server.root, - item.get('clangfile',''))) - c.files.append(posixpath.join(self.server.root, - item.get('stderr',''))) - c.files.append(posixpath.join(self.server.root, - item.get('info',''))) - # Just in case something failed, ignore files which don't - # exist. - c.files = [f for f in c.files - if os.path.exists(f) and os.path.isfile(f)] - else: - # Check that this is a valid report. - path = posixpath.join(self.server.root, 'report-%s.html' % report) - if not posixpath.exists(path): - raise ValueError, 'Invalid report ID' - keys = self.load_report(report) - c = Context() - c.title = keys.get('DESC','clang error (unrecognized') - c.description = """\ -Bug reported by the clang static analyzer. - -Description: %s -File: %s -Line: %s -"""%(c.title, keys.get('FILE','<unknown>'), keys.get('LINE', '<unknown>')) - c.reportSource = 'report-%s.html' % report - c.navMarkup = """<a href="/%s">Report %s</a> > """ % (c.reportSource, - report) - - c.files = [path] - return c - - def send_report(self, report, configOverrides=None): - def getConfigOption(section, field): - if (configOverrides is not None and - section in configOverrides and - field in configOverrides[section]): - return configOverrides[section][field] - return self.server.config.get(section, field) - - # report is None is used for crashes - try: - c = self.get_report_context(report) - except ValueError, e: - return self.send_error(400, e.message) - - title = c.title - description= c.description - reportingFor = c.navMarkup - if c.reportSource is None: - extraIFrame = "" - else: - extraIFrame = """\ -<iframe src="/%s" width="100%%" height="40%%" - scrolling="auto" frameborder="1"> - <a href="/%s">View Bug Report</a> -</iframe>""" % (c.reportSource, c.reportSource) - - reporterSelections = [] - reporterOptions = [] - - try: - active = int(getConfigOption('ScanView','reporter')) - except: - active = 0 - for i,r in enumerate(self.server.reporters): - selected = (i == active) - if selected: - selectedStr = ' selected' - else: - selectedStr = '' - reporterSelections.append('<option value="%d"%s>%s</option>'%(i,selectedStr,r.getName())) - options = '\n'.join([ o.getHTML(r,title,getConfigOption) for o in r.getParameters()]) - display = ('none','')[selected] - reporterOptions.append("""\ -<tr id="%sReporterOptions" style="display:%s"> - <td class="form_label">%s Options</td> - <td class="form_value"> - <table class="form_inner_group"> -%s - </table> - </td> -</tr> -"""%(r.getName(),display,r.getName(),options)) - reporterSelections = '\n'.join(reporterSelections) - reporterOptionsDivs = '\n'.join(reporterOptions) - reportersArray = '[%s]'%(','.join([`r.getName()` for r in self.server.reporters])) - - if c.files: - fieldSize = min(5, len(c.files)) - attachFileOptions = '\n'.join(["""\ -<option value="%d" selected>%s</option>""" % (i,v) for i,v in enumerate(c.files)]) - attachFileRow = """\ -<tr> - <td class="form_label">Attach:</td> - <td class="form_value"> -<select style="width:100%%" name="files" multiple size=%d> -%s -</select> - </td> -</tr> -""" % (min(5, len(c.files)), attachFileOptions) - else: - attachFileRow = "" - - result = """<html> -<head> - <title>File Bug</title> - <link rel="stylesheet" type="text/css" href="/scanview.css" /> -</head> -<script language="javascript" type="text/javascript"> -var reporters = %(reportersArray)s; -function updateReporterOptions() { - index = document.getElementById('reporter').selectedIndex; - for (var i=0; i < reporters.length; ++i) { - o = document.getElementById(reporters[i] + "ReporterOptions"); - if (i == index) { - o.style.display = ""; - } else { - o.style.display = "none"; - } - } -} -</script> -<body onLoad="updateReporterOptions()"> -<h3> -<a href="/">Summary</a> > -%(reportingFor)s -File Bug</h3> -<form name="form" action="/report_submit" method="post"> -<input type="hidden" name="report" value="%(report)s"> - -<table class="form"> -<tr><td> -<table class="form_group"> -<tr> - <td class="form_clabel">Title:</td> - <td class="form_value"> - <input type="text" name="title" size="50" value="%(title)s"> - </td> -</tr> -<tr> - <td class="form_label">Description:</td> - <td class="form_value"> -<textarea rows="10" cols="80" name="description"> -%(description)s -</textarea> - </td> -</tr> - -%(attachFileRow)s - -</table> -<br> -<table class="form_group"> -<tr> - <td class="form_clabel">Method:</td> - <td class="form_value"> - <select id="reporter" name="reporter" onChange="updateReporterOptions()"> - %(reporterSelections)s - </select> - </td> -</tr> -%(reporterOptionsDivs)s -</table> -<br> -</td></tr> -<tr><td class="form_submit"> - <input align="right" type="submit" name="Submit" value="Submit"> -</td></tr> -</table> -</form> - -%(extraIFrame)s - -</body> -</html>"""%locals() - - return self.send_string(result) - - def send_head(self, fields=None): - if (self.server.options.onlyServeLocal and - self.client_address[0] != '127.0.0.1'): - return self.send_error(401, 'Unauthorized host.') - - if fields is None: - fields = {} - self.fields = fields - - o = urlparse.urlparse(self.path) - self.fields = parse_query(o.query, fields) - path = posixpath.normpath(urllib.unquote(o.path)) - - # Split the components and strip the root prefix. - components = path.split('/')[1:] - - # Special case some top-level entries. - if components: - name = components[0] - if len(components)==2: - if name=='report': - return self.send_report(components[1]) - elif name=='open': - return self.send_open_report(components[1]) - elif len(components)==1: - if name=='quit': - self.server.halt() - return self.send_string('Goodbye.', 'text/plain') - elif name=='report_submit': - return self.send_report_submit() - elif name=='report_crashes': - overrides = { 'ScanView' : {}, - 'Radar' : {}, - 'Email' : {} } - for i,r in enumerate(self.server.reporters): - if r.getName() == 'Radar': - overrides['ScanView']['reporter'] = i - break - overrides['Radar']['Component'] = 'llvm - checker' - overrides['Radar']['Component Version'] = 'X' - return self.send_report(None, overrides) - elif name=='favicon.ico': - return self.send_path(posixpath.join(kShare,'bugcatcher.ico')) - - # Match directory entries. - if components[-1] == '': - components[-1] = 'index.html' - - relpath = '/'.join(components) - path = posixpath.join(self.server.root, relpath) - - if self.server.options.debug > 1: - print >>sys.stderr, '%s: SERVER: sending path "%s"'%(sys.argv[0], - path) - return self.send_path(path) - - def send_404(self): - self.send_error(404, "File not found") - return None - - def send_path(self, path): - # If the requested path is outside the root directory, do not open it - rel = os.path.abspath(path) - if not rel.startswith(os.path.abspath(self.server.root)): - return self.send_404() - - ctype = self.guess_type(path) - if ctype.startswith('text/'): - # Patch file instead - return self.send_patched_file(path, ctype) - else: - mode = 'rb' - try: - f = open(path, mode) - except IOError: - return self.send_404() - return self.send_file(f, ctype) - - def send_file(self, f, ctype): - # Patch files to add links, but skip binary files. - self.send_response(200) - self.send_header("Content-type", ctype) - fs = os.fstat(f.fileno()) - self.send_header("Content-Length", str(fs[6])) - self.send_header("Last-Modified", self.date_time_string(fs.st_mtime)) - self.end_headers() - return f - - def send_string(self, s, ctype='text/html', headers=True, mtime=None): - if headers: - self.send_response(200) - self.send_header("Content-type", ctype) - self.send_header("Content-Length", str(len(s))) - if mtime is None: - mtime = self.dynamic_mtime - self.send_header("Last-Modified", self.date_time_string(mtime)) - self.end_headers() - return StringIO.StringIO(s) - - def send_patched_file(self, path, ctype): - # Allow a very limited set of variables. This is pretty gross. - variables = {} - variables['report'] = '' - m = kReportFileRE.match(path) - if m: - variables['report'] = m.group(2) - - try: - f = open(path,'r') - except IOError: - return self.send_404() - fs = os.fstat(f.fileno()) - data = f.read() - for a,b in kReportReplacements: - data = a.sub(b % variables, data) - return self.send_string(data, ctype, mtime=fs.st_mtime) - - -def create_server(address, options, root): - import Reporter - - reporters = Reporter.getReporters() - - return ScanViewServer(address, ScanViewRequestHandler, - root, - reporters, - options) Modified: cfe/trunk/tools/scan-view/scan-view URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-view/scan-view?rev=253068&r1=253067&r2=253068&view=diff ============================================================================== --- cfe/trunk/tools/scan-view/scan-view (original) +++ cfe/trunk/tools/scan-view/scan-view Fri Nov 13 13:56:07 2015 @@ -4,6 +4,8 @@ """ import sys +import imp +import os import posixpath import thread import time @@ -54,6 +56,7 @@ def start_browser(port, options): webbrowser.open(url) def run(port, options, root): + sys.path.append(os.path.dirname(__file__) + "/../share/scan-view") import ScanView try: print 'Starting scan-view at: http://%s:%d'%(options.host, Removed: cfe/trunk/tools/scan-view/startfile.py URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-view/startfile.py?rev=253067&view=auto ============================================================================== --- cfe/trunk/tools/scan-view/startfile.py (original) +++ cfe/trunk/tools/scan-view/startfile.py (removed) @@ -1,203 +0,0 @@ -"""Utility for opening a file using the default application in a cross-platform -manner. Modified from http://code.activestate.com/recipes/511443/. -""" - -__version__ = '1.1x' -__all__ = ['open'] - -import os -import sys -import webbrowser -import subprocess - -_controllers = {} -_open = None - - -class BaseController(object): - '''Base class for open program controllers.''' - - def __init__(self, name): - self.name = name - - def open(self, filename): - raise NotImplementedError - - -class Controller(BaseController): - '''Controller for a generic open program.''' - - def __init__(self, *args): - super(Controller, self).__init__(os.path.basename(args[0])) - self.args = list(args) - - def _invoke(self, cmdline): - if sys.platform[:3] == 'win': - closefds = False - startupinfo = subprocess.STARTUPINFO() - startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW - else: - closefds = True - startupinfo = None - - if (os.environ.get('DISPLAY') or sys.platform[:3] == 'win' or - sys.platform == 'darwin'): - inout = file(os.devnull, 'r+') - else: - # for TTY programs, we need stdin/out - inout = None - - # if possible, put the child precess in separate process group, - # so keyboard interrupts don't affect child precess as well as - # Python - setsid = getattr(os, 'setsid', None) - if not setsid: - setsid = getattr(os, 'setpgrp', None) - - pipe = subprocess.Popen(cmdline, stdin=inout, stdout=inout, - stderr=inout, close_fds=closefds, - preexec_fn=setsid, startupinfo=startupinfo) - - # It is assumed that this kind of tools (gnome-open, kfmclient, - # exo-open, xdg-open and open for OSX) immediately exit after lauching - # the specific application - returncode = pipe.wait() - if hasattr(self, 'fixreturncode'): - returncode = self.fixreturncode(returncode) - return not returncode - - def open(self, filename): - if isinstance(filename, basestring): - cmdline = self.args + [filename] - else: - # assume it is a sequence - cmdline = self.args + filename - try: - return self._invoke(cmdline) - except OSError: - return False - - -# Platform support for Windows -if sys.platform[:3] == 'win': - - class Start(BaseController): - '''Controller for the win32 start progam through os.startfile.''' - - def open(self, filename): - try: - os.startfile(filename) - except WindowsError: - # [Error 22] No application is associated with the specified - # file for this operation: '<URL>' - return False - else: - return True - - _controllers['windows-default'] = Start('start') - _open = _controllers['windows-default'].open - - -# Platform support for MacOS -elif sys.platform == 'darwin': - _controllers['open']= Controller('open') - _open = _controllers['open'].open - - -# Platform support for Unix -else: - - import commands - - # @WARNING: use the private API of the webbrowser module - from webbrowser import _iscommand - - class KfmClient(Controller): - '''Controller for the KDE kfmclient program.''' - - def __init__(self, kfmclient='kfmclient'): - super(KfmClient, self).__init__(kfmclient, 'exec') - self.kde_version = self.detect_kde_version() - - def detect_kde_version(self): - kde_version = None - try: - info = commands.getoutput('kde-config --version') - - for line in info.splitlines(): - if line.startswith('KDE'): - kde_version = line.split(':')[-1].strip() - break - except (OSError, RuntimeError): - pass - - return kde_version - - def fixreturncode(self, returncode): - if returncode is not None and self.kde_version > '3.5.4': - return returncode - else: - return os.EX_OK - - def detect_desktop_environment(): - '''Checks for known desktop environments - - Return the desktop environments name, lowercase (kde, gnome, xfce) - or "generic" - - ''' - - desktop_environment = 'generic' - - if os.environ.get('KDE_FULL_SESSION') == 'true': - desktop_environment = 'kde' - elif os.environ.get('GNOME_DESKTOP_SESSION_ID'): - desktop_environment = 'gnome' - else: - try: - info = commands.getoutput('xprop -root _DT_SAVE_MODE') - if ' = "xfce4"' in info: - desktop_environment = 'xfce' - except (OSError, RuntimeError): - pass - - return desktop_environment - - - def register_X_controllers(): - if _iscommand('kfmclient'): - _controllers['kde-open'] = KfmClient() - - for command in ('gnome-open', 'exo-open', 'xdg-open'): - if _iscommand(command): - _controllers[command] = Controller(command) - - def get(): - controllers_map = { - 'gnome': 'gnome-open', - 'kde': 'kde-open', - 'xfce': 'exo-open', - } - - desktop_environment = detect_desktop_environment() - - try: - controller_name = controllers_map[desktop_environment] - return _controllers[controller_name].open - - except KeyError: - if _controllers.has_key('xdg-open'): - return _controllers['xdg-open'].open - else: - return webbrowser.open - - - if os.environ.get("DISPLAY"): - register_X_controllers() - _open = get() - - -def open(filename): - '''Open a file or an URL in the registered default application.''' - - return _open(filename) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits