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