]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Eot/Parser.py
MdeModulePkg:
[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
5# Copyright (c) 2008 - 2010, Intel Corporation\r
6# All rights reserved. This program and the accompanying materials\r
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
18import os, re\r
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
24from Common.Misc import sdict\r
25\r
26## PreProcess() method\r
27#\r
28# Pre process a file\r
29#\r
30# 1. Remove all comments\r
31# 2. Merge multiple lines code to one line\r
32#\r
33# @param Filename: Name of the file to be parsed\r
34# @param MergeMultipleLines: Switch for if merge multiple lines\r
35# @param LineNo: Default line no\r
36#\r
37# @return Lines: The file contents after remvoing comments\r
38#\r
39def PreProcess(Filename, MergeMultipleLines = True, LineNo = -1):\r
40 Lines = []\r
41 Filename = os.path.normpath(Filename)\r
42 if not os.path.isfile(Filename):\r
43 EdkLogger.error("Eot", EdkLogger.FILE_NOT_FOUND, ExtraData=Filename)\r
44\r
45 IsFindBlockComment = False\r
46 IsFindBlockCode = False\r
47 ReservedLine = ''\r
48 ReservedLineLength = 0\r
49 for Line in open(Filename, 'r'):\r
50 Line = Line.strip()\r
51 # Remove comment block\r
52 if Line.find(TAB_COMMENT_R8_START) > -1:\r
53 ReservedLine = GetSplitValueList(Line, TAB_COMMENT_R8_START, 1)[0]\r
54 IsFindBlockComment = True\r
55 if Line.find(TAB_COMMENT_R8_END) > -1:\r
56 Line = ReservedLine + GetSplitValueList(Line, TAB_COMMENT_R8_END, 1)[1]\r
57 ReservedLine = ''\r
58 IsFindBlockComment = False\r
59 if IsFindBlockComment:\r
60 Lines.append('')\r
61 continue\r
62\r
63 # Remove comments at tail and remove spaces again\r
64 Line = CleanString(Line)\r
65 if Line == '':\r
66 Lines.append('')\r
67 continue\r
68\r
69 if MergeMultipleLines:\r
70 # Add multiple lines to one line\r
71 if IsFindBlockCode and Line[-1] != TAB_SLASH:\r
72 ReservedLine = (ReservedLine + TAB_SPACE_SPLIT + Line).strip()\r
73 Lines.append(ReservedLine)\r
74 for Index in (0, ReservedLineLength):\r
75 Lines.append('')\r
76 ReservedLine = ''\r
77 ReservedLineLength = 0\r
78 IsFindBlockCode = False\r
79 continue\r
80 if Line[-1] == TAB_SLASH:\r
81 ReservedLine = ReservedLine + TAB_SPACE_SPLIT + Line[0:-1].strip()\r
82 ReservedLineLength = ReservedLineLength + 1\r
83 IsFindBlockCode = True\r
84 continue\r
85\r
86 Lines.append(Line)\r
87\r
88 return Lines\r
89\r
90## AddToGlobalMacro() method\r
91#\r
92# Add a macro to EotGlobalData.gMACRO\r
93#\r
94# @param Name: Name of the macro\r
95# @param Value: Value of the macro\r
96#\r
97def AddToGlobalMacro(Name, Value):\r
98 Value = ReplaceMacro(Value, EotGlobalData.gMACRO, True)\r
99 EotGlobalData.gMACRO[Name] = Value\r
100\r
101## AddToSelfMacro() method\r
102#\r
103# Parse a line of macro definition and add it to a macro set\r
104#\r
105# @param SelfMacro: The self macro set\r
106# @param Line: The line of a macro definition\r
107#\r
108# @return Name: Name of macro\r
109# @return Value: Value of macro\r
110#\r
111def AddToSelfMacro(SelfMacro, Line):\r
112 Name, Value = '', ''\r
113 List = GetSplitValueList(Line, TAB_EQUAL_SPLIT, 1)\r
114 if len(List) == 2:\r
115 Name = List[0]\r
116 Value = List[1]\r
117 Value = ReplaceMacro(Value, EotGlobalData.gMACRO, True)\r
118 Value = ReplaceMacro(Value, SelfMacro, True)\r
119 SelfMacro[Name] = Value\r
120\r
121 return (Name, Value)\r
122\r
123## GetIncludeListOfFile() method\r
124#\r
125# Get the include path list for a source file\r
126#\r
127# 1. Find the source file belongs to which INF file\r
128# 2. Find the inf's package\r
129# 3. Return the include path list of the package\r
130#\r
131# @param WorkSpace: WORKSPACE path\r
132# @param Filepath: File path\r
133# @param Db: Eot database\r
134#\r
135# @return IncludeList: A list of include directories\r
136#\r
137def GetIncludeListOfFile(WorkSpace, Filepath, Db):\r
138 IncludeList = []\r
139 Filepath = os.path.normpath(Filepath)\r
140 SqlCommand = """\r
141 select Value1 from Inf where Model = %s and BelongsToFile in(\r
142 select distinct B.BelongsToFile from File as A left join Inf as B\r
143 where A.ID = B.BelongsToFile and B.Model = %s and (A.Path || '%s' || B.Value1) = '%s')""" \\r
144 % (MODEL_META_DATA_PACKAGE, MODEL_EFI_SOURCE_FILE, '\\', Filepath)\r
145 RecordSet = Db.TblFile.Exec(SqlCommand)\r
146 for Record in RecordSet:\r
147 DecFullPath = os.path.normpath(os.path.join(WorkSpace, Record[0]))\r
148 (DecPath, DecName) = os.path.split(DecFullPath)\r
149 SqlCommand = """select Value1 from Dec where BelongsToFile =\r
150 (select ID from File where FullPath = '%s') and Model = %s""" \\r
151 % (DecFullPath, MODEL_EFI_INCLUDE)\r
152 NewRecordSet = Db.TblDec.Exec(SqlCommand)\r
153 for NewRecord in NewRecordSet:\r
154 IncludePath = os.path.normpath(os.path.join(DecPath, NewRecord[0]))\r
155 if IncludePath not in IncludeList:\r
156 IncludeList.append(IncludePath)\r
157\r
158 return IncludeList\r
159\r
160## GetTableList() method\r
161#\r
162# Search table file and find all small tables\r
163#\r
164# @param FileModelList: Model code for the file list\r
165# @param Table: Table to insert records\r
166# @param Db: Eot database\r
167#\r
168# @return TableList: A list of tables\r
169#\r
170def GetTableList(FileModelList, Table, Db):\r
171 TableList = []\r
172 SqlCommand = """select ID, FullPath from File where Model in %s""" % str(FileModelList)\r
173 RecordSet = Db.TblFile.Exec(SqlCommand)\r
174 for Record in RecordSet:\r
175 TableName = Table + str(Record[0])\r
176 TableList.append([TableName, Record[1]])\r
177\r
178 return TableList\r
179\r
180## GetAllIncludeDir() method\r
181#\r
182# Find all Include directories\r
183#\r
184# @param Db: Eot database\r
185#\r
186# @return IncludeList: A list of include directories\r
187#\r
188def GetAllIncludeDirs(Db):\r
189 IncludeList = []\r
190 SqlCommand = """select distinct Value1 from Inf where Model = %s order by Value1""" % MODEL_EFI_INCLUDE\r
191 RecordSet = Db.TblInf.Exec(SqlCommand)\r
192\r
193 for Record in RecordSet:\r
194 IncludeList.append(Record[0])\r
195\r
196 return IncludeList\r
197\r
198## GetAllIncludeFiles() method\r
199#\r
200# Find all Include files\r
201#\r
202# @param Db: Eot database\r
203#\r
204# @return IncludeFileList: A list of include files\r
205#\r
206def GetAllIncludeFiles(Db):\r
207 IncludeList = GetAllIncludeDirs(Db)\r
208 IncludeFileList = []\r
209\r
210 for Dir in IncludeList:\r
211 if os.path.isdir(Dir):\r
212 SubDir = os.listdir(Dir)\r
213 for Item in SubDir:\r
214 if os.path.isfile(Item):\r
215 IncludeFileList.append(Item)\r
216\r
217 return IncludeFileList\r
218\r
219## GetAllSourceFiles() method\r
220#\r
221# Find all source files\r
222#\r
223# @param Db: Eot database\r
224#\r
225# @return SourceFileList: A list of source files\r
226#\r
227def GetAllSourceFiles(Db):\r
228 SourceFileList = []\r
229 SqlCommand = """select distinct Value1 from Inf where Model = %s order by Value1""" % MODEL_EFI_SOURCE_FILE\r
230 RecordSet = Db.TblInf.Exec(SqlCommand)\r
231\r
232 for Record in RecordSet:\r
233 SourceFileList.append(Record[0])\r
234\r
235 return SourceFileList\r
236\r
237## GetAllFiles() method\r
238#\r
239# Find all files, both source files and include files\r
240#\r
241# @param Db: Eot database\r
242#\r
243# @return FileList: A list of files\r
244#\r
245def GetAllFiles(Db):\r
246 FileList = []\r
247 IncludeFileList = GetAllIncludeFiles(Db)\r
248 SourceFileList = GetAllSourceFiles(Db)\r
249 for Item in IncludeFileList:\r
250 if os.path.isfile(Item) and Item not in FileList:\r
251 FileList.append(Item)\r
252 for Item in SourceFileList:\r
253 if os.path.isfile(Item) and Item not in FileList:\r
254 FileList.append(Item)\r
255\r
256 return FileList\r
257\r
258## ParseConditionalStatement() method\r
259#\r
260# Parse conditional statement\r
261#\r
262# @param Line: One line to be parsed\r
263# @param Macros: A set of all macro\r
264# @param StatusSet: A set of all status\r
265#\r
266# @retval True: Find keyword of conditional statement\r
267# @retval False: Not find keyword of conditional statement\r
268#\r
269def ParseConditionalStatement(Line, Macros, StatusSet):\r
270 NewLine = Line.upper()\r
271 if NewLine.find(TAB_IF_EXIST.upper()) > -1:\r
272 IfLine = Line[NewLine.find(TAB_IF_EXIST) + len(TAB_IF_EXIST) + 1:].strip()\r
273 IfLine = ReplaceMacro(IfLine, EotGlobalData.gMACRO, True)\r
274 IfLine = ReplaceMacro(IfLine, Macros, True)\r
275 IfLine = IfLine.replace("\"", '')\r
276 IfLine = IfLine.replace("(", '')\r
277 IfLine = IfLine.replace(")", '')\r
278 Status = os.path.exists(os.path.normpath(IfLine))\r
279 StatusSet.append([Status])\r
280 return True\r
281 if NewLine.find(TAB_IF_DEF.upper()) > -1:\r
282 IfLine = Line[NewLine.find(TAB_IF_DEF) + len(TAB_IF_DEF) + 1:].strip()\r
283 Status = False\r
284 if IfLine in Macros or IfLine in EotGlobalData.gMACRO:\r
285 Status = True\r
286 StatusSet.append([Status])\r
287 return True\r
288 if NewLine.find(TAB_IF_N_DEF.upper()) > -1:\r
289 IfLine = Line[NewLine.find(TAB_IF_N_DEF) + len(TAB_IF_N_DEF) + 1:].strip()\r
290 Status = False\r
291 if IfLine not in Macros and IfLine not in EotGlobalData.gMACRO:\r
292 Status = True\r
293 StatusSet.append([Status])\r
294 return True\r
295 if NewLine.find(TAB_IF.upper()) > -1:\r
296 IfLine = Line[NewLine.find(TAB_IF) + len(TAB_IF) + 1:].strip()\r
297 Status = ParseConditionalStatementMacros(IfLine, Macros)\r
298 StatusSet.append([Status])\r
299 return True\r
300 if NewLine.find(TAB_ELSE_IF.upper()) > -1:\r
301 IfLine = Line[NewLine.find(TAB_ELSE_IF) + len(TAB_ELSE_IF) + 1:].strip()\r
302 Status = ParseConditionalStatementMacros(IfLine, Macros)\r
303 StatusSet[-1].append(Status)\r
304 return True\r
305 if NewLine.find(TAB_ELSE.upper()) > -1:\r
306 Status = False\r
307 for Item in StatusSet[-1]:\r
308 Status = Status or Item\r
309 StatusSet[-1].append(not Status)\r
310 return True\r
311 if NewLine.find(TAB_END_IF.upper()) > -1:\r
312 StatusSet.pop()\r
313 return True\r
314\r
315 return False\r
316\r
317## ParseConditionalStatement() method\r
318#\r
319# Parse conditional statement with Macros\r
320#\r
321# @param Line: One line to be parsed\r
322# @param Macros: A set of macros\r
323#\r
324# @return Line: New line after replacing macros\r
325#\r
326def ParseConditionalStatementMacros(Line, Macros):\r
327 if Line.upper().find('DEFINED(') > -1 or Line.upper().find('EXIST') > -1:\r
328 return False\r
329 Line = ReplaceMacro(Line, EotGlobalData.gMACRO, True)\r
330 Line = ReplaceMacro(Line, Macros, True)\r
331 Line = Line.replace("&&", "and")\r
332 Line = Line.replace("||", "or")\r
333 return eval(Line)\r
334\r
335## GetConditionalStatementStatus() method\r
336#\r
337# 1. Assume the latest status as True\r
338# 2. Pop the top status of status set, previous status\r
339# 3. Compare the latest one and the previous one and get new status\r
340#\r
341# @param StatusSet: A set of all status\r
342#\r
343# @return Status: The final status\r
344#\r
345def GetConditionalStatementStatus(StatusSet):\r
346 Status = True\r
347 for Item in StatusSet:\r
348 Status = Status and Item[-1]\r
349\r
350 return Status\r
351\r
352## SearchBelongsToFunction() method\r
353#\r
354# Search all functions belong to the file\r
355#\r
356# @param BelongsToFile: File id\r
357# @param StartLine: Start line of search scope\r
358# @param EndLine: End line of search scope\r
359#\r
360# @return: The found function\r
361#\r
362def SearchBelongsToFunction(BelongsToFile, StartLine, EndLine):\r
363 SqlCommand = """select ID, Name from Function where BelongsToFile = %s and StartLine <= %s and EndLine >= %s""" %(BelongsToFile, StartLine, EndLine)\r
364 RecordSet = EotGlobalData.gDb.TblFunction.Exec(SqlCommand)\r
365 if RecordSet != []:\r
366 return RecordSet[0][0], RecordSet[0][1]\r
367 else:\r
368 return -1, ''\r
369\r
370## SearchPpiCallFunction() method\r
371#\r
372# Search all used PPI calling function 'PeiServicesReInstallPpi' and 'PeiServicesInstallPpi'\r
373# Store the result to database\r
374#\r
375# @param Identifier: Table id\r
376# @param SourceFileID: Source file id\r
377# @param SourceFileFullPath: Source file full path\r
378# @param ItemMode: Mode of the item\r
379#\r
380def SearchPpiCallFunction(Identifier, SourceFileID, SourceFileFullPath, ItemMode):\r
381 ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Ppi', '', '', ''\r
382 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
383 where (Name like '%%%s%%' and Model = %s)""" \\r
384 % (Identifier, 'PeiServicesReInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
385 BelongsToFunctionID, BelongsToFunction = -1, ''\r
386 Db = EotGlobalData.gDb.TblReport\r
387 RecordSet = Db.Exec(SqlCommand)\r
388 for Record in RecordSet:\r
389 Index = 0\r
390 BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]\r
391 BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)\r
392 VariableList = Record[0].split(',')\r
393 for Variable in VariableList:\r
394 Variable = Variable.strip()\r
395 # Get index of the variable\r
396 if Variable.find('[') > -1:\r
397 Index = int(Variable[Variable.find('[') + 1 : Variable.find(']')])\r
398 Variable = Variable[:Variable.find('[')]\r
399 # Get variable name\r
400 if Variable.startswith('&'):\r
401 Variable = Variable[1:]\r
402 # Get variable value\r
403 SqlCommand = """select Value from %s where (Name like '%%%s%%') and Model = %s""" \\r
404 % (Identifier, Variable, MODEL_IDENTIFIER_VARIABLE)\r
405 NewRecordSet = Db.Exec(SqlCommand)\r
406 if NewRecordSet:\r
407 NewRecord = NewRecordSet[0][0]\r
408 VariableValueList = NewRecord.split('},')\r
409 if len(VariableValueList) > Index:\r
410 VariableValue = VariableValueList[Index]\r
411 NewVariableValueList = VariableValue.split(',')\r
412 if len(NewVariableValueList) > 1:\r
413 NewVariableValue = NewVariableValueList[1].strip()\r
414 if NewVariableValue.startswith('&'):\r
415 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, NewVariableValue[1:], GuidMacro, GuidValue, BelongsToFunction, 0)\r
416 continue\r
417 else:\r
418 EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, NewParameter))\r
419\r
420 ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Ppi', '', '', ''\r
421 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
422 where (Value like '%%%s%%' and Model = %s)""" \\r
423 % (Identifier, 'PeiServicesInstallPpi', MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION)\r
424 BelongsToFunctionID, BelongsToFunction = -1, ''\r
425 Db = EotGlobalData.gDb.TblReport\r
426 RecordSet = Db.Exec(SqlCommand)\r
427\r
428 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
429 where (Name like '%%%s%%' and Model = %s)""" \\r
430 % (Identifier, 'PeiServicesInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
431 Db = EotGlobalData.gDb.TblReport\r
432 RecordSet2 = Db.Exec(SqlCommand)\r
433\r
434 for Record in RecordSet + RecordSet2:\r
435 if Record == []:\r
436 continue\r
437 Index = 0\r
438 BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]\r
439 BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)\r
440 Variable = Record[0].replace('PeiServicesInstallPpi', '').replace('(', '').replace(')', '').replace('&', '').strip()\r
441 Variable = Variable[Variable.find(',') + 1:].strip()\r
442 # Get index of the variable\r
443 if Variable.find('[') > -1:\r
444 Index = int(Variable[Variable.find('[') + 1 : Variable.find(']')])\r
445 Variable = Variable[:Variable.find('[')]\r
446 # Get variable name\r
447 if Variable.startswith('&'):\r
448 Variable = Variable[1:]\r
449 # Get variable value\r
450 SqlCommand = """select Value from %s where (Name like '%%%s%%') and Model = %s""" \\r
451 % (Identifier, Variable, MODEL_IDENTIFIER_VARIABLE)\r
452 NewRecordSet = Db.Exec(SqlCommand)\r
453 if NewRecordSet:\r
454 NewRecord = NewRecordSet[0][0]\r
455 VariableValueList = NewRecord.split('},')\r
456 if len(VariableValueList) > Index:\r
457 VariableValue = VariableValueList[Index]\r
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
625 LibraryList = sdict()\r
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