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