]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Eot/Parser.py
Sync EDKII BaseTools to BaseTools project r1903.
[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
6 # All rights reserved. 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_R8_START) > -1:
53 ReservedLine = GetSplitValueList(Line, TAB_COMMENT_R8_START, 1)[0]
54 IsFindBlockComment = True
55 if Line.find(TAB_COMMENT_R8_END) > -1:
56 Line = ReservedLine + GetSplitValueList(Line, TAB_COMMENT_R8_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 if len(VariableValueList) > Index:
457 VariableValue = VariableValueList[Index]
458 NewVariableValueList = VariableValue.split(',')
459 if len(NewVariableValueList) > 1:
460 NewVariableValue = NewVariableValueList[1].strip()
461 if NewVariableValue.startswith('&'):
462 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, NewVariableValue[1:], GuidMacro, GuidValue, BelongsToFunction, 0)
463 continue
464 else:
465 EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, NewParameter))
466
467 ## SearchPpis() method
468 #
469 # Search all used PPI calling function
470 # Store the result to database
471 #
472 # @param SqlCommand: SQL command statement
473 # @param Table: Table id
474 # @param SourceFileID: Source file id
475 # @param SourceFileFullPath: Source file full path
476 # @param ItemMode: Mode of the item
477 # @param PpiMode: Mode of PPI
478 #
479 def SearchPpi(SqlCommand, Table, SourceFileID, SourceFileFullPath, ItemMode, PpiMode = 1):
480 ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Ppi', '', '', ''
481 BelongsToFunctionID, BelongsToFunction = -1, ''
482 Db = EotGlobalData.gDb.TblReport
483 RecordSet = Db.Exec(SqlCommand)
484 for Record in RecordSet:
485 Parameter = GetPpiParameter(Record[0], PpiMode)
486 BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]
487 # Get BelongsToFunction
488 BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)
489
490 # Default is Not Found
491 IsFound = False
492
493 # For Consumed Ppi
494 if ItemMode == 'Consumed':
495 if Parameter.startswith('g'):
496 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, Parameter, GuidMacro, GuidValue, BelongsToFunction, 0)
497 else:
498 EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))
499 continue
500
501 # Direct Parameter.Guid
502 SqlCommand = """select Value from %s where (Name like '%%%s.Guid%%' or Name like '%%%s->Guid%%') and Model = %s""" % (Table, Parameter, Parameter, MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION)
503 NewRecordSet = Db.Exec(SqlCommand)
504 for NewRecord in NewRecordSet:
505 GuidName = GetParameterName(NewRecord[0])
506 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
507 IsFound = True
508
509 # Defined Parameter
510 if not IsFound:
511 Key = Parameter
512 if Key.rfind(' ') > -1:
513 Key = Key[Key.rfind(' ') : ].strip().replace('&', '')
514 Value = FindKeyValue(EotGlobalData.gDb.TblFile, Table, Key)
515 List = GetSplitValueList(Value.replace('\n', ''), TAB_COMMA_SPLIT)
516 if len(List) > 1:
517 GuidName = GetParameterName(List[1])
518 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
519 IsFound = True
520
521 # A list Parameter
522 if not IsFound:
523 Start = Parameter.find('[')
524 End = Parameter.find(']')
525 if Start > -1 and End > -1 and Start < End:
526 try:
527 Index = int(Parameter[Start + 1 : End])
528 Parameter = Parameter[0 : Start]
529 SqlCommand = """select Value from %s where Name = '%s' and Model = %s""" % (Table, Parameter, MODEL_IDENTIFIER_VARIABLE)
530 NewRecordSet = Db.Exec(SqlCommand)
531 for NewRecord in NewRecordSet:
532 NewParameter = GetSplitValueList(NewRecord[0], '}')[Index]
533 GuidName = GetPpiParameter(NewParameter[NewParameter.find('{') : ])
534 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
535 IsFound = True
536 except Exception:
537 pass
538
539 # A External Parameter
540 if not IsFound:
541 SqlCommand = """select File.ID from Inf, File
542 where BelongsToFile = (select BelongsToFile from Inf where Value1 = '%s')
543 and Inf.Model = %s and Inf.Value1 = File.FullPath and File.Model = %s""" % (SourceFileFullPath, MODEL_EFI_SOURCE_FILE, MODEL_FILE_C)
544 NewRecordSet = Db.Exec(SqlCommand)
545 for NewRecord in NewRecordSet:
546 Table = 'Identifier' + str(NewRecord[0])
547 SqlCommand = """select Value from %s where Name = '%s' and Modifier = 'EFI_PEI_PPI_DESCRIPTOR' and Model = %s""" % (Table, Parameter, MODEL_IDENTIFIER_VARIABLE)
548 PpiSet = Db.Exec(SqlCommand)
549 if PpiSet != []:
550 GuidName = GetPpiParameter(PpiSet[0][0])
551 if GuidName != '':
552 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
553 IsFound = True
554 break
555
556 if not IsFound:
557 EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))
558
559 ## SearchProtocols() method
560 #
561 # Search all used PROTOCOL calling function
562 # Store the result to database
563 #
564 # @param SqlCommand: SQL command statement
565 # @param Table: Table id
566 # @param SourceFileID: Source file id
567 # @param SourceFileFullPath: Source file full path
568 # @param ItemMode: Mode of the item
569 # @param ProtocolMode: Mode of PROTOCOL
570 #
571 def SearchProtocols(SqlCommand, Table, SourceFileID, SourceFileFullPath, ItemMode, ProtocolMode):
572 ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Protocol', '', '', ''
573 BelongsToFunctionID, BelongsToFunction = -1, ''
574 Db = EotGlobalData.gDb.TblReport
575 RecordSet = Db.Exec(SqlCommand)
576 for Record in RecordSet:
577 Parameter = ''
578 BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]
579 # Get BelongsToFunction
580 BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)
581
582 # Default is Not Found
583 IsFound = False
584
585 if ProtocolMode == 0 or ProtocolMode == 1:
586 Parameter = GetProtocolParameter(Record[0], ProtocolMode)
587 if Parameter.startswith('g') or Parameter.endswith('Guid') or Parameter == 'ShellEnvProtocol' or Parameter == 'ShellInterfaceProtocol':
588 GuidName = GetParameterName(Parameter)
589 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
590 IsFound = True
591
592 if ProtocolMode == 2:
593 Protocols = GetSplitValueList(Record[0], TAB_COMMA_SPLIT)
594 for Protocol in Protocols:
595 if Protocol.startswith('&') and Protocol.endswith('Guid'):
596 GuidName = GetParameterName(Protocol)
597 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
598 IsFound = True
599 else:
600 NewValue = FindKeyValue(EotGlobalData.gDb.TblFile, Table, Protocol)
601 if Protocol != NewValue and NewValue.endswith('Guid'):
602 GuidName = GetParameterName(NewValue)
603 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
604 IsFound = True
605
606 if not IsFound:
607 if BelongsToFunction in EotGlobalData.gProducedProtocolLibrary or BelongsToFunction in EotGlobalData.gConsumedProtocolLibrary:
608 EotGlobalData.gOP_UN_MATCHED_IN_LIBRARY_CALLING.write('%s, %s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter, BelongsToFunction))
609 else:
610 EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))
611
612 ## SearchFunctionCalling() method
613 #
614 # Search all used PPI/PROTOCOL calling function by library
615 # Store the result to database
616 #
617 # @param SqlCommand: SQL command statement
618 # @param Table: Table id
619 # @param SourceFileID: Source file id
620 # @param SourceFileFullPath: Source file full path
621 # @param ItemType: Type of the item, PPI or PROTOCOL
622 # @param ItemMode: Mode of item
623 #
624 def SearchFunctionCalling(Table, SourceFileID, SourceFileFullPath, ItemType, ItemMode):
625 LibraryList = sdict()
626 Db = EotGlobalData.gDb.TblReport
627 Parameters, ItemName, GuidName, GuidMacro, GuidValue, BelongsToFunction = [], '', '', '', '', ''
628 if ItemType == 'Protocol' and ItemMode == 'Produced':
629 LibraryList = EotGlobalData.gProducedProtocolLibrary
630 elif ItemType == 'Protocol' and ItemMode == 'Consumed':
631 LibraryList = EotGlobalData.gConsumedProtocolLibrary
632 elif ItemType == 'Protocol' and ItemMode == 'Callback':
633 LibraryList = EotGlobalData.gCallbackProtocolLibrary
634 elif ItemType == 'Ppi' and ItemMode == 'Produced':
635 LibraryList = EotGlobalData.gProducedPpiLibrary
636 elif ItemType == 'Ppi' and ItemMode == 'Consumed':
637 LibraryList = EotGlobalData.gConsumedPpiLibrary
638
639 for Library in LibraryList:
640 Index = LibraryList[Library]
641 SqlCommand = """select Value, StartLine from %s
642 where Name like '%%%s%%' and Model = %s""" \
643 % (Table, Library, MODEL_IDENTIFIER_FUNCTION_CALLING)
644 RecordSet = Db.Exec(SqlCommand)
645 for Record in RecordSet:
646 IsFound = False
647 if Index == -1:
648 ParameterList = GetSplitValueList(Record[0], TAB_COMMA_SPLIT)
649 for Parameter in ParameterList:
650 Parameters.append(GetParameterName(Parameter))
651 else:
652 Parameters = [GetProtocolParameter(Record[0], Index)]
653 StartLine = Record[1]
654 for Parameter in Parameters:
655 if Parameter.startswith('g') or Parameter.endswith('Guid') or Parameter == 'ShellEnvProtocol' or Parameter == 'ShellInterfaceProtocol':
656 GuidName = GetParameterName(Parameter)
657 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
658 IsFound = True
659
660 if not IsFound:
661 EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))
662
663 ## FindProtocols() method
664 #
665 # Find defined protocols
666 #
667 # @param SqlCommand: SQL command statement
668 # @param Table: Table id
669 # @param SourceFileID: Source file id
670 # @param SourceFileFullPath: Source file full path
671 # @param ItemName: String of protocol definition
672 # @param ItemType: Type of the item, PPI or PROTOCOL
673 # @param ItemMode: Mode of item
674 #
675 #def FindProtocols(Db, SqlCommand, Table, SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue):
676 # BelongsToFunction = ''
677 # RecordSet = Db.Exec(SqlCommand)
678 # for Record in RecordSet:
679 # IsFound = True
680 # Parameter = GetProtocolParameter(Record[0])
681
682 ## GetProtocolParameter() method
683 #
684 # Parse string of protocol and find parameters
685 #
686 # @param Parameter: Parameter to be parsed
687 # @param Index: The index of the parameter
688 #
689 # @return: call common GetParameter
690 #
691 def GetProtocolParameter(Parameter, Index = 1):
692 return GetParameter(Parameter, Index)
693
694 ## GetPpiParameter() method
695 #
696 # Parse string of ppi and find parameters
697 #
698 # @param Parameter: Parameter to be parsed
699 # @param Index: The index of the parameter
700 #
701 # @return: call common GetParameter
702 #
703 def GetPpiParameter(Parameter, Index = 1):
704 return GetParameter(Parameter, Index)
705
706 ## GetParameter() method
707 #
708 # Get a parameter by index
709 #
710 # @param Parameter: Parameter to be parsed
711 # @param Index: The index of the parameter
712 #
713 # @return Parameter: The found parameter
714 #
715 def GetParameter(Parameter, Index = 1):
716 ParameterList = GetSplitValueList(Parameter, TAB_COMMA_SPLIT)
717 if len(ParameterList) > Index:
718 Parameter = GetParameterName(ParameterList[Index])
719
720 return Parameter
721
722 return ''
723
724 ## GetParameterName() method
725 #
726 # Get a parameter name
727 #
728 # @param Parameter: Parameter to be parsed
729 #
730 # @return: The name of parameter
731 #
732 def GetParameterName(Parameter):
733 if type(Parameter) == type('') and Parameter.startswith('&'):
734 return Parameter[1:].replace('{', '').replace('}', '').replace('\r', '').replace('\n', '').strip()
735 else:
736 return Parameter.strip()
737
738 ## FindKeyValue() method
739 #
740 # Find key value of a variable
741 #
742 # @param Db: Database to be searched
743 # @param Table: Table to be searched
744 # @param Key: The keyword
745 #
746 # @return Value: The value of the the keyword
747 #
748 def FindKeyValue(Db, Table, Key):
749 SqlCommand = """select Value from %s where Name = '%s' and (Model = %s or Model = %s)""" % (Table, Key, MODEL_IDENTIFIER_VARIABLE, MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION)
750 RecordSet = Db.Exec(SqlCommand)
751 Value = ''
752 for Record in RecordSet:
753 if Record[0] != 'NULL':
754 Value = FindKeyValue(Db, Table, GetParameterName(Record[0]))
755
756 if Value != '':
757 return Value
758 else:
759 return Key
760
761 ## ParseMapFile() method
762 #
763 # Parse map files to get a dict of 'ModuleName' : {FunName : FunAddress}
764 #
765 # @param Files: A list of map files
766 #
767 # @return AllMaps: An object of all map files
768 #
769 def ParseMapFile(Files):
770 AllMaps = {}
771 CurrentModule = ''
772 CurrentMaps = {}
773 for File in Files:
774 Content = open(File, 'r').readlines()
775 for Line in Content:
776 Line = CleanString(Line)
777 # skip empty line
778 if Line == '':
779 continue
780
781 if Line.find('(') > -1 and Line.find(')') > -1:
782 if CurrentModule != '' and CurrentMaps != {}:
783 AllMaps[CurrentModule] = CurrentMaps
784 CurrentModule = Line[:Line.find('(')]
785 CurrentMaps = {}
786 continue
787 else:
788 Name = ''
789 Address = ''
790 List = Line.split()
791 Address = List[0]
792 if List[1] == 'F' or List[1] == 'FS':
793 Name = List[2]
794 else:
795 Name = List[1]
796 CurrentMaps[Name] = Address
797 continue
798
799 return AllMaps
800
801 ## ConvertGuid
802 #
803 # Convert a GUID to a GUID with all upper letters
804 #
805 # @param guid: The GUID to be converted
806 #
807 # @param newGuid: The GUID with all upper letters.
808 #
809 def ConvertGuid(guid):
810 numList = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
811 newGuid = ''
812 if guid.startswith('g'):
813 guid = guid[1:]
814 for i in guid:
815 if i.upper() == i and i not in numList:
816 newGuid = newGuid + ('_' + i)
817 else:
818 newGuid = newGuid + i.upper()
819 if newGuid.startswith('_'):
820 newGuid = newGuid[1:]
821 if newGuid.endswith('_'):
822 newGuid = newGuid[:-1]
823
824 return newGuid
825
826 ## ConvertGuid2() method
827 #
828 # Convert a GUID to a GUID with new string instead of old string
829 #
830 # @param guid: The GUID to be converted
831 # @param old: Old string to be replaced
832 # @param new: New string to replace the old one
833 #
834 # @param newGuid: The GUID after replacement
835 #
836 def ConvertGuid2(guid, old, new):
837 newGuid = ConvertGuid(guid)
838 newGuid = newGuid.replace(old, new)
839
840 return newGuid
841
842 ##
843 #
844 # This acts like the main() function for the script, unless it is 'import'ed into another
845 # script.
846 #
847 if __name__ == '__main__':
848 pass