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# 18import Common.LongFilePathOs as os, re 19import Common.EdkLogger as EdkLogger 20from Common.DataType import * 21from CommonDataClass.DataClass import * 22from Common.String import CleanString, GetSplitValueList, ReplaceMacro 23import EotGlobalData 24from Common.Misc import sdict 25from Common.String import GetSplitList 26from 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# 41def 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# 99def 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# 113def 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# 139def 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# 172def 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# 190def 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# 208def 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# 229def 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# 247def 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# 271def 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# 328def 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# 347def 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# 364def 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# 382def 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# 480def 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# 572def 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# 625def SearchFunctionCalling(Table, SourceFileID, SourceFileFullPath, ItemType, ItemMode): 626 LibraryList = sdict() 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# 692def 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# 704def 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# 716def 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# 733def GetParameterName(Parameter): 734 if type(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# 749def 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# 770def 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# 810def 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# 837def 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# 848if __name__ == '__main__': 849 pass 850