Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / tools / scan-view / share / Reporter.py
blob21874b378687eb082b2f4834a3905a93cd022c0a
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
4 """Methods for reporting bugs."""
6 import subprocess, sys, os
8 __all__ = ["ReportFailure", "BugReport", "getReporters"]
13 class ReportFailure(Exception):
14 """Generic exception for failures in bug reporting."""
16 def __init__(self, value):
17 self.value = value
20 # Collect information about a bug.
23 class BugReport(object):
24 def __init__(self, title, description, files):
25 self.title = title
26 self.description = description
27 self.files = files
30 # Reporter interfaces.
32 import os
34 import email, mimetypes, smtplib
35 from email import encoders
36 from email.message import Message
37 from email.mime.base import MIMEBase
38 from email.mime.multipart import MIMEMultipart
39 from email.mime.text import MIMEText
41 # ===------------------------------------------------------------------------===#
42 # ReporterParameter
43 # ===------------------------------------------------------------------------===#
46 class ReporterParameter(object):
47 def __init__(self, n):
48 self.name = n
50 def getName(self):
51 return self.name
53 def getValue(self, r, bugtype, getConfigOption):
54 return getConfigOption(r.getName(), self.getName())
56 def saveConfigValue(self):
57 return True
60 class TextParameter(ReporterParameter):
61 def getHTML(self, r, bugtype, getConfigOption):
62 return """\
63 <tr>
64 <td class="form_clabel">%s:</td>
65 <td class="form_value"><input type="text" name="%s_%s" value="%s"></td>
66 </tr>""" % (
67 self.getName(),
68 r.getName(),
69 self.getName(),
70 self.getValue(r, bugtype, getConfigOption),
74 class SelectionParameter(ReporterParameter):
75 def __init__(self, n, values):
76 ReporterParameter.__init__(self, n)
77 self.values = values
79 def getHTML(self, r, bugtype, getConfigOption):
80 default = self.getValue(r, bugtype, getConfigOption)
81 return """\
82 <tr>
83 <td class="form_clabel">%s:</td><td class="form_value"><select name="%s_%s">
85 </select></td>""" % (
86 self.getName(),
87 r.getName(),
88 self.getName(),
89 "\n".join(
91 """\
92 <option value="%s"%s>%s</option>"""
93 % (o[0], o[0] == default and ' selected="selected"' or "", o[1])
94 for o in self.values
100 # ===------------------------------------------------------------------------===#
101 # Reporters
102 # ===------------------------------------------------------------------------===#
105 class EmailReporter(object):
106 def getName(self):
107 return "Email"
109 def getParameters(self):
110 return [TextParameter(x) for x in ["To", "From", "SMTP Server", "SMTP Port"]]
112 # Lifted from python email module examples.
113 def attachFile(self, outer, path):
114 # Guess the content type based on the file's extension. Encoding
115 # will be ignored, although we should check for simple things like
116 # gzip'd or compressed files.
117 ctype, encoding = mimetypes.guess_type(path)
118 if ctype is None or encoding is not None:
119 # No guess could be made, or the file is encoded (compressed), so
120 # use a generic bag-of-bits type.
121 ctype = "application/octet-stream"
122 maintype, subtype = ctype.split("/", 1)
123 if maintype == "text":
124 fp = open(path)
125 # Note: we should handle calculating the charset
126 msg = MIMEText(fp.read(), _subtype=subtype)
127 fp.close()
128 else:
129 fp = open(path, "rb")
130 msg = MIMEBase(maintype, subtype)
131 msg.set_payload(fp.read())
132 fp.close()
133 # Encode the payload using Base64
134 encoders.encode_base64(msg)
135 # Set the filename parameter
136 msg.add_header(
137 "Content-Disposition", "attachment", filename=os.path.basename(path)
139 outer.attach(msg)
141 def fileReport(self, report, parameters):
142 mainMsg = """\
143 BUG REPORT
145 Title: %s
146 Description: %s
147 """ % (
148 report.title,
149 report.description,
152 if not parameters.get("To"):
153 raise ReportFailure('No "To" address specified.')
154 if not parameters.get("From"):
155 raise ReportFailure('No "From" address specified.')
157 msg = MIMEMultipart()
158 msg["Subject"] = "BUG REPORT: %s" % (report.title)
159 # FIXME: Get config parameters
160 msg["To"] = parameters.get("To")
161 msg["From"] = parameters.get("From")
162 msg.preamble = mainMsg
164 msg.attach(MIMEText(mainMsg, _subtype="text/plain"))
165 for file in report.files:
166 self.attachFile(msg, file)
168 try:
169 s = smtplib.SMTP(
170 host=parameters.get("SMTP Server"), port=parameters.get("SMTP Port")
172 s.sendmail(msg["From"], msg["To"], msg.as_string())
173 s.close()
174 except:
175 raise ReportFailure("Unable to send message via SMTP.")
177 return "Message sent!"
180 class BugzillaReporter(object):
181 def getName(self):
182 return "Bugzilla"
184 def getParameters(self):
185 return [TextParameter(x) for x in ["URL", "Product"]]
187 def fileReport(self, report, parameters):
188 raise NotImplementedError
191 class RadarClassificationParameter(SelectionParameter):
192 def __init__(self):
193 SelectionParameter.__init__(
194 self,
195 "Classification",
197 ["1", "Security"],
198 ["2", "Crash/Hang/Data Loss"],
199 ["3", "Performance"],
200 ["4", "UI/Usability"],
201 ["6", "Serious Bug"],
202 ["7", "Other"],
206 def saveConfigValue(self):
207 return False
209 def getValue(self, r, bugtype, getConfigOption):
210 if bugtype.find("leak") != -1:
211 return "3"
212 elif bugtype.find("dereference") != -1:
213 return "2"
214 elif bugtype.find("missing ivar release") != -1:
215 return "3"
216 else:
217 return "7"
223 def getReporters():
224 reporters = []
225 reporters.append(EmailReporter())
226 return reporters