]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Eot/Report.py
BaseTools: use set instead of list for a variable to be used with in
[mirror_edk2.git] / BaseTools / Source / Python / Eot / Report.py
1 ## @file
2 # This file is used to create report for Eot tool
3 #
4 # Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
9 #
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 #
13
14 ##
15 # Import Modules
16 #
17 import Common.LongFilePathOs as os
18 import EotGlobalData
19 from Common.LongFilePathSupport import OpenLongFilePath as open
20
21 ## Report() class
22 #
23 # This class defined Report
24 #
25 # @param object: Inherited from object class
26 #
27 class Report(object):
28 ## The constructor
29 #
30 # @param self: The object pointer
31 # @param ReportName: name of the report
32 # @param FvObj: FV object after parsing FV images
33 #
34 def __init__(self, ReportName = 'Report.html', FvObj = None, DispatchName=None):
35 self.ReportName = ReportName
36 self.Op = open(ReportName, 'w+')
37 self.DispatchList = None
38 if DispatchName:
39 self.DispatchList = open(DispatchName, 'w+')
40 self.FvObj = FvObj
41 self.FfsIndex = 0
42 self.PpiIndex = 0
43 self.ProtocolIndex = 0
44 if EotGlobalData.gMACRO['EFI_SOURCE'] == '':
45 EotGlobalData.gMACRO['EFI_SOURCE'] = EotGlobalData.gMACRO['EDK_SOURCE']
46
47 ## WriteLn() method
48 #
49 # Write a line in the report
50 #
51 # @param self: The object pointer
52 # @param Line: The lint to be written into
53 #
54 def WriteLn(self, Line):
55 self.Op.write('%s\n' % Line)
56
57 ## GenerateReport() method
58 #
59 # A caller to generate report
60 #
61 # @param self: The object pointer
62 #
63 def GenerateReport(self):
64 self.GenerateHeader()
65 self.GenerateFv()
66 self.GenerateTail()
67 self.Op.close()
68 self.GenerateUnDispatchedList()
69
70 ## GenerateUnDispatchedList() method
71 #
72 # Create a list for not dispatched items
73 #
74 # @param self: The object pointer
75 #
76 def GenerateUnDispatchedList(self):
77 FvObj = self.FvObj
78 EotGlobalData.gOP_UN_DISPATCHED.write('%s\n' % FvObj.Name)
79 for Item in FvObj.UnDispatchedFfsDict:
80 EotGlobalData.gOP_UN_DISPATCHED.write('%s\n' % FvObj.UnDispatchedFfsDict[Item])
81
82 ## GenerateFv() method
83 #
84 # Generate FV information
85 #
86 # @param self: The object pointer
87 #
88 def GenerateFv(self):
89 FvObj = self.FvObj
90 Content = """ <tr>
91 <td width="20%%"><strong>Name</strong></td>
92 <td width="60%%"><strong>Guid</strong></td>
93 <td width="20%%"><strong>Size</strong></td>
94 </tr>"""
95 self.WriteLn(Content)
96
97 for Info in FvObj.BasicInfo:
98 FvName = Info[0]
99 FvGuid = Info[1]
100 FvSize = Info[2]
101
102 Content = """ <tr>
103 <td>%s</td>
104 <td>%s</td>
105 <td>%s</td>
106 </tr>""" % (FvName, FvGuid, FvSize)
107 self.WriteLn(Content)
108
109 Content = """ <td colspan="3"><table width="100%%" border="1">
110 <tr>"""
111 self.WriteLn(Content)
112
113 EotGlobalData.gOP_DISPATCH_ORDER.write('Dispatched:\n')
114 for FfsId in FvObj.OrderedFfsDict:
115 self.GenerateFfs(FvObj.OrderedFfsDict[FfsId])
116 Content = """ </table></td>
117 </tr>"""
118 self.WriteLn(Content)
119
120 # For UnDispatched
121 Content = """ <td colspan="3"><table width="100%%" border="1">
122 <tr>
123 <tr><strong>UnDispatched</strong></tr>"""
124 self.WriteLn(Content)
125
126 EotGlobalData.gOP_DISPATCH_ORDER.write('\nUnDispatched:\n')
127 for FfsId in FvObj.UnDispatchedFfsDict:
128 self.GenerateFfs(FvObj.UnDispatchedFfsDict[FfsId])
129 Content = """ </table></td>
130 </tr>"""
131 self.WriteLn(Content)
132
133 ## GenerateDepex() method
134 #
135 # Generate Depex information
136 #
137 # @param self: The object pointer
138 # @param DepexString: A DEPEX string needed to be parsed
139 #
140 def GenerateDepex(self, DepexString):
141 NonGuidList = ['AND', 'OR', 'NOT', 'BEFORE', 'AFTER', 'TRUE', 'FALSE']
142 ItemList = DepexString.split(' ')
143 DepexString = ''
144 for Item in ItemList:
145 if Item not in NonGuidList:
146 SqlCommand = """select DISTINCT GuidName from Report where GuidValue like '%s' and ItemMode = 'Produced' group by GuidName""" % (Item)
147 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
148 if RecordSet != []:
149 Item = RecordSet[0][0]
150 DepexString = DepexString + Item + ' '
151 Content = """ <tr>
152 <td width="5%%"></td>
153 <td width="95%%">%s</td>
154 </tr>""" % (DepexString)
155 self.WriteLn(Content)
156
157 ## GeneratePpi() method
158 #
159 # Generate PPI information
160 #
161 # @param self: The object pointer
162 # @param Name: CName of a GUID
163 # @param Guid: Value of a GUID
164 # @param Type: Type of a GUID
165 #
166 def GeneratePpi(self, Name, Guid, Type):
167 self.GeneratePpiProtocol('Ppi', Name, Guid, Type, self.PpiIndex)
168
169 ## GenerateProtocol() method
170 #
171 # Generate PROTOCOL information
172 #
173 # @param self: The object pointer
174 # @param Name: CName of a GUID
175 # @param Guid: Value of a GUID
176 # @param Type: Type of a GUID
177 #
178 def GenerateProtocol(self, Name, Guid, Type):
179 self.GeneratePpiProtocol('Protocol', Name, Guid, Type, self.ProtocolIndex)
180
181 ## GeneratePpiProtocol() method
182 #
183 # Generate PPI/PROTOCOL information
184 #
185 # @param self: The object pointer
186 # @param Model: Model of a GUID, PPI or PROTOCOL
187 # @param Name: Name of a GUID
188 # @param Guid: Value of a GUID
189 # @param Type: Type of a GUID
190 # @param CName: CName(Index) of a GUID
191 #
192 def GeneratePpiProtocol(self, Model, Name, Guid, Type, CName):
193 Content = """ <tr>
194 <td width="5%%"></td>
195 <td width="10%%">%s</td>
196 <td width="85%%" colspan="3">%s</td>
197 <!-- %s -->
198 </tr>""" % (Model, Name, Guid)
199 self.WriteLn(Content)
200 if Type == 'Produced':
201 SqlCommand = """select DISTINCT SourceFileFullPath, BelongsToFunction from Report where GuidName like '%s' and ItemMode = 'Callback'""" % Name
202 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
203 for Record in RecordSet:
204 SqlCommand = """select FullPath from File
205 where ID = (
206 select DISTINCT BelongsToFile from Inf
207 where Value1 like '%s')""" % Record[0]
208 ModuleSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
209 Inf = ModuleSet[0][0].replace(EotGlobalData.gMACRO['WORKSPACE'], '.')
210 Function = Record[1]
211 Address = ''
212 for Item in EotGlobalData.gMap:
213 if Function in EotGlobalData.gMap[Item]:
214 Address = EotGlobalData.gMap[Item][Function]
215 break
216 if '_' + Function in EotGlobalData.gMap[Item]:
217 Address = EotGlobalData.gMap[Item]['_' + Function]
218 break
219 Content = """ <tr>
220 <td width="5%%"></td>
221 <td width="10%%">%s</td>
222 <td width="40%%">%s</td>
223 <td width="35%%">%s</td>
224 <td width="10%%">%s</td>
225 </tr>""" % ('Callback', Inf, Function, Address)
226 self.WriteLn(Content)
227
228 ## GenerateFfs() method
229 #
230 # Generate FFS information
231 #
232 # @param self: The object pointer
233 # @param FfsObj: FFS object after FV image is parsed
234 #
235 def GenerateFfs(self, FfsObj):
236 self.FfsIndex = self.FfsIndex + 1
237 if FfsObj is not None and FfsObj.Type in [0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0xA]:
238 FfsGuid = FfsObj.Guid
239 FfsOffset = FfsObj._OFF_
240 FfsName = 'Unknown-Module'
241 FfsPath = FfsGuid
242 FfsType = FfsObj._TypeName[FfsObj.Type]
243
244 # Hard code for Binary INF
245 if FfsGuid.upper() == '7BB28B99-61BB-11D5-9A5D-0090273FC14D':
246 FfsName = 'Logo'
247
248 if FfsGuid.upper() == '7E374E25-8E01-4FEE-87F2-390C23C606CD':
249 FfsName = 'AcpiTables'
250
251 if FfsGuid.upper() == '961578FE-B6B7-44C3-AF35-6BC705CD2B1F':
252 FfsName = 'Fat'
253
254 # Find FFS Path and Name
255 SqlCommand = """select Value2 from Inf
256 where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
257 and Model = %s and Value1='BASE_NAME'""" % (FfsGuid, 5001, 5001)
258 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
259 if RecordSet != []:
260 FfsName = RecordSet[0][0]
261
262 SqlCommand = """select FullPath from File
263 where ID = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
264 and Model = %s""" % (FfsGuid, 5001, 1011)
265 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
266 if RecordSet != []:
267 FfsPath = RecordSet[0][0]
268
269 Content = """ <tr>
270 <tr class='styleFfs' id='FfsHeader%s'>
271 <td width="55%%"><span onclick="Display('FfsHeader%s', 'Ffs%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">%s</span></td>
272 <td width="15%%">%s</td>
273 <!--<td width="20%%">%s</td>-->
274 <!--<td width="20%%">%s</td>-->
275 <td width="10%%">%s</td>
276 </tr>
277 <tr id='Ffs%s' style='display:none;'>
278 <td colspan="4"><table width="100%%" border="1">""" % (self.FfsIndex, self.FfsIndex, self.FfsIndex, FfsPath, FfsName, FfsGuid, FfsOffset, FfsType, self.FfsIndex)
279
280 if self.DispatchList:
281 if FfsObj.Type in [0x04, 0x06]:
282 self.DispatchList.write("%s %s %s %s\n" % (FfsGuid, "P", FfsName, FfsPath))
283 if FfsObj.Type in [0x05, 0x07, 0x08, 0x0A]:
284 self.DispatchList.write("%s %s %s %s\n" % (FfsGuid, "D", FfsName, FfsPath))
285
286 self.WriteLn(Content)
287
288 EotGlobalData.gOP_DISPATCH_ORDER.write('%s\n' %FfsName)
289
290 if FfsObj.Depex != '':
291 Content = """ <tr>
292 <td><span id='DepexHeader%s' class="styleDepex" onclick="Display('DepexHeader%s', 'Depex%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">&nbsp&nbspDEPEX expression</span></td>
293 </tr>
294 <tr id='Depex%s' style='display:none;'>
295 <td><table width="100%%" border="1">""" % (self.FfsIndex, self.FfsIndex, self.FfsIndex, self.FfsIndex)
296 self.WriteLn(Content)
297 self.GenerateDepex(FfsObj.Depex)
298 Content = """ </table></td>
299 </tr>"""
300 self.WriteLn(Content)
301 # End of DEPEX
302
303 # Find Consumed Ppi/Protocol
304 SqlCommand = """select ModuleName, ItemType, GuidName, GuidValue, GuidMacro from Report
305 where SourceFileFullPath in
306 (select Value1 from Inf where BelongsToFile =
307 (select BelongsToFile from Inf
308 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
309 and Model = %s)
310 and ItemMode = 'Consumed' group by GuidName order by ItemType""" \
311 % (FfsGuid, 5001, 3007)
312
313 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
314 if RecordSet != []:
315 Count = len(RecordSet)
316 Content = """ <tr>
317 <td><span id='ConsumedHeader%s' class="styleConsumed" onclick="Display('ConsumedHeader%s', 'Consumed%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">&nbsp&nbspConsumed Ppis/Protocols List (%s)</span></td>
318 </tr>
319 <tr id='Consumed%s' style='display:none;'>
320 <td><table width="100%%" border="1">""" % (self.FfsIndex, self.FfsIndex, self.FfsIndex, Count, self.FfsIndex)
321 self.WriteLn(Content)
322 self.ProtocolIndex = 0
323 for Record in RecordSet:
324 self.ProtocolIndex = self.ProtocolIndex + 1
325 Name = Record[2]
326 CName = Record[4]
327 Guid = Record[3]
328 Type = Record[1]
329 self.GeneratePpiProtocol(Type, Name, Guid, 'Consumed', CName)
330
331 Content = """ </table></td>
332 </tr>"""
333 self.WriteLn(Content)
334 #End of Consumed Ppi/Portocol
335
336 # Find Produced Ppi/Protocol
337 SqlCommand = """select ModuleName, ItemType, GuidName, GuidValue, GuidMacro from Report
338 where SourceFileFullPath in
339 (select Value1 from Inf where BelongsToFile =
340 (select BelongsToFile from Inf
341 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
342 and Model = %s)
343 and ItemMode = 'Produced' group by GuidName order by ItemType""" \
344 % (FfsGuid, 5001, 3007)
345
346 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
347 if RecordSet != []:
348 Count = len(RecordSet)
349 Content = """ <tr>
350 <td><span id='ProducedHeader%s' class="styleProduced" onclick="Display('ProducedHeader%s', 'Produced%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">&nbsp&nbspProduced Ppis/Protocols List (%s)</span></td>
351 </tr>
352 <tr id='Produced%s' style='display:none;'>
353 <td><table width="100%%" border="1">""" % (self.FfsIndex, self.FfsIndex, self.FfsIndex, Count, self.FfsIndex)
354 self.WriteLn(Content)
355 self.PpiIndex = 0
356 for Record in RecordSet:
357 self.PpiIndex = self.PpiIndex + 1
358 Name = Record[2]
359 CName = Record[4]
360 Guid = Record[3]
361 Type = Record[1]
362 self.GeneratePpiProtocol(Type, Name, Guid, 'Produced', CName)
363
364 Content = """ </table></td>
365 </tr>"""
366 self.WriteLn(Content)
367 RecordSet = None
368 # End of Produced Ppi/Protocol
369
370 Content = """ </table></td>
371 </tr>"""
372 self.WriteLn(Content)
373
374 ## GenerateTail() method
375 #
376 # Generate end tags of HTML report
377 #
378 # @param self: The object pointer
379 #
380 def GenerateTail(self):
381 Tail = """</table>
382 </body>
383 </html>"""
384 self.WriteLn(Tail)
385
386 ## GenerateHeader() method
387 #
388 # Generate start tags of HTML report
389 #
390 # @param self: The object pointer
391 #
392 def GenerateHeader(self):
393 Header = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
394 "http://www.w3.org/TR/html4/loose.dtd">
395 <html>
396 <head>
397 <title>Execution Order Tool Report</title>
398 <meta http-equiv="Content-Type" content="text/html">
399 <style type="text/css">
400 <!--
401 .styleFfs {
402 color: #006600;
403 font-weight: bold;
404 }
405 .styleDepex {
406 color: #FF0066;
407 font-weight: bold;
408 }
409 .styleProduced {
410 color: #0000FF;
411 font-weight: bold;
412 }
413 .styleConsumed {
414 color: #FF00FF;
415 font-weight: bold;
416 }
417 -->
418 </style>
419 <Script type="text/javascript">
420 function Display(ParentID, SubID)
421 {
422 SubItem = document.getElementById(SubID);
423 ParentItem = document.getElementById(ParentID);
424 if (SubItem.style.display == 'none')
425 {
426 SubItem.style.display = ''
427 ParentItem.style.fontWeight = 'normal'
428 }
429 else
430 {
431 SubItem.style.display = 'none'
432 ParentItem.style.fontWeight = 'bold'
433 }
434
435 }
436
437 function funOnMouseOver()
438 {
439 document.body.style.cursor = "hand";
440 }
441
442 function funOnMouseOut()
443 {
444 document.body.style.cursor = "";
445 }
446
447 </Script>
448 </head>
449
450 <body>
451 <table width="100%%" border="1">"""
452 self.WriteLn(Header)
453
454 ##
455 #
456 # This acts like the main() function for the script, unless it is 'import'ed into another
457 # script.
458 #
459 if __name__ == '__main__':
460 # Initialize log system
461 FilePath = 'FVRECOVERYFLOPPY.fv'
462 if FilePath.lower().endswith(".fv"):
463 fd = open(FilePath, 'rb')
464 buf = array('B')
465 try:
466 buf.fromfile(fd, os.path.getsize(FilePath))
467 except EOFError:
468 pass
469
470 fv = FirmwareVolume("FVRECOVERY", buf, 0)
471
472 report = Report('Report.html', fv)
473 report.GenerateReport()