]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Eot/Parser.py
Sync EDKII BaseTools to BaseTools project r1903.
[mirror_edk2.git] / BaseTools / Source / Python / Eot / Parser.py
diff --git a/BaseTools/Source/Python/Eot/Parser.py b/BaseTools/Source/Python/Eot/Parser.py
new file mode 100644 (file)
index 0000000..6850c8d
--- /dev/null
@@ -0,0 +1,848 @@
+## @file\r
+# This file is used to define common parsing related functions used in parsing\r
+# Inf/Dsc/Makefile process\r
+#\r
+# Copyright (c) 2008 - 2010, Intel Corporation\r
+# All rights reserved. This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+\r
+##\r
+# Import Modules\r
+#\r
+import os, re\r
+import Common.EdkLogger as EdkLogger\r
+from Common.DataType import *\r
+from CommonDataClass.DataClass import *\r
+from Common.String import CleanString, GetSplitValueList, ReplaceMacro\r
+import EotGlobalData\r
+from Common.Misc import sdict\r
+\r
+## PreProcess() method\r
+#\r
+#  Pre process a file\r
+#\r
+#  1. Remove all comments\r
+#  2. Merge multiple lines code to one line\r
+#\r
+#  @param  Filename: Name of the file to be parsed\r
+#  @param  MergeMultipleLines: Switch for if merge multiple lines\r
+#  @param  LineNo: Default line no\r
+#\r
+#  @return Lines: The file contents after remvoing comments\r
+#\r
+def PreProcess(Filename, MergeMultipleLines = True, LineNo = -1):\r
+    Lines = []\r
+    Filename = os.path.normpath(Filename)\r
+    if not os.path.isfile(Filename):\r
+        EdkLogger.error("Eot", EdkLogger.FILE_NOT_FOUND, ExtraData=Filename)\r
+\r
+    IsFindBlockComment = False\r
+    IsFindBlockCode = False\r
+    ReservedLine = ''\r
+    ReservedLineLength = 0\r
+    for Line in open(Filename, 'r'):\r
+        Line = Line.strip()\r
+        # Remove comment block\r
+        if Line.find(TAB_COMMENT_R8_START) > -1:\r
+            ReservedLine = GetSplitValueList(Line, TAB_COMMENT_R8_START, 1)[0]\r
+            IsFindBlockComment = True\r
+        if Line.find(TAB_COMMENT_R8_END) > -1:\r
+            Line = ReservedLine + GetSplitValueList(Line, TAB_COMMENT_R8_END, 1)[1]\r
+            ReservedLine = ''\r
+            IsFindBlockComment = False\r
+        if IsFindBlockComment:\r
+            Lines.append('')\r
+            continue\r
+\r
+        # Remove comments at tail and remove spaces again\r
+        Line = CleanString(Line)\r
+        if Line == '':\r
+            Lines.append('')\r
+            continue\r
+\r
+        if MergeMultipleLines:\r
+            # Add multiple lines to one line\r
+            if IsFindBlockCode and Line[-1] != TAB_SLASH:\r
+                ReservedLine = (ReservedLine + TAB_SPACE_SPLIT + Line).strip()\r
+                Lines.append(ReservedLine)\r
+                for Index in (0, ReservedLineLength):\r
+                    Lines.append('')\r
+                ReservedLine = ''\r
+                ReservedLineLength = 0\r
+                IsFindBlockCode = False\r
+                continue\r
+            if Line[-1] == TAB_SLASH:\r
+                ReservedLine = ReservedLine +  TAB_SPACE_SPLIT + Line[0:-1].strip()\r
+                ReservedLineLength = ReservedLineLength + 1\r
+                IsFindBlockCode = True\r
+                continue\r
+\r
+        Lines.append(Line)\r
+\r
+    return Lines\r
+\r
+## AddToGlobalMacro() method\r
+#\r
+#  Add a macro to EotGlobalData.gMACRO\r
+#\r
+#  @param  Name: Name of the macro\r
+#  @param  Value: Value of the macro\r
+#\r
+def AddToGlobalMacro(Name, Value):\r
+    Value = ReplaceMacro(Value, EotGlobalData.gMACRO, True)\r
+    EotGlobalData.gMACRO[Name] = Value\r
+\r
+## AddToSelfMacro() method\r
+#\r
+#  Parse a line of macro definition and add it to a macro set\r
+#\r
+#  @param  SelfMacro: The self macro set\r
+#  @param  Line: The line of a macro definition\r
+#\r
+#  @return Name: Name of macro\r
+#  @return Value: Value of macro\r
+#\r
+def AddToSelfMacro(SelfMacro, Line):\r
+    Name, Value = '', ''\r
+    List = GetSplitValueList(Line, TAB_EQUAL_SPLIT, 1)\r
+    if len(List) == 2:\r
+        Name = List[0]\r
+        Value = List[1]\r
+        Value = ReplaceMacro(Value, EotGlobalData.gMACRO, True)\r
+        Value = ReplaceMacro(Value, SelfMacro, True)\r
+        SelfMacro[Name] = Value\r
+\r
+    return (Name, Value)\r
+\r
+## GetIncludeListOfFile() method\r
+#\r
+#  Get the include path list for a source file\r
+#\r
+#  1. Find the source file belongs to which INF file\r
+#  2. Find the inf's package\r
+#  3. Return the include path list of the package\r
+#\r
+#  @param  WorkSpace: WORKSPACE path\r
+#  @param  Filepath: File path\r
+#  @param  Db: Eot database\r
+#\r
+#  @return IncludeList: A list of include directories\r
+#\r
+def GetIncludeListOfFile(WorkSpace, Filepath, Db):\r
+    IncludeList = []\r
+    Filepath = os.path.normpath(Filepath)\r
+    SqlCommand = """\r
+                select Value1 from Inf where Model = %s and BelongsToFile in(\r
+                    select distinct B.BelongsToFile from File as A left join Inf as B\r
+                        where A.ID = B.BelongsToFile and B.Model = %s and (A.Path || '%s' || B.Value1) = '%s')""" \\r
+                % (MODEL_META_DATA_PACKAGE, MODEL_EFI_SOURCE_FILE, '\\', Filepath)\r
+    RecordSet = Db.TblFile.Exec(SqlCommand)\r
+    for Record in RecordSet:\r
+        DecFullPath = os.path.normpath(os.path.join(WorkSpace, Record[0]))\r
+        (DecPath, DecName) = os.path.split(DecFullPath)\r
+        SqlCommand = """select Value1 from Dec where BelongsToFile =\r
+                           (select ID from File where FullPath = '%s') and Model = %s""" \\r
+                    % (DecFullPath, MODEL_EFI_INCLUDE)\r
+        NewRecordSet = Db.TblDec.Exec(SqlCommand)\r
+        for NewRecord in NewRecordSet:\r
+            IncludePath = os.path.normpath(os.path.join(DecPath, NewRecord[0]))\r
+            if IncludePath not in IncludeList:\r
+                IncludeList.append(IncludePath)\r
+\r
+    return IncludeList\r
+\r
+## GetTableList() method\r
+#\r
+#  Search table file and find all small tables\r
+#\r
+#  @param  FileModelList: Model code for the file list\r
+#  @param  Table: Table to insert records\r
+#  @param  Db: Eot database\r
+#\r
+#  @return TableList: A list of tables\r
+#\r
+def GetTableList(FileModelList, Table, Db):\r
+    TableList = []\r
+    SqlCommand = """select ID, FullPath from File where Model in %s""" % str(FileModelList)\r
+    RecordSet = Db.TblFile.Exec(SqlCommand)\r
+    for Record in RecordSet:\r
+        TableName = Table + str(Record[0])\r
+        TableList.append([TableName, Record[1]])\r
+\r
+    return TableList\r
+\r
+## GetAllIncludeDir() method\r
+#\r
+#  Find all Include directories\r
+#\r
+#  @param  Db: Eot database\r
+#\r
+#  @return IncludeList: A list of include directories\r
+#\r
+def GetAllIncludeDirs(Db):\r
+    IncludeList = []\r
+    SqlCommand = """select distinct Value1 from Inf where Model = %s order by Value1""" % MODEL_EFI_INCLUDE\r
+    RecordSet = Db.TblInf.Exec(SqlCommand)\r
+\r
+    for Record in RecordSet:\r
+        IncludeList.append(Record[0])\r
+\r
+    return IncludeList\r
+\r
+## GetAllIncludeFiles() method\r
+#\r
+#  Find all Include files\r
+#\r
+#  @param  Db: Eot database\r
+#\r
+#  @return IncludeFileList: A list of include files\r
+#\r
+def GetAllIncludeFiles(Db):\r
+    IncludeList = GetAllIncludeDirs(Db)\r
+    IncludeFileList = []\r
+\r
+    for Dir in IncludeList:\r
+        if os.path.isdir(Dir):\r
+            SubDir = os.listdir(Dir)\r
+            for Item in SubDir:\r
+                if os.path.isfile(Item):\r
+                    IncludeFileList.append(Item)\r
+\r
+    return IncludeFileList\r
+\r
+## GetAllSourceFiles() method\r
+#\r
+#  Find all source files\r
+#\r
+#  @param  Db: Eot database\r
+#\r
+#  @return SourceFileList: A list of source files\r
+#\r
+def GetAllSourceFiles(Db):\r
+    SourceFileList = []\r
+    SqlCommand = """select distinct Value1 from Inf where Model = %s order by Value1""" % MODEL_EFI_SOURCE_FILE\r
+    RecordSet = Db.TblInf.Exec(SqlCommand)\r
+\r
+    for Record in RecordSet:\r
+        SourceFileList.append(Record[0])\r
+\r
+    return SourceFileList\r
+\r
+## GetAllFiles() method\r
+#\r
+#  Find all files, both source files and include files\r
+#\r
+#  @param  Db: Eot database\r
+#\r
+#  @return FileList: A list of files\r
+#\r
+def GetAllFiles(Db):\r
+    FileList = []\r
+    IncludeFileList = GetAllIncludeFiles(Db)\r
+    SourceFileList = GetAllSourceFiles(Db)\r
+    for Item in IncludeFileList:\r
+        if os.path.isfile(Item) and Item not in FileList:\r
+            FileList.append(Item)\r
+    for Item in SourceFileList:\r
+        if os.path.isfile(Item) and Item not in FileList:\r
+            FileList.append(Item)\r
+\r
+    return FileList\r
+\r
+## ParseConditionalStatement() method\r
+#\r
+#  Parse conditional statement\r
+#\r
+#  @param Line: One line to be parsed\r
+#  @param Macros: A set of all macro\r
+#  @param StatusSet: A set of all status\r
+#\r
+#  @retval True: Find keyword of conditional statement\r
+#  @retval False: Not find keyword of conditional statement\r
+#\r
+def ParseConditionalStatement(Line, Macros, StatusSet):\r
+    NewLine = Line.upper()\r
+    if NewLine.find(TAB_IF_EXIST.upper()) > -1:\r
+        IfLine = Line[NewLine.find(TAB_IF_EXIST) + len(TAB_IF_EXIST) + 1:].strip()\r
+        IfLine = ReplaceMacro(IfLine, EotGlobalData.gMACRO, True)\r
+        IfLine = ReplaceMacro(IfLine, Macros, True)\r
+        IfLine = IfLine.replace("\"", '')\r
+        IfLine = IfLine.replace("(", '')\r
+        IfLine = IfLine.replace(")", '')\r
+        Status = os.path.exists(os.path.normpath(IfLine))\r
+        StatusSet.append([Status])\r
+        return True\r
+    if NewLine.find(TAB_IF_DEF.upper()) > -1:\r
+        IfLine = Line[NewLine.find(TAB_IF_DEF) + len(TAB_IF_DEF) + 1:].strip()\r
+        Status = False\r
+        if IfLine in Macros or IfLine in EotGlobalData.gMACRO:\r
+            Status = True\r
+        StatusSet.append([Status])\r
+        return True\r
+    if NewLine.find(TAB_IF_N_DEF.upper()) > -1:\r
+        IfLine = Line[NewLine.find(TAB_IF_N_DEF) + len(TAB_IF_N_DEF) + 1:].strip()\r
+        Status = False\r
+        if IfLine not in Macros and IfLine not in EotGlobalData.gMACRO:\r
+            Status = True\r
+        StatusSet.append([Status])\r
+        return True\r
+    if NewLine.find(TAB_IF.upper()) > -1:\r
+        IfLine = Line[NewLine.find(TAB_IF) + len(TAB_IF) + 1:].strip()\r
+        Status = ParseConditionalStatementMacros(IfLine, Macros)\r
+        StatusSet.append([Status])\r
+        return True\r
+    if NewLine.find(TAB_ELSE_IF.upper()) > -1:\r
+        IfLine = Line[NewLine.find(TAB_ELSE_IF) + len(TAB_ELSE_IF) + 1:].strip()\r
+        Status = ParseConditionalStatementMacros(IfLine, Macros)\r
+        StatusSet[-1].append(Status)\r
+        return True\r
+    if NewLine.find(TAB_ELSE.upper()) > -1:\r
+        Status = False\r
+        for Item in StatusSet[-1]:\r
+            Status = Status or Item\r
+        StatusSet[-1].append(not Status)\r
+        return True\r
+    if NewLine.find(TAB_END_IF.upper()) > -1:\r
+        StatusSet.pop()\r
+        return True\r
+\r
+    return False\r
+\r
+## ParseConditionalStatement() method\r
+#\r
+#  Parse conditional statement with Macros\r
+#\r
+#  @param Line: One line to be parsed\r
+#  @param Macros: A set of macros\r
+#\r
+#  @return Line: New line after replacing macros\r
+#\r
+def ParseConditionalStatementMacros(Line, Macros):\r
+    if Line.upper().find('DEFINED(') > -1 or Line.upper().find('EXIST') > -1:\r
+        return False\r
+    Line = ReplaceMacro(Line, EotGlobalData.gMACRO, True)\r
+    Line = ReplaceMacro(Line, Macros, True)\r
+    Line = Line.replace("&&", "and")\r
+    Line = Line.replace("||", "or")\r
+    return eval(Line)\r
+\r
+## GetConditionalStatementStatus() method\r
+#\r
+#  1. Assume the latest status as True\r
+#  2. Pop the top status of status set, previous status\r
+#  3. Compare the latest one and the previous one and get new status\r
+#\r
+#  @param StatusSet: A set of all status\r
+#\r
+#  @return Status: The final status\r
+#\r
+def GetConditionalStatementStatus(StatusSet):\r
+    Status = True\r
+    for Item in StatusSet:\r
+        Status = Status and Item[-1]\r
+\r
+    return Status\r
+\r
+## SearchBelongsToFunction() method\r
+#\r
+#  Search all functions belong to the file\r
+#\r
+#  @param BelongsToFile: File id\r
+#  @param StartLine: Start line of search scope\r
+#  @param EndLine: End line of search scope\r
+#\r
+#  @return: The found function\r
+#\r
+def SearchBelongsToFunction(BelongsToFile, StartLine, EndLine):\r
+    SqlCommand = """select ID, Name from Function where BelongsToFile = %s and StartLine <= %s and EndLine >= %s""" %(BelongsToFile, StartLine, EndLine)\r
+    RecordSet = EotGlobalData.gDb.TblFunction.Exec(SqlCommand)\r
+    if RecordSet != []:\r
+        return RecordSet[0][0], RecordSet[0][1]\r
+    else:\r
+        return -1, ''\r
+\r
+## SearchPpiCallFunction() method\r
+#\r
+#  Search all used PPI calling function 'PeiServicesReInstallPpi' and 'PeiServicesInstallPpi'\r
+#  Store the result to database\r
+#\r
+#  @param Identifier: Table id\r
+#  @param SourceFileID: Source file id\r
+#  @param SourceFileFullPath: Source file full path\r
+#  @param ItemMode: Mode of the item\r
+#\r
+def SearchPpiCallFunction(Identifier, SourceFileID, SourceFileFullPath, ItemMode):\r
+    ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Ppi', '', '', ''\r
+    SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
+                    where (Name like '%%%s%%' and Model = %s)""" \\r
+                    % (Identifier, 'PeiServicesReInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
+    BelongsToFunctionID, BelongsToFunction = -1, ''\r
+    Db = EotGlobalData.gDb.TblReport\r
+    RecordSet = Db.Exec(SqlCommand)\r
+    for Record in RecordSet:\r
+        Index = 0\r
+        BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]\r
+        BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)\r
+        VariableList = Record[0].split(',')\r
+        for Variable in VariableList:\r
+            Variable = Variable.strip()\r
+            # Get index of the variable\r
+            if Variable.find('[') > -1:\r
+                Index = int(Variable[Variable.find('[') + 1 : Variable.find(']')])\r
+                Variable = Variable[:Variable.find('[')]\r
+            # Get variable name\r
+            if Variable.startswith('&'):\r
+                Variable = Variable[1:]\r
+            # Get variable value\r
+            SqlCommand = """select Value from %s where (Name like '%%%s%%') and Model = %s""" \\r
+                         % (Identifier, Variable, MODEL_IDENTIFIER_VARIABLE)\r
+            NewRecordSet = Db.Exec(SqlCommand)\r
+            if NewRecordSet:\r
+                NewRecord = NewRecordSet[0][0]\r
+                VariableValueList = NewRecord.split('},')\r
+                if len(VariableValueList) > Index:\r
+                    VariableValue = VariableValueList[Index]\r
+                    NewVariableValueList = VariableValue.split(',')\r
+                    if len(NewVariableValueList) > 1:\r
+                        NewVariableValue = NewVariableValueList[1].strip()\r
+                        if NewVariableValue.startswith('&'):\r
+                            Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, NewVariableValue[1:], GuidMacro, GuidValue, BelongsToFunction, 0)\r
+                            continue\r
+                        else:\r
+                            EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, NewParameter))\r
+\r
+    ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Ppi', '', '', ''\r
+    SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
+                    where (Value like '%%%s%%' and Model = %s)""" \\r
+                    % (Identifier, 'PeiServicesInstallPpi', MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION)\r
+    BelongsToFunctionID, BelongsToFunction = -1, ''\r
+    Db = EotGlobalData.gDb.TblReport\r
+    RecordSet = Db.Exec(SqlCommand)\r
+\r
+    SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
+                    where (Name like '%%%s%%' and Model = %s)""" \\r
+                    % (Identifier, 'PeiServicesInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
+    Db = EotGlobalData.gDb.TblReport\r
+    RecordSet2 = Db.Exec(SqlCommand)\r
+\r
+    for Record in RecordSet + RecordSet2:\r
+        if Record == []:\r
+            continue\r
+        Index = 0\r
+        BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]\r
+        BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)\r
+        Variable = Record[0].replace('PeiServicesInstallPpi', '').replace('(', '').replace(')', '').replace('&', '').strip()\r
+        Variable = Variable[Variable.find(',') + 1:].strip()\r
+        # Get index of the variable\r
+        if Variable.find('[') > -1:\r
+            Index = int(Variable[Variable.find('[') + 1 : Variable.find(']')])\r
+            Variable = Variable[:Variable.find('[')]\r
+        # Get variable name\r
+        if Variable.startswith('&'):\r
+            Variable = Variable[1:]\r
+        # Get variable value\r
+        SqlCommand = """select Value from %s where (Name like '%%%s%%') and Model = %s""" \\r
+                     % (Identifier, Variable, MODEL_IDENTIFIER_VARIABLE)\r
+        NewRecordSet = Db.Exec(SqlCommand)\r
+        if NewRecordSet:\r
+            NewRecord = NewRecordSet[0][0]\r
+            VariableValueList = NewRecord.split('},')\r
+            if len(VariableValueList) > Index:\r
+                VariableValue = VariableValueList[Index]\r
+                NewVariableValueList = VariableValue.split(',')\r
+                if len(NewVariableValueList) > 1:\r
+                    NewVariableValue = NewVariableValueList[1].strip()\r
+                    if NewVariableValue.startswith('&'):\r
+                        Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, NewVariableValue[1:], GuidMacro, GuidValue, BelongsToFunction, 0)\r
+                        continue\r
+                    else:\r
+                        EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, NewParameter))\r
+\r
+## SearchPpis() method\r
+#\r
+#  Search all used PPI calling function\r
+#  Store the result to database\r
+#\r
+#  @param SqlCommand: SQL command statement\r
+#  @param Table: Table id\r
+#  @param SourceFileID: Source file id\r
+#  @param SourceFileFullPath: Source file full path\r
+#  @param ItemMode: Mode of the item\r
+#  @param PpiMode: Mode of PPI\r
+#\r
+def SearchPpi(SqlCommand, Table, SourceFileID, SourceFileFullPath, ItemMode, PpiMode = 1):\r
+    ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Ppi', '', '', ''\r
+    BelongsToFunctionID, BelongsToFunction = -1, ''\r
+    Db = EotGlobalData.gDb.TblReport\r
+    RecordSet = Db.Exec(SqlCommand)\r
+    for Record in RecordSet:\r
+        Parameter = GetPpiParameter(Record[0], PpiMode)\r
+        BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]\r
+        # Get BelongsToFunction\r
+        BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)\r
+\r
+        # Default is Not Found\r
+        IsFound = False\r
+\r
+        # For Consumed Ppi\r
+        if ItemMode == 'Consumed':\r
+            if Parameter.startswith('g'):\r
+                Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, Parameter, GuidMacro, GuidValue, BelongsToFunction, 0)\r
+            else:\r
+                EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))\r
+            continue\r
+\r
+        # Direct Parameter.Guid\r
+        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)\r
+        NewRecordSet = Db.Exec(SqlCommand)\r
+        for NewRecord in NewRecordSet:\r
+            GuidName = GetParameterName(NewRecord[0])\r
+            Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r
+            IsFound = True\r
+\r
+        # Defined Parameter\r
+        if not IsFound:\r
+            Key = Parameter\r
+            if Key.rfind(' ') > -1:\r
+                Key = Key[Key.rfind(' ') : ].strip().replace('&', '')\r
+            Value = FindKeyValue(EotGlobalData.gDb.TblFile, Table, Key)\r
+            List = GetSplitValueList(Value.replace('\n', ''), TAB_COMMA_SPLIT)\r
+            if len(List) > 1:\r
+                GuidName = GetParameterName(List[1])\r
+                Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r
+                IsFound = True\r
+\r
+        # A list Parameter\r
+        if not IsFound:\r
+            Start = Parameter.find('[')\r
+            End = Parameter.find(']')\r
+            if Start > -1 and End > -1 and Start < End:\r
+                try:\r
+                    Index = int(Parameter[Start + 1 : End])\r
+                    Parameter = Parameter[0 : Start]\r
+                    SqlCommand = """select Value from %s where Name = '%s' and Model = %s""" % (Table, Parameter, MODEL_IDENTIFIER_VARIABLE)\r
+                    NewRecordSet = Db.Exec(SqlCommand)\r
+                    for NewRecord in NewRecordSet:\r
+                        NewParameter = GetSplitValueList(NewRecord[0], '}')[Index]\r
+                        GuidName = GetPpiParameter(NewParameter[NewParameter.find('{') : ])\r
+                        Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r
+                        IsFound = True\r
+                except Exception:\r
+                    pass\r
+\r
+        # A External Parameter\r
+        if not IsFound:\r
+            SqlCommand = """select File.ID from Inf, File\r
+                            where BelongsToFile = (select BelongsToFile from Inf where Value1 = '%s')\r
+                            and Inf.Model = %s and Inf.Value1 = File.FullPath and File.Model = %s""" % (SourceFileFullPath, MODEL_EFI_SOURCE_FILE, MODEL_FILE_C)\r
+            NewRecordSet = Db.Exec(SqlCommand)\r
+            for NewRecord in NewRecordSet:\r
+                Table = 'Identifier' + str(NewRecord[0])\r
+                SqlCommand = """select Value from %s where Name = '%s' and Modifier = 'EFI_PEI_PPI_DESCRIPTOR' and Model = %s""" % (Table, Parameter, MODEL_IDENTIFIER_VARIABLE)\r
+                PpiSet = Db.Exec(SqlCommand)\r
+                if PpiSet != []:\r
+                    GuidName = GetPpiParameter(PpiSet[0][0])\r
+                    if GuidName != '':\r
+                        Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r
+                        IsFound = True\r
+                        break\r
+\r
+        if not IsFound:\r
+            EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))\r
+\r
+## SearchProtocols() method\r
+#\r
+#  Search all used PROTOCOL calling function\r
+#  Store the result to database\r
+#\r
+#  @param SqlCommand: SQL command statement\r
+#  @param Table: Table id\r
+#  @param SourceFileID: Source file id\r
+#  @param SourceFileFullPath: Source file full path\r
+#  @param ItemMode: Mode of the item\r
+#  @param ProtocolMode: Mode of PROTOCOL\r
+#\r
+def SearchProtocols(SqlCommand, Table, SourceFileID, SourceFileFullPath, ItemMode, ProtocolMode):\r
+    ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Protocol', '', '', ''\r
+    BelongsToFunctionID, BelongsToFunction = -1, ''\r
+    Db = EotGlobalData.gDb.TblReport\r
+    RecordSet = Db.Exec(SqlCommand)\r
+    for Record in RecordSet:\r
+        Parameter = ''\r
+        BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]\r
+        # Get BelongsToFunction\r
+        BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)\r
+\r
+        # Default is Not Found\r
+        IsFound = False\r
+\r
+        if ProtocolMode == 0 or ProtocolMode == 1:\r
+            Parameter = GetProtocolParameter(Record[0], ProtocolMode)\r
+            if Parameter.startswith('g') or Parameter.endswith('Guid') or Parameter == 'ShellEnvProtocol' or Parameter == 'ShellInterfaceProtocol':\r
+                GuidName = GetParameterName(Parameter)\r
+                Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r
+                IsFound = True\r
+\r
+        if ProtocolMode == 2:\r
+            Protocols = GetSplitValueList(Record[0], TAB_COMMA_SPLIT)\r
+            for Protocol in Protocols:\r
+                if Protocol.startswith('&') and Protocol.endswith('Guid'):\r
+                    GuidName = GetParameterName(Protocol)\r
+                    Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r
+                    IsFound = True\r
+                else:\r
+                    NewValue = FindKeyValue(EotGlobalData.gDb.TblFile, Table, Protocol)\r
+                    if Protocol != NewValue and NewValue.endswith('Guid'):\r
+                        GuidName = GetParameterName(NewValue)\r
+                        Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r
+                        IsFound = True\r
+\r
+        if not IsFound:\r
+            if BelongsToFunction in EotGlobalData.gProducedProtocolLibrary or BelongsToFunction in EotGlobalData.gConsumedProtocolLibrary:\r
+                EotGlobalData.gOP_UN_MATCHED_IN_LIBRARY_CALLING.write('%s, %s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter, BelongsToFunction))\r
+            else:\r
+                EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))\r
+\r
+## SearchFunctionCalling() method\r
+#\r
+#  Search all used PPI/PROTOCOL calling function by library\r
+#  Store the result to database\r
+#\r
+#  @param SqlCommand: SQL command statement\r
+#  @param Table: Table id\r
+#  @param SourceFileID: Source file id\r
+#  @param SourceFileFullPath: Source file full path\r
+#  @param ItemType: Type of the item, PPI or PROTOCOL\r
+#  @param ItemMode: Mode of item\r
+#\r
+def SearchFunctionCalling(Table, SourceFileID, SourceFileFullPath, ItemType, ItemMode):\r
+    LibraryList = sdict()\r
+    Db = EotGlobalData.gDb.TblReport\r
+    Parameters, ItemName, GuidName, GuidMacro, GuidValue, BelongsToFunction = [], '', '', '', '', ''\r
+    if ItemType == 'Protocol' and ItemMode == 'Produced':\r
+        LibraryList = EotGlobalData.gProducedProtocolLibrary\r
+    elif ItemType == 'Protocol' and ItemMode == 'Consumed':\r
+        LibraryList = EotGlobalData.gConsumedProtocolLibrary\r
+    elif ItemType == 'Protocol' and ItemMode == 'Callback':\r
+        LibraryList = EotGlobalData.gCallbackProtocolLibrary\r
+    elif ItemType == 'Ppi' and ItemMode == 'Produced':\r
+        LibraryList = EotGlobalData.gProducedPpiLibrary\r
+    elif ItemType == 'Ppi' and ItemMode == 'Consumed':\r
+        LibraryList = EotGlobalData.gConsumedPpiLibrary\r
+\r
+    for Library in LibraryList:\r
+        Index = LibraryList[Library]\r
+        SqlCommand = """select Value, StartLine from %s\r
+                        where Name like '%%%s%%' and Model = %s""" \\r
+                        % (Table, Library, MODEL_IDENTIFIER_FUNCTION_CALLING)\r
+        RecordSet = Db.Exec(SqlCommand)\r
+        for Record in RecordSet:\r
+            IsFound = False\r
+            if Index == -1:\r
+                ParameterList = GetSplitValueList(Record[0], TAB_COMMA_SPLIT)\r
+                for Parameter in ParameterList:\r
+                    Parameters.append(GetParameterName(Parameter))\r
+            else:\r
+                Parameters = [GetProtocolParameter(Record[0], Index)]\r
+            StartLine = Record[1]\r
+            for Parameter in Parameters:\r
+                if Parameter.startswith('g') or Parameter.endswith('Guid') or Parameter == 'ShellEnvProtocol' or Parameter == 'ShellInterfaceProtocol':\r
+                    GuidName = GetParameterName(Parameter)\r
+                    Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)\r
+                    IsFound = True\r
+\r
+            if not IsFound:\r
+                EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))\r
+\r
+## FindProtocols() method\r
+#\r
+#  Find defined protocols\r
+#\r
+#  @param SqlCommand: SQL command statement\r
+#  @param Table: Table id\r
+#  @param SourceFileID: Source file id\r
+#  @param SourceFileFullPath: Source file full path\r
+#  @param ItemName: String of protocol definition\r
+#  @param ItemType: Type of the item, PPI or PROTOCOL\r
+#  @param ItemMode: Mode of item\r
+#\r
+#def FindProtocols(Db, SqlCommand, Table, SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue):\r
+#    BelongsToFunction = ''\r
+#    RecordSet = Db.Exec(SqlCommand)\r
+#    for Record in RecordSet:\r
+#        IsFound = True\r
+#        Parameter = GetProtocolParameter(Record[0])\r
+\r
+## GetProtocolParameter() method\r
+#\r
+# Parse string of protocol and find parameters\r
+#\r
+#  @param Parameter: Parameter to be parsed\r
+#  @param Index: The index of the parameter\r
+#\r
+#  @return: call common GetParameter\r
+#\r
+def GetProtocolParameter(Parameter, Index = 1):\r
+    return GetParameter(Parameter, Index)\r
+\r
+## GetPpiParameter() method\r
+#\r
+# Parse string of ppi and find parameters\r
+#\r
+#  @param Parameter: Parameter to be parsed\r
+#  @param Index: The index of the parameter\r
+#\r
+#  @return: call common GetParameter\r
+#\r
+def GetPpiParameter(Parameter, Index = 1):\r
+    return GetParameter(Parameter, Index)\r
+\r
+## GetParameter() method\r
+#\r
+# Get a parameter by index\r
+#\r
+#  @param Parameter: Parameter to be parsed\r
+#  @param Index: The index of the parameter\r
+#\r
+#  @return Parameter: The found parameter\r
+#\r
+def GetParameter(Parameter, Index = 1):\r
+    ParameterList = GetSplitValueList(Parameter, TAB_COMMA_SPLIT)\r
+    if len(ParameterList) > Index:\r
+        Parameter = GetParameterName(ParameterList[Index])\r
+\r
+        return Parameter\r
+\r
+    return ''\r
+\r
+## GetParameterName() method\r
+#\r
+# Get a parameter name\r
+#\r
+#  @param Parameter: Parameter to be parsed\r
+#\r
+#  @return: The name of parameter\r
+#\r
+def GetParameterName(Parameter):\r
+    if type(Parameter) == type('') and Parameter.startswith('&'):\r
+        return Parameter[1:].replace('{', '').replace('}', '').replace('\r', '').replace('\n', '').strip()\r
+    else:\r
+        return Parameter.strip()\r
+\r
+## FindKeyValue() method\r
+#\r
+# Find key value of a variable\r
+#\r
+#  @param Db: Database to be searched\r
+#  @param Table: Table to be searched\r
+#  @param Key: The keyword\r
+#\r
+#  @return Value: The value of the the keyword\r
+#\r
+def FindKeyValue(Db, Table, Key):\r
+    SqlCommand = """select Value from %s where Name = '%s' and (Model = %s or Model = %s)""" % (Table, Key, MODEL_IDENTIFIER_VARIABLE, MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION)\r
+    RecordSet = Db.Exec(SqlCommand)\r
+    Value = ''\r
+    for Record in RecordSet:\r
+        if Record[0] != 'NULL':\r
+            Value = FindKeyValue(Db, Table, GetParameterName(Record[0]))\r
+\r
+    if Value != '':\r
+        return Value\r
+    else:\r
+        return Key\r
+\r
+## ParseMapFile() method\r
+#\r
+#  Parse map files to get a dict of 'ModuleName' : {FunName : FunAddress}\r
+#\r
+#  @param Files: A list of map files\r
+#\r
+#  @return AllMaps: An object of all map files\r
+#\r
+def ParseMapFile(Files):\r
+    AllMaps = {}\r
+    CurrentModule = ''\r
+    CurrentMaps = {}\r
+    for File in Files:\r
+        Content = open(File, 'r').readlines()\r
+        for Line in Content:\r
+            Line = CleanString(Line)\r
+            # skip empty line\r
+            if Line == '':\r
+                continue\r
+\r
+            if Line.find('(') > -1 and Line.find(')') > -1:\r
+                if CurrentModule != '' and CurrentMaps != {}:\r
+                    AllMaps[CurrentModule] = CurrentMaps\r
+                CurrentModule = Line[:Line.find('(')]\r
+                CurrentMaps = {}\r
+                continue\r
+            else:\r
+                Name = ''\r
+                Address = ''\r
+                List = Line.split()\r
+                Address = List[0]\r
+                if List[1] == 'F' or List[1] == 'FS':\r
+                    Name = List[2]\r
+                else:\r
+                    Name = List[1]\r
+                CurrentMaps[Name] = Address\r
+                continue\r
+\r
+    return AllMaps\r
+\r
+## ConvertGuid\r
+#\r
+#  Convert a GUID to a GUID with all upper letters\r
+#\r
+#  @param guid:  The GUID to be converted\r
+#\r
+#  @param newGuid: The GUID with all upper letters.\r
+#\r
+def ConvertGuid(guid):\r
+    numList = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']\r
+    newGuid = ''\r
+    if guid.startswith('g'):\r
+        guid = guid[1:]\r
+    for i in guid:\r
+        if i.upper() == i and i not in numList:\r
+            newGuid = newGuid + ('_' + i)\r
+        else:\r
+            newGuid = newGuid + i.upper()\r
+    if newGuid.startswith('_'):\r
+        newGuid = newGuid[1:]\r
+    if newGuid.endswith('_'):\r
+        newGuid = newGuid[:-1]\r
+\r
+    return newGuid\r
+\r
+## ConvertGuid2() method\r
+#\r
+#  Convert a GUID to a GUID with new string instead of old string\r
+#\r
+#  @param guid: The GUID to be converted\r
+#  @param old: Old string to be replaced\r
+#  @param new: New string to replace the old one\r
+#\r
+#  @param newGuid: The GUID after replacement\r
+#\r
+def ConvertGuid2(guid, old, new):\r
+    newGuid = ConvertGuid(guid)\r
+    newGuid = newGuid.replace(old, new)\r
+\r
+    return newGuid\r
+\r
+##\r
+#\r
+# This acts like the main() function for the script, unless it is 'import'ed into another\r
+# script.\r
+#\r
+if __name__ == '__main__':\r
+    pass\r