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