]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Eot/Parser.py
edk2: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / BaseTools / Source / Python / Eot / Parser.py
CommitLineData
52302d4d
LG
1## @file\r
2# This file is used to define common parsing related functions used in parsing\r
3# Inf/Dsc/Makefile process\r
4#\r
47f15da1 5# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>\r
40d841f6 6# This program and the accompanying materials\r
52302d4d
LG
7# are licensed and made available under the terms and conditions of the BSD License\r
8# which accompanies this distribution. The full text of the license may be found at\r
9# http://opensource.org/licenses/bsd-license.php\r
10#\r
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13#\r
14\r
15##\r
16# Import Modules\r
17#\r
64429fbd 18from __future__ import absolute_import\r
1be2ed90 19import Common.LongFilePathOs as os, re\r
52302d4d
LG
20import Common.EdkLogger as EdkLogger\r
21from Common.DataType import *\r
22from CommonDataClass.DataClass import *\r
5a57246e 23from Common.StringUtils import CleanString, GetSplitValueList, ReplaceMacro\r
64429fbd 24from . import EotGlobalData\r
5a57246e 25from Common.StringUtils import GetSplitList\r
1be2ed90 26from Common.LongFilePathSupport import OpenLongFilePath as open\r
52302d4d 27\r
47f15da1
HC
28import subprocess\r
29\r
30## DeCompress\r
31#\r
32# Call external decompress tool to decompress the fv section\r
33#\r
34def DeCompress(Method, Input):\r
35 # Write the input to a temp file\r
36 open('_Temp.bin', 'wb').write(Input)\r
37 cmd = ''\r
38 if Method == 'Lzma':\r
39 cmd = r'LzmaCompress -o _New.bin -d _Temp.bin'\r
40 if Method == 'Efi':\r
41 cmd = r'TianoCompress -d --uefi -o _New.bin _Temp.bin'\r
42 if Method == 'Framework':\r
43 cmd = r'TianoCompress -d -o _New.bin _Temp.bin'\r
44\r
45 # Call tool to create the decompressed output file\r
46 Process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)\r
47 Process.communicate()[0]\r
48\r
49 # Return the beffer of New.bin\r
50 if os.path.exists('_New.bin'):\r
51 return open('_New.bin', 'rb').read()\r
52\r
53\r
52302d4d
LG
54## PreProcess() method\r
55#\r
56# Pre process a file\r
57#\r
58# 1. Remove all comments\r
59# 2. Merge multiple lines code to one line\r
60#\r
61# @param Filename: Name of the file to be parsed\r
62# @param MergeMultipleLines: Switch for if merge multiple lines\r
63# @param LineNo: Default line no\r
64#\r
fb0b35e0 65# @return Lines: The file contents after removing comments\r
52302d4d
LG
66#\r
67def PreProcess(Filename, MergeMultipleLines = True, LineNo = -1):\r
68 Lines = []\r
69 Filename = os.path.normpath(Filename)\r
70 if not os.path.isfile(Filename):\r
71 EdkLogger.error("Eot", EdkLogger.FILE_NOT_FOUND, ExtraData=Filename)\r
72\r
73 IsFindBlockComment = False\r
74 IsFindBlockCode = False\r
75 ReservedLine = ''\r
76 ReservedLineLength = 0\r
77 for Line in open(Filename, 'r'):\r
78 Line = Line.strip()\r
79 # Remove comment block\r
b36d134f 80 if Line.find(TAB_COMMENT_EDK_START) > -1:\r
d40b2ee6 81 ReservedLine = GetSplitList(Line, TAB_COMMENT_EDK_START, 1)[0]\r
52302d4d 82 IsFindBlockComment = True\r
b36d134f 83 if Line.find(TAB_COMMENT_EDK_END) > -1:\r
d40b2ee6 84 Line = ReservedLine + GetSplitList(Line, TAB_COMMENT_EDK_END, 1)[1]\r
52302d4d
LG
85 ReservedLine = ''\r
86 IsFindBlockComment = False\r
87 if IsFindBlockComment:\r
88 Lines.append('')\r
89 continue\r
90\r
91 # Remove comments at tail and remove spaces again\r
92 Line = CleanString(Line)\r
93 if Line == '':\r
94 Lines.append('')\r
95 continue\r
96\r
97 if MergeMultipleLines:\r
98 # Add multiple lines to one line\r
99 if IsFindBlockCode and Line[-1] != TAB_SLASH:\r
100 ReservedLine = (ReservedLine + TAB_SPACE_SPLIT + Line).strip()\r
101 Lines.append(ReservedLine)\r
102 for Index in (0, ReservedLineLength):\r
103 Lines.append('')\r
104 ReservedLine = ''\r
105 ReservedLineLength = 0\r
106 IsFindBlockCode = False\r
107 continue\r
108 if Line[-1] == TAB_SLASH:\r
109 ReservedLine = ReservedLine + TAB_SPACE_SPLIT + Line[0:-1].strip()\r
110 ReservedLineLength = ReservedLineLength + 1\r
111 IsFindBlockCode = True\r
112 continue\r
113\r
114 Lines.append(Line)\r
115\r
116 return Lines\r
117\r
118## AddToGlobalMacro() method\r
119#\r
120# Add a macro to EotGlobalData.gMACRO\r
121#\r
122# @param Name: Name of the macro\r
123# @param Value: Value of the macro\r
124#\r
125def AddToGlobalMacro(Name, Value):\r
126 Value = ReplaceMacro(Value, EotGlobalData.gMACRO, True)\r
127 EotGlobalData.gMACRO[Name] = Value\r
128\r
129## AddToSelfMacro() method\r
130#\r
131# Parse a line of macro definition and add it to a macro set\r
132#\r
133# @param SelfMacro: The self macro set\r
134# @param Line: The line of a macro definition\r
135#\r
136# @return Name: Name of macro\r
137# @return Value: Value of macro\r
138#\r
139def AddToSelfMacro(SelfMacro, Line):\r
140 Name, Value = '', ''\r
141 List = GetSplitValueList(Line, TAB_EQUAL_SPLIT, 1)\r
142 if len(List) == 2:\r
143 Name = List[0]\r
144 Value = List[1]\r
145 Value = ReplaceMacro(Value, EotGlobalData.gMACRO, True)\r
146 Value = ReplaceMacro(Value, SelfMacro, True)\r
147 SelfMacro[Name] = Value\r
148\r
149 return (Name, Value)\r
150\r
151## GetIncludeListOfFile() method\r
152#\r
153# Get the include path list for a source file\r
154#\r
155# 1. Find the source file belongs to which INF file\r
156# 2. Find the inf's package\r
157# 3. Return the include path list of the package\r
158#\r
159# @param WorkSpace: WORKSPACE path\r
160# @param Filepath: File path\r
161# @param Db: Eot database\r
162#\r
163# @return IncludeList: A list of include directories\r
164#\r
165def GetIncludeListOfFile(WorkSpace, Filepath, Db):\r
166 IncludeList = []\r
167 Filepath = os.path.normpath(Filepath)\r
168 SqlCommand = """\r
169 select Value1 from Inf where Model = %s and BelongsToFile in(\r
170 select distinct B.BelongsToFile from File as A left join Inf as B\r
171 where A.ID = B.BelongsToFile and B.Model = %s and (A.Path || '%s' || B.Value1) = '%s')""" \\r
172 % (MODEL_META_DATA_PACKAGE, MODEL_EFI_SOURCE_FILE, '\\', Filepath)\r
173 RecordSet = Db.TblFile.Exec(SqlCommand)\r
174 for Record in RecordSet:\r
175 DecFullPath = os.path.normpath(os.path.join(WorkSpace, Record[0]))\r
176 (DecPath, DecName) = os.path.split(DecFullPath)\r
177 SqlCommand = """select Value1 from Dec where BelongsToFile =\r
178 (select ID from File where FullPath = '%s') and Model = %s""" \\r
179 % (DecFullPath, MODEL_EFI_INCLUDE)\r
180 NewRecordSet = Db.TblDec.Exec(SqlCommand)\r
181 for NewRecord in NewRecordSet:\r
182 IncludePath = os.path.normpath(os.path.join(DecPath, NewRecord[0]))\r
183 if IncludePath not in IncludeList:\r
184 IncludeList.append(IncludePath)\r
185\r
186 return IncludeList\r
187\r
188## GetTableList() method\r
189#\r
190# Search table file and find all small tables\r
191#\r
192# @param FileModelList: Model code for the file list\r
193# @param Table: Table to insert records\r
194# @param Db: Eot database\r
195#\r
196# @return TableList: A list of tables\r
197#\r
198def GetTableList(FileModelList, Table, Db):\r
199 TableList = []\r
200 SqlCommand = """select ID, FullPath from File where Model in %s""" % str(FileModelList)\r
201 RecordSet = Db.TblFile.Exec(SqlCommand)\r
202 for Record in RecordSet:\r
203 TableName = Table + str(Record[0])\r
204 TableList.append([TableName, Record[1]])\r
205\r
206 return TableList\r
207\r
208## GetAllIncludeDir() method\r
209#\r
210# Find all Include directories\r
211#\r
212# @param Db: Eot database\r
213#\r
214# @return IncludeList: A list of include directories\r
215#\r
216def GetAllIncludeDirs(Db):\r
217 IncludeList = []\r
218 SqlCommand = """select distinct Value1 from Inf where Model = %s order by Value1""" % MODEL_EFI_INCLUDE\r
219 RecordSet = Db.TblInf.Exec(SqlCommand)\r
220\r
221 for Record in RecordSet:\r
222 IncludeList.append(Record[0])\r
223\r
224 return IncludeList\r
225\r
226## GetAllIncludeFiles() method\r
227#\r
228# Find all Include files\r
229#\r
230# @param Db: Eot database\r
231#\r
232# @return IncludeFileList: A list of include files\r
233#\r
234def GetAllIncludeFiles(Db):\r
235 IncludeList = GetAllIncludeDirs(Db)\r
236 IncludeFileList = []\r
237\r
238 for Dir in IncludeList:\r
239 if os.path.isdir(Dir):\r
240 SubDir = os.listdir(Dir)\r
241 for Item in SubDir:\r
242 if os.path.isfile(Item):\r
243 IncludeFileList.append(Item)\r
244\r
245 return IncludeFileList\r
246\r
247## GetAllSourceFiles() method\r
248#\r
249# Find all source files\r
250#\r
251# @param Db: Eot database\r
252#\r
253# @return SourceFileList: A list of source files\r
254#\r
255def GetAllSourceFiles(Db):\r
256 SourceFileList = []\r
257 SqlCommand = """select distinct Value1 from Inf where Model = %s order by Value1""" % MODEL_EFI_SOURCE_FILE\r
258 RecordSet = Db.TblInf.Exec(SqlCommand)\r
259\r
260 for Record in RecordSet:\r
261 SourceFileList.append(Record[0])\r
262\r
263 return SourceFileList\r
264\r
265## GetAllFiles() method\r
266#\r
267# Find all files, both source files and include files\r
268#\r
269# @param Db: Eot database\r
270#\r
271# @return FileList: A list of files\r
272#\r
273def GetAllFiles(Db):\r
274 FileList = []\r
275 IncludeFileList = GetAllIncludeFiles(Db)\r
276 SourceFileList = GetAllSourceFiles(Db)\r
277 for Item in IncludeFileList:\r
278 if os.path.isfile(Item) and Item not in FileList:\r
279 FileList.append(Item)\r
280 for Item in SourceFileList:\r
281 if os.path.isfile(Item) and Item not in FileList:\r
282 FileList.append(Item)\r
283\r
284 return FileList\r
285\r
286## ParseConditionalStatement() method\r
287#\r
288# Parse conditional statement\r
289#\r
290# @param Line: One line to be parsed\r
291# @param Macros: A set of all macro\r
292# @param StatusSet: A set of all status\r
293#\r
294# @retval True: Find keyword of conditional statement\r
295# @retval False: Not find keyword of conditional statement\r
296#\r
297def ParseConditionalStatement(Line, Macros, StatusSet):\r
298 NewLine = Line.upper()\r
299 if NewLine.find(TAB_IF_EXIST.upper()) > -1:\r
300 IfLine = Line[NewLine.find(TAB_IF_EXIST) + len(TAB_IF_EXIST) + 1:].strip()\r
301 IfLine = ReplaceMacro(IfLine, EotGlobalData.gMACRO, True)\r
302 IfLine = ReplaceMacro(IfLine, Macros, True)\r
303 IfLine = IfLine.replace("\"", '')\r
304 IfLine = IfLine.replace("(", '')\r
305 IfLine = IfLine.replace(")", '')\r
306 Status = os.path.exists(os.path.normpath(IfLine))\r
307 StatusSet.append([Status])\r
308 return True\r
309 if NewLine.find(TAB_IF_DEF.upper()) > -1:\r
310 IfLine = Line[NewLine.find(TAB_IF_DEF) + len(TAB_IF_DEF) + 1:].strip()\r
311 Status = False\r
312 if IfLine in Macros or IfLine in EotGlobalData.gMACRO:\r
313 Status = True\r
314 StatusSet.append([Status])\r
315 return True\r
316 if NewLine.find(TAB_IF_N_DEF.upper()) > -1:\r
317 IfLine = Line[NewLine.find(TAB_IF_N_DEF) + len(TAB_IF_N_DEF) + 1:].strip()\r
318 Status = False\r
319 if IfLine not in Macros and IfLine not in EotGlobalData.gMACRO:\r
320 Status = True\r
321 StatusSet.append([Status])\r
322 return True\r
323 if NewLine.find(TAB_IF.upper()) > -1:\r
324 IfLine = Line[NewLine.find(TAB_IF) + len(TAB_IF) + 1:].strip()\r
325 Status = ParseConditionalStatementMacros(IfLine, Macros)\r
326 StatusSet.append([Status])\r
327 return True\r
328 if NewLine.find(TAB_ELSE_IF.upper()) > -1:\r
329 IfLine = Line[NewLine.find(TAB_ELSE_IF) + len(TAB_ELSE_IF) + 1:].strip()\r
330 Status = ParseConditionalStatementMacros(IfLine, Macros)\r
331 StatusSet[-1].append(Status)\r
332 return True\r
333 if NewLine.find(TAB_ELSE.upper()) > -1:\r
334 Status = False\r
335 for Item in StatusSet[-1]:\r
336 Status = Status or Item\r
337 StatusSet[-1].append(not Status)\r
338 return True\r
339 if NewLine.find(TAB_END_IF.upper()) > -1:\r
340 StatusSet.pop()\r
341 return True\r
342\r
343 return False\r
344\r
345## ParseConditionalStatement() method\r
346#\r
347# Parse conditional statement with Macros\r
348#\r
349# @param Line: One line to be parsed\r
350# @param Macros: A set of macros\r
351#\r
352# @return Line: New line after replacing macros\r
353#\r
354def ParseConditionalStatementMacros(Line, Macros):\r
355 if Line.upper().find('DEFINED(') > -1 or Line.upper().find('EXIST') > -1:\r
356 return False\r
357 Line = ReplaceMacro(Line, EotGlobalData.gMACRO, True)\r
358 Line = ReplaceMacro(Line, Macros, True)\r
359 Line = Line.replace("&&", "and")\r
360 Line = Line.replace("||", "or")\r
361 return eval(Line)\r
362\r
363## GetConditionalStatementStatus() method\r
364#\r
365# 1. Assume the latest status as True\r
366# 2. Pop the top status of status set, previous status\r
367# 3. Compare the latest one and the previous one and get new status\r
368#\r
369# @param StatusSet: A set of all status\r
370#\r
371# @return Status: The final status\r
372#\r
373def GetConditionalStatementStatus(StatusSet):\r
374 Status = True\r
375 for Item in StatusSet:\r
376 Status = Status and Item[-1]\r
377\r
378 return Status\r
379\r
380## SearchBelongsToFunction() method\r
381#\r
382# Search all functions belong to the file\r
383#\r
384# @param BelongsToFile: File id\r
385# @param StartLine: Start line of search scope\r
386# @param EndLine: End line of search scope\r
387#\r
388# @return: The found function\r
389#\r
390def SearchBelongsToFunction(BelongsToFile, StartLine, EndLine):\r
391 SqlCommand = """select ID, Name from Function where BelongsToFile = %s and StartLine <= %s and EndLine >= %s""" %(BelongsToFile, StartLine, EndLine)\r
392 RecordSet = EotGlobalData.gDb.TblFunction.Exec(SqlCommand)\r
393 if RecordSet != []:\r
394 return RecordSet[0][0], RecordSet[0][1]\r
395 else:\r
396 return -1, ''\r
397\r
398## SearchPpiCallFunction() method\r
399#\r
400# Search all used PPI calling function 'PeiServicesReInstallPpi' and 'PeiServicesInstallPpi'\r
401# Store the result to database\r
402#\r
403# @param Identifier: Table id\r
404# @param SourceFileID: Source file id\r
405# @param SourceFileFullPath: Source file full path\r
406# @param ItemMode: Mode of the item\r
407#\r
408def SearchPpiCallFunction(Identifier, SourceFileID, SourceFileFullPath, ItemMode):\r
409 ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Ppi', '', '', ''\r
410 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
411 where (Name like '%%%s%%' and Model = %s)""" \\r
412 % (Identifier, 'PeiServicesReInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
413 BelongsToFunctionID, BelongsToFunction = -1, ''\r
414 Db = EotGlobalData.gDb.TblReport\r
415 RecordSet = Db.Exec(SqlCommand)\r
416 for Record in RecordSet:\r
417 Index = 0\r
418 BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]\r
419 BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)\r
420 VariableList = Record[0].split(',')\r
421 for Variable in VariableList:\r
422 Variable = Variable.strip()\r
423 # Get index of the variable\r
424 if Variable.find('[') > -1:\r
425 Index = int(Variable[Variable.find('[') + 1 : Variable.find(']')])\r
426 Variable = Variable[:Variable.find('[')]\r
427 # Get variable name\r
428 if Variable.startswith('&'):\r
429 Variable = Variable[1:]\r
430 # Get variable value\r
431 SqlCommand = """select Value from %s where (Name like '%%%s%%') and Model = %s""" \\r
432 % (Identifier, Variable, MODEL_IDENTIFIER_VARIABLE)\r
433 NewRecordSet = Db.Exec(SqlCommand)\r
434 if NewRecordSet:\r
435 NewRecord = NewRecordSet[0][0]\r
436 VariableValueList = NewRecord.split('},')\r
437 if len(VariableValueList) > Index:\r
438 VariableValue = VariableValueList[Index]\r
439 NewVariableValueList = VariableValue.split(',')\r
440 if len(NewVariableValueList) > 1:\r
441 NewVariableValue = NewVariableValueList[1].strip()\r
442 if NewVariableValue.startswith('&'):\r
443 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, NewVariableValue[1:], GuidMacro, GuidValue, BelongsToFunction, 0)\r
444 continue\r
445 else:\r
446 EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, NewParameter))\r
447\r
448 ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Ppi', '', '', ''\r
449 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
450 where (Value like '%%%s%%' and Model = %s)""" \\r
451 % (Identifier, 'PeiServicesInstallPpi', MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION)\r
452 BelongsToFunctionID, BelongsToFunction = -1, ''\r
453 Db = EotGlobalData.gDb.TblReport\r
454 RecordSet = Db.Exec(SqlCommand)\r
455\r
456 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
457 where (Name like '%%%s%%' and Model = %s)""" \\r
458 % (Identifier, 'PeiServicesInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
459 Db = EotGlobalData.gDb.TblReport\r
460 RecordSet2 = Db.Exec(SqlCommand)\r
461\r
462 for Record in RecordSet + RecordSet2:\r
463 if Record == []:\r
464 continue\r
465 Index = 0\r
466 BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]\r
467 BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)\r
468 Variable = Record[0].replace('PeiServicesInstallPpi', '').replace('(', '').replace(')', '').replace('&', '').strip()\r
469 Variable = Variable[Variable.find(',') + 1:].strip()\r
470 # Get index of the variable\r
471 if Variable.find('[') > -1:\r
472 Index = int(Variable[Variable.find('[') + 1 : Variable.find(']')])\r
473 Variable = Variable[:Variable.find('[')]\r
474 # Get variable name\r
475 if Variable.startswith('&'):\r
476 Variable = Variable[1:]\r
477 # Get variable value\r
478 SqlCommand = """select Value from %s where (Name like '%%%s%%') and Model = %s""" \\r
479 % (Identifier, Variable, MODEL_IDENTIFIER_VARIABLE)\r
480 NewRecordSet = Db.Exec(SqlCommand)\r
481 if NewRecordSet:\r
482 NewRecord = NewRecordSet[0][0]\r
483 VariableValueList = NewRecord.split('},')\r
40d841f6 484 for VariableValue in VariableValueList[Index:]:\r
52302d4d
LG
485 NewVariableValueList = VariableValue.split(',')\r
486 if len(NewVariableValueList) > 1:\r
487 NewVariableValue = NewVariableValueList[1].strip()\r
488 if NewVariableValue.startswith('&'):\r
489 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, NewVariableValue[1:], GuidMacro, GuidValue, BelongsToFunction, 0)\r
490 continue\r
491 else:\r
492 EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, NewParameter))\r
493\r
494## SearchPpis() method\r
495#\r
496# Search all used PPI calling function\r
497# Store the result to database\r
498#\r
499# @param SqlCommand: SQL command statement\r
500# @param Table: Table id\r
501# @param SourceFileID: Source file id\r
502# @param SourceFileFullPath: Source file full path\r
503# @param ItemMode: Mode of the item\r
504# @param PpiMode: Mode of PPI\r
505#\r
506def SearchPpi(SqlCommand, Table, SourceFileID, SourceFileFullPath, ItemMode, PpiMode = 1):\r
507 ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Ppi', '', '', ''\r
508 BelongsToFunctionID, BelongsToFunction = -1, ''\r
509 Db = EotGlobalData.gDb.TblReport\r
510 RecordSet = Db.Exec(SqlCommand)\r
511 for Record in RecordSet:\r
512 Parameter = GetPpiParameter(Record[0], PpiMode)\r
513 BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]\r
514 # Get BelongsToFunction\r
515 BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)\r
516\r
517 # Default is Not Found\r
518 IsFound = False\r
519\r
520 # For Consumed Ppi\r
521 if ItemMode == 'Consumed':\r
522 if Parameter.startswith('g'):\r
523 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, Parameter, GuidMacro, GuidValue, BelongsToFunction, 0)\r
524 else:\r
525 EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))\r
526 continue\r
527\r
528 # Direct Parameter.Guid\r
529 SqlCommand = """select Value from %s where (Name like '%%%s.Guid%%' or Name like '%%%s->Guid%%') and Model = %s""" % (Table, Parameter, Parameter, MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION)\r
530 NewRecordSet = Db.Exec(SqlCommand)\r
531 for NewRecord in NewRecordSet:\r
532 GuidName = GetParameterName(NewRecord[0])\r
533 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r
534 IsFound = True\r
535\r
536 # Defined Parameter\r
537 if not IsFound:\r
538 Key = Parameter\r
539 if Key.rfind(' ') > -1:\r
540 Key = Key[Key.rfind(' ') : ].strip().replace('&', '')\r
541 Value = FindKeyValue(EotGlobalData.gDb.TblFile, Table, Key)\r
542 List = GetSplitValueList(Value.replace('\n', ''), TAB_COMMA_SPLIT)\r
543 if len(List) > 1:\r
544 GuidName = GetParameterName(List[1])\r
545 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r
546 IsFound = True\r
547\r
548 # A list Parameter\r
549 if not IsFound:\r
550 Start = Parameter.find('[')\r
551 End = Parameter.find(']')\r
552 if Start > -1 and End > -1 and Start < End:\r
553 try:\r
554 Index = int(Parameter[Start + 1 : End])\r
555 Parameter = Parameter[0 : Start]\r
556 SqlCommand = """select Value from %s where Name = '%s' and Model = %s""" % (Table, Parameter, MODEL_IDENTIFIER_VARIABLE)\r
557 NewRecordSet = Db.Exec(SqlCommand)\r
558 for NewRecord in NewRecordSet:\r
559 NewParameter = GetSplitValueList(NewRecord[0], '}')[Index]\r
560 GuidName = GetPpiParameter(NewParameter[NewParameter.find('{') : ])\r
561 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r
562 IsFound = True\r
563 except Exception:\r
564 pass\r
565\r
566 # A External Parameter\r
567 if not IsFound:\r
568 SqlCommand = """select File.ID from Inf, File\r
569 where BelongsToFile = (select BelongsToFile from Inf where Value1 = '%s')\r
570 and Inf.Model = %s and Inf.Value1 = File.FullPath and File.Model = %s""" % (SourceFileFullPath, MODEL_EFI_SOURCE_FILE, MODEL_FILE_C)\r
571 NewRecordSet = Db.Exec(SqlCommand)\r
572 for NewRecord in NewRecordSet:\r
573 Table = 'Identifier' + str(NewRecord[0])\r
574 SqlCommand = """select Value from %s where Name = '%s' and Modifier = 'EFI_PEI_PPI_DESCRIPTOR' and Model = %s""" % (Table, Parameter, MODEL_IDENTIFIER_VARIABLE)\r
575 PpiSet = Db.Exec(SqlCommand)\r
576 if PpiSet != []:\r
577 GuidName = GetPpiParameter(PpiSet[0][0])\r
578 if GuidName != '':\r
579 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r
580 IsFound = True\r
581 break\r
582\r
583 if not IsFound:\r
584 EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))\r
585\r
586## SearchProtocols() method\r
587#\r
588# Search all used PROTOCOL calling function\r
589# Store the result to database\r
590#\r
591# @param SqlCommand: SQL command statement\r
592# @param Table: Table id\r
593# @param SourceFileID: Source file id\r
594# @param SourceFileFullPath: Source file full path\r
595# @param ItemMode: Mode of the item\r
596# @param ProtocolMode: Mode of PROTOCOL\r
597#\r
598def SearchProtocols(SqlCommand, Table, SourceFileID, SourceFileFullPath, ItemMode, ProtocolMode):\r
599 ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Protocol', '', '', ''\r
600 BelongsToFunctionID, BelongsToFunction = -1, ''\r
601 Db = EotGlobalData.gDb.TblReport\r
602 RecordSet = Db.Exec(SqlCommand)\r
603 for Record in RecordSet:\r
604 Parameter = ''\r
605 BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]\r
606 # Get BelongsToFunction\r
607 BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)\r
608\r
609 # Default is Not Found\r
610 IsFound = False\r
611\r
612 if ProtocolMode == 0 or ProtocolMode == 1:\r
613 Parameter = GetProtocolParameter(Record[0], ProtocolMode)\r
614 if Parameter.startswith('g') or Parameter.endswith('Guid') or Parameter == 'ShellEnvProtocol' or Parameter == 'ShellInterfaceProtocol':\r
615 GuidName = GetParameterName(Parameter)\r
616 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r
617 IsFound = True\r
618\r
619 if ProtocolMode == 2:\r
620 Protocols = GetSplitValueList(Record[0], TAB_COMMA_SPLIT)\r
621 for Protocol in Protocols:\r
622 if Protocol.startswith('&') and Protocol.endswith('Guid'):\r
623 GuidName = GetParameterName(Protocol)\r
624 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r
625 IsFound = True\r
626 else:\r
627 NewValue = FindKeyValue(EotGlobalData.gDb.TblFile, Table, Protocol)\r
628 if Protocol != NewValue and NewValue.endswith('Guid'):\r
629 GuidName = GetParameterName(NewValue)\r
630 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r
631 IsFound = True\r
632\r
633 if not IsFound:\r
634 if BelongsToFunction in EotGlobalData.gProducedProtocolLibrary or BelongsToFunction in EotGlobalData.gConsumedProtocolLibrary:\r
635 EotGlobalData.gOP_UN_MATCHED_IN_LIBRARY_CALLING.write('%s, %s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter, BelongsToFunction))\r
636 else:\r
637 EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))\r
638\r
639## SearchFunctionCalling() method\r
640#\r
641# Search all used PPI/PROTOCOL calling function by library\r
642# Store the result to database\r
643#\r
644# @param SqlCommand: SQL command statement\r
645# @param Table: Table id\r
646# @param SourceFileID: Source file id\r
647# @param SourceFileFullPath: Source file full path\r
648# @param ItemType: Type of the item, PPI or PROTOCOL\r
649# @param ItemMode: Mode of item\r
650#\r
651def SearchFunctionCalling(Table, SourceFileID, SourceFileFullPath, ItemType, ItemMode):\r
6e6d767e 652 LibraryList = {}\r
52302d4d
LG
653 Db = EotGlobalData.gDb.TblReport\r
654 Parameters, ItemName, GuidName, GuidMacro, GuidValue, BelongsToFunction = [], '', '', '', '', ''\r
655 if ItemType == 'Protocol' and ItemMode == 'Produced':\r
656 LibraryList = EotGlobalData.gProducedProtocolLibrary\r
657 elif ItemType == 'Protocol' and ItemMode == 'Consumed':\r
658 LibraryList = EotGlobalData.gConsumedProtocolLibrary\r
659 elif ItemType == 'Protocol' and ItemMode == 'Callback':\r
660 LibraryList = EotGlobalData.gCallbackProtocolLibrary\r
661 elif ItemType == 'Ppi' and ItemMode == 'Produced':\r
662 LibraryList = EotGlobalData.gProducedPpiLibrary\r
663 elif ItemType == 'Ppi' and ItemMode == 'Consumed':\r
664 LibraryList = EotGlobalData.gConsumedPpiLibrary\r
665\r
666 for Library in LibraryList:\r
667 Index = LibraryList[Library]\r
668 SqlCommand = """select Value, StartLine from %s\r
669 where Name like '%%%s%%' and Model = %s""" \\r
670 % (Table, Library, MODEL_IDENTIFIER_FUNCTION_CALLING)\r
671 RecordSet = Db.Exec(SqlCommand)\r
672 for Record in RecordSet:\r
673 IsFound = False\r
674 if Index == -1:\r
675 ParameterList = GetSplitValueList(Record[0], TAB_COMMA_SPLIT)\r
676 for Parameter in ParameterList:\r
677 Parameters.append(GetParameterName(Parameter))\r
678 else:\r
679 Parameters = [GetProtocolParameter(Record[0], Index)]\r
680 StartLine = Record[1]\r
681 for Parameter in Parameters:\r
682 if Parameter.startswith('g') or Parameter.endswith('Guid') or Parameter == 'ShellEnvProtocol' or Parameter == 'ShellInterfaceProtocol':\r
683 GuidName = GetParameterName(Parameter)\r
684 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r
685 IsFound = True\r
686\r
687 if not IsFound:\r
688 EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))\r
689\r
690## FindProtocols() method\r
691#\r
692# Find defined protocols\r
693#\r
694# @param SqlCommand: SQL command statement\r
695# @param Table: Table id\r
696# @param SourceFileID: Source file id\r
697# @param SourceFileFullPath: Source file full path\r
698# @param ItemName: String of protocol definition\r
699# @param ItemType: Type of the item, PPI or PROTOCOL\r
700# @param ItemMode: Mode of item\r
701#\r
702#def FindProtocols(Db, SqlCommand, Table, SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue):\r
703# BelongsToFunction = ''\r
704# RecordSet = Db.Exec(SqlCommand)\r
705# for Record in RecordSet:\r
706# IsFound = True\r
707# Parameter = GetProtocolParameter(Record[0])\r
708\r
709## GetProtocolParameter() method\r
710#\r
711# Parse string of protocol and find parameters\r
712#\r
713# @param Parameter: Parameter to be parsed\r
714# @param Index: The index of the parameter\r
715#\r
716# @return: call common GetParameter\r
717#\r
718def GetProtocolParameter(Parameter, Index = 1):\r
719 return GetParameter(Parameter, Index)\r
720\r
721## GetPpiParameter() method\r
722#\r
723# Parse string of ppi and find parameters\r
724#\r
725# @param Parameter: Parameter to be parsed\r
726# @param Index: The index of the parameter\r
727#\r
728# @return: call common GetParameter\r
729#\r
730def GetPpiParameter(Parameter, Index = 1):\r
731 return GetParameter(Parameter, Index)\r
732\r
733## GetParameter() method\r
734#\r
735# Get a parameter by index\r
736#\r
737# @param Parameter: Parameter to be parsed\r
738# @param Index: The index of the parameter\r
739#\r
740# @return Parameter: The found parameter\r
741#\r
742def GetParameter(Parameter, Index = 1):\r
743 ParameterList = GetSplitValueList(Parameter, TAB_COMMA_SPLIT)\r
744 if len(ParameterList) > Index:\r
745 Parameter = GetParameterName(ParameterList[Index])\r
746\r
747 return Parameter\r
748\r
749 return ''\r
750\r
751## GetParameterName() method\r
752#\r
753# Get a parameter name\r
754#\r
755# @param Parameter: Parameter to be parsed\r
756#\r
757# @return: The name of parameter\r
758#\r
759def GetParameterName(Parameter):\r
0d1f5b2b 760 if isinstance(Parameter, type('')) and Parameter.startswith('&'):\r
52302d4d
LG
761 return Parameter[1:].replace('{', '').replace('}', '').replace('\r', '').replace('\n', '').strip()\r
762 else:\r
763 return Parameter.strip()\r
764\r
765## FindKeyValue() method\r
766#\r
767# Find key value of a variable\r
768#\r
769# @param Db: Database to be searched\r
770# @param Table: Table to be searched\r
771# @param Key: The keyword\r
772#\r
fb0b35e0 773# @return Value: The value of the keyword\r
52302d4d
LG
774#\r
775def FindKeyValue(Db, Table, Key):\r
776 SqlCommand = """select Value from %s where Name = '%s' and (Model = %s or Model = %s)""" % (Table, Key, MODEL_IDENTIFIER_VARIABLE, MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION)\r
777 RecordSet = Db.Exec(SqlCommand)\r
778 Value = ''\r
779 for Record in RecordSet:\r
780 if Record[0] != 'NULL':\r
781 Value = FindKeyValue(Db, Table, GetParameterName(Record[0]))\r
782\r
783 if Value != '':\r
784 return Value\r
785 else:\r
786 return Key\r
787\r
788## ParseMapFile() method\r
789#\r
790# Parse map files to get a dict of 'ModuleName' : {FunName : FunAddress}\r
791#\r
792# @param Files: A list of map files\r
793#\r
794# @return AllMaps: An object of all map files\r
795#\r
796def ParseMapFile(Files):\r
797 AllMaps = {}\r
798 CurrentModule = ''\r
799 CurrentMaps = {}\r
800 for File in Files:\r
801 Content = open(File, 'r').readlines()\r
802 for Line in Content:\r
803 Line = CleanString(Line)\r
804 # skip empty line\r
805 if Line == '':\r
806 continue\r
807\r
808 if Line.find('(') > -1 and Line.find(')') > -1:\r
809 if CurrentModule != '' and CurrentMaps != {}:\r
810 AllMaps[CurrentModule] = CurrentMaps\r
811 CurrentModule = Line[:Line.find('(')]\r
812 CurrentMaps = {}\r
813 continue\r
814 else:\r
815 Name = ''\r
816 Address = ''\r
817 List = Line.split()\r
818 Address = List[0]\r
819 if List[1] == 'F' or List[1] == 'FS':\r
820 Name = List[2]\r
821 else:\r
822 Name = List[1]\r
823 CurrentMaps[Name] = Address\r
824 continue\r
825\r
826 return AllMaps\r
827\r
828## ConvertGuid\r
829#\r
830# Convert a GUID to a GUID with all upper letters\r
831#\r
832# @param guid: The GUID to be converted\r
833#\r
834# @param newGuid: The GUID with all upper letters.\r
835#\r
836def ConvertGuid(guid):\r
837 numList = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']\r
838 newGuid = ''\r
839 if guid.startswith('g'):\r
840 guid = guid[1:]\r
841 for i in guid:\r
842 if i.upper() == i and i not in numList:\r
843 newGuid = newGuid + ('_' + i)\r
844 else:\r
845 newGuid = newGuid + i.upper()\r
846 if newGuid.startswith('_'):\r
847 newGuid = newGuid[1:]\r
848 if newGuid.endswith('_'):\r
849 newGuid = newGuid[:-1]\r
850\r
851 return newGuid\r
852\r
853## ConvertGuid2() method\r
854#\r
855# Convert a GUID to a GUID with new string instead of old string\r
856#\r
857# @param guid: The GUID to be converted\r
858# @param old: Old string to be replaced\r
859# @param new: New string to replace the old one\r
860#\r
861# @param newGuid: The GUID after replacement\r
862#\r
863def ConvertGuid2(guid, old, new):\r
864 newGuid = ConvertGuid(guid)\r
865 newGuid = newGuid.replace(old, new)\r
866\r
867 return newGuid\r
868\r
869##\r
870#\r
871# This acts like the main() function for the script, unless it is 'import'ed into another\r
872# script.\r
873#\r
874if __name__ == '__main__':\r
875 pass\r