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