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