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