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