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