Home | History | Annotate | Download | only in Eot
      1 ## @file

      2 # This file is used to define common parsing related functions used in parsing

      3 # Inf/Dsc/Makefile process

      4 #

      5 # Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>

      6 # This program and the accompanying materials

      7 # are licensed and made available under the terms and conditions of the BSD License

      8 # which accompanies this distribution.  The full text of the license may be found at

      9 # http://opensource.org/licenses/bsd-license.php

     10 #

     11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

     12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

     13 #

     14 
     15 ##

     16 # Import Modules

     17 #

     18 import Common.LongFilePathOs as 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 from Common.String import GetSplitList
     26 from Common.LongFilePathSupport import OpenLongFilePath as open
     27 
     28 ## PreProcess() method

     29 #

     30 #  Pre process a file

     31 #

     32 #  1. Remove all comments

     33 #  2. Merge multiple lines code to one line

     34 #

     35 #  @param  Filename: Name of the file to be parsed

     36 #  @param  MergeMultipleLines: Switch for if merge multiple lines

     37 #  @param  LineNo: Default line no

     38 #

     39 #  @return Lines: The file contents after remvoing comments

     40 #

     41 def PreProcess(Filename, MergeMultipleLines = True, LineNo = -1):
     42     Lines = []
     43     Filename = os.path.normpath(Filename)
     44     if not os.path.isfile(Filename):
     45         EdkLogger.error("Eot", EdkLogger.FILE_NOT_FOUND, ExtraData=Filename)
     46 
     47     IsFindBlockComment = False
     48     IsFindBlockCode = False
     49     ReservedLine = ''
     50     ReservedLineLength = 0
     51     for Line in open(Filename, 'r'):
     52         Line = Line.strip()
     53         # Remove comment block

     54         if Line.find(TAB_COMMENT_EDK_START) > -1:
     55             ReservedLine = GetSplitList(Line, TAB_COMMENT_EDK_START, 1)[0]
     56             IsFindBlockComment = True
     57         if Line.find(TAB_COMMENT_EDK_END) > -1:
     58             Line = ReservedLine + GetSplitList(Line, TAB_COMMENT_EDK_END, 1)[1]
     59             ReservedLine = ''
     60             IsFindBlockComment = False
     61         if IsFindBlockComment:
     62             Lines.append('')
     63             continue
     64 
     65         # Remove comments at tail and remove spaces again

     66         Line = CleanString(Line)
     67         if Line == '':
     68             Lines.append('')
     69             continue
     70 
     71         if MergeMultipleLines:
     72             # Add multiple lines to one line

     73             if IsFindBlockCode and Line[-1] != TAB_SLASH:
     74                 ReservedLine = (ReservedLine + TAB_SPACE_SPLIT + Line).strip()
     75                 Lines.append(ReservedLine)
     76                 for Index in (0, ReservedLineLength):
     77                     Lines.append('')
     78                 ReservedLine = ''
     79                 ReservedLineLength = 0
     80                 IsFindBlockCode = False
     81                 continue
     82             if Line[-1] == TAB_SLASH:
     83                 ReservedLine = ReservedLine +  TAB_SPACE_SPLIT + Line[0:-1].strip()
     84                 ReservedLineLength = ReservedLineLength + 1
     85                 IsFindBlockCode = True
     86                 continue
     87 
     88         Lines.append(Line)
     89 
     90     return Lines
     91 
     92 ## AddToGlobalMacro() method

     93 #

     94 #  Add a macro to EotGlobalData.gMACRO

     95 #

     96 #  @param  Name: Name of the macro

     97 #  @param  Value: Value of the macro

     98 #

     99 def AddToGlobalMacro(Name, Value):
    100     Value = ReplaceMacro(Value, EotGlobalData.gMACRO, True)
    101     EotGlobalData.gMACRO[Name] = Value
    102 
    103 ## AddToSelfMacro() method

    104 #

    105 #  Parse a line of macro definition and add it to a macro set

    106 #

    107 #  @param  SelfMacro: The self macro set

    108 #  @param  Line: The line of a macro definition

    109 #

    110 #  @return Name: Name of macro

    111 #  @return Value: Value of macro

    112 #

    113 def AddToSelfMacro(SelfMacro, Line):
    114     Name, Value = '', ''
    115     List = GetSplitValueList(Line, TAB_EQUAL_SPLIT, 1)
    116     if len(List) == 2:
    117         Name = List[0]
    118         Value = List[1]
    119         Value = ReplaceMacro(Value, EotGlobalData.gMACRO, True)
    120         Value = ReplaceMacro(Value, SelfMacro, True)
    121         SelfMacro[Name] = Value
    122 
    123     return (Name, Value)
    124 
    125 ## GetIncludeListOfFile() method

    126 #

    127 #  Get the include path list for a source file

    128 #

    129 #  1. Find the source file belongs to which INF file

    130 #  2. Find the inf's package

    131 #  3. Return the include path list of the package

    132 #

    133 #  @param  WorkSpace: WORKSPACE path

    134 #  @param  Filepath: File path

    135 #  @param  Db: Eot database

    136 #

    137 #  @return IncludeList: A list of include directories

    138 #

    139 def GetIncludeListOfFile(WorkSpace, Filepath, Db):
    140     IncludeList = []
    141     Filepath = os.path.normpath(Filepath)
    142     SqlCommand = """
    143                 select Value1 from Inf where Model = %s and BelongsToFile in(
    144                     select distinct B.BelongsToFile from File as A left join Inf as B
    145                         where A.ID = B.BelongsToFile and B.Model = %s and (A.Path || '%s' || B.Value1) = '%s')""" \
    146                 % (MODEL_META_DATA_PACKAGE, MODEL_EFI_SOURCE_FILE, '\\', Filepath)
    147     RecordSet = Db.TblFile.Exec(SqlCommand)
    148     for Record in RecordSet:
    149         DecFullPath = os.path.normpath(os.path.join(WorkSpace, Record[0]))
    150         (DecPath, DecName) = os.path.split(DecFullPath)
    151         SqlCommand = """select Value1 from Dec where BelongsToFile =
    152                            (select ID from File where FullPath = '%s') and Model = %s""" \
    153                     % (DecFullPath, MODEL_EFI_INCLUDE)
    154         NewRecordSet = Db.TblDec.Exec(SqlCommand)
    155         for NewRecord in NewRecordSet:
    156             IncludePath = os.path.normpath(os.path.join(DecPath, NewRecord[0]))
    157             if IncludePath not in IncludeList:
    158                 IncludeList.append(IncludePath)
    159 
    160     return IncludeList
    161 
    162 ## GetTableList() method
    163 #
    164 #  Search table file and find all small tables
    165 #
    166 #  @param  FileModelList: Model code for the file list
    167 #  @param  Table: Table to insert records
    168 #  @param  Db: Eot database
    169 #
    170 #  @return TableList: A list of tables
    171 #
    172 def GetTableList(FileModelList, Table, Db):
    173     TableList = []
    174     SqlCommand = """select ID, FullPath from File where Model in %s""" % str(FileModelList)
    175     RecordSet = Db.TblFile.Exec(SqlCommand)
    176     for Record in RecordSet:
    177         TableName = Table + str(Record[0])
    178         TableList.append([TableName, Record[1]])
    179 
    180     return TableList
    181 
    182 ## GetAllIncludeDir() method
    183 #
    184 #  Find all Include directories
    185 #
    186 #  @param  Db: Eot database
    187 #
    188 #  @return IncludeList: A list of include directories
    189 #
    190 def GetAllIncludeDirs(Db):
    191     IncludeList = []
    192     SqlCommand = """select distinct Value1 from Inf where Model = %s order by Value1""" % MODEL_EFI_INCLUDE
    193     RecordSet = Db.TblInf.Exec(SqlCommand)
    194 
    195     for Record in RecordSet:
    196         IncludeList.append(Record[0])
    197 
    198     return IncludeList
    199 
    200 ## GetAllIncludeFiles() method
    201 #
    202 #  Find all Include files
    203 #
    204 #  @param  Db: Eot database
    205 #
    206 #  @return IncludeFileList: A list of include files
    207 #
    208 def GetAllIncludeFiles(Db):
    209     IncludeList = GetAllIncludeDirs(Db)
    210     IncludeFileList = []
    211 
    212     for Dir in IncludeList:
    213         if os.path.isdir(Dir):
    214             SubDir = os.listdir(Dir)
    215             for Item in SubDir:
    216                 if os.path.isfile(Item):
    217                     IncludeFileList.append(Item)
    218 
    219     return IncludeFileList
    220 
    221 ## GetAllSourceFiles() method
    222 #
    223 #  Find all source files
    224 #
    225 #  @param  Db: Eot database
    226 #
    227 #  @return SourceFileList: A list of source files
    228 #
    229 def GetAllSourceFiles(Db):
    230     SourceFileList = []
    231     SqlCommand = """select distinct Value1 from Inf where Model = %s order by Value1""" % MODEL_EFI_SOURCE_FILE
    232     RecordSet = Db.TblInf.Exec(SqlCommand)
    233 
    234     for Record in RecordSet:
    235         SourceFileList.append(Record[0])
    236 
    237     return SourceFileList
    238 
    239 ## GetAllFiles() method
    240 #
    241 #  Find all files, both source files and include files
    242 #
    243 #  @param  Db: Eot database
    244 #
    245 #  @return FileList: A list of files
    246 #
    247 def GetAllFiles(Db):
    248     FileList = []
    249     IncludeFileList = GetAllIncludeFiles(Db)
    250     SourceFileList = GetAllSourceFiles(Db)
    251     for Item in IncludeFileList:
    252         if os.path.isfile(Item) and Item not in FileList:
    253             FileList.append(Item)
    254     for Item in SourceFileList:
    255         if os.path.isfile(Item) and Item not in FileList:
    256             FileList.append(Item)
    257 
    258     return FileList
    259 
    260 ## ParseConditionalStatement() method
    261 #
    262 #  Parse conditional statement
    263 #
    264 #  @param Line: One line to be parsed
    265 #  @param Macros: A set of all macro
    266 #  @param StatusSet: A set of all status
    267 #
    268 #  @retval True: Find keyword of conditional statement
    269 #  @retval False: Not find keyword of conditional statement
    270 #
    271 def ParseConditionalStatement(Line, Macros, StatusSet):
    272     NewLine = Line.upper()
    273     if NewLine.find(TAB_IF_EXIST.upper()) > -1:
    274         IfLine = Line[NewLine.find(TAB_IF_EXIST) + len(TAB_IF_EXIST) + 1:].strip()
    275         IfLine = ReplaceMacro(IfLine, EotGlobalData.gMACRO, True)
    276         IfLine = ReplaceMacro(IfLine, Macros, True)
    277         IfLine = IfLine.replace("\"", '')
    278         IfLine = IfLine.replace("(", '')
    279         IfLine = IfLine.replace(")", '')
    280         Status = os.path.exists(os.path.normpath(IfLine))
    281         StatusSet.append([Status])
    282         return True
    283     if NewLine.find(TAB_IF_DEF.upper()) > -1:
    284         IfLine = Line[NewLine.find(TAB_IF_DEF) + len(TAB_IF_DEF) + 1:].strip()
    285         Status = False
    286         if IfLine in Macros or IfLine in EotGlobalData.gMACRO:
    287             Status = True
    288         StatusSet.append([Status])
    289         return True
    290     if NewLine.find(TAB_IF_N_DEF.upper()) > -1:
    291         IfLine = Line[NewLine.find(TAB_IF_N_DEF) + len(TAB_IF_N_DEF) + 1:].strip()
    292         Status = False
    293         if IfLine not in Macros and IfLine not in EotGlobalData.gMACRO:
    294             Status = True
    295         StatusSet.append([Status])
    296         return True
    297     if NewLine.find(TAB_IF.upper()) > -1:
    298         IfLine = Line[NewLine.find(TAB_IF) + len(TAB_IF) + 1:].strip()
    299         Status = ParseConditionalStatementMacros(IfLine, Macros)
    300         StatusSet.append([Status])
    301         return True
    302     if NewLine.find(TAB_ELSE_IF.upper()) > -1:
    303         IfLine = Line[NewLine.find(TAB_ELSE_IF) + len(TAB_ELSE_IF) + 1:].strip()
    304         Status = ParseConditionalStatementMacros(IfLine, Macros)
    305         StatusSet[-1].append(Status)
    306         return True
    307     if NewLine.find(TAB_ELSE.upper()) > -1:
    308         Status = False
    309         for Item in StatusSet[-1]:
    310             Status = Status or Item
    311         StatusSet[-1].append(not Status)
    312         return True
    313     if NewLine.find(TAB_END_IF.upper()) > -1:
    314         StatusSet.pop()
    315         return True
    316 
    317     return False
    318 
    319 ## ParseConditionalStatement() method
    320 #
    321 #  Parse conditional statement with Macros
    322 #
    323 #  @param Line: One line to be parsed
    324 #  @param Macros: A set of macros
    325 #
    326 #  @return Line: New line after replacing macros
    327 #
    328 def ParseConditionalStatementMacros(Line, Macros):
    329     if Line.upper().find('DEFINED(') > -1 or Line.upper().find('EXIST') > -1:
    330         return False
    331     Line = ReplaceMacro(Line, EotGlobalData.gMACRO, True)
    332     Line = ReplaceMacro(Line, Macros, True)
    333     Line = Line.replace("&&", "and")
    334     Line = Line.replace("||", "or")
    335     return eval(Line)
    336 
    337 ## GetConditionalStatementStatus() method
    338 #
    339 #  1. Assume the latest status as True
    340 #  2. Pop the top status of status set, previous status
    341 #  3. Compare the latest one and the previous one and get new status
    342 #
    343 #  @param StatusSet: A set of all status
    344 #
    345 #  @return Status: The final status
    346 #
    347 def GetConditionalStatementStatus(StatusSet):
    348     Status = True
    349     for Item in StatusSet:
    350         Status = Status and Item[-1]
    351 
    352     return Status
    353 
    354 ## SearchBelongsToFunction() method
    355 #
    356 #  Search all functions belong to the file
    357 #
    358 #  @param BelongsToFile: File id
    359 #  @param StartLine: Start line of search scope
    360 #  @param EndLine: End line of search scope
    361 #
    362 #  @return: The found function
    363 #
    364 def SearchBelongsToFunction(BelongsToFile, StartLine, EndLine):
    365     SqlCommand = """select ID, Name from Function where BelongsToFile = %s and StartLine <= %s and EndLine >= %s""" %(BelongsToFile, StartLine, EndLine)
    366     RecordSet = EotGlobalData.gDb.TblFunction.Exec(SqlCommand)
    367     if RecordSet != []:
    368         return RecordSet[0][0], RecordSet[0][1]
    369     else:
    370         return -1, ''
    371 
    372 ## SearchPpiCallFunction() method
    373 #
    374 #  Search all used PPI calling function 'PeiServicesReInstallPpi' and 'PeiServicesInstallPpi'
    375 #  Store the result to database
    376 #
    377 #  @param Identifier: Table id
    378 #  @param SourceFileID: Source file id
    379 #  @param SourceFileFullPath: Source file full path
    380 #  @param ItemMode: Mode of the item
    381 #
    382 def SearchPpiCallFunction(Identifier, SourceFileID, SourceFileFullPath, ItemMode):
    383     ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Ppi', '', '', ''
    384     SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s
    385                     where (Name like '%%%s%%' and Model = %s)""" \
    386                     % (Identifier, 'PeiServicesReInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)
    387     BelongsToFunctionID, BelongsToFunction = -1, ''
    388     Db = EotGlobalData.gDb.TblReport
    389     RecordSet = Db.Exec(SqlCommand)
    390     for Record in RecordSet:
    391         Index = 0
    392         BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]
    393         BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)
    394         VariableList = Record[0].split(',')
    395         for Variable in VariableList:
    396             Variable = Variable.strip()
    397             # Get index of the variable
    398             if Variable.find('[') > -1:
    399                 Index = int(Variable[Variable.find('[') + 1 : Variable.find(']')])
    400                 Variable = Variable[:Variable.find('[')]
    401             # Get variable name
    402             if Variable.startswith('&'):
    403                 Variable = Variable[1:]
    404             # Get variable value
    405             SqlCommand = """select Value from %s where (Name like '%%%s%%') and Model = %s""" \
    406                          % (Identifier, Variable, MODEL_IDENTIFIER_VARIABLE)
    407             NewRecordSet = Db.Exec(SqlCommand)
    408             if NewRecordSet:
    409                 NewRecord = NewRecordSet[0][0]
    410                 VariableValueList = NewRecord.split('},')
    411                 if len(VariableValueList) > Index:
    412                     VariableValue = VariableValueList[Index]
    413                     NewVariableValueList = VariableValue.split(',')
    414                     if len(NewVariableValueList) > 1:
    415                         NewVariableValue = NewVariableValueList[1].strip()
    416                         if NewVariableValue.startswith('&'):
    417                             Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, NewVariableValue[1:], GuidMacro, GuidValue, BelongsToFunction, 0)
    418                             continue
    419                         else:
    420                             EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, NewParameter))
    421 
    422     ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Ppi', '', '', ''
    423     SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s
    424                     where (Value like '%%%s%%' and Model = %s)""" \
    425                     % (Identifier, 'PeiServicesInstallPpi', MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION)
    426     BelongsToFunctionID, BelongsToFunction = -1, ''
    427     Db = EotGlobalData.gDb.TblReport
    428     RecordSet = Db.Exec(SqlCommand)
    429 
    430     SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s
    431                     where (Name like '%%%s%%' and Model = %s)""" \
    432                     % (Identifier, 'PeiServicesInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)
    433     Db = EotGlobalData.gDb.TblReport
    434     RecordSet2 = Db.Exec(SqlCommand)
    435 
    436     for Record in RecordSet + RecordSet2:
    437         if Record == []:
    438             continue
    439         Index = 0
    440         BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]
    441         BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)
    442         Variable = Record[0].replace('PeiServicesInstallPpi', '').replace('(', '').replace(')', '').replace('&', '').strip()
    443         Variable = Variable[Variable.find(',') + 1:].strip()
    444         # Get index of the variable
    445         if Variable.find('[') > -1:
    446             Index = int(Variable[Variable.find('[') + 1 : Variable.find(']')])
    447             Variable = Variable[:Variable.find('[')]
    448         # Get variable name
    449         if Variable.startswith('&'):
    450             Variable = Variable[1:]
    451         # Get variable value
    452         SqlCommand = """select Value from %s where (Name like '%%%s%%') and Model = %s""" \
    453                      % (Identifier, Variable, MODEL_IDENTIFIER_VARIABLE)
    454         NewRecordSet = Db.Exec(SqlCommand)
    455         if NewRecordSet:
    456             NewRecord = NewRecordSet[0][0]
    457             VariableValueList = NewRecord.split('},')
    458             for VariableValue in VariableValueList[Index:]:
    459                 NewVariableValueList = VariableValue.split(',')
    460                 if len(NewVariableValueList) > 1:
    461                     NewVariableValue = NewVariableValueList[1].strip()
    462                     if NewVariableValue.startswith('&'):
    463                         Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, NewVariableValue[1:], GuidMacro, GuidValue, BelongsToFunction, 0)
    464                         continue
    465                     else:
    466                         EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, NewParameter))
    467 
    468 ## SearchPpis() method
    469 #
    470 #  Search all used PPI calling function
    471 #  Store the result to database
    472 #
    473 #  @param SqlCommand: SQL command statement
    474 #  @param Table: Table id
    475 #  @param SourceFileID: Source file id
    476 #  @param SourceFileFullPath: Source file full path
    477 #  @param ItemMode: Mode of the item
    478 #  @param PpiMode: Mode of PPI
    479 #
    480 def SearchPpi(SqlCommand, Table, SourceFileID, SourceFileFullPath, ItemMode, PpiMode = 1):
    481     ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Ppi', '', '', ''
    482     BelongsToFunctionID, BelongsToFunction = -1, ''
    483     Db = EotGlobalData.gDb.TblReport
    484     RecordSet = Db.Exec(SqlCommand)
    485     for Record in RecordSet:
    486         Parameter = GetPpiParameter(Record[0], PpiMode)
    487         BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]
    488         # Get BelongsToFunction
    489         BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)
    490 
    491         # Default is Not Found
    492         IsFound = False
    493 
    494         # For Consumed Ppi
    495         if ItemMode == 'Consumed':
    496             if Parameter.startswith('g'):
    497                 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, Parameter, GuidMacro, GuidValue, BelongsToFunction, 0)
    498             else:
    499                 EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))
    500             continue
    501 
    502         # Direct Parameter.Guid
    503         SqlCommand = """select Value from %s where (Name like '%%%s.Guid%%' or Name like '%%%s->Guid%%') and Model = %s""" % (Table, Parameter, Parameter, MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION)
    504         NewRecordSet = Db.Exec(SqlCommand)
    505         for NewRecord in NewRecordSet:
    506             GuidName = GetParameterName(NewRecord[0])
    507             Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
    508             IsFound = True
    509 
    510         # Defined Parameter
    511         if not IsFound:
    512             Key = Parameter
    513             if Key.rfind(' ') > -1:
    514                 Key = Key[Key.rfind(' ') : ].strip().replace('&', '')
    515             Value = FindKeyValue(EotGlobalData.gDb.TblFile, Table, Key)
    516             List = GetSplitValueList(Value.replace('\n', ''), TAB_COMMA_SPLIT)
    517             if len(List) > 1:
    518                 GuidName = GetParameterName(List[1])
    519                 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
    520                 IsFound = True
    521 
    522         # A list Parameter
    523         if not IsFound:
    524             Start = Parameter.find('[')
    525             End = Parameter.find(']')
    526             if Start > -1 and End > -1 and Start < End:
    527                 try:
    528                     Index = int(Parameter[Start + 1 : End])
    529                     Parameter = Parameter[0 : Start]
    530                     SqlCommand = """select Value from %s where Name = '%s' and Model = %s""" % (Table, Parameter, MODEL_IDENTIFIER_VARIABLE)
    531                     NewRecordSet = Db.Exec(SqlCommand)
    532                     for NewRecord in NewRecordSet:
    533                         NewParameter = GetSplitValueList(NewRecord[0], '}')[Index]
    534                         GuidName = GetPpiParameter(NewParameter[NewParameter.find('{') : ])
    535                         Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
    536                         IsFound = True
    537                 except Exception:
    538                     pass
    539 
    540         # A External Parameter
    541         if not IsFound:
    542             SqlCommand = """select File.ID from Inf, File
    543                             where BelongsToFile = (select BelongsToFile from Inf where Value1 = '%s')
    544                             and Inf.Model = %s and Inf.Value1 = File.FullPath and File.Model = %s""" % (SourceFileFullPath, MODEL_EFI_SOURCE_FILE, MODEL_FILE_C)
    545             NewRecordSet = Db.Exec(SqlCommand)
    546             for NewRecord in NewRecordSet:
    547                 Table = 'Identifier' + str(NewRecord[0])
    548                 SqlCommand = """select Value from %s where Name = '%s' and Modifier = 'EFI_PEI_PPI_DESCRIPTOR' and Model = %s""" % (Table, Parameter, MODEL_IDENTIFIER_VARIABLE)
    549                 PpiSet = Db.Exec(SqlCommand)
    550                 if PpiSet != []:
    551                     GuidName = GetPpiParameter(PpiSet[0][0])
    552                     if GuidName != '':
    553                         Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
    554                         IsFound = True
    555                         break
    556 
    557         if not IsFound:
    558             EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))
    559 
    560 ## SearchProtocols() method
    561 #
    562 #  Search all used PROTOCOL calling function
    563 #  Store the result to database
    564 #
    565 #  @param SqlCommand: SQL command statement
    566 #  @param Table: Table id
    567 #  @param SourceFileID: Source file id
    568 #  @param SourceFileFullPath: Source file full path
    569 #  @param ItemMode: Mode of the item
    570 #  @param ProtocolMode: Mode of PROTOCOL
    571 #
    572 def SearchProtocols(SqlCommand, Table, SourceFileID, SourceFileFullPath, ItemMode, ProtocolMode):
    573     ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Protocol', '', '', ''
    574     BelongsToFunctionID, BelongsToFunction = -1, ''
    575     Db = EotGlobalData.gDb.TblReport
    576     RecordSet = Db.Exec(SqlCommand)
    577     for Record in RecordSet:
    578         Parameter = ''
    579         BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]
    580         # Get BelongsToFunction
    581         BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)
    582 
    583         # Default is Not Found
    584         IsFound = False
    585 
    586         if ProtocolMode == 0 or ProtocolMode == 1:
    587             Parameter = GetProtocolParameter(Record[0], ProtocolMode)
    588             if Parameter.startswith('g') or Parameter.endswith('Guid') or Parameter == 'ShellEnvProtocol' or Parameter == 'ShellInterfaceProtocol':
    589                 GuidName = GetParameterName(Parameter)
    590                 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
    591                 IsFound = True
    592 
    593         if ProtocolMode == 2:
    594             Protocols = GetSplitValueList(Record[0], TAB_COMMA_SPLIT)
    595             for Protocol in Protocols:
    596                 if Protocol.startswith('&') and Protocol.endswith('Guid'):
    597                     GuidName = GetParameterName(Protocol)
    598                     Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
    599                     IsFound = True
    600                 else:
    601                     NewValue = FindKeyValue(EotGlobalData.gDb.TblFile, Table, Protocol)
    602                     if Protocol != NewValue and NewValue.endswith('Guid'):
    603                         GuidName = GetParameterName(NewValue)
    604                         Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
    605                         IsFound = True
    606 
    607         if not IsFound:
    608             if BelongsToFunction in EotGlobalData.gProducedProtocolLibrary or BelongsToFunction in EotGlobalData.gConsumedProtocolLibrary:
    609                 EotGlobalData.gOP_UN_MATCHED_IN_LIBRARY_CALLING.write('%s, %s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter, BelongsToFunction))
    610             else:
    611                 EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))
    612 
    613 ## SearchFunctionCalling() method
    614 #
    615 #  Search all used PPI/PROTOCOL calling function by library
    616 #  Store the result to database
    617 #
    618 #  @param SqlCommand: SQL command statement
    619 #  @param Table: Table id
    620 #  @param SourceFileID: Source file id
    621 #  @param SourceFileFullPath: Source file full path
    622 #  @param ItemType: Type of the item, PPI or PROTOCOL
    623 #  @param ItemMode: Mode of item
    624 #
    625 def SearchFunctionCalling(Table, SourceFileID, SourceFileFullPath, ItemType, ItemMode):
    626     LibraryList = 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 #
    692 def GetProtocolParameter(Parameter, Index = 1):
    693     return GetParameter(Parameter, Index)
    694 
    695 ## GetPpiParameter() method
    696 #
    697 # Parse string of ppi and find parameters
    698 #
    699 #  @param Parameter: Parameter to be parsed
    700 #  @param Index: The index of the parameter
    701 #
    702 #  @return: call common GetParameter
    703 #
    704 def GetPpiParameter(Parameter, Index = 1):
    705     return GetParameter(Parameter, Index)
    706 
    707 ## GetParameter() method
    708 #
    709 # Get a parameter by index
    710 #
    711 #  @param Parameter: Parameter to be parsed
    712 #  @param Index: The index of the parameter
    713 #
    714 #  @return Parameter: The found parameter
    715 #
    716 def GetParameter(Parameter, Index = 1):
    717     ParameterList = GetSplitValueList(Parameter, TAB_COMMA_SPLIT)
    718     if len(ParameterList) > Index:
    719         Parameter = GetParameterName(ParameterList[Index])
    720 
    721         return Parameter
    722 
    723     return ''
    724 
    725 ## GetParameterName() method
    726 #
    727 # Get a parameter name
    728 #
    729 #  @param Parameter: Parameter to be parsed
    730 #
    731 #  @return: The name of parameter
    732 #
    733 def GetParameterName(Parameter):
    734     if 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 #
    749 def FindKeyValue(Db, Table, Key):
    750     SqlCommand = """select Value from %s where Name = '%s' and (Model = %s or Model = %s)""" % (Table, Key, MODEL_IDENTIFIER_VARIABLE, MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION)
    751     RecordSet = Db.Exec(SqlCommand)
    752     Value = ''
    753     for Record in RecordSet:
    754         if Record[0] != 'NULL':
    755             Value = FindKeyValue(Db, Table, GetParameterName(Record[0]))
    756 
    757     if Value != '':
    758         return Value
    759     else:
    760         return Key
    761 
    762 ## ParseMapFile() method
    763 #
    764 #  Parse map files to get a dict of 'ModuleName' : {FunName : FunAddress}
    765 #
    766 #  @param Files: A list of map files
    767 #
    768 #  @return AllMaps: An object of all map files
    769 #
    770 def ParseMapFile(Files):
    771     AllMaps = {}
    772     CurrentModule = ''
    773     CurrentMaps = {}
    774     for File in Files:
    775         Content = open(File, 'r').readlines()
    776         for Line in Content:
    777             Line = CleanString(Line)
    778             # skip empty line
    779             if Line == '':
    780                 continue
    781 
    782             if Line.find('(') > -1 and Line.find(')') > -1:
    783                 if CurrentModule != '' and CurrentMaps != {}:
    784                     AllMaps[CurrentModule] = CurrentMaps
    785                 CurrentModule = Line[:Line.find('(')]
    786                 CurrentMaps = {}
    787                 continue
    788             else:
    789                 Name = ''
    790                 Address = ''
    791                 List = Line.split()
    792                 Address = List[0]
    793                 if List[1] == 'F' or List[1] == 'FS':
    794                     Name = List[2]
    795                 else:
    796                     Name = List[1]
    797                 CurrentMaps[Name] = Address
    798                 continue
    799 
    800     return AllMaps
    801 
    802 ## ConvertGuid
    803 #
    804 #  Convert a GUID to a GUID with all upper letters
    805 #
    806 #  @param guid:  The GUID to be converted
    807 #
    808 #  @param newGuid: The GUID with all upper letters.
    809 #
    810 def ConvertGuid(guid):
    811     numList = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
    812     newGuid = ''
    813     if guid.startswith('g'):
    814         guid = guid[1:]
    815     for i in guid:
    816         if i.upper() == i and i not in numList:
    817             newGuid = newGuid + ('_' + i)
    818         else:
    819             newGuid = newGuid + i.upper()
    820     if newGuid.startswith('_'):
    821         newGuid = newGuid[1:]
    822     if newGuid.endswith('_'):
    823         newGuid = newGuid[:-1]
    824 
    825     return newGuid
    826 
    827 ## ConvertGuid2() method
    828 #
    829 #  Convert a GUID to a GUID with new string instead of old string
    830 #
    831 #  @param guid: The GUID to be converted
    832 #  @param old: Old string to be replaced
    833 #  @param new: New string to replace the old one
    834 #
    835 #  @param newGuid: The GUID after replacement
    836 #
    837 def ConvertGuid2(guid, old, new):
    838     newGuid = ConvertGuid(guid)
    839     newGuid = newGuid.replace(old, new)
    840 
    841     return newGuid
    842 
    843 ##
    844 #
    845 # This acts like the main() function for the script, unless it is 'import'ed into another
    846 # script.
    847 #
    848 if __name__ == '__main__':
    849     pass
    850