1. Added more error check
authorjwang36 <jwang36@7335b38e-4728-0410-8992-fb3ffe349368>
Mon, 7 Jul 2008 07:29:33 +0000 (07:29 +0000)
committerjwang36 <jwang36@7335b38e-4728-0410-8992-fb3ffe349368>
Mon, 7 Jul 2008 07:29:33 +0000 (07:29 +0000)
2. Added more or more exact information in error message
3. Cleaned error message

git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@1277 7335b38e-4728-0410-8992-fb3ffe349368

Source/Python/AutoGen/AutoGen.py
Source/Python/AutoGen/BuildEngine.py
Source/Python/AutoGen/GenC.py
Source/Python/AutoGen/GenMake.py
Source/Python/Common/EdkLogger.py
Source/Python/Workspace/MetaFileParser.py
Source/Python/Workspace/WorkspaceDatabase.py
Source/Python/build/build.py

index a65e893..6da0649 100755 (executable)
@@ -506,6 +506,9 @@ class PlatformAutoGen(AutoGen):
     #
     def _GetToolDefinition(self):
         ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDictionary
+        if "COMMAND_TYPE" not in self.Workspace.ToolDef.ToolsDefTxtDatabase:
+            EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No tools found in configuration",
+                            ExtraData="[%s]" % self._MetaFile)
         ToolCodeList = self.Workspace.ToolDef.ToolsDefTxtDatabase["COMMAND_TYPE"]
         self._ToolPath = {}
         self._ToolDllPath = {}
@@ -551,7 +554,10 @@ class PlatformAutoGen(AutoGen):
             else:
                 OutputFlag = gDefaultOutputFlag
 
-            InputFlag = gIncludeFlag[Family]
+            if Family in gIncludeFlag:
+                InputFlag = gIncludeFlag[Family]
+            else:
+                InputFlag = '-I'
 
             self._ToolPath[Tool] = Path
             self._ToolDllPath[Tool] = Dll
@@ -668,7 +674,8 @@ class PlatformAutoGen(AutoGen):
         # print out error information and break the build, if error found
         if len(NoDatumTypePcdList) > 0:
             NoDatumTypePcdListString = "\n\t\t".join(NoDatumTypePcdList)
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "PCD setting error",
+            EdkLogger.error("build", AUTOGEN_ERROR, "PCD setting error",
+                            File=self._MetaFile,
                             ExtraData="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"
                                       % NoDatumTypePcdListString)
 
@@ -782,9 +789,10 @@ class PlatformAutoGen(AutoGen):
                 LibraryPath = M.LibraryClasses[LibraryClassName]
                 if LibraryPath == None or LibraryPath == "":
                     LibraryPath = self.Platform.LibraryClasses[LibraryClassName, ModuleType]
-                    if LibraryPath == None and LibraryClassName not in LibraryInstance:
-                        LibraryInstance[LibraryClassName] = None
-                        continue
+                    if LibraryPath == None:
+                        EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
+                                        "Instance of library class [%s] is not found" % LibraryClassName,
+                                        File=self._MetaFile, ExtraData="consumed by [%s] [%s]" % (str(M), self.Arch))
                 if LibraryClassName not in LibraryInstance:
                     LibraryModule = self.BuildDatabase[LibraryPath, self.Arch]
                     # for those forced library instance (NULL library), add a fake library class
@@ -826,10 +834,10 @@ class PlatformAutoGen(AutoGen):
         Q = []
         for LibraryClassName in LibraryInstance:
             M = LibraryInstance[LibraryClassName]
-            if M == None:
-                EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
-                                "Library instance of library class [%s] is not found" % LibraryClassName,
-                                File=self._MetaFile, ExtraData="consumed by [%s] [%s]" % (str(Module), self.Arch))
+            #if M == None:
+            #    EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
+            #                    "Library instance of library class [%s] is not found" % LibraryClassName,
+            #                    File=self._MetaFile, ExtraData="consumed by [%s] [%s]" % (str(Module), self.Arch))
             LibraryList.append(M)
             #
             # check if there're library classes
@@ -996,7 +1004,7 @@ class PlatformAutoGen(AutoGen):
                     EdkLogger.error(
                                 'build',
                                 RESOURCE_NOT_AVAILABLE,
-                                "Value of [%s] is not found in" % Sku.VariableGuid,
+                                "Value of GUID [%s] is not found in" % Sku.VariableGuid,
                                 ExtraData=PackageList + "\n\t(used with %s.%s from module %s)" \
                                                         % (Guid, Name, str(Module)),
                                 File=self._MetaFile
@@ -1284,7 +1292,10 @@ class ModuleAutoGen(AutoGen):
         if self._CustomMakefile == None:
             self._CustomMakefile = {}
             for Type in self.Module.CustomMakefile:
-                MakeType = gMakeTypeMap[Type]
+                if Type in gMakeTypeMap:
+                    MakeType = gMakeTypeMap[Type]
+                else:
+                    MakeType = 'nmake'
                 self._CustomMakefile[MakeType] = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])
         return self._CustomMakefile
 
@@ -1372,8 +1383,9 @@ class ModuleAutoGen(AutoGen):
         self._UnicodeFileList = []
         # use toolchain family of CC as the primary toolchain family
         if "CC" not in self.PlatformInfo.ToolChainFamily:
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Tool [CC] is not defined for %s [%s, %s]" \
-                             % (self.ToolChain, self.BuildTarget, self.Arch))
+            EdkLogger.error("build", AUTOGEN_ERROR, "Tool [CC] is not defined for %s [%s, %s]" \
+                             % (self.ToolChain, self.BuildTarget, self.Arch),
+                            ExtraData="[%s]" % self._MetaFile)
         ToolChainFamily = self.PlatformInfo.ToolChainFamily["CC"]
         BuildRule = self.PlatformInfo.BuildRule
         for F in self.Module.Sources:
@@ -1545,7 +1557,7 @@ class ModuleAutoGen(AutoGen):
                     self._IncludePathList.append(Inc)
                     # for r8 modules
                     self._IncludePathList.append(path.join(Inc, self.Arch.capitalize()))
-                # r8 module needs to put DEBUG_DIR at the end search path and not to use SOURCE_DIR all the time
+                # r8 module needs to put DEBUG_DIR at the end of search path and not to use SOURCE_DIR all the time
                 self._IncludePathList.append(self.DebugDir)
             else:
                 self._IncludePathList.append(os.path.join(self.WorkspaceDir, self.SourceDir))
index c81f104..a869b5f 100644 (file)
-## @file\r
-# The engine for building files\r
-#\r
-# Copyright (c) 2007, 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\r
-import string\r
-\r
-from Common.BuildToolError import *\r
-import Common.EdkLogger as EdkLogger\r
-\r
-## Convert file type to makefile macro name\r
-#\r
-#   @param      FileType    The name of file type\r
-#\r
-#   @retval     string      The name of macro\r
-#\r
-def FileType2Macro(FileType):\r
-    return "$(%s_LIST)" % FileType.replace("-", "_").upper()\r
-\r
-## Class for one build rule\r
-#\r
-# This represents a build rule which can give out corresponding command list for\r
-# building the given source file(s). The result can be used for generating the\r
-# target for makefile.\r
-#\r
-class FileBuildRule:\r
-    ## constructor\r
-    #\r
-    #   @param  Input       The dictionary represeting input file(s) for a rule\r
-    #   @param  Output      The list represeting output file(s) for a rule\r
-    #   @param  Command     The list containing commands to generate the output from input\r
-    #\r
-    def __init__(self, Input, Output, Command):\r
-        # The Input should not be empty\r
-        if Input == {}:\r
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No input files for a build rule")\r
-        # The Output should not be empty\r
-        if Output == []:\r
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No output files for a build rule")\r
-\r
-        self.SourceFileType = {}\r
-        self.SourceFileExtList = []\r
-        # source files listed not in "*" or "?" pattern format\r
-        self.ExtraSourceFileList = []\r
-        self.IsMultipleInput = False\r
-        for FileType in Input:\r
-            if FileType not in self.SourceFileType:\r
-                self.SourceFileType[FileType] = []\r
-            for File in Input[FileType]:\r
-                Base, Ext = os.path.splitext(File)\r
-                if Base.find("*") >= 0:\r
-                    # There's "*" in the file name\r
-                    self.IsMultipleInput = True\r
-                elif Base.find("?") < 0:\r
-                    # There's no "*" and "?" in file name\r
-                    self.ExtraSourceFileList.append(File)\r
-                    continue\r
-                self.SourceFileType[FileType].append(Ext)\r
-                self.SourceFileExtList.append(Ext)\r
-\r
-        if len(self.SourceFileType) > 1:\r
-            self.IsMultipleInput = True\r
-\r
-        self.DestFileList = Output\r
-        self.DestFile = ""\r
-        self.DestFileExt = os.path.splitext(Output[0])[1]\r
-        self.DestPath = ""\r
-        self.DestFileName = ""\r
-        self.DestFileBase = ""\r
-        self.CommandList = Command\r
-\r
-    ## str() function support\r
-    #\r
-    #   @retval     string\r
-    #\r
-    def __str__(self):\r
-        SourceString = ""\r
-        for FileType in self.SourceFileType:\r
-            SourceString += " %s(%s)" % (FileType, " ".join(self.SourceFileType[FileType]))\r
-        DestString = ", ".join(self.DestFileList)\r
-        CommandString = "\n\t".join(self.CommandList)\r
-        return "%s : %s\n\t%s" % (DestString, SourceString, CommandString)\r
-\r
-    ## Check if given file extension is supported by this rule\r
-    #\r
-    #   @param  FileExt     The extension of a file\r
-    #\r
-    #   @retval True        If the extension is supported\r
-    #   @retval False       If the extension is not supported\r
-    #\r
-    def IsSupported(self, FileExt):\r
-        return FileExt in self.SourceFileExtList\r
-\r
-    ## Apply the rule to given source file(s)\r
-    #\r
-    #   @param  SourceFile      One file or a list of files to be built\r
-    #   @param  RelativeToDir   The relative path of the source file\r
-    #   @param  PathSeparator   Path separator\r
-    #\r
-    #   @retval     tuple       (Source file in full path, List of individual sourcefiles, Destionation file, List of build commands)\r
-    #\r
-    def Apply(self, SourceFile, RelativeToDir, PathSeparator):\r
-        # source file\r
-        if not self.IsMultipleInput:\r
-            SrcFileName = os.path.basename(SourceFile)\r
-            SrcFileBase, SrcFileExt = os.path.splitext(SrcFileName)\r
-            if RelativeToDir != None:\r
-                SrcFileDir = os.path.dirname(SourceFile)\r
-                if SrcFileDir == "":\r
-                    SrcFileDir = "."\r
-\r
-                SrcFile = PathSeparator.join([RelativeToDir, SourceFile])\r
-            else:\r
-                SrcFileDir = "."\r
-                SrcFile = SourceFile\r
-            SrcPath = os.path.dirname(SrcFile)\r
-        else:\r
-            SrcFileName = ""\r
-            SrcFileBase = ""\r
-            SrcFileExt = ""\r
-            SrcFileDir = ""\r
-            SrcPath = ""\r
-            # SourceFile must be a list\r
-            SrcFileList = []\r
-            for FileType in self.SourceFileType:\r
-                Macro = FileType2Macro(FileType)\r
-                SrcFileList.append(Macro)\r
-            SrcFile = " ".join(SrcFileList)\r
-\r
-        # destination file\r
-        for Index in range(len(self.DestFileList)):\r
-            self.DestFileList[Index] = self.DestFileList[Index].replace("(+)", PathSeparator)\r
-        for Index in range(len(self.CommandList)):\r
-            self.CommandList[Index] = self.CommandList[Index].replace("(+)", PathSeparator)\r
-\r
-        if self.DestFile == "":\r
-            self.DestFile = self.DestFileList[0]\r
-        if self.DestPath == "":\r
-            self.DestPath = os.path.dirname(self.DestFile)\r
-        if self.DestFileName == "":\r
-            self.DestFileName = os.path.basename(self.DestFile)\r
-        if self.DestFileBase == "":\r
-            self.DestFileBase = os.path.splitext(self.DestFileName)[0]\r
-\r
-        BuildRulePlaceholderDict = {\r
-            # source file\r
-            "src"       :   SrcFile,\r
-            "s_path"    :   SrcPath,\r
-            "s_dir"     :   SrcFileDir,\r
-            "s_name"    :   SrcFileName,\r
-            "s_base"    :   SrcFileBase,\r
-            "s_ext"     :   SrcFileExt,\r
-            # destination file\r
-            "dst"       :   self.DestFile,\r
-            "d_path"    :   self.DestPath,\r
-            "d_name"    :   self.DestFileName,\r
-            "d_base"    :   self.DestFileBase,\r
-            "d_ext"     :   self.DestFileExt,\r
-        }\r
-\r
-        DstFileList = []\r
-        for FileString in self.DestFileList:\r
-            FileString = string.Template(FileString).safe_substitute(BuildRulePlaceholderDict)\r
-            FileString = string.Template(FileString).safe_substitute(BuildRulePlaceholderDict)\r
-            DstFileList.append(FileString)\r
-        CommandList = []\r
-        for CommandString in self.CommandList:\r
-            CommandString = string.Template(CommandString).safe_substitute(BuildRulePlaceholderDict)\r
-            CommandString = string.Template(CommandString).safe_substitute(BuildRulePlaceholderDict)\r
-            CommandList.append(CommandString)\r
-\r
-        return SrcFile, self.ExtraSourceFileList, DstFileList[0], CommandList\r
-\r
-## Class for build rules\r
-#\r
-# BuildRule class parses rules defined in a file or passed by caller, and converts\r
-# the rule into FileBuildRule object.\r
-#\r
-class BuildRule:\r
-    _SectionHeader = "SECTIONHEADER"\r
-    _Section = "SECTION"\r
-    _SubSectionHeader = "SUBSECTIONHEADER"\r
-    _SubSection = "SUBSECTION"\r
-    _InputFile = "INPUTFILE"\r
-    _OutputFile = "OUTPUTFILE"\r
-    _Command = "COMMAND"\r
-    _UnknownSection = "UNKNOWNSECTION"\r
-\r
-    _SubSectionList = [_InputFile, _OutputFile, _Command]\r
-\r
-    ## Constructor\r
-    #\r
-    #   @param  File                The file containing build rules in a well defined format\r
-    #   @param  Content             The string list of build rules in a well defined format\r
-    #   @param  LineIndex           The line number from which the parsing will begin\r
-    #   @param  SupportedFamily     The list of supported tool chain families\r
-    #\r
-    def __init__(self, File=None, Content=None, LineIndex=0, SupportedFamily=["MSFT", "INTEL", "GCC"]):\r
-        self.RuleFile = File\r
-        # Read build rules from file if it's not none\r
-        if File != None:\r
-            try:\r
-                self.RuleContent = open(File, 'r').readlines()\r
-            except:\r
-                EdkLogger.error("BuildRuleParser", FILE_OPEN_FAILURE, ExtraData=File)\r
-        elif Content != None:\r
-            self.RuleContent = Content\r
-        else:\r
-            EdkLogger.error("BuildRuleParser", PARAMETER_MISSING, ExtraData="No rule file or string given")\r
-\r
-        self.SupportedToolChainFamilyList = SupportedFamily\r
-        self.RuleDatabase = {}  # {version : {family : {file type : FileBuildRule object}}}\r
-        self.FileTypeDict = {}  # {ext : file-type}\r
-\r
-        self._LineIndex = LineIndex\r
-        self._BuildVersion = "*"\r
-        self._RuleInfo = {}     # {toolchain family : {"InputFile": {}, "OutputFile" : [], "Command" : []}}\r
-        self._FileTypeList = []\r
-        self._FamilyList = []\r
-        self._State = ""\r
-        self._RuleObjectList = [] # FileBuildRule object list\r
-\r
-        self.Parse()\r
-\r
-    ## Parse the build rule strings\r
-    def Parse(self):\r
-        self._State = self._Section\r
-        for Index in range(self._LineIndex, len(self.RuleContent)):\r
-            Line = self.RuleContent[Index].strip()\r
-            self.RuleContent[Index] = Line\r
-\r
-            # skip empty or comment line\r
-            if Line == "" or Line[0] == "#":\r
-                continue\r
-\r
-            # find out section header, enclosed by []\r
-            if Line[0] == '[' and Line[-1] == ']':\r
-                # merge last section information into rule database\r
-                self.EndOfSection()\r
-                self._State = self._SectionHeader\r
-            # find out sub-section header, enclosed by <>\r
-            elif Line[0] == '<' and Line[-1] == '>':\r
-                if self._State != self._UnknownSection:\r
-                    self._State = self._SubSectionHeader\r
-            # call section handler to parse each (sub)section\r
-            self._StateHandler[self._State](self, Index)\r
-        # merge last section information into rule database\r
-        self.EndOfSection()\r
-\r
-        # setup the relationship between file extension and file type\r
-        for RuleObject in self._RuleObjectList:\r
-            for FileType in RuleObject.SourceFileType:\r
-                for FileExt in RuleObject.SourceFileType[FileType]:\r
-                    self.FileTypeDict[FileExt] = FileType\r
-\r
-    ## Parse definitions under a section\r
-    #\r
-    #   @param  LineIndex   The line index of build rule text\r
-    #\r
-    def ParseSection(self, LineIndex):\r
-        TokenList = self.RuleContent[LineIndex].split("=", 1)\r
-        # currently only BUILD_VERSION is supported\r
-        if len(TokenList) != 2 or TokenList[0] != "BUILD_VERSION":\r
-            EdkLogger.error("BuildRuleParser", FORMAT_INVALID, File=RuleFile, Line=LineIndex+1, \r
-                            ExtraData="Invalid definition: " + self.RuleContent[LineIndex])\r
-\r
-        try:\r
-            self._BuildVersion = int(TokenList[1].strip(), 0)\r
-        except:\r
-            EdkLogger.error("BuildRuleParser", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1, \r
-                            ExtraData="Version is not a valid number: " + self.RuleContent[LineIndex])\r
-\r
-    ## Parse definitions under a subsection\r
-    #\r
-    #   @param  LineIndex   The line index of build rule text\r
-    #\r
-    def ParseSubSection(self, LineIndex):\r
-        # currenly nothing here\r
-        pass\r
-\r
-    ## Placeholder for not supported sections\r
-    #\r
-    #   @param  LineIndex   The line index of build rule text\r
-    #\r
-    def SkipSection(self, LineIndex):\r
-        pass\r
-\r
-    ## Merge section information just got into rule database\r
-    def EndOfSection(self):\r
-        if self._FileTypeList == [] or self._RuleInfo == {}:\r
-            return\r
-\r
-        Database = self.RuleDatabase\r
-        if self._BuildVersion not in Database:\r
-            Database[self._BuildVersion] = {}\r
-        Database = self.RuleDatabase[self._BuildVersion]\r
-\r
-        # expand *\r
-        FamilyList = self._RuleInfo.keys()\r
-        if "*" in FamilyList and len(FamilyList) > 1:\r
-            FamilyList.remove("*")\r
-\r
-        NewRuleInfo = {}\r
-        for Family in self._RuleInfo:\r
-            Rule = self._RuleInfo[Family]\r
-            if Family == "*" and Family not in FamilyList:\r
-                NewFamilyList = FamilyList\r
-            else:\r
-                NewFamilyList = [Family]\r
-\r
-            for NewFamily in NewFamilyList:\r
-                if NewFamily not in NewRuleInfo:\r
-                    NewRuleInfo[NewFamily] = {}\r
-\r
-                if self._InputFile in Rule:\r
-                    NewRuleInfo[NewFamily][self._InputFile] = Rule[self._InputFile]\r
-                if self._OutputFile in Rule:\r
-                    NewRuleInfo[NewFamily][self._OutputFile] = Rule[self._OutputFile]\r
-                if self._Command in Rule:\r
-                    NewRuleInfo[NewFamily][self._Command] = Rule[self._Command]\r
-\r
-        for NewFamily in FamilyList:\r
-            Rule = NewRuleInfo[NewFamily]\r
-            if NewFamily not in Database:\r
-                Database[NewFamily] = {}\r
-\r
-            if self._InputFile in Rule:\r
-                Input = Rule[self._InputFile]\r
-            else:\r
-                EdkLogger.error("BuildRuleParser", FORMAT_INVALID, ExtraData="No input files found for a rule")\r
-\r
-            if self._OutputFile in Rule:\r
-                Output = Rule[self._OutputFile]\r
-            else:\r
-                EdkLogger.error("BuildRuleParser", FORMAT_INVALID, ExtraData="No output files found a rule")\r
-\r
-            if self._Command in Rule:\r
-                Command = Rule[self._Command]\r
-            else:\r
-                Command = []\r
-\r
-            if NewFamily == "*":\r
-                for Family in self.SupportedToolChainFamilyList:\r
-                    if Family not in Database:\r
-                        Database[Family] = {}\r
-                    RuleObject = FileBuildRule(Input, Output, Command)\r
-                    self._RuleObjectList.append(RuleObject)\r
-                    for FileType in RuleObject.SourceFileType:\r
-                        Database[Family][FileType] = RuleObject\r
-            else:\r
-                RuleObject = FileBuildRule(Input, Output, Command)\r
-                self._RuleObjectList.append(RuleObject)\r
-                for FileType in RuleObject.SourceFileType:\r
-                    Database[NewFamily][FileType] = RuleObject\r
-        # for new section\r
-        self._RuleInfo = {}\r
-\r
-    ## Parse section header\r
-    #\r
-    #   @param  LineIndex   The line index of build rule text\r
-    #\r
-    def ParseSectionHeader(self, LineIndex):\r
-        BuildVersion = ""\r
-        FileTypeList = []\r
-        RuleNameList = self.RuleContent[LineIndex][1:-1].split(',')\r
-        for RuleName in RuleNameList:\r
-            TokenList = RuleName.split('.')\r
-            if len(TokenList) == 1:\r
-                EdkLogger.error("BuildRuleParser", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1, \r
-                                ExtraData="Invalid rule section: " + self.RuleContent[LineIndex])\r
-\r
-            Rule = TokenList[0].strip()\r
-            if Rule.upper() != "BUILD":\r
-                self._State = self._UnknownSection\r
-                return\r
-\r
-            FileType = TokenList[1].strip()\r
-            if FileType == '':\r
-                EdkLogger.error("BuildRuleParser", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1, \r
-                                ExtraData="No file type given: " + Line)\r
-            FileTypeList.append(FileType)\r
-\r
-        self._FileTypeList = FileTypeList\r
-        self._BuildVersion = "*"\r
-        self._State = self._Section\r
-\r
-    ## Parse sub-section header\r
-    #\r
-    #   @param  LineIndex   The line index of build rule text\r
-    #\r
-    def ParseSubSectionHeader(self, LineIndex):\r
-        SectionType = ""\r
-        List = self.RuleContent[LineIndex][1:-1].split(',')\r
-        FamilyList = []\r
-        for Section in List:\r
-            TokenList = Section.split('.')\r
-            Type = TokenList[0].strip().upper()\r
-\r
-            if SectionType == "":\r
-                SectionType = Type\r
-            elif SectionType != Type:\r
-                EdkLogger.error("BuildRuleParser", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1, \r
-                                ExtraData="Two different section types are not allowed: " + Line)\r
-\r
-            if len(TokenList) > 1:\r
-                Family = TokenList[1].strip().upper()\r
-            else:\r
-                Family = "*"\r
-\r
-            if Family not in FamilyList:\r
-                FamilyList.append(Family)\r
-\r
-        self._FamilyList = FamilyList\r
-        self._State = SectionType.upper()\r
-\r
-    ## Parse <InputFile> sub-section\r
-    #\r
-    #   @param  LineIndex   The line index of build rule text\r
-    #\r
-    def ParseInputFile(self, LineIndex):\r
-        Line = self.RuleContent[LineIndex]\r
-        TokenList = Line.split("=")\r
-        FileType = ""\r
-        if len(TokenList) > 1:\r
-            FileType = TokenList[0].strip()\r
-            if FileType not in self._FileTypeList:\r
-                EdkLogger.error("BuildRuleParser", FORMAT_INVALID, File=self.RuleFile,  Line=LineIndex+1,\r
-                                ExtraData="File type must be one of %s: %s" % (self._FileTypeList, FileType))\r
-            FileString = TokenList[1]\r
-        else:\r
-            if len(self._FileTypeList) > 1:\r
-                EdkLogger.error("BuildRuleParser", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex, \r
-                                ExtraData="File type must be given: " + Line)\r
-            else:\r
-                FileType = self._FileTypeList[0]\r
-            FileString = TokenList[0]\r
-\r
-        FileList = FileString.split(",")\r
-        for File in FileList:\r
-            File = File.strip()\r
-            for Family in self._FamilyList:\r
-                if Family not in self._RuleInfo:\r
-                    self._RuleInfo[Family] = {}\r
-                if self._State not in self._RuleInfo[Family]:\r
-                    self._RuleInfo[Family][self._State] = {}\r
-                if FileType not in self._RuleInfo[Family][self._State]:\r
-                    self._RuleInfo[Family][self._State][FileType] = []\r
-                self._RuleInfo[Family][self._State][FileType].append(File)\r
-\r
-    ## Parse <OutputFile> sub-section\r
-    #\r
-    #   @param  LineIndex   The line index of build rule text\r
-    #\r
-    def ParseOutputFile(self, LineIndex):\r
-        FileList = self.RuleContent[LineIndex].split(",")\r
-        for File in FileList:\r
-            File = File.strip()\r
-            for Family in self._FamilyList:\r
-                if Family not in self._RuleInfo:\r
-                    self._RuleInfo[Family] = {}\r
-                    self._RuleInfo[Family][self._State] = []\r
-                if self._State not in self._RuleInfo[Family]:\r
-                    self._RuleInfo[Family][self._State] = []\r
-                self._RuleInfo[Family][self._State].append(File)\r
-\r
-    ## Parse <Command> sub-section\r
-    #\r
-    #   @param  LineIndex   The line index of build rule text\r
-    #\r
-    def ParseCommand(self, LineIndex):\r
-        Command = self.RuleContent[LineIndex]\r
-        for Family in self._FamilyList:\r
-            if Family not in self._RuleInfo:\r
-                self._RuleInfo[Family] = {}\r
-                self._RuleInfo[Family][self._State] = []\r
-            if self._State not in self._RuleInfo[Family]:\r
-                self._RuleInfo[Family][self._State] = []\r
-            self._RuleInfo[Family][self._State].append(Command)\r
-\r
-    ## Get a build rule\r
-    #\r
-    #   @param  FileExt             The extension of a file\r
-    #   @param  ToolChainFamily     The tool chain family name\r
-    #   @param  BuildVersion        The build version number. "*" means any rule\r
-    #                               is applicalbe.\r
-    #\r
-    #   @retval FileType        The file type string\r
-    #   @retval FileBuildRule   The object of FileBuildRule\r
-    # \r
-    def Get(self, FileExt, ToolChainFamily, BuildVersion="*"):\r
-        if FileExt not in self.FileTypeDict:\r
-            return None, None\r
-        FileType = self.FileTypeDict[FileExt]\r
-        Database = {}\r
-        BuildRuleObject = None\r
-        if BuildVersion in self.RuleDatabase:\r
-            Database = self.RuleDatabase[BuildVersion]\r
-        elif BuildVersion != "*":\r
-            if "*" not in self.RuleDatabase:\r
-                return FileType, None\r
-            Database = self.RuleDatabase["*"]\r
-        else:\r
-            # BuildVersion == "*" and "*" not in self.RuleDatabase\r
-            # try to match ToolChainFamily\r
-            for Ver in self.RuleDatabase:\r
-                Database = self.RuleDatabase[Ver]\r
-                if ToolChainFamily not in Database:\r
-                    continue\r
-                if FileType not in Database[ToolChainFamily]:\r
-                    continue\r
-                break\r
-            else:\r
-                return FileType, None\r
-\r
-        if ToolChainFamily not in Database:\r
-            return FileType, None\r
-        if FileType not in Database[ToolChainFamily]:\r
-            return FileType, None\r
-        if not Database[ToolChainFamily][FileType].IsSupported(FileExt):\r
-            return FileType, None\r
-\r
-        return FileType, Database[ToolChainFamily][FileType]\r
-\r
-    _StateHandler = {\r
-        _SectionHeader     : ParseSectionHeader,\r
-        _Section           : ParseSection,\r
-        _SubSectionHeader  : ParseSubSectionHeader,\r
-        _SubSection        : ParseSubSection,\r
-        _InputFile         : ParseInputFile,\r
-        _OutputFile        : ParseOutputFile,\r
-        _Command           : ParseCommand,\r
-        _UnknownSection    : SkipSection,\r
-    }\r
-\r
-# This acts like the main() function for the script, unless it is 'import'ed into another\r
-# script.\r
-if __name__ == '__main__':\r
-    pass\r
-\r
+## @file
+# The engine for building files
+#
+# Copyright (c) 2007, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+##
+# Import Modules
+#
+import os
+import re
+import string
+
+from Common.BuildToolError import *
+import Common.EdkLogger as EdkLogger
+
+## Convert file type to makefile macro name
+#
+#   @param      FileType    The name of file type
+#
+#   @retval     string      The name of macro
+#
+def FileType2Macro(FileType):
+    return "$(%s_LIST)" % FileType.replace("-", "_").upper()
+
+## Class for one build rule
+#
+# This represents a build rule which can give out corresponding command list for
+# building the given source file(s). The result can be used for generating the
+# target for makefile.
+#
+class FileBuildRule:
+    ## constructor
+    #
+    #   @param  Input       The dictionary represeting input file(s) for a rule
+    #   @param  Output      The list represeting output file(s) for a rule
+    #   @param  Command     The list containing commands to generate the output from input
+    #
+    def __init__(self, Input, Output, Command):
+        # The Input should not be empty
+        if Input == {}:
+            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No input files for a build rule")
+        # The Output should not be empty
+        if Output == []:
+            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No output files for a build rule")
+
+        self.SourceFileType = {}
+        self.SourceFileExtList = []
+        # source files listed not in "*" or "?" pattern format
+        self.ExtraSourceFileList = []
+        self.IsMultipleInput = False
+        for FileType in Input:
+            if FileType not in self.SourceFileType:
+                self.SourceFileType[FileType] = []
+            for File in Input[FileType]:
+                Base, Ext = os.path.splitext(File)
+                if Base.find("*") >= 0:
+                    # There's "*" in the file name
+                    self.IsMultipleInput = True
+                elif Base.find("?") < 0:
+                    # There's no "*" and "?" in file name
+                    self.ExtraSourceFileList.append(File)
+                    continue
+                self.SourceFileType[FileType].append(Ext)
+                self.SourceFileExtList.append(Ext)
+
+        if len(self.SourceFileType) > 1:
+            self.IsMultipleInput = True
+
+        self.DestFileList = Output
+        self.DestFile = ""
+        self.DestFileExt = os.path.splitext(Output[0])[1]
+        self.DestPath = ""
+        self.DestFileName = ""
+        self.DestFileBase = ""
+        self.CommandList = Command
+
+    ## str() function support
+    #
+    #   @retval     string
+    #
+    def __str__(self):
+        SourceString = ""
+        for FileType in self.SourceFileType:
+            SourceString += " %s(%s)" % (FileType, " ".join(self.SourceFileType[FileType]))
+        DestString = ", ".join(self.DestFileList)
+        CommandString = "\n\t".join(self.CommandList)
+        return "%s : %s\n\t%s" % (DestString, SourceString, CommandString)
+
+    ## Check if given file extension is supported by this rule
+    #
+    #   @param  FileExt     The extension of a file
+    #
+    #   @retval True        If the extension is supported
+    #   @retval False       If the extension is not supported
+    #
+    def IsSupported(self, FileExt):
+        return FileExt in self.SourceFileExtList
+
+    ## Apply the rule to given source file(s)
+    #
+    #   @param  SourceFile      One file or a list of files to be built
+    #   @param  RelativeToDir   The relative path of the source file
+    #   @param  PathSeparator   Path separator
+    #
+    #   @retval     tuple       (Source file in full path, List of individual sourcefiles, Destionation file, List of build commands)
+    #
+    def Apply(self, SourceFile, RelativeToDir, PathSeparator):
+        # source file
+        if not self.IsMultipleInput:
+            SrcFileName = os.path.basename(SourceFile)
+            SrcFileBase, SrcFileExt = os.path.splitext(SrcFileName)
+            if RelativeToDir != None:
+                SrcFileDir = os.path.dirname(SourceFile)
+                if SrcFileDir == "":
+                    SrcFileDir = "."
+
+                SrcFile = PathSeparator.join([RelativeToDir, SourceFile])
+            else:
+                SrcFileDir = "."
+                SrcFile = SourceFile
+            SrcPath = os.path.dirname(SrcFile)
+        else:
+            SrcFileName = ""
+            SrcFileBase = ""
+            SrcFileExt = ""
+            SrcFileDir = ""
+            SrcPath = ""
+            # SourceFile must be a list
+            SrcFileList = []
+            for FileType in self.SourceFileType:
+                Macro = FileType2Macro(FileType)
+                SrcFileList.append(Macro)
+            SrcFile = " ".join(SrcFileList)
+
+        # destination file
+        for Index in range(len(self.DestFileList)):
+            self.DestFileList[Index] = self.DestFileList[Index].replace("(+)", PathSeparator)
+        for Index in range(len(self.CommandList)):
+            self.CommandList[Index] = self.CommandList[Index].replace("(+)", PathSeparator)
+
+        if self.DestFile == "":
+            self.DestFile = self.DestFileList[0]
+        if self.DestPath == "":
+            self.DestPath = os.path.dirname(self.DestFile)
+        if self.DestFileName == "":
+            self.DestFileName = os.path.basename(self.DestFile)
+        if self.DestFileBase == "":
+            self.DestFileBase = os.path.splitext(self.DestFileName)[0]
+
+        BuildRulePlaceholderDict = {
+            # source file
+            "src"       :   SrcFile,
+            "s_path"    :   SrcPath,
+            "s_dir"     :   SrcFileDir,
+            "s_name"    :   SrcFileName,
+            "s_base"    :   SrcFileBase,
+            "s_ext"     :   SrcFileExt,
+            # destination file
+            "dst"       :   self.DestFile,
+            "d_path"    :   self.DestPath,
+            "d_name"    :   self.DestFileName,
+            "d_base"    :   self.DestFileBase,
+            "d_ext"     :   self.DestFileExt,
+        }
+
+        DstFileList = []
+        for FileString in self.DestFileList:
+            FileString = string.Template(FileString).safe_substitute(BuildRulePlaceholderDict)
+            FileString = string.Template(FileString).safe_substitute(BuildRulePlaceholderDict)
+            DstFileList.append(FileString)
+        CommandList = []
+        for CommandString in self.CommandList:
+            CommandString = string.Template(CommandString).safe_substitute(BuildRulePlaceholderDict)
+            CommandString = string.Template(CommandString).safe_substitute(BuildRulePlaceholderDict)
+            CommandList.append(CommandString)
+
+        return SrcFile, self.ExtraSourceFileList, DstFileList[0], CommandList
+
+## Class for build rules
+#
+# BuildRule class parses rules defined in a file or passed by caller, and converts
+# the rule into FileBuildRule object.
+#
+class BuildRule:
+    _SectionHeader = "SECTIONHEADER"
+    _Section = "SECTION"
+    _SubSectionHeader = "SUBSECTIONHEADER"
+    _SubSection = "SUBSECTION"
+    _InputFile = "INPUTFILE"
+    _OutputFile = "OUTPUTFILE"
+    _Command = "COMMAND"
+    _UnknownSection = "UNKNOWNSECTION"
+
+    _SubSectionList = [_InputFile, _OutputFile, _Command]
+
+    _FileTypePattern = re.compile("^[_a-zA-Z][_\-0-9a-zA-Z]*$")
+
+    ## Constructor
+    #
+    #   @param  File                The file containing build rules in a well defined format
+    #   @param  Content             The string list of build rules in a well defined format
+    #   @param  LineIndex           The line number from which the parsing will begin
+    #   @param  SupportedFamily     The list of supported tool chain families
+    #
+    def __init__(self, File=None, Content=None, LineIndex=0, SupportedFamily=["MSFT", "INTEL", "GCC"]):
+        self.RuleFile = File
+        # Read build rules from file if it's not none
+        if File != None:
+            try:
+                self.RuleContent = open(File, 'r').readlines()
+            except:
+                EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=File)
+        elif Content != None:
+            self.RuleContent = Content
+        else:
+            EdkLogger.error("build", PARAMETER_MISSING, ExtraData="No rule file or string given")
+
+        self.SupportedToolChainFamilyList = SupportedFamily
+        self.RuleDatabase = {}  # {version : {family : {file type : FileBuildRule object}}}
+        self.FileTypeDict = {}  # {ext : file-type}
+
+        self._LineIndex = LineIndex
+        self._BuildVersion = "*"
+        self._RuleInfo = {}     # {toolchain family : {"InputFile": {}, "OutputFile" : [], "Command" : []}}
+        self._FileTypeList = []
+        self._FamilyList = []
+        self._State = ""
+        self._RuleObjectList = [] # FileBuildRule object list
+
+        self.Parse()
+
+    ## Parse the build rule strings
+    def Parse(self):
+        self._State = self._Section
+        for Index in range(self._LineIndex, len(self.RuleContent)):
+            Line = self.RuleContent[Index].strip()
+            self.RuleContent[Index] = Line
+
+            # skip empty or comment line
+            if Line == "" or Line[0] == "#":
+                continue
+
+            # find out section header, enclosed by []
+            if Line[0] == '[' and Line[-1] == ']':
+                # merge last section information into rule database
+                self.EndOfSection()
+                self._State = self._SectionHeader
+            # find out sub-section header, enclosed by <>
+            elif Line[0] == '<' and Line[-1] == '>':
+                if self._State != self._UnknownSection:
+                    self._State = self._SubSectionHeader
+            # call section handler to parse each (sub)section
+            self._StateHandler[self._State](self, Index)
+        # merge last section information into rule database
+        self.EndOfSection()
+
+        # setup the relationship between file extension and file type
+        for RuleObject in self._RuleObjectList:
+            for FileType in RuleObject.SourceFileType:
+                for FileExt in RuleObject.SourceFileType[FileType]:
+                    self.FileTypeDict[FileExt] = FileType
+
+    ## Parse definitions under a section
+    #
+    #   @param  LineIndex   The line index of build rule text
+    #
+    def ParseSection(self, LineIndex):
+        TokenList = self.RuleContent[LineIndex].split("=", 1)
+        # currently only BUILD_VERSION is supported
+        if len(TokenList) != 2 or TokenList[0] != "BUILD_VERSION":
+            EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1,
+                            ExtraData="Invalid definition: " + self.RuleContent[LineIndex])
+
+        try:
+            self._BuildVersion = int(TokenList[1].strip(), 0)
+        except:
+            EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1,
+                            ExtraData="Version is not a valid number: " + self.RuleContent[LineIndex])
+
+    ## Parse definitions under a subsection
+    #
+    #   @param  LineIndex   The line index of build rule text
+    #
+    def ParseSubSection(self, LineIndex):
+        # currenly nothing here
+        pass
+
+    ## Placeholder for not supported sections
+    #
+    #   @param  LineIndex   The line index of build rule text
+    #
+    def SkipSection(self, LineIndex):
+        pass
+
+    ## Merge section information just got into rule database
+    def EndOfSection(self):
+        if self._FileTypeList == [] or self._RuleInfo == {}:
+            return
+
+        Database = self.RuleDatabase
+        if self._BuildVersion not in Database:
+            Database[self._BuildVersion] = {}
+        Database = self.RuleDatabase[self._BuildVersion]
+
+        # expand *
+        FamilyList = self._RuleInfo.keys()
+        if "*" in FamilyList and len(FamilyList) > 1:
+            FamilyList.remove("*")
+
+        NewRuleInfo = {}
+        for Family in self._RuleInfo:
+            Rule = self._RuleInfo[Family]
+            if Family == "*" and Family not in FamilyList:
+                NewFamilyList = FamilyList
+            else:
+                NewFamilyList = [Family]
+
+            for NewFamily in NewFamilyList:
+                if NewFamily not in NewRuleInfo:
+                    NewRuleInfo[NewFamily] = {}
+
+                if self._InputFile in Rule:
+                    NewRuleInfo[NewFamily][self._InputFile] = Rule[self._InputFile]
+                if self._OutputFile in Rule:
+                    NewRuleInfo[NewFamily][self._OutputFile] = Rule[self._OutputFile]
+                if self._Command in Rule:
+                    NewRuleInfo[NewFamily][self._Command] = Rule[self._Command]
+
+        for NewFamily in FamilyList:
+            Rule = NewRuleInfo[NewFamily]
+            if NewFamily not in Database:
+                Database[NewFamily] = {}
+
+            if self._InputFile in Rule:
+                Input = Rule[self._InputFile]
+            else:
+                EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile,
+                                ExtraData="No input files found for rule %s" % self._FileTypeList)
+
+            if self._OutputFile in Rule:
+                Output = Rule[self._OutputFile]
+            else:
+                EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile,
+                                ExtraData="No output files found for rule %s" % self._FileTypeList)
+
+            if self._Command in Rule:
+                Command = Rule[self._Command]
+            else:
+                Command = []
+
+            if NewFamily == "*":
+                for Family in self.SupportedToolChainFamilyList:
+                    if Family not in Database:
+                        Database[Family] = {}
+                    RuleObject = FileBuildRule(Input, Output, Command)
+                    self._RuleObjectList.append(RuleObject)
+                    for FileType in RuleObject.SourceFileType:
+                        Database[Family][FileType] = RuleObject
+            else:
+                RuleObject = FileBuildRule(Input, Output, Command)
+                self._RuleObjectList.append(RuleObject)
+                for FileType in RuleObject.SourceFileType:
+                    Database[NewFamily][FileType] = RuleObject
+        # for new section
+        self._RuleInfo = {}
+
+    ## Parse section header
+    #
+    #   @param  LineIndex   The line index of build rule text
+    #
+    def ParseSectionHeader(self, LineIndex):
+        BuildVersion = ""
+        FileTypeList = []
+        RuleNameList = self.RuleContent[LineIndex][1:-1].split(',')
+        for RuleName in RuleNameList:
+            TokenList = RuleName.split('.')
+            if len(TokenList) == 1:
+                EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1,
+                                ExtraData="Invalid rule section: " + self.RuleContent[LineIndex])
+
+            Rule = TokenList[0].strip()
+            if Rule.upper() != "BUILD":
+                self._State = self._UnknownSection
+                return
+
+            FileType = TokenList[1].strip()
+            if FileType == '':
+                EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1,
+                                ExtraData="No file type given: " + Line)
+            if self._FileTypePattern.match(FileType) == None:
+                EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1,
+                                ExtraData="Only character, number (non-first character), '_' and '-' are allowed in file type")
+            FileTypeList.append(FileType)
+
+        self._FileTypeList = FileTypeList
+        self._BuildVersion = "*"
+        self._State = self._Section
+
+    ## Parse sub-section header
+    #
+    #   @param  LineIndex   The line index of build rule text
+    #
+    def ParseSubSectionHeader(self, LineIndex):
+        SectionType = ""
+        List = self.RuleContent[LineIndex][1:-1].split(',')
+        FamilyList = []
+        for Section in List:
+            TokenList = Section.split('.')
+            Type = TokenList[0].strip().upper()
+
+            if SectionType == "":
+                SectionType = Type
+            elif SectionType != Type:
+                EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1,
+                                ExtraData="Two different section types are not allowed: " + Line)
+
+            if len(TokenList) > 1:
+                Family = TokenList[1].strip().upper()
+            else:
+                Family = "*"
+
+            if Family not in FamilyList:
+                FamilyList.append(Family)
+
+        self._FamilyList = FamilyList
+        self._State = SectionType.upper()
+        if self._State not in self._StateHandler:
+            EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1,
+                            ExtraData="Unknown subsection: %s" % self.RuleContent[LineIndex])
+    ## Parse <InputFile> sub-section
+    #
+    #   @param  LineIndex   The line index of build rule text
+    #
+    def ParseInputFile(self, LineIndex):
+        Line = self.RuleContent[LineIndex]
+        TokenList = Line.split("=")
+        FileType = ""
+        if len(TokenList) > 1:
+            FileType = TokenList[0].strip()
+            if FileType not in self._FileTypeList:
+                EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile,  Line=LineIndex+1,
+                                ExtraData="File type must be one of %s: %s" % (self._FileTypeList, FileType))
+            FileString = TokenList[1]
+        else:
+            if len(self._FileTypeList) > 1:
+                EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex,
+                                ExtraData="File type must be given: " + Line)
+            else:
+                FileType = self._FileTypeList[0]
+            FileString = TokenList[0]
+
+        FileList = FileString.split(",")
+        for File in FileList:
+            File = File.strip()
+            for Family in self._FamilyList:
+                if Family not in self._RuleInfo:
+                    self._RuleInfo[Family] = {}
+                if self._State not in self._RuleInfo[Family]:
+                    self._RuleInfo[Family][self._State] = {}
+                if FileType not in self._RuleInfo[Family][self._State]:
+                    self._RuleInfo[Family][self._State][FileType] = []
+                self._RuleInfo[Family][self._State][FileType].append(File)
+
+    ## Parse <OutputFile> sub-section
+    #
+    #   @param  LineIndex   The line index of build rule text
+    #
+    def ParseOutputFile(self, LineIndex):
+        FileList = self.RuleContent[LineIndex].split(",")
+        for File in FileList:
+            File = File.strip()
+            for Family in self._FamilyList:
+                if Family not in self._RuleInfo:
+                    self._RuleInfo[Family] = {}
+                    self._RuleInfo[Family][self._State] = []
+                if self._State not in self._RuleInfo[Family]:
+                    self._RuleInfo[Family][self._State] = []
+                self._RuleInfo[Family][self._State].append(File)
+
+    ## Parse <Command> sub-section
+    #
+    #   @param  LineIndex   The line index of build rule text
+    #
+    def ParseCommand(self, LineIndex):
+        Command = self.RuleContent[LineIndex]
+        for Family in self._FamilyList:
+            if Family not in self._RuleInfo:
+                self._RuleInfo[Family] = {}
+                self._RuleInfo[Family][self._State] = []
+            if self._State not in self._RuleInfo[Family]:
+                self._RuleInfo[Family][self._State] = []
+            self._RuleInfo[Family][self._State].append(Command)
+
+    ## Get a build rule
+    #
+    #   @param  FileExt             The extension of a file
+    #   @param  ToolChainFamily     The tool chain family name
+    #   @param  BuildVersion        The build version number. "*" means any rule
+    #                               is applicalbe.
+    #
+    #   @retval FileType        The file type string
+    #   @retval FileBuildRule   The object of FileBuildRule
+    #
+    def Get(self, FileExt, ToolChainFamily, BuildVersion="*"):
+        if FileExt not in self.FileTypeDict:
+            return None, None
+        FileType = self.FileTypeDict[FileExt]
+        Database = {}
+        BuildRuleObject = None
+        if BuildVersion in self.RuleDatabase:
+            Database = self.RuleDatabase[BuildVersion]
+        elif BuildVersion != "*":
+            if "*" not in self.RuleDatabase:
+                return FileType, None
+            Database = self.RuleDatabase["*"]
+        else:
+            # BuildVersion == "*" and "*" not in self.RuleDatabase
+            # try to match ToolChainFamily
+            for Ver in self.RuleDatabase:
+                Database = self.RuleDatabase[Ver]
+                if ToolChainFamily not in Database:
+                    continue
+                if FileType not in Database[ToolChainFamily]:
+                    continue
+                break
+            else:
+                return FileType, None
+
+        if ToolChainFamily not in Database:
+            return FileType, None
+        if FileType not in Database[ToolChainFamily]:
+            return FileType, None
+        if not Database[ToolChainFamily][FileType].IsSupported(FileExt):
+            return FileType, None
+
+        return FileType, Database[ToolChainFamily][FileType]
+
+    _StateHandler = {
+        _SectionHeader     : ParseSectionHeader,
+        _Section           : ParseSection,
+        _SubSectionHeader  : ParseSubSectionHeader,
+        _SubSection        : ParseSubSection,
+        _InputFile         : ParseInputFile,
+        _OutputFile        : ParseOutputFile,
+        _Command           : ParseCommand,
+        _UnknownSection    : SkipSection,
+    }
+
+# This acts like the main() function for the script, unless it is 'import'ed into another
+# script.
+if __name__ == '__main__':
+    pass
+
index 9ddb9cf..ad78d32 100644 (file)
-## @file\r
-# Routines for generating AutoGen.h and AutoGen.c\r
-#\r
-# Copyright (c) 2007, 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
-## Import Modules\r
-#\r
-import string\r
-\r
-from Common import EdkLogger\r
-\r
-from Common.BuildToolError import *\r
-from Common.DataType import *\r
-from Common.EdkIIWorkspace import *\r
-from Common.Misc import *\r
-from StrGather import *\r
-\r
-## PCD type string\r
-gItemTypeStringDatabase  = {\r
-    TAB_PCDS_FEATURE_FLAG       :   'FixedAtBuild',\r
-    TAB_PCDS_FIXED_AT_BUILD     :   'FixedAtBuild',\r
-    TAB_PCDS_PATCHABLE_IN_MODULE:   'BinaryPatch',\r
-    TAB_PCDS_DYNAMIC            :   '',\r
-    TAB_PCDS_DYNAMIC_DEFAULT    :   '',\r
-    TAB_PCDS_DYNAMIC_VPD        :   '',\r
-    TAB_PCDS_DYNAMIC_HII        :   '',\r
-    TAB_PCDS_DYNAMIC_EX         :   '',\r
-    TAB_PCDS_DYNAMIC_EX_DEFAULT :   '',\r
-    TAB_PCDS_DYNAMIC_EX_VPD     :   '',\r
-    TAB_PCDS_DYNAMIC_EX_HII     :   '',\r
-}\r
-\r
-## Dynamic PCD types\r
-gDynamicPcd = [TAB_PCDS_DYNAMIC, TAB_PCDS_DYNAMIC_DEFAULT, TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_HII]\r
-\r
-## Dynamic-ex PCD types\r
-gDynamicExPcd = [TAB_PCDS_DYNAMIC_EX, TAB_PCDS_DYNAMIC_EX_DEFAULT, TAB_PCDS_DYNAMIC_EX_VPD, TAB_PCDS_DYNAMIC_EX_HII]\r
-\r
-## Datum size\r
-gDatumSizeStringDatabase = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'BOOLEAN','VOID*':'8'}\r
-gDatumSizeStringDatabaseH = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'BOOL','VOID*':'PTR'}\r
-gDatumSizeStringDatabaseLib = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'Bool','VOID*':'Ptr'}\r
-\r
-## Mapping between PCD driver type and EFI phase\r
-gPcdPhaseMap = {\r
-    "PEI_PCD_DRIVER"    :   "PEI",\r
-    "DXE_PCD_DRIVER"    :   "DXE"\r
-}\r
-\r
-gPcdDatabaseCommonAutoGenH = """\r
-//\r
-// The following definition will be generated by build tool\r
-//\r
-\r
-//\r
-// Common definitions\r
-//\r
-typedef UINT8 SKU_ID;\r
-\r
-#define PCD_TYPE_SHIFT        28\r
-\r
-#define PCD_TYPE_DATA         (0x0 << PCD_TYPE_SHIFT)\r
-#define PCD_TYPE_HII          (0x8 << PCD_TYPE_SHIFT)\r
-#define PCD_TYPE_VPD          (0x4 << PCD_TYPE_SHIFT)\r
-#define PCD_TYPE_SKU_ENABLED  (0x2 << PCD_TYPE_SHIFT)\r
-#define PCD_TYPE_STRING       (0x1 << PCD_TYPE_SHIFT)\r
-\r
-#define PCD_TYPE_ALL_SET      (PCD_TYPE_DATA | PCD_TYPE_HII | PCD_TYPE_VPD | PCD_TYPE_SKU_ENABLED | PCD_TYPE_STRING)\r
-\r
-#define PCD_DATUM_TYPE_SHIFT  24\r
-\r
-#define PCD_DATUM_TYPE_POINTER  (0x0 << PCD_DATUM_TYPE_SHIFT)\r
-#define PCD_DATUM_TYPE_UINT8    (0x1 << PCD_DATUM_TYPE_SHIFT)\r
-#define PCD_DATUM_TYPE_UINT16   (0x2 << PCD_DATUM_TYPE_SHIFT)\r
-#define PCD_DATUM_TYPE_UINT32   (0x4 << PCD_DATUM_TYPE_SHIFT)\r
-#define PCD_DATUM_TYPE_UINT64   (0x8 << PCD_DATUM_TYPE_SHIFT)\r
-\r
-#define PCD_DATUM_TYPE_ALL_SET  (PCD_DATUM_TYPE_POINTER | \\\r
-                                 PCD_DATUM_TYPE_UINT8   | \\\r
-                                 PCD_DATUM_TYPE_UINT16  | \\\r
-                                 PCD_DATUM_TYPE_UINT32  | \\\r
-                                 PCD_DATUM_TYPE_UINT64)\r
-\r
-#define PCD_DATABASE_OFFSET_MASK (~(PCD_TYPE_ALL_SET | PCD_DATUM_TYPE_ALL_SET))\r
-\r
-typedef struct  {\r
-  UINT32  ExTokenNumber;\r
-  UINT16  LocalTokenNumber;   // PCD Number of this particular platform build\r
-  UINT16  ExGuidIndex;        // Index of GuidTable\r
-} DYNAMICEX_MAPPING;\r
-\r
-typedef struct {\r
-  UINT32  SkuDataStartOffset; //We have to use offsetof MACRO as we don't know padding done by compiler\r
-  UINT32  SkuIdTableOffset;   //Offset from the PCD_DB\r
-} SKU_HEAD;\r
-\r
-typedef struct {\r
-  UINT16  GuidTableIndex;     // Offset in Guid Table in units of GUID.\r
-  UINT16  StringIndex;        // Offset in String Table in units of UINT16.\r
-  UINT16  Offset;             // Offset in Variable\r
-  UINT16  DefaultValueOffset; // Offset of the Default Value\r
-} VARIABLE_HEAD;\r
-\r
-typedef  struct {\r
-  UINT32  Offset;\r
-} VPD_HEAD;\r
-\r
-typedef UINT16 STRING_HEAD;\r
-\r
-typedef UINT16 SIZE_INFO;\r
-\r
-#define offsetof(s,m)  (UINT32) (UINTN) &(((s *)0)->m)\r
-\r
-"""\r
-\r
-gPcdDatabaseEpilogueAutoGenH = """\r
-typedef struct {\r
-  PEI_PCD_DATABASE PeiDb;\r
-  DXE_PCD_DATABASE DxeDb;\r
-} PCD_DATABASE;\r
-\r
-#define PCD_TOTAL_TOKEN_NUMBER (PEI_LOCAL_TOKEN_NUMBER + DXE_LOCAL_TOKEN_NUMBER)\r
-\r
-"""\r
-\r
-gPcdDatabaseAutoGenH = """\r
-#define ${PHASE}_GUID_TABLE_SIZE                ${GUID_TABLE_SIZE}\r
-#define ${PHASE}_STRING_TABLE_SIZE              ${STRING_TABLE_SIZE}\r
-#define ${PHASE}_SKUID_TABLE_SIZE               ${SKUID_TABLE_SIZE}\r
-#define ${PHASE}_LOCAL_TOKEN_NUMBER_TABLE_SIZE  ${LOCAL_TOKEN_NUMBER_TABLE_SIZE}\r
-#define ${PHASE}_LOCAL_TOKEN_NUMBER             ${LOCAL_TOKEN_NUMBER}\r
-#define ${PHASE}_EXMAPPING_TABLE_SIZE           ${EXMAPPING_TABLE_SIZE}\r
-#define ${PHASE}_EX_TOKEN_NUMBER                ${EX_TOKEN_NUMBER}\r
-#define ${PHASE}_SIZE_TABLE_SIZE                ${SIZE_TABLE_SIZE}\r
-#define ${PHASE}_GUID_TABLE_EMPTY               ${GUID_TABLE_EMPTY}\r
-#define ${PHASE}_STRING_TABLE_EMPTY             ${STRING_TABLE_EMPTY}\r
-#define ${PHASE}_SKUID_TABLE_EMPTY              ${SKUID_TABLE_EMPTY}\r
-#define ${PHASE}_DATABASE_EMPTY                 ${DATABASE_EMPTY}\r
-#define ${PHASE}_EXMAP_TABLE_EMPTY              ${EXMAP_TABLE_EMPTY}\r
-\r
-typedef struct {\r
-${BEGIN}  UINT64             ${INIT_CNAME_DECL_UINT64}_${INIT_GUID_DECL_UINT64}[${INIT_NUMSKUS_DECL_UINT64}];\r
-${END}\r
-${BEGIN}  UINT64             ${VARDEF_CNAME_UINT64}_${VARDEF_GUID_UINT64}_VariableDefault_${VARDEF_SKUID_UINT64};\r
-${END}\r
-${BEGIN}  UINT32             ${INIT_CNAME_DECL_UINT32}_${INIT_GUID_DECL_UINT32}[${INIT_NUMSKUS_DECL_UINT32}];\r
-${END}\r
-${BEGIN}  UINT32             ${VARDEF_CNAME_UINT32}_${VARDEF_GUID_UINT32}_VariableDefault_${VARDEF_SKUID_UINT32};\r
-${END}\r
-${BEGIN}  VPD_HEAD           ${VPD_HEAD_CNAME_DECL}_${VPD_HEAD_GUID_DECL}[${VPD_HEAD_NUMSKUS_DECL}];\r
-${END}\r
-  DYNAMICEX_MAPPING  ExMapTable[${PHASE}_EXMAPPING_TABLE_SIZE];\r
-  UINT32             LocalTokenNumberTable[${PHASE}_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r
-  GUID               GuidTable[${PHASE}_GUID_TABLE_SIZE];\r
-${BEGIN}  STRING_HEAD        ${STRING_HEAD_CNAME_DECL}_${STRING_HEAD_GUID_DECL}[${STRING_HEAD_NUMSKUS_DECL}];\r
-${END}\r
-${BEGIN}  VARIABLE_HEAD      ${VARIABLE_HEAD_CNAME_DECL}_${VARIABLE_HEAD_GUID_DECL}[${VARIABLE_HEAD_NUMSKUS_DECL}];\r
-${END}\r
-${BEGIN}  UINT16             StringTable${STRING_TABLE_INDEX}[${STRING_TABLE_LENGTH}]; /* ${STRING_TABLE_CNAME}_${STRING_TABLE_GUID} */\r
-${END}\r
-  SIZE_INFO          SizeTable[${PHASE}_SIZE_TABLE_SIZE];\r
-${BEGIN}  UINT16             ${INIT_CNAME_DECL_UINT16}_${INIT_GUID_DECL_UINT16}[${INIT_NUMSKUS_DECL_UINT16}];\r
-${END}\r
-${BEGIN}  UINT16             ${VARDEF_CNAME_UINT16}_${VARDEF_GUID_UINT16}_VariableDefault_${VARDEF_SKUID_UINT16};\r
-${END}\r
-${BEGIN}  UINT8              ${INIT_CNAME_DECL_UINT8}_${INIT_GUID_DECL_UINT8}[${INIT_NUMSKUS_DECL_UINT8}];\r
-${END}\r
-${BEGIN}  UINT8              ${VARDEF_CNAME_UINT8}_${VARDEF_GUID_UINT8}_VariableDefault_${VARDEF_SKUID_UINT8};\r
-${END}\r
-${BEGIN}  BOOLEAN            ${INIT_CNAME_DECL_BOOLEAN}_${INIT_GUID_DECL_BOOLEAN}[${INIT_NUMSKUS_DECL_BOOLEAN}];\r
-${END}\r
-${BEGIN}  BOOLEAN            ${VARDEF_CNAME_BOOLEAN}_${VARDEF_GUID_BOOLEAN}_VariableDefault_${VARDEF_SKUID_BOOLEAN};\r
-${END}\r
-  UINT8              SkuIdTable[${PHASE}_SKUID_TABLE_SIZE];\r
-${SYSTEM_SKU_ID}\r
-} ${PHASE}_PCD_DATABASE_INIT;\r
-\r
-typedef struct {\r
-${PCD_DATABASE_UNINIT_EMPTY}\r
-${BEGIN}  UINT64   ${UNINIT_CNAME_DECL_UINT64}_${UNINIT_GUID_DECL_UINT64}[${UNINIT_NUMSKUS_DECL_UINT64}];\r
-${END}\r
-${BEGIN}  UINT32   ${UNINIT_CNAME_DECL_UINT32}_${UNINIT_GUID_DECL_UINT32}[${UNINIT_NUMSKUS_DECL_UINT32}];\r
-${END}\r
-${BEGIN}  UINT16   ${UNINIT_CNAME_DECL_UINT16}_${UNINIT_GUID_DECL_UINT16}[${UNINIT_NUMSKUS_DECL_UINT16}];\r
-${END}\r
-${BEGIN}  UINT8    ${UNINIT_CNAME_DECL_UINT8}_${UNINIT_GUID_DECL_UINT8}[${UNINIT_NUMSKUS_DECL_UINT8}];\r
-${END}\r
-${BEGIN}  BOOLEAN  ${UNINIT_CNAME_DECL_BOOLEAN}_${UNINIT_GUID_DECL_BOOLEAN}[${UNINIT_NUMSKUS_DECL_BOOLEAN}];\r
-${END}\r
-} ${PHASE}_PCD_DATABASE_UNINIT;\r
-\r
-#define PCD_${PHASE}_SERVICE_DRIVER_VERSION         2\r
-\r
-typedef struct {\r
-  ${PHASE}_PCD_DATABASE_INIT    Init;\r
-  ${PHASE}_PCD_DATABASE_UNINIT  Uninit;\r
-} ${PHASE}_PCD_DATABASE;\r
-\r
-#define ${PHASE}_NEX_TOKEN_NUMBER (${PHASE}_LOCAL_TOKEN_NUMBER - ${PHASE}_EX_TOKEN_NUMBER)\r
-"""\r
-\r
-gEmptyPcdDatabaseAutoGenC = """\r
-${PHASE}_PCD_DATABASE_INIT g${PHASE}PcdDbInit = {\r
-  /* ExMapTable */\r
-  {\r
-    {0, 0, 0}\r
-  },\r
-  /* LocalTokenNumberTable */\r
-  {\r
-    0\r
-  },\r
-  /* GuidTable */\r
-  {\r
-    {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}\r
-  },\r
-  /* StringTable */\r
-  { 0 },\r
-  /* SizeTable */\r
-  {\r
-    0, 0\r
-  },\r
-  /* SkuIdTable */\r
-  { 0 },\r
-  ${SYSTEM_SKU_ID_VALUE}\r
-};\r
-"""\r
-\r
-gPcdDatabaseAutoGenC = """\r
-${PHASE}_PCD_DATABASE_INIT g${PHASE}PcdDbInit = {\r
-${BEGIN}  { ${INIT_VALUE_UINT64} }, /*  ${INIT_CNAME_DECL_UINT64}_${INIT_GUID_DECL_UINT64}[${INIT_NUMSKUS_DECL_UINT64}] */\r
-${END}\r
-${BEGIN}  ${VARDEF_VALUE_UINT64}, /* ${VARDEF_CNAME_UINT64}_${VARDEF_GUID_UINT64}_VariableDefault_${VARDEF_SKUID_UINT64} */\r
-${END}\r
-${BEGIN}  { ${INIT_VALUE_UINT32} }, /*  ${INIT_CNAME_DECL_UINT32}_${INIT_GUID_DECL_UINT32}[${INIT_NUMSKUS_DECL_UINT32}] */\r
-${END}\r
-${BEGIN}  ${VARDEF_VALUE_UINT32}, /* ${VARDEF_CNAME_UINT32}_${VARDEF_GUID_UINT32}_VariableDefault_${VARDEF_SKUID_UINT32} */\r
-${END}\r
-  /* VPD */\r
-${BEGIN}  { ${VPD_HEAD_VALUE} }, /* ${VPD_HEAD_CNAME_DECL}_${VPD_HEAD_GUID_DECL}[${VPD_HEAD_NUMSKUS_DECL}] */\r
-${END}\r
-  /* ExMapTable */\r
-  {\r
-${BEGIN}    { ${EXMAPPING_TABLE_EXTOKEN}, ${EXMAPPING_TABLE_LOCAL_TOKEN}, ${EXMAPPING_TABLE_GUID_INDEX} },\r
-${END}\r
-  },\r
-  /* LocalTokenNumberTable */\r
-  {\r
-${BEGIN}    offsetof(${PHASE}_PCD_DATABASE, ${TOKEN_INIT}.${TOKEN_CNAME}_${TOKEN_GUID}) | ${TOKEN_TYPE},\r
-${END}\r
-  },\r
-  /* GuidTable */\r
-  {\r
-${BEGIN}    ${GUID_STRUCTURE},\r
-${END}\r
-  },\r
-${BEGIN}  { ${STRING_HEAD_VALUE} }, /* ${STRING_HEAD_CNAME_DECL}_${STRING_HEAD_GUID_DECL}[${STRING_HEAD_NUMSKUS_DECL}] */\r
-${END}\r
-${BEGIN}  /* ${VARIABLE_HEAD_CNAME_DECL}_${VARIABLE_HEAD_GUID_DECL}[${VARIABLE_HEAD_NUMSKUS_DECL}] */\r
-  {\r
-    ${VARIABLE_HEAD_VALUE}\r
-  },\r
-${END}\r
- /* StringTable */\r
-${BEGIN}  ${STRING_TABLE_VALUE}, /* ${STRING_TABLE_CNAME}_${STRING_TABLE_GUID} */\r
-${END}\r
-  /* SizeTable */\r
-  {\r
-${BEGIN}    ${SIZE_TABLE_MAXIMUM_LENGTH}, ${SIZE_TABLE_CURRENT_LENGTH}, /* ${SIZE_TABLE_CNAME}_${SIZE_TABLE_GUID} */\r
-${END}\r
-  },\r
-${BEGIN}  { ${INIT_VALUE_UINT16} }, /*  ${INIT_CNAME_DECL_UINT16}_${INIT_GUID_DECL_UINT16}[${INIT_NUMSKUS_DECL_UINT16}] */\r
-${END}\r
-${BEGIN}  ${VARDEF_VALUE_UINT16}, /* ${VARDEF_CNAME_UINT16}_${VARDEF_GUID_UINT16}_VariableDefault_${VARDEF_SKUID_UINT16} */\r
-${END}\r
-${BEGIN}  { ${INIT_VALUE_UINT8} }, /*  ${INIT_CNAME_DECL_UINT8}_${INIT_GUID_DECL_UINT8}[${INIT_NUMSKUS_DECL_UINT8}] */\r
-${END}\r
-${BEGIN}  ${VARDEF_VALUE_UINT8}, /* ${VARDEF_CNAME_UINT8}_${VARDEF_GUID_UINT8}_VariableDefault_${VARDEF_SKUID_UINT8} */\r
-${END}\r
-${BEGIN}  { ${INIT_VALUE_BOOLEAN} }, /*  ${INIT_CNAME_DECL_BOOLEAN}_${INIT_GUID_DECL_BOOLEAN}[${INIT_NUMSKUS_DECL_BOOLEAN}] */\r
-${END}\r
-${BEGIN}  ${VARDEF_VALUE_BOOLEAN}, /* ${VARDEF_CNAME_BOOLEAN}_${VARDEF_GUID_BOOLEAN}_VariableDefault_${VARDEF_SKUID_BOOLEAN} */\r
-${END}\r
-  /* SkuIdTable */\r
-  { ${BEGIN}${SKUID_VALUE}, ${END} },\r
-  ${SYSTEM_SKU_ID_VALUE}\r
-};\r
-"""\r
-\r
-\r
-## AutoGen File Header Templates\r
-gAutoGenHeaderString = """\\r
-/**\r
-  DO NOT EDIT\r
-  FILE auto-generated\r
-  Module name:\r
-    $FileName\r
-  Abstract:       Auto-generated $FileName for building module or library.\r
-**/\r
-"""\r
-\r
-gAutoGenHPrologueString = """\r
-#ifndef _AUTOGENH_${Guid}\r
-#define _AUTOGENH_${Guid}\r
-\r
-"""\r
-\r
-gAutoGenHEpilogueString = """\r
-#endif\r
-"""\r
-\r
-## PEI Core Entry Point Templates\r
-gPeiCoreEntryPointString = """\r
-${BEGIN}\r
-EFI_STATUS\r
-${Function} (\r
-  IN CONST  EFI_SEC_PEI_HAND_OFF    *SecCoreData,\r
-  IN CONST  EFI_PEI_PPI_DESCRIPTOR  *PpiList,\r
-  IN VOID                           *OldCoreData\r
-  );\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ProcessModuleEntryPointList (\r
-  IN CONST  EFI_SEC_PEI_HAND_OFF    *SecCoreData,\r
-  IN CONST  EFI_PEI_PPI_DESCRIPTOR  *PpiList,\r
-  IN VOID                           *OldCoreData\r
-  )\r
-\r
-{\r
-  return ${Function} (SecCoreData, PpiList, OldCoreData);\r
-}\r
-${END}\r
-"""\r
-\r
-\r
-## DXE Core Entry Point Templates\r
-gDxeCoreEntryPointString = """\r
-const UINT32 _gUefiDriverRevision = 0;\r
-${BEGIN}\r
-VOID\r
-${Function} (\r
-  IN VOID  *HobStart\r
-  );\r
-\r
-VOID\r
-EFIAPI\r
-ProcessModuleEntryPointList (\r
-  IN VOID  *HobStart\r
-  )\r
-\r
-{\r
-  ${Function} (HobStart);\r
-}\r
-${END}\r
-"""\r
-\r
-## PEIM Entry Point Templates\r
-gPeimEntryPointString = [\r
-"""\r
-GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = 0;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ProcessModuleEntryPointList (\r
-  IN EFI_PEI_FILE_HANDLE  FileHandle,\r
-  IN EFI_PEI_SERVICES     **PeiServices\r
-  )\r
-\r
-{\r
-  return EFI_SUCCESS;\r
-}\r
-""",\r
-"""\r
-GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = 0;\r
-${BEGIN}\r
-EFI_STATUS\r
-${Function} (\r
-  IN EFI_PEI_FILE_HANDLE  FileHandle,\r
-  IN EFI_PEI_SERVICES     **PeiServices\r
-  );\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ProcessModuleEntryPointList (\r
-  IN EFI_PEI_FILE_HANDLE  FileHandle,\r
-  IN EFI_PEI_SERVICES     **PeiServices\r
-  )\r
-\r
-{\r
-  return ${Function} (FileHandle, PeiServices);\r
-}\r
-${END}\r
-""",\r
-"""\r
-GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = 0;\r
-\r
-${BEGIN}\r
-EFI_STATUS\r
-${Function} (\r
-  IN EFI_PEI_FILE_HANDLE  FileHandle,\r
-  IN EFI_PEI_SERVICES     **PeiServices\r
-  );\r
-${END}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ProcessModuleEntryPointList (\r
-  IN EFI_PEI_FILE_HANDLE  FileHandle,\r
-  IN EFI_PEI_SERVICES     **PeiServices\r
-  )\r
-\r
-{\r
-  EFI_STATUS  Status;\r
-  EFI_STATUS  CombinedStatus;\r
-\r
-  CombinedStatus = EFI_LOAD_ERROR;\r
-${BEGIN}\r
-  Status = ${Function} (FileHandle, PeiServices);\r
-  if (!EFI_ERROR (Status) || EFI_ERROR (CombinedStatus)) {\r
-    CombinedStatus = Status;\r
-  }\r
-${END}\r
-  return CombinedStatus;\r
-}\r
-"""\r
-]\r
-\r
-## DXE SMM Entry Point Templates\r
-gDxeSmmEntryPointString = [\r
-"""\r
-EFI_STATUS\r
-EFIAPI\r
-ProcessModuleEntryPointList (\r
-  IN EFI_HANDLE        ImageHandle,\r
-  IN EFI_SYSTEM_TABLE  *SystemTable\r
-  )\r
-\r
-{\r
-  return EFI_SUCCESS;\r
-}\r
-""",\r
-"""\r
-${BEGIN}\r
-EFI_STATUS\r
-${Function} (\r
-  IN EFI_HANDLE        ImageHandle,\r
-  IN EFI_SYSTEM_TABLE  *SystemTable\r
-  );\r
-${END}\r
-\r
-static BASE_LIBRARY_JUMP_BUFFER  mJumpContext;\r
-static EFI_STATUS  mDriverEntryPointStatus = EFI_LOAD_ERROR;\r
-\r
-VOID\r
-EFIAPI\r
-ExitDriver (\r
-  IN EFI_STATUS  Status\r
-  )\r
-{\r
-  if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {\r
-    mDriverEntryPointStatus = Status;\r
-  }\r
-  LongJump (&mJumpContext, (UINTN)-1);\r
-  ASSERT (FALSE);\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ProcessModuleEntryPointList (\r
-  IN EFI_HANDLE        ImageHandle,\r
-  IN EFI_SYSTEM_TABLE  *SystemTable\r
-  )\r
-\r
-{\r
-${BEGIN}\r
-  if (SetJump (&mJumpContext) == 0) {\r
-    ExitDriver (${Function} (ImageHandle, SystemTable));\r
-    ASSERT (FALSE);\r
-  }\r
-${END}\r
-\r
-  return mDriverEntryPointStatus;\r
-}\r
-"""\r
-]\r
-\r
-## UEFI Entry Point Templates\r
-gUefiEntryPointString = [\r
-"""\r
-const UINT32 _gUefiDriverRevision = 0;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ProcessModuleEntryPointList (\r
-  IN EFI_HANDLE        ImageHandle,\r
-  IN EFI_SYSTEM_TABLE  *SystemTable\r
-  )\r
-{\r
-  return EFI_SUCCESS;\r
-}\r
-""",\r
-"""\r
-const UINT32 _gUefiDriverRevision = 0;\r
-${BEGIN}\r
-EFI_STATUS\r
-${Function} (\r
-  IN EFI_HANDLE        ImageHandle,\r
-  IN EFI_SYSTEM_TABLE  *SystemTable\r
-  );\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ProcessModuleEntryPointList (\r
-  IN EFI_HANDLE        ImageHandle,\r
-  IN EFI_SYSTEM_TABLE  *SystemTable\r
-  )\r
-\r
-{\r
-  return ${Function} (ImageHandle, SystemTable);\r
-}\r
-${END}\r
-VOID\r
-EFIAPI\r
-ExitDriver (\r
-  IN EFI_STATUS  Status\r
-  )\r
-{\r
-  if (EFI_ERROR (Status)) {\r
-    ProcessLibraryDestructorList (gImageHandle, gST);\r
-  }\r
-  gBS->Exit (gImageHandle, Status, 0, NULL);\r
-}\r
-""",\r
-"""\r
-const UINT32 _gUefiDriverRevision = 0;\r
-\r
-${BEGIN}\r
-EFI_STATUS\r
-${Function} (\r
-  IN EFI_HANDLE        ImageHandle,\r
-  IN EFI_SYSTEM_TABLE  *SystemTable\r
-  );\r
-${END}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ProcessModuleEntryPointList (\r
-  IN EFI_HANDLE        ImageHandle,\r
-  IN EFI_SYSTEM_TABLE  *SystemTable\r
-  )\r
-\r
-{\r
-  ${BEGIN}\r
-  if (SetJump (&mJumpContext) == 0) {\r
-    ExitDriver (${Function} (ImageHandle, SystemTable));\r
-    ASSERT (FALSE);\r
-  }\r
-  ${END}\r
-  return mDriverEntryPointStatus;\r
-}\r
-\r
-static BASE_LIBRARY_JUMP_BUFFER  mJumpContext;\r
-static EFI_STATUS  mDriverEntryPointStatus = EFI_LOAD_ERROR;\r
-\r
-VOID\r
-EFIAPI\r
-ExitDriver (\r
-  IN EFI_STATUS  Status\r
-  )\r
-{\r
-  if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {\r
-    mDriverEntryPointStatus = Status;\r
-  }\r
-  LongJump (&mJumpContext, (UINTN)-1);\r
-  ASSERT (FALSE);\r
-}\r
-"""\r
-]\r
-\r
-## UEFI Unload Image Templates\r
-gUefiUnloadImageString = [\r
-"""\r
-GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count};\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ProcessModuleUnloadList (\r
-  IN EFI_HANDLE        ImageHandle\r
-  )\r
-{\r
-  return EFI_SUCCESS;\r
-}\r
-""",\r
-"""\r
-GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count};\r
-\r
-${BEGIN}\r
-EFI_STATUS\r
-${Function} (\r
-  IN EFI_HANDLE        ImageHandle\r
-  );\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ProcessModuleUnloadList (\r
-  IN EFI_HANDLE        ImageHandle\r
-  )\r
-{\r
-  return ${Function} (ImageHandle);\r
-}\r
-${END}\r
-""",\r
-"""\r
-GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count};\r
-\r
-${BEGIN}\r
-EFI_STATUS\r
-${Function} (\r
-  IN EFI_HANDLE        ImageHandle\r
-  );\r
-${END}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ProcessModuleUnloadList (\r
-  IN EFI_HANDLE        ImageHandle\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-\r
-  Status = EFI_SUCCESS;\r
-${BEGIN}\r
-  if (EFI_ERROR (Status)) {\r
-    ${Function} (ImageHandle);\r
-  } else {\r
-    Status = ${Function} (ImageHandle);\r
-  }\r
-${END}\r
-  return Status;\r
-}\r
-"""\r
-]\r
-\r
-gLibraryStructorPrototype = {\r
-'BASE'  : """${BEGIN}\r
-EFI_STATUS\r
-EFIAPI\r
-${Function} (\r
-  VOID\r
-  );${END}\r
-""",\r
-\r
-'PEI'   : """${BEGIN}\r
-EFI_STATUS\r
-EFIAPI\r
-${Function} (\r
-  IN EFI_PEI_FILE_HANDLE       FileHandle,\r
-  IN EFI_PEI_SERVICES          **PeiServices\r
-  );${END}\r
-""",\r
-\r
-'DXE'   : """${BEGIN}\r
-EFI_STATUS\r
-EFIAPI\r
-${Function} (\r
-  IN EFI_HANDLE        ImageHandle,\r
-  IN EFI_SYSTEM_TABLE  *SystemTable\r
-  );${END}\r
-""",\r
-}\r
-\r
-gLibraryStructorCall = {\r
-'BASE'  : """${BEGIN}\r
-  Status = ${Function} ();\r
-  ASSERT_EFI_ERROR (Status);${END}\r
-""",\r
-\r
-'PEI'   : """${BEGIN}\r
-  Status = ${Function} (FileHandle, PeiServices);\r
-  ASSERT_EFI_ERROR (Status);${END}\r
-""",\r
-\r
-'DXE'   : """${BEGIN}\r
-  Status = ${Function} (ImageHandle, SystemTable);\r
-  ASSERT_EFI_ERROR (Status);${END}\r
-""",\r
-}\r
-\r
-## Library Constructor and Destructor Templates\r
-gLibraryString = {\r
-'BASE'  :   """\r
-${BEGIN}${FunctionPrototype}${END}\r
-\r
-VOID\r
-EFIAPI\r
-ProcessLibrary${Type}List (\r
-  VOID\r
-  )\r
-{\r
-${BEGIN}  EFI_STATUS  Status;\r
-${FunctionCall}${END}\r
-}\r
-""",\r
-\r
-'PEI'   :   """\r
-${BEGIN}${FunctionPrototype}${END}\r
-\r
-VOID\r
-EFIAPI\r
-ProcessLibrary${Type}List (\r
-  IN EFI_PEI_FILE_HANDLE       FileHandle,\r
-  IN EFI_PEI_SERVICES          **PeiServices\r
-  )\r
-{\r
-${BEGIN}  EFI_STATUS  Status;\r
-${FunctionCall}${END}\r
-}\r
-""",\r
-\r
-'DXE'   :   """\r
-${BEGIN}${FunctionPrototype}${END}\r
-\r
-VOID\r
-EFIAPI\r
-ProcessLibrary${Type}List (\r
-  IN EFI_HANDLE        ImageHandle,\r
-  IN EFI_SYSTEM_TABLE  *SystemTable\r
-  )\r
-{\r
-${BEGIN}  EFI_STATUS  Status;\r
-${FunctionCall}${END}\r
-}\r
-""",\r
-}\r
-\r
-gSpecificationString = """\r
-${BEGIN}\r
-#undef ${SpecificationName}\r
-#define ${SpecificationName} ${SpecificationValue}\r
-${END}\r
-"""\r
-\r
-gBasicHeaderFile = "Base.h"\r
-\r
-gModuleTypeHeaderFile = {\r
-    "BASE"              :   [gBasicHeaderFile],\r
-    "SEC"               :   ["PiPei.h", "Library/DebugLib.h"],\r
-    "PEI_CORE"          :   ["PiPei.h", "Library/DebugLib.h"],\r
-    "PEIM"              :   ["PiPei.h", "Library/DebugLib.h"],\r
-    "DXE_CORE"          :   ["PiDxe.h", "Library/DebugLib.h"],\r
-    "DXE_DRIVER"        :   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h"],\r
-    "DXE_SMM_DRIVER"    :   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h"],\r
-    "DXE_RUNTIME_DRIVER":   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h"],\r
-    "DXE_SAL_DRIVER"    :   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h"],\r
-    "UEFI_DRIVER"       :   ["Uefi.h",  "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h"],\r
-    "UEFI_APPLICATION"  :   ["Uefi.h",  "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h"],\r
-    "USER_DEFINED"      :   [gBasicHeaderFile]\r
-}\r
-\r
-## Create code for module PCDs\r
-#\r
-#   @param      Info        The ModuleAutoGen object\r
-#   @param      AutoGenC    The TemplateString object for C code\r
-#   @param      AutoGenH    The TemplateString object for header file\r
-#   @param      Pcd         The PCD object\r
-#\r
-def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):\r
-    TokenSpaceGuidValue = Pcd.TokenSpaceGuidValue   #Info.GuidList[Pcd.TokenSpaceGuidCName]\r
-    PcdTokenNumber = Info.PlatformInfo.PcdTokenNumber\r
-    #\r
-    # Write PCDs\r
-    #\r
-    PcdTokenName = '_PCD_TOKEN_' + Pcd.TokenCName\r
-    if Pcd.Type in gDynamicExPcd:\r
-        TokenNumber = int(Pcd.TokenValue, 0)\r
-    else:\r
-        if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) not in PcdTokenNumber:\r
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No generated token number for %s|%s\n" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName))\r
-        TokenNumber = PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName]\r
-    AutoGenH.Append('#define %s  %d\n' % (PcdTokenName, TokenNumber))\r
-\r
-    EdkLogger.debug(EdkLogger.DEBUG_3, "Creating code for " + Pcd.TokenCName + "|" + Pcd.TokenSpaceGuidCName)\r
-    if Pcd.Type not in gItemTypeStringDatabase:\r
-        EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Unknown PCD type [%s] of PCD %s|%s" % (Pcd.Type, Pcd.TokenCName, Pcd.TokenSpaceGuidCName))\r
-    if Pcd.DatumType not in gDatumSizeStringDatabase:\r
-        EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Unknown datum type [%s] of PCD %s|%s" % (Pcd.DatumType, Pcd.TokenCName, Pcd.TokenSpaceGuidCName))\r
-\r
-    DatumSize = gDatumSizeStringDatabase[Pcd.DatumType]\r
-    DatumSizeLib = gDatumSizeStringDatabaseLib[Pcd.DatumType]\r
-    GetModeName = '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName\r
-    SetModeName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName\r
-\r
-    if Pcd.Type in gDynamicExPcd:\r
-        AutoGenH.Append('#define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
-        if Pcd.DatumType == 'VOID*':\r
-            AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
-        else:\r
-            AutoGenH.Append('#define %s(Value)  LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
-    elif Pcd.Type in gDynamicPcd:\r
-        AutoGenH.Append('#define %s  LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))\r
-        if Pcd.DatumType == 'VOID*':\r
-            AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))\r
-        else:\r
-            AutoGenH.Append('#define %s(Value)  LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName))\r
-    else:\r
-        PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[Pcd.Type] + '_' + Pcd.TokenCName\r
-        Const = 'const'\r
-        if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:\r
-            Const = ''\r
-        Type = ''\r
-        Array = ''\r
-        Value = Pcd.DefaultValue\r
-        if Pcd.DatumType == 'UINT64':\r
-            if not Value.endswith('ULL'):\r
-                Value += 'ULL'\r
-        if Pcd.DatumType == 'VOID*':\r
-            if Pcd.MaxDatumSize == None or Pcd.MaxDatumSize == '':\r
-                EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName))\r
-\r
-            ArraySize = int(Pcd.MaxDatumSize, 0)\r
-            if Value[0] == '{':\r
-                Type = '(VOID *)'\r
-            else:\r
-                Unicode = False\r
-                if Value[0] == 'L':\r
-                    Unicode = True\r
-                Value = Value.lstrip('L').strip('"')\r
-                NewValue = '{'\r
-                for Index in range(0,len(Value)):\r
-                    NewValue = NewValue + str(ord(Value[Index]) % 0x100) + ', '\r
-                    if Unicode:\r
-                        NewValue = NewValue + str(ord(Value[Index]) / 0x100) + ', '\r
-                if Unicode:\r
-                    if ArraySize < (len(Value)*2 + 2):\r
-                        ArraySize = len(Value)*2 + 2\r
-                    NewValue = NewValue + '0, '\r
-                else:\r
-                    if ArraySize < (len(Value) + 1):\r
-                        ArraySize = len(Value) + 1\r
-                Value = NewValue + '0 }'\r
-            Array = '[%d]' % ArraySize\r
-\r
-        PcdValueName = '_PCD_VALUE_' + Pcd.TokenCName\r
-        if Pcd.DatumType == 'VOID*' and Value[0] == '{':\r
-            AutoGenH.Append('#define _PCD_PATCHABLE_%s_SIZE %s\n' % (Pcd.TokenCName, Pcd.MaxDatumSize))\r
-            AutoGenH.Append('#define %s  %s%s\n' %(PcdValueName, Type, PcdVariableName))\r
-            AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s UINT8 %s%s = %s;\n' % (Const, PcdVariableName, Array, Value))\r
-            AutoGenH.Append('extern %s UINT8 %s%s;\n' %(Const, PcdVariableName, Array))\r
-            AutoGenH.Append('#define %s  %s%s\n' %(GetModeName, Type, PcdVariableName))\r
-        else:\r
-            AutoGenH.Append('#define %s  %s\n' %(PcdValueName, Value))\r
-            AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s %s = %s;\n' %(Const, Pcd.DatumType, PcdVariableName, PcdValueName))\r
-            AutoGenH.Append('extern %s  %s  %s%s;\n' % (Const, Pcd.DatumType, PcdVariableName, Array))\r
-            AutoGenH.Append('#define %s  %s%s\n' % (GetModeName, Type, PcdVariableName))\r
-\r
-        if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:\r
-            if Pcd.DatumType == 'VOID*':\r
-                AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtr(_gPcd_BinaryPatch_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeName, Pcd.TokenCName, Pcd.TokenCName))\r
-            else:\r
-                AutoGenH.Append('#define %s(Value)  (%s = (Value))\n' % (SetModeName, PcdVariableName))\r
-        else:\r
-            AutoGenH.Append('//#define %s  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD\n' % SetModeName)\r
-\r
-## Create code for library module PCDs\r
-#\r
-#   @param      Info        The ModuleAutoGen object\r
-#   @param      AutoGenC    The TemplateString object for C code\r
-#   @param      AutoGenH    The TemplateString object for header file\r
-#   @param      Pcd         The PCD object\r
-#\r
-def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):\r
-    PcdTokenNumber = Info.PlatformInfo.PcdTokenNumber\r
-    TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName\r
-    TokenCName  = Pcd.TokenCName\r
-    TokenSpaceGuidValue = Pcd.TokenSpaceGuidValue   #Info.GuidList[TokenSpaceGuidCName]\r
-    if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) not in PcdTokenNumber:\r
-        EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No generated token number for %s|%s\n" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName))\r
-    TokenNumber = PcdTokenNumber[TokenCName, TokenSpaceGuidCName]\r
-\r
-    if Pcd.Type not in gItemTypeStringDatabase:\r
-        EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Unknown PCD type [%s] of PCD %s|%s" % (Pcd.Type, Pcd.TokenCName, Pcd.TokenSpaceGuidCName))\r
-    if Pcd.DatumType not in gDatumSizeStringDatabase:\r
-        EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Unknown datum type [%s] of PCD %s|%s" % (Pcd.DatumType, Pcd.TokenCName, Pcd.TokenSpaceGuidCName))\r
-\r
-    DatumType   = Pcd.DatumType\r
-    DatumSize   = gDatumSizeStringDatabaseH[DatumType]\r
-    DatumSizeLib= gDatumSizeStringDatabaseLib[DatumType]\r
-    GetModeName = '_PCD_GET_MODE_' + DatumSize + '_' + TokenCName\r
-    SetModeName = '_PCD_SET_MODE_' + DatumSize + '_' + TokenCName\r
-\r
-    Type = ''\r
-    Array = ''\r
-    if Pcd.DatumType == 'VOID*':\r
-        Type = '(VOID *)'\r
-        Array = '[]'\r
-\r
-    AutoGenH.Append('#define _PCD_TOKEN_%s  %d\n' % (TokenCName, TokenNumber))\r
-\r
-    PcdItemType = Pcd.Type\r
-    #if PcdItemType in gDynamicPcd:\r
-    #    PcdItemType = TAB_PCDS_FIXED_AT_BUILD\r
-    #    if (TokenCName, TokenSpaceGuidCName) in Info.PlatformInfo.Platform.Pcds:\r
-    #        PcdItemType  = Info.PlatformInfo.Platform.Pcds[TokenCName, TokenSpaceGuidCName].Type\r
-    if PcdItemType in gDynamicExPcd:\r
-        PcdTokenName = '_PCD_TOKEN_' + TokenCName\r
-        AutoGenH.Append('#define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, TokenSpaceGuidCName, PcdTokenName))\r
-        if DatumType == 'VOID*':\r
-            AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName,DatumSizeLib, TokenSpaceGuidCName, PcdTokenName))\r
-        else:\r
-            AutoGenH.Append('#define %s(Value)  LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, TokenSpaceGuidCName, PcdTokenName))\r
-    if PcdItemType in gDynamicPcd:\r
-        PcdTokenName = '_PCD_TOKEN_' + TokenCName\r
-        AutoGenH.Append('#define %s  LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))\r
-        if DatumType == 'VOID*':\r
-            AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))\r
-        else:\r
-            AutoGenH.Append('#define %s(Value)  LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName))\r
-    if PcdItemType == TAB_PCDS_PATCHABLE_IN_MODULE:\r
-        PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[TAB_PCDS_PATCHABLE_IN_MODULE] + '_' + TokenCName\r
-        AutoGenH.Append('extern %s _gPcd_BinaryPatch_%s%s;\n' %(DatumType, TokenCName, Array) )\r
-        AutoGenH.Append('#define %s  %s_gPcd_BinaryPatch_%s\n' %(GetModeName, Type, TokenCName))\r
-        AutoGenH.Append('#define %s(Value)  (%s = (Value))\n' % (SetModeName, PcdVariableName))\r
-    if PcdItemType == TAB_PCDS_FIXED_AT_BUILD or PcdItemType == TAB_PCDS_FEATURE_FLAG:\r
-        AutoGenH.Append('extern const %s _gPcd_FixedAtBuild_%s%s;\n' %(DatumType, TokenCName, Array))\r
-        #AutoGenH.Append('#define _PCD_VALUE_%s  _gPcd_FixedAtBuild_%s\n' %(TokenCName, TokenCName))\r
-        AutoGenH.Append('#define %s  %s_gPcd_FixedAtBuild_%s\n' %(GetModeName, Type, TokenCName))\r
-        AutoGenH.Append('//#define %s  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD\n' % SetModeName)\r
-\r
-## Create code for PCD database in DXE or PEI phase\r
-#\r
-#   @param      Platform    The platform object\r
-#   @retval     tuple       Two TemplateString objects for C code and header file,\r
-#                           respectively\r
-#\r
-def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):\r
-    AutoGenC = TemplateString()\r
-    AutoGenH = TemplateString()\r
-\r
-    Dict = {\r
-        'PHASE'                         : Phase,\r
-        'GUID_TABLE_SIZE'               : '1',\r
-        'STRING_TABLE_SIZE'             : '1',\r
-        'SKUID_TABLE_SIZE'              : '1',\r
-        'LOCAL_TOKEN_NUMBER_TABLE_SIZE' : '1',\r
-        'LOCAL_TOKEN_NUMBER'            : '0',\r
-        'EXMAPPING_TABLE_SIZE'          : '1',\r
-        'EX_TOKEN_NUMBER'               : '0',\r
-        'SIZE_TABLE_SIZE'               : '2',\r
-        'GUID_TABLE_EMPTY'              : 'TRUE',\r
-        'STRING_TABLE_EMPTY'            : 'TRUE',\r
-        'SKUID_TABLE_EMPTY'             : 'TRUE',\r
-        'DATABASE_EMPTY'                : 'TRUE',\r
-        'EXMAP_TABLE_EMPTY'             : 'TRUE',\r
-        'PCD_DATABASE_UNINIT_EMPTY'     : '  UINT8  dummy; /* PCD_DATABASE_UNINIT is emptry */',\r
-        'SYSTEM_SKU_ID'                 : '  SKU_ID             SystemSkuId;',\r
-        'SYSTEM_SKU_ID_VALUE'           : '0'\r
-    }\r
-\r
-    for DatumType in ['UINT64','UINT32','UINT16','UINT8','BOOLEAN']:\r
-        Dict['VARDEF_CNAME_' + DatumType] = []\r
-        Dict['VARDEF_GUID_' + DatumType]  = []\r
-        Dict['VARDEF_SKUID_' + DatumType] = []\r
-        Dict['VARDEF_VALUE_' + DatumType] = []\r
-        for Init in ['INIT','UNINIT']:\r
-            Dict[Init+'_CNAME_DECL_' + DatumType]   = []\r
-            Dict[Init+'_GUID_DECL_' + DatumType]    = []\r
-            Dict[Init+'_NUMSKUS_DECL_' + DatumType] = []\r
-            Dict[Init+'_VALUE_' + DatumType]        = []\r
-\r
-    for Type in ['STRING_HEAD','VPD_HEAD','VARIABLE_HEAD']:\r
-        Dict[Type + '_CNAME_DECL']   = []\r
-        Dict[Type + '_GUID_DECL']    = []\r
-        Dict[Type + '_NUMSKUS_DECL'] = []\r
-        Dict[Type + '_VALUE'] = []\r
-\r
-    Dict['STRING_TABLE_INDEX'] = []\r
-    Dict['STRING_TABLE_LENGTH']  = []\r
-    Dict['STRING_TABLE_CNAME'] = []\r
-    Dict['STRING_TABLE_GUID']  = []\r
-    Dict['STRING_TABLE_VALUE'] = []\r
-\r
-    Dict['SIZE_TABLE_CNAME'] = []\r
-    Dict['SIZE_TABLE_GUID']  = []\r
-    Dict['SIZE_TABLE_CURRENT_LENGTH']  = []\r
-    Dict['SIZE_TABLE_MAXIMUM_LENGTH']  = []\r
-\r
-    Dict['EXMAPPING_TABLE_EXTOKEN'] = []\r
-    Dict['EXMAPPING_TABLE_LOCAL_TOKEN'] = []\r
-    Dict['EXMAPPING_TABLE_GUID_INDEX'] = []\r
-\r
-    Dict['GUID_STRUCTURE'] = []\r
-\r
-    Dict['SKUID_VALUE'] = []\r
-\r
-    if Phase == 'DXE':\r
-        Dict['SYSTEM_SKU_ID'] = ''\r
-        Dict['SYSTEM_SKU_ID_VALUE'] = ''\r
-\r
-    StringTableIndex = 0\r
-    StringTableSize = 0\r
-    NumberOfLocalTokens = 0\r
-    NumberOfPeiLocalTokens = 0\r
-    NumberOfDxeLocalTokens = 0\r
-    NumberOfExTokens = 0\r
-    NumberOfSizeItems = 0\r
-    GuidList = []\r
-\r
-    for Pcd in Platform.DynamicPcdList:\r
-        CName = Pcd.TokenCName\r
-        TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName\r
-\r
-        EdkLogger.debug(EdkLogger.DEBUG_3, "PCD: %s %s (%s : %s)" % (CName, TokenSpaceGuidCName, Pcd.Phase, Phase))\r
-        if Pcd.DatumType not in gDatumSizeStringDatabase:\r
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Unknown datum type [%s] of PCD %s|%s" % (Pcd.DatumType, Pcd.TokenCName, Pcd.TokenSpaceGuidCName))\r
-\r
-        if Pcd.Phase == 'PEI':\r
-            NumberOfPeiLocalTokens += 1\r
-        if Pcd.Phase == 'DXE':\r
-            NumberOfDxeLocalTokens += 1\r
-        if Pcd.Phase != Phase:\r
-            continue\r
-\r
-        #\r
-        # TODO: need GetGuidValue() definition\r
-        #\r
-        TokenSpaceGuidStructure = Pcd.TokenSpaceGuidValue\r
-        TokenSpaceGuid = GuidStructureStringToGuidValueName(TokenSpaceGuidStructure)\r
-        if Pcd.Type in gDynamicExPcd:\r
-            if TokenSpaceGuid not in GuidList:\r
-                GuidList += [TokenSpaceGuid]\r
-                Dict['GUID_STRUCTURE'].append(TokenSpaceGuidStructure)\r
-            NumberOfExTokens += 1\r
-\r
-        ValueList = []\r
-        StringHeadOffsetList = []\r
-        VpdHeadOffsetList = []\r
-        VariableHeadValueList = []\r
-        Pcd.InitString = 'UNINIT'\r
-\r
-        if Pcd.DatumType == 'VOID*':\r
-            Pcd.TokenTypeList = ['PCD_DATUM_TYPE_POINTER']\r
-        elif Pcd.DatumType == 'BOOLEAN':\r
-            Pcd.TokenTypeList = ['PCD_DATUM_TYPE_UINT8']\r
-        else:\r
-            Pcd.TokenTypeList = ['PCD_DATUM_TYPE_' + Pcd.DatumType]\r
-\r
-        if len(Pcd.SkuInfoList) > 1:\r
-            Pcd.TokenTypeList += ['PCD_TYPE_SKU_ENABLED']\r
-\r
-        for SkuName in Pcd.SkuInfoList:\r
-            Sku = Pcd.SkuInfoList[SkuName]\r
-            SkuId = Sku.SkuId\r
-            if SkuId == None or SkuId == '':\r
-                continue\r
-\r
-            if SkuId not in Dict['SKUID_VALUE']:\r
-                Dict['SKUID_VALUE'].append(SkuId)\r
-\r
-            SkuIdIndex =   Dict['SKUID_VALUE'].index(SkuId)\r
-            if len(Sku.VariableName) > 0:\r
-                Pcd.TokenTypeList += ['PCD_TYPE_HII']\r
-                Pcd.InitString = 'INIT'\r
-                VariableNameStructure = '{' + ', '.join(Sku.VariableName.split(" ")) + ', 0x0000}'\r
-                if VariableNameStructure not in Dict['STRING_TABLE_VALUE']:\r
-                    Dict['STRING_TABLE_CNAME'].append(CName)\r
-                    Dict['STRING_TABLE_GUID'].append(TokenSpaceGuid)\r
-                    if StringTableIndex == 0:\r
-                        Dict['STRING_TABLE_INDEX'].append('')\r
-                    else:\r
-                        Dict['STRING_TABLE_INDEX'].append('_%d' % StringTableIndex)\r
-\r
-                    Dict['STRING_TABLE_LENGTH'].append(len(Sku.VariableName) + 1)\r
-                    Dict['STRING_TABLE_VALUE'].append(VariableNameStructure)\r
-                    StringTableIndex += 1\r
-                    StringTableSize += len(Sku.VariableName) + 1\r
-\r
-                VariableHeadStringIndex = 0\r
-                for Index in range(Dict['STRING_TABLE_VALUE'].index(VariableNameStructure)):\r
-                    VariableHeadStringIndex += Dict['STRING_TABLE_LENGTH'][Index]\r
-\r
-                VariableGuidStructure = Sku.VariableGuidValue\r
-                VariableGuid = GuidStructureStringToGuidValueName(VariableGuidStructure)\r
-                if VariableGuid not in GuidList:\r
-                    GuidList += [VariableGuid]\r
-                    Dict['GUID_STRUCTURE'].append(VariableGuidStructure)\r
-                VariableHeadGuidIndex = GuidList.index(VariableGuid)\r
-\r
-                VariableHeadValueList.append('%d, %d, %s, offsetof(${PHASE}_PCD_DATABASE, Init.%s_%s_VariableDefault_%s)' %\r
-                                             (VariableHeadGuidIndex, VariableHeadStringIndex, Sku.VariableOffset, CName, TokenSpaceGuid, SkuIdIndex))\r
-                Dict['VARDEF_CNAME_'+Pcd.DatumType].append(CName)\r
-                Dict['VARDEF_GUID_'+Pcd.DatumType].append(TokenSpaceGuid)\r
-                Dict['VARDEF_SKUID_'+Pcd.DatumType].append(SkuIdIndex)\r
-                Dict['VARDEF_VALUE_'+Pcd.DatumType].append(Sku.HiiDefaultValue)\r
-            elif Sku.VpdOffset != '':\r
-                Pcd.TokenTypeList += ['PCD_TYPE_VPD']\r
-                Pcd.InitString = 'INIT'\r
-                VpdHeadOffsetList.append(Sku.VpdOffset)\r
-            else:\r
-                if Pcd.DatumType == 'VOID*':\r
-                    Pcd.TokenTypeList += ['PCD_TYPE_STRING']\r
-                    Pcd.InitString = 'INIT'\r
-                    if Sku.DefaultValue != '':\r
-                        NumberOfSizeItems += 1\r
-                        Dict['STRING_TABLE_CNAME'].append(CName)\r
-                        Dict['STRING_TABLE_GUID'].append(TokenSpaceGuid)\r
-\r
-                        if StringTableIndex == 0:\r
-                            Dict['STRING_TABLE_INDEX'].append('')\r
-                        else:\r
-                            Dict['STRING_TABLE_INDEX'].append('_%d' % StringTableIndex)\r
-                        if Sku.DefaultValue[0] == 'L':\r
-                            Size = (len(Sku.DefaultValue) - 3) * 2\r
-                            Dict['STRING_TABLE_VALUE'].append(Sku.DefaultValue)\r
-                        elif Sku.DefaultValue[0] == '"':\r
-                            Size = len(Sku.DefaultValue) - 2\r
-                            Dict['STRING_TABLE_VALUE'].append(Sku.DefaultValue)\r
-                        elif Sku.DefaultValue[0] == '{':\r
-                            Size = len(Sku.DefaultValue.replace(',',' ').split())\r
-                            Dict['STRING_TABLE_VALUE'].append('{' + Sku.DefaultValue + '}')\r
-\r
-                        StringHeadOffsetList.append(str(StringTableSize))\r
-                        Dict['SIZE_TABLE_CNAME'].append(CName)\r
-                        Dict['SIZE_TABLE_GUID'].append(TokenSpaceGuid)\r
-                        Dict['SIZE_TABLE_CURRENT_LENGTH'].append(Size)\r
-                        Dict['SIZE_TABLE_MAXIMUM_LENGTH'].append(Pcd.MaxDatumSize)\r
-                        if Pcd.MaxDatumSize != '':\r
-                            MaxDatumSize = int(Pcd.MaxDatumSize, 0)\r
-                            if MaxDatumSize > Size:\r
-                                Size = MaxDatumSize\r
-                        Dict['STRING_TABLE_LENGTH'].append(Size / 2 + 1)\r
-                        StringTableIndex += 1\r
-                        StringTableSize += (Size / 2 + 1)\r
-                else:\r
-                    Pcd.TokenTypeList += ['PCD_TYPE_DATA']\r
-                    if Sku.DefaultValue == 'TRUE':\r
-                        Pcd.InitString = 'INIT'\r
-                    else:\r
-                        try:\r
-                            if int(Sku.DefaultValue, 0) != 0:\r
-                                Pcd.InitString = 'INIT'\r
-                        except:\r
-                            pass\r
-                    ValueList.append(Sku.DefaultValue)\r
-\r
-        Pcd.TokenTypeList = list(set(Pcd.TokenTypeList))\r
-\r
-        if 'PCD_TYPE_HII' in Pcd.TokenTypeList:\r
-            Dict['VARIABLE_HEAD_CNAME_DECL'].append(CName)\r
-            Dict['VARIABLE_HEAD_GUID_DECL'].append(TokenSpaceGuid)\r
-            Dict['VARIABLE_HEAD_NUMSKUS_DECL'].append(len(Pcd.SkuInfoList))\r
-            Dict['VARIABLE_HEAD_VALUE'].append('{ %s }\n' % ' },\n    { '.join(VariableHeadValueList))\r
-        if 'PCD_TYPE_VPD' in Pcd.TokenTypeList:\r
-            Dict['VPD_HEAD_CNAME_DECL'].append(CName)\r
-            Dict['VPD_HEAD_GUID_DECL'].append(TokenSpaceGuid)\r
-            Dict['VPD_HEAD_NUMSKUS_DECL'].append(len(Pcd.SkuInfoList))\r
-            Dict['VPD_HEAD_VALUE'].append('{ %s }' % ' }, { '.join(VpdHeadOffsetList))\r
-        if 'PCD_TYPE_STRING' in Pcd.TokenTypeList:\r
-            Dict['STRING_HEAD_CNAME_DECL'].append(CName)\r
-            Dict['STRING_HEAD_GUID_DECL'].append(TokenSpaceGuid)\r
-            Dict['STRING_HEAD_NUMSKUS_DECL'].append(len(Pcd.SkuInfoList))\r
-            Dict['STRING_HEAD_VALUE'].append(', '.join(StringHeadOffsetList))\r
-        if 'PCD_TYPE_DATA' in Pcd.TokenTypeList:\r
-            Dict[Pcd.InitString+'_CNAME_DECL_'+Pcd.DatumType].append(CName)\r
-            Dict[Pcd.InitString+'_GUID_DECL_'+Pcd.DatumType].append(TokenSpaceGuid)\r
-            Dict[Pcd.InitString+'_NUMSKUS_DECL_'+Pcd.DatumType].append(len(Pcd.SkuInfoList))\r
-            if Pcd.InitString == 'UNINIT':\r
-                Dict['PCD_DATABASE_UNINIT_EMPTY'] = ''\r
-            else:\r
-                Dict[Pcd.InitString+'_VALUE_'+Pcd.DatumType].append(', '.join(ValueList))\r
-\r
-    if Phase == 'PEI':\r
-        NumberOfLocalTokens = NumberOfPeiLocalTokens\r
-    if Phase == 'DXE':\r
-        NumberOfLocalTokens = NumberOfDxeLocalTokens\r
-\r
-    Dict['TOKEN_INIT']       = ['' for x in range(NumberOfLocalTokens)]\r
-    Dict['TOKEN_CNAME']      = ['' for x in range(NumberOfLocalTokens)]\r
-    Dict['TOKEN_GUID']       = ['' for x in range(NumberOfLocalTokens)]\r
-    Dict['TOKEN_TYPE']       = ['' for x in range(NumberOfLocalTokens)]\r
-\r
-    for Pcd in Platform.DynamicPcdList:\r
-        CName = Pcd.TokenCName\r
-        TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName\r
-        if Pcd.Phase != Phase:\r
-            continue\r
-\r
-        TokenSpaceGuid = GuidStructureStringToGuidValueName(Pcd.TokenSpaceGuidValue) #(Platform.PackageList, TokenSpaceGuidCName))\r
-        GeneratedTokenNumber = Platform.PcdTokenNumber[CName, TokenSpaceGuidCName] - 1\r
-        if Phase == 'DXE':\r
-            GeneratedTokenNumber -= NumberOfPeiLocalTokens\r
-\r
-        EdkLogger.debug(EdkLogger.DEBUG_1, "PCD = %s | %s" % (CName, TokenSpaceGuidCName))\r
-        EdkLogger.debug(EdkLogger.DEBUG_1, "phase = %s" % Phase)\r
-        EdkLogger.debug(EdkLogger.DEBUG_1, "GeneratedTokenNumber = %s" % str(GeneratedTokenNumber))\r
-\r
-        Dict['TOKEN_INIT'][GeneratedTokenNumber] = 'Init'\r
-        if Pcd.InitString == 'UNINIT':\r
-            Dict['TOKEN_INIT'][GeneratedTokenNumber] = 'Uninit'\r
-        Dict['TOKEN_CNAME'][GeneratedTokenNumber] = CName\r
-        Dict['TOKEN_GUID'][GeneratedTokenNumber] = TokenSpaceGuid\r
-        Dict['TOKEN_TYPE'][GeneratedTokenNumber] = ' | '.join(Pcd.TokenTypeList)\r
-        if Pcd.Type in gDynamicExPcd:\r
-            Dict['EXMAPPING_TABLE_EXTOKEN'].append(Pcd.TokenValue)\r
-            if Phase == 'DXE':\r
-                GeneratedTokenNumber += NumberOfPeiLocalTokens\r
-            Dict['EXMAPPING_TABLE_LOCAL_TOKEN'].append(GeneratedTokenNumber)\r
-            Dict['EXMAPPING_TABLE_GUID_INDEX'].append(GuidList.index(TokenSpaceGuid))\r
-\r
-    if GuidList != []:\r
-        Dict['GUID_TABLE_EMPTY'] = 'FALSE'\r
-        Dict['GUID_TABLE_SIZE'] = len(GuidList)\r
-    else:\r
-        Dict['GUID_STRUCTURE'] = [GuidStringToGuidStructureString('00000000-0000-0000-0000-000000000000')]\r
-\r
-    if StringTableIndex == 0:\r
-        Dict['STRING_TABLE_INDEX'].append('')\r
-        Dict['STRING_TABLE_LENGTH'].append(1)\r
-        Dict['STRING_TABLE_CNAME'].append('')\r
-        Dict['STRING_TABLE_GUID'].append('')\r
-        Dict['STRING_TABLE_VALUE'].append('{ 0 }')\r
-    else:\r
-        Dict['STRING_TABLE_EMPTY'] = 'FALSE'\r
-        Dict['STRING_TABLE_SIZE'] = StringTableSize\r
-\r
-    if Dict['SIZE_TABLE_CNAME'] == []:\r
-        Dict['SIZE_TABLE_CNAME'].append('')\r
-        Dict['SIZE_TABLE_GUID'].append('')\r
-        Dict['SIZE_TABLE_CURRENT_LENGTH'].append(0)\r
-        Dict['SIZE_TABLE_MAXIMUM_LENGTH'].append(0)\r
-\r
-    if NumberOfLocalTokens != 0:\r
-        Dict['DATABASE_EMPTY']                = 'FALSE'\r
-        Dict['LOCAL_TOKEN_NUMBER_TABLE_SIZE'] = NumberOfLocalTokens\r
-        Dict['LOCAL_TOKEN_NUMBER']            = NumberOfLocalTokens\r
-\r
-    if NumberOfExTokens != 0:\r
-        Dict['EXMAP_TABLE_EMPTY']    = 'FALSE'\r
-        Dict['EXMAPPING_TABLE_SIZE'] = NumberOfExTokens\r
-        Dict['EX_TOKEN_NUMBER']      = NumberOfExTokens\r
-    else:\r
-        Dict['EXMAPPING_TABLE_EXTOKEN'].append(0)\r
-        Dict['EXMAPPING_TABLE_LOCAL_TOKEN'].append(0)\r
-        Dict['EXMAPPING_TABLE_GUID_INDEX'].append(0)\r
-\r
-    if NumberOfSizeItems != 0:\r
-        Dict['SIZE_TABLE_SIZE'] = NumberOfSizeItems * 2\r
-\r
-    AutoGenH.Append(gPcdDatabaseAutoGenH, Dict)\r
-    if NumberOfLocalTokens == 0:\r
-        AutoGenC.Append(gEmptyPcdDatabaseAutoGenC, Dict)\r
-    else:\r
-        AutoGenC.Append(gPcdDatabaseAutoGenC, Dict)\r
-\r
-    return AutoGenH, AutoGenC\r
-\r
-## Create code for PCD database\r
-#\r
-#   @param      Info        The ModuleAutoGen object\r
-#   @param      AutoGenC    The TemplateString object for C code\r
-#   @param      AutoGenH    The TemplateString object for header file\r
-#\r
-def CreatePcdDatabaseCode (Info, AutoGenC, AutoGenH):\r
-    if Info.PcdIsDriver == "":\r
-        return\r
-    if Info.PcdIsDriver not in gPcdPhaseMap:\r
-        EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Not supported PcdIsDriver type:%s\n" % Info.PcdIsDriver)\r
-\r
-    AutoGenH.Append(gPcdDatabaseCommonAutoGenH)\r
-    AdditionalAutoGenH, AdditionalAutoGenC = CreatePcdDatabasePhaseSpecificAutoGen (Info.PlatformInfo, 'PEI')\r
-    AutoGenH.Append(AdditionalAutoGenH.String)\r
-\r
-    Phase = gPcdPhaseMap[Info.PcdIsDriver]\r
-    if Phase == 'PEI':\r
-        AutoGenC.Append(AdditionalAutoGenC.String)\r
-\r
-    if Phase == 'DXE':\r
-        AdditionalAutoGenH, AdditionalAutoGenC = CreatePcdDatabasePhaseSpecificAutoGen (Info.PlatformInfo, Phase)\r
-        AutoGenH.Append(AdditionalAutoGenH.String)\r
-        AutoGenC.Append(AdditionalAutoGenC.String)\r
-        AutoGenH.Append(gPcdDatabaseEpilogueAutoGenH)\r
-\r
-## Create code for library constructor\r
-#\r
-#   @param      Info        The ModuleAutoGen object\r
-#   @param      AutoGenC    The TemplateString object for C code\r
-#   @param      AutoGenH    The TemplateString object for header file\r
-#\r
-def CreateLibraryConstructorCode(Info, AutoGenC, AutoGenH):\r
-    if Info.IsLibrary:\r
-        return\r
-    #\r
-    # Library Constructors\r
-    #\r
-    ConstructorPrototypeString = TemplateString()\r
-    ConstructorCallingString = TemplateString()\r
-    for Lib in Info.DependentLibraryList:\r
-        if len(Lib.ConstructorList) <= 0:\r
-            continue\r
-        Dict = {'Function':Lib.ConstructorList}\r
-        if Lib.ModuleType == 'BASE':\r
-            ConstructorPrototypeString.Append(gLibraryStructorPrototype['BASE'], Dict)\r
-            ConstructorCallingString.Append(gLibraryStructorCall['BASE'], Dict)\r
-        elif Lib.ModuleType in ['PEI_CORE','PEIM']:\r
-            ConstructorPrototypeString.Append(gLibraryStructorPrototype['PEI'], Dict)\r
-            ConstructorCallingString.Append(gLibraryStructorCall['PEI'], Dict)\r
-        elif Lib.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER','DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION']:\r
-            ConstructorPrototypeString.Append(gLibraryStructorPrototype['DXE'], Dict)\r
-            ConstructorCallingString.Append(gLibraryStructorCall['DXE'], Dict)\r
-\r
-    if str(ConstructorPrototypeString) == '':\r
-        ConstructorPrototypeList = []\r
-    else:\r
-        ConstructorPrototypeList = [str(ConstructorPrototypeString)]\r
-    if str(ConstructorCallingString) == '':\r
-        ConstructorCallingList = []\r
-    else:\r
-        ConstructorCallingList = [str(ConstructorCallingString)]\r
-\r
-    Dict = {\r
-        'Type'              :   'Constructor',\r
-        'FunctionPrototype' :   ConstructorPrototypeList,\r
-        'FunctionCall'      :   ConstructorCallingList\r
-    }\r
-    if Info.ModuleType == 'BASE':\r
-        AutoGenC.Append(gLibraryString['BASE'], Dict)\r
-    elif Info.ModuleType in ['PEI_CORE','PEIM']:\r
-        AutoGenC.Append(gLibraryString['PEI'], Dict)\r
-    elif Info.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER','DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION']:\r
-        AutoGenC.Append(gLibraryString['DXE'], Dict)\r
-\r
-## Create code for library destructor\r
-#\r
-#   @param      Info        The ModuleAutoGen object\r
-#   @param      AutoGenC    The TemplateString object for C code\r
-#   @param      AutoGenH    The TemplateString object for header file\r
-#\r
-def CreateLibraryDestructorCode(Info, AutoGenC, AutoGenH):\r
-    if Info.IsLibrary:\r
-        return\r
-    #\r
-    # Library Destructors\r
-    #\r
-    DestructorPrototypeString = TemplateString()\r
-    DestructorCallingString = TemplateString()\r
-    for Index in range(len(Info.DependentLibraryList)-1, -1, -1):\r
-        Lib = Info.DependentLibraryList[Index]\r
-        if len(Lib.DestructorList) <= 0:\r
-            continue\r
-        Dict = {'Function':Lib.DestructorList}\r
-        if Lib.ModuleType == 'BASE':\r
-            DestructorPrototypeString.Append(gLibraryStructorPrototype['BASE'], Dict)\r
-            DestructorCallingString.Append(gLibraryStructorCall['BASE'], Dict)\r
-        elif Lib.ModuleType in ['PEI_CORE','PEIM']:\r
-            DestructorPrototypeString.Append(gLibraryStructorPrototype['PEI'], Dict)\r
-            DestructorCallingString.Append(gLibraryStructorCall['PEI'], Dict)\r
-        elif Lib.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER','DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION']:\r
-            DestructorPrototypeString.Append(gLibraryStructorPrototype['DXE'], Dict)\r
-            DestructorCallingString.Append(gLibraryStructorCall['DXE'], Dict)\r
-\r
-    if str(DestructorPrototypeString) == '':\r
-        DestructorPrototypeList = []\r
-    else:\r
-        DestructorPrototypeList = [str(DestructorPrototypeString)]\r
-    if str(DestructorCallingString) == '':\r
-        DestructorCallingList = []\r
-    else:\r
-        DestructorCallingList = [str(DestructorCallingString)]\r
-\r
-    Dict = {\r
-        'Type'              :   'Destructor',\r
-        'FunctionPrototype' :   DestructorPrototypeList,\r
-        'FunctionCall'      :   DestructorCallingList\r
-    }\r
-    if Info.ModuleType == 'BASE':\r
-        AutoGenC.Append(gLibraryString['BASE'], Dict)\r
-    elif Info.ModuleType in ['PEI_CORE','PEIM']:\r
-        AutoGenC.Append(gLibraryString['PEI'], Dict)\r
-    elif Info.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER','DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION']:\r
-        AutoGenC.Append(gLibraryString['DXE'], Dict)\r
-\r
-\r
-## Create code for ModuleEntryPoint\r
-#\r
-#   @param      Info        The ModuleAutoGen object\r
-#   @param      AutoGenC    The TemplateString object for C code\r
-#   @param      AutoGenH    The TemplateString object for header file\r
-#\r
-def CreateModuleEntryPointCode(Info, AutoGenC, AutoGenH):\r
-    if Info.IsLibrary or Info.ModuleType == "USER_DEFINED":\r
-        return\r
-    #\r
-    # Module Entry Points\r
-    #\r
-    NumEntryPoints = len(Info.Module.ModuleEntryPointList)\r
-    Dict = {'Function':Info.Module.ModuleEntryPointList}\r
-\r
-    if Info.ModuleType in ['PEI_CORE', 'DXE_CORE']:\r
-        if NumEntryPoints != 1:\r
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, '%s must have exactly one entry point' % Info.ModuleType,\r
-                            ExtraData=", ".join(Info.Module.ModuleEntryPointList))\r
-    if Info.ModuleType == 'PEI_CORE':\r
-        AutoGenC.Append(gPeiCoreEntryPointString, Dict)\r
-    elif Info.ModuleType == 'DXE_CORE':\r
-        AutoGenC.Append(gDxeCoreEntryPointString, Dict)\r
-    elif Info.ModuleType == 'PEIM':\r
-        if NumEntryPoints < 2:\r
-            AutoGenC.Append(gPeimEntryPointString[NumEntryPoints], Dict)\r
-        else:\r
-            AutoGenC.Append(gPeimEntryPointString[2], Dict)\r
-    elif Info.ModuleType in ['DXE_RUNTIME_DRIVER','DXE_DRIVER','DXE_SMM_DRIVER', 'DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION']:\r
-        if Info.ModuleType == 'DXE_SMM_DRIVER':\r
-            if NumEntryPoints == 0:\r
-                AutoGenC.Append(gDxeSmmEntryPointString[0], Dict)\r
-            else:\r
-                AutoGenC.Append(gDxeSmmEntryPointString[1], Dict)\r
-        else:\r
-            if NumEntryPoints < 2:\r
-                AutoGenC.Append(gUefiEntryPointString[NumEntryPoints], Dict)\r
-            else:\r
-                AutoGenC.Append(gUefiEntryPointString[2], Dict)\r
-\r
-## Create code for ModuleUnloadImage\r
-#\r
-#   @param      Info        The ModuleAutoGen object\r
-#   @param      AutoGenC    The TemplateString object for C code\r
-#   @param      AutoGenH    The TemplateString object for header file\r
-#\r
-def CreateModuleUnloadImageCode(Info, AutoGenC, AutoGenH):\r
-    if Info.IsLibrary or Info.ModuleType == "USER_DEFINED":\r
-        return\r
-    #\r
-    # Unload Image Handlers\r
-    #\r
-    NumUnloadImage = len(Info.Module.ModuleUnloadImageList)\r
-    Dict = {'Count':NumUnloadImage, 'Function':Info.Module.ModuleUnloadImageList}\r
-    if NumUnloadImage < 2:\r
-        AutoGenC.Append(gUefiUnloadImageString[NumUnloadImage], Dict)\r
-    else:\r
-        AutoGenC.Append(gUefiUnloadImageString[2], Dict)\r
-\r
-## Create code for GUID\r
-#\r
-#   @param      Info        The ModuleAutoGen object\r
-#   @param      AutoGenC    The TemplateString object for C code\r
-#   @param      AutoGenH    The TemplateString object for header file\r
-#\r
-def CreateGuidDefinitionCode(Info, AutoGenC, AutoGenH):\r
-    if Info.IsLibrary:\r
-        return\r
-\r
-    if Info.ModuleType in ["USER_DEFINED", "BASE"]:\r
-        GuidType = "GUID"\r
-    else:\r
-        GuidType = "EFI_GUID"\r
-\r
-    #\r
-    # GUIDs\r
-    #\r
-    for Key in Info.GuidList:\r
-        AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.GuidList[Key]))\r
-\r
-## Create code for protocol\r
-#\r
-#   @param      Info        The ModuleAutoGen object\r
-#   @param      AutoGenC    The TemplateString object for C code\r
-#   @param      AutoGenH    The TemplateString object for header file\r
-#\r
-def CreateProtocolDefinitionCode(Info, AutoGenC, AutoGenH):\r
-    if Info.IsLibrary:\r
-        return\r
-\r
-    if Info.ModuleType in ["USER_DEFINED", "BASE"]:\r
-        GuidType = "GUID"\r
-    else:\r
-        GuidType = "EFI_GUID"\r
-\r
-    #\r
-    # Protocol GUIDs\r
-    #\r
-    for Key in Info.ProtocolList:\r
-        AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.ProtocolList[Key]))\r
-\r
-## Create code for PPI\r
-#\r
-#   @param      Info        The ModuleAutoGen object\r
-#   @param      AutoGenC    The TemplateString object for C code\r
-#   @param      AutoGenH    The TemplateString object for header file\r
-#\r
-def CreatePpiDefinitionCode(Info, AutoGenC, AutoGenH):\r
-    if Info.IsLibrary:\r
-        return\r
-\r
-    if Info.ModuleType in ["USER_DEFINED", "BASE"]:\r
-        GuidType = "GUID"\r
-    else:\r
-        GuidType = "EFI_GUID"\r
-\r
-    #\r
-    # PPI GUIDs\r
-    #\r
-    for Key in Info.PpiList:\r
-        AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.PpiList[Key]))\r
-\r
-## Create code for PCD\r
-#\r
-#   @param      Info        The ModuleAutoGen object\r
-#   @param      AutoGenC    The TemplateString object for C code\r
-#   @param      AutoGenH    The TemplateString object for header file\r
-#\r
-def CreatePcdCode(Info, AutoGenC, AutoGenH):\r
-    if Info.IsLibrary:\r
-        for Pcd in Info.PcdList:\r
-            CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd)\r
-    else:\r
-        for Pcd in Info.PcdList:\r
-            CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd)\r
-    CreatePcdDatabaseCode(Info, AutoGenC, AutoGenH)\r
-\r
-## Create code for unicode string definition\r
-#\r
-#   @param      Info        The ModuleAutoGen object\r
-#   @param      AutoGenC    The TemplateString object for C code\r
-#   @param      AutoGenH    The TemplateString object for header file\r
-#\r
-def CreateUnicodeStringCode(Info, AutoGenC, AutoGenH):\r
-    if len(Info.UnicodeFileList) == 0:\r
-        return\r
-\r
-    WorkingDir = os.getcwd()\r
-    os.chdir(Info.WorkspaceDir)\r
-\r
-    #IncList = [os.path.join(Info.WorkspaceDir, Inc) for Inc in Info.IncludePathList]\r
-    IncList = [Info.SourceDir]\r
-    SrcList = [F[0] for F in Info.SourceFileList]\r
-    Header, Code = GetStringFiles(Info.UnicodeFileList, SrcList, IncList, ['.uni'], Info.Name)\r
-    AutoGenC.Append("\n//\n//Unicode String Pack Definition\n//\n")\r
-    AutoGenC.Append(Code)\r
-    AutoGenC.Append("\n")\r
-    AutoGenH.Append("\n//\n//Unicode String ID\n//\n")\r
-    AutoGenH.Append(Header)\r
-    AutoGenH.Append("\n#define STRING_ARRAY_NAME %sStrings\n" % Info.Name)\r
-    os.chdir(WorkingDir)\r
-\r
-## Create common code\r
-#\r
-#   @param      Info        The ModuleAutoGen object\r
-#   @param      AutoGenC    The TemplateString object for C code\r
-#   @param      AutoGenH    The TemplateString object for header file\r
-#\r
-def CreateHeaderCode(Info, AutoGenC, AutoGenH):\r
-    # file header\r
-    AutoGenH.Append(gAutoGenHeaderString,   {'FileName':'AutoGen.h'})\r
-    # header file Prologue\r
-    AutoGenH.Append(gAutoGenHPrologueString,{'Guid':Info.Guid.replace('-','_')})\r
-    if Info.AutoGenVersion >= 0x00010005:\r
-        # specification macros\r
-        AutoGenH.Append(gSpecificationString,   {'SpecificationName':Info.Macro.keys(), \r
-                                                 'SpecificationValue':Info.Macro.values()})\r
-        # header files includes\r
-        AutoGenH.Append("#include <%s>\n\n" % gBasicHeaderFile)\r
-        AutoGenH.Append('\nextern GUID  gEfiCallerIdGuid;\n\n')\r
-    \r
-        if Info.IsLibrary:\r
-            return\r
-    \r
-        AutoGenH.Append("#define EFI_CALLER_ID_GUID \\\n  %s\n" % GuidStringToGuidStructureString(Info.Guid))\r
-    \r
-    if Info.IsLibrary:\r
-        return\r
-    # C file header\r
-    AutoGenC.Append(gAutoGenHeaderString, {'FileName':'AutoGen.c'})\r
-    if Info.AutoGenVersion >= 0x00010005:\r
-        # C file header files includes\r
-        for Inc in gModuleTypeHeaderFile[Info.ModuleType]:\r
-            AutoGenC.Append("#include <%s>\n" % Inc)\r
-    \r
-        #\r
-        # Publish the CallerId Guid\r
-        #\r
-        AutoGenC.Append('\nGLOBAL_REMOVE_IF_UNREFERENCED GUID gEfiCallerIdGuid = %s;\n' % GuidStringToGuidStructureString(Info.Guid))\r
-    else:\r
-        # R8 modules my have nothing in the AutoGen.c. So it needs following line\r
-        AutoGenC.Append('\nextern int __make_me_compile_correctly;\n\n')\r
-\r
-\r
-## Create common code for header file\r
-#\r
-#   @param      Info        The ModuleAutoGen object\r
-#   @param      AutoGenC    The TemplateString object for C code\r
-#   @param      AutoGenH    The TemplateString object for header file\r
-#\r
-def CreateFooterCode(Info, AutoGenC, AutoGenH):\r
-    AutoGenH.Append(gAutoGenHEpilogueString)\r
-\r
-## Create code for a module\r
-#\r
-#   @param      Info        The ModuleAutoGen object\r
-#   @param      AutoGenC    The TemplateString object for C code\r
-#   @param      AutoGenH    The TemplateString object for header file\r
-#\r
-def CreateCode(Info, AutoGenC, AutoGenH):\r
-    CreateHeaderCode(Info, AutoGenC, AutoGenH)\r
-\r
-    if Info.AutoGenVersion >= 0x00010005:\r
-        CreateLibraryConstructorCode(Info, AutoGenC, AutoGenH)\r
-        CreateLibraryDestructorCode(Info, AutoGenC, AutoGenH)\r
-        CreateModuleEntryPointCode(Info, AutoGenC, AutoGenH)\r
-        CreateModuleUnloadImageCode(Info, AutoGenC, AutoGenH)\r
-        CreateGuidDefinitionCode(Info, AutoGenC, AutoGenH)\r
-        CreateProtocolDefinitionCode(Info, AutoGenC, AutoGenH)\r
-        CreatePpiDefinitionCode(Info, AutoGenC, AutoGenH)\r
-        CreatePcdCode(Info, AutoGenC, AutoGenH)\r
-    CreateUnicodeStringCode(Info, AutoGenC, AutoGenH)\r
-\r
-    CreateFooterCode(Info, AutoGenC, AutoGenH)\r
-\r
-## Create the code file\r
-#\r
-#   @param      FilePath    The path of code file\r
-#   @param      Content     The content of code file\r
-#\r
-#   @retval     True        If file content is changed or file doesn't exist\r
-#   @retval     False       If the file exists and the content is not changed\r
-#\r
-def Generate(FilePath, Content):\r
-    return SaveFileOnChange(FilePath, Content)\r
+## @file
+# Routines for generating AutoGen.h and AutoGen.c
+#
+# Copyright (c) 2007, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+## Import Modules
+#
+import string
+
+from Common import EdkLogger
+
+from Common.BuildToolError import *
+from Common.DataType import *
+from Common.EdkIIWorkspace import *
+from Common.Misc import *
+from StrGather import *
+
+## PCD type string
+gItemTypeStringDatabase  = {
+    TAB_PCDS_FEATURE_FLAG       :   'FixedAtBuild',
+    TAB_PCDS_FIXED_AT_BUILD     :   'FixedAtBuild',
+    TAB_PCDS_PATCHABLE_IN_MODULE:   'BinaryPatch',
+    TAB_PCDS_DYNAMIC            :   '',
+    TAB_PCDS_DYNAMIC_DEFAULT    :   '',
+    TAB_PCDS_DYNAMIC_VPD        :   '',
+    TAB_PCDS_DYNAMIC_HII        :   '',
+    TAB_PCDS_DYNAMIC_EX         :   '',
+    TAB_PCDS_DYNAMIC_EX_DEFAULT :   '',
+    TAB_PCDS_DYNAMIC_EX_VPD     :   '',
+    TAB_PCDS_DYNAMIC_EX_HII     :   '',
+}
+
+## Dynamic PCD types
+gDynamicPcd = [TAB_PCDS_DYNAMIC, TAB_PCDS_DYNAMIC_DEFAULT, TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_HII]
+
+## Dynamic-ex PCD types
+gDynamicExPcd = [TAB_PCDS_DYNAMIC_EX, TAB_PCDS_DYNAMIC_EX_DEFAULT, TAB_PCDS_DYNAMIC_EX_VPD, TAB_PCDS_DYNAMIC_EX_HII]
+
+## Datum size
+gDatumSizeStringDatabase = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'BOOLEAN','VOID*':'8'}
+gDatumSizeStringDatabaseH = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'BOOL','VOID*':'PTR'}
+gDatumSizeStringDatabaseLib = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'Bool','VOID*':'Ptr'}
+
+## Mapping between PCD driver type and EFI phase
+gPcdPhaseMap = {
+    "PEI_PCD_DRIVER"    :   "PEI",
+    "DXE_PCD_DRIVER"    :   "DXE"
+}
+
+gPcdDatabaseCommonAutoGenH = """
+//
+// The following definition will be generated by build tool
+//
+
+//
+// Common definitions
+//
+typedef UINT8 SKU_ID;
+
+#define PCD_TYPE_SHIFT        28
+
+#define PCD_TYPE_DATA         (0x0 << PCD_TYPE_SHIFT)
+#define PCD_TYPE_HII          (0x8 << PCD_TYPE_SHIFT)
+#define PCD_TYPE_VPD          (0x4 << PCD_TYPE_SHIFT)
+#define PCD_TYPE_SKU_ENABLED  (0x2 << PCD_TYPE_SHIFT)
+#define PCD_TYPE_STRING       (0x1 << PCD_TYPE_SHIFT)
+
+#define PCD_TYPE_ALL_SET      (PCD_TYPE_DATA | PCD_TYPE_HII | PCD_TYPE_VPD | PCD_TYPE_SKU_ENABLED | PCD_TYPE_STRING)
+
+#define PCD_DATUM_TYPE_SHIFT  24
+
+#define PCD_DATUM_TYPE_POINTER  (0x0 << PCD_DATUM_TYPE_SHIFT)
+#define PCD_DATUM_TYPE_UINT8    (0x1 << PCD_DATUM_TYPE_SHIFT)
+#define PCD_DATUM_TYPE_UINT16   (0x2 << PCD_DATUM_TYPE_SHIFT)
+#define PCD_DATUM_TYPE_UINT32   (0x4 << PCD_DATUM_TYPE_SHIFT)
+#define PCD_DATUM_TYPE_UINT64   (0x8 << PCD_DATUM_TYPE_SHIFT)
+
+#define PCD_DATUM_TYPE_ALL_SET  (PCD_DATUM_TYPE_POINTER | \\
+                                 PCD_DATUM_TYPE_UINT8   | \\
+                                 PCD_DATUM_TYPE_UINT16  | \\
+                                 PCD_DATUM_TYPE_UINT32  | \\
+                                 PCD_DATUM_TYPE_UINT64)
+
+#define PCD_DATABASE_OFFSET_MASK (~(PCD_TYPE_ALL_SET | PCD_DATUM_TYPE_ALL_SET))
+
+typedef struct  {
+  UINT32  ExTokenNumber;
+  UINT16  LocalTokenNumber;   // PCD Number of this particular platform build
+  UINT16  ExGuidIndex;        // Index of GuidTable
+} DYNAMICEX_MAPPING;
+
+typedef struct {
+  UINT32  SkuDataStartOffset; //We have to use offsetof MACRO as we don't know padding done by compiler
+  UINT32  SkuIdTableOffset;   //Offset from the PCD_DB
+} SKU_HEAD;
+
+typedef struct {
+  UINT16  GuidTableIndex;     // Offset in Guid Table in units of GUID.
+  UINT16  StringIndex;        // Offset in String Table in units of UINT16.
+  UINT16  Offset;             // Offset in Variable
+  UINT16  DefaultValueOffset; // Offset of the Default Value
+} VARIABLE_HEAD;
+
+typedef  struct {
+  UINT32  Offset;
+} VPD_HEAD;
+
+typedef UINT16 STRING_HEAD;
+
+typedef UINT16 SIZE_INFO;
+
+#define offsetof(s,m)  (UINT32) (UINTN) &(((s *)0)->m)
+
+"""
+
+gPcdDatabaseEpilogueAutoGenH = """
+typedef struct {
+  PEI_PCD_DATABASE PeiDb;
+  DXE_PCD_DATABASE DxeDb;
+} PCD_DATABASE;
+
+#define PCD_TOTAL_TOKEN_NUMBER (PEI_LOCAL_TOKEN_NUMBER + DXE_LOCAL_TOKEN_NUMBER)
+
+"""
+
+gPcdDatabaseAutoGenH = """
+#define ${PHASE}_GUID_TABLE_SIZE                ${GUID_TABLE_SIZE}
+#define ${PHASE}_STRING_TABLE_SIZE              ${STRING_TABLE_SIZE}
+#define ${PHASE}_SKUID_TABLE_SIZE               ${SKUID_TABLE_SIZE}
+#define ${PHASE}_LOCAL_TOKEN_NUMBER_TABLE_SIZE  ${LOCAL_TOKEN_NUMBER_TABLE_SIZE}
+#define ${PHASE}_LOCAL_TOKEN_NUMBER             ${LOCAL_TOKEN_NUMBER}
+#define ${PHASE}_EXMAPPING_TABLE_SIZE           ${EXMAPPING_TABLE_SIZE}
+#define ${PHASE}_EX_TOKEN_NUMBER                ${EX_TOKEN_NUMBER}
+#define ${PHASE}_SIZE_TABLE_SIZE                ${SIZE_TABLE_SIZE}
+#define ${PHASE}_GUID_TABLE_EMPTY               ${GUID_TABLE_EMPTY}
+#define ${PHASE}_STRING_TABLE_EMPTY             ${STRING_TABLE_EMPTY}
+#define ${PHASE}_SKUID_TABLE_EMPTY              ${SKUID_TABLE_EMPTY}
+#define ${PHASE}_DATABASE_EMPTY                 ${DATABASE_EMPTY}
+#define ${PHASE}_EXMAP_TABLE_EMPTY              ${EXMAP_TABLE_EMPTY}
+
+typedef struct {
+${BEGIN}  UINT64             ${INIT_CNAME_DECL_UINT64}_${INIT_GUID_DECL_UINT64}[${INIT_NUMSKUS_DECL_UINT64}];
+${END}
+${BEGIN}  UINT64             ${VARDEF_CNAME_UINT64}_${VARDEF_GUID_UINT64}_VariableDefault_${VARDEF_SKUID_UINT64};
+${END}
+${BEGIN}  UINT32             ${INIT_CNAME_DECL_UINT32}_${INIT_GUID_DECL_UINT32}[${INIT_NUMSKUS_DECL_UINT32}];
+${END}
+${BEGIN}  UINT32             ${VARDEF_CNAME_UINT32}_${VARDEF_GUID_UINT32}_VariableDefault_${VARDEF_SKUID_UINT32};
+${END}
+${BEGIN}  VPD_HEAD           ${VPD_HEAD_CNAME_DECL}_${VPD_HEAD_GUID_DECL}[${VPD_HEAD_NUMSKUS_DECL}];
+${END}
+  DYNAMICEX_MAPPING  ExMapTable[${PHASE}_EXMAPPING_TABLE_SIZE];
+  UINT32             LocalTokenNumberTable[${PHASE}_LOCAL_TOKEN_NUMBER_TABLE_SIZE];
+  GUID               GuidTable[${PHASE}_GUID_TABLE_SIZE];
+${BEGIN}  STRING_HEAD        ${STRING_HEAD_CNAME_DECL}_${STRING_HEAD_GUID_DECL}[${STRING_HEAD_NUMSKUS_DECL}];
+${END}
+${BEGIN}  VARIABLE_HEAD      ${VARIABLE_HEAD_CNAME_DECL}_${VARIABLE_HEAD_GUID_DECL}[${VARIABLE_HEAD_NUMSKUS_DECL}];
+${END}
+${BEGIN}  UINT16             StringTable${STRING_TABLE_INDEX}[${STRING_TABLE_LENGTH}]; /* ${STRING_TABLE_CNAME}_${STRING_TABLE_GUID} */
+${END}
+  SIZE_INFO          SizeTable[${PHASE}_SIZE_TABLE_SIZE];
+${BEGIN}  UINT16             ${INIT_CNAME_DECL_UINT16}_${INIT_GUID_DECL_UINT16}[${INIT_NUMSKUS_DECL_UINT16}];
+${END}
+${BEGIN}  UINT16             ${VARDEF_CNAME_UINT16}_${VARDEF_GUID_UINT16}_VariableDefault_${VARDEF_SKUID_UINT16};
+${END}
+${BEGIN}  UINT8              ${INIT_CNAME_DECL_UINT8}_${INIT_GUID_DECL_UINT8}[${INIT_NUMSKUS_DECL_UINT8}];
+${END}
+${BEGIN}  UINT8              ${VARDEF_CNAME_UINT8}_${VARDEF_GUID_UINT8}_VariableDefault_${VARDEF_SKUID_UINT8};
+${END}
+${BEGIN}  BOOLEAN            ${INIT_CNAME_DECL_BOOLEAN}_${INIT_GUID_DECL_BOOLEAN}[${INIT_NUMSKUS_DECL_BOOLEAN}];
+${END}
+${BEGIN}  BOOLEAN            ${VARDEF_CNAME_BOOLEAN}_${VARDEF_GUID_BOOLEAN}_VariableDefault_${VARDEF_SKUID_BOOLEAN};
+${END}
+  UINT8              SkuIdTable[${PHASE}_SKUID_TABLE_SIZE];
+${SYSTEM_SKU_ID}
+} ${PHASE}_PCD_DATABASE_INIT;
+
+typedef struct {
+${PCD_DATABASE_UNINIT_EMPTY}
+${BEGIN}  UINT64   ${UNINIT_CNAME_DECL_UINT64}_${UNINIT_GUID_DECL_UINT64}[${UNINIT_NUMSKUS_DECL_UINT64}];
+${END}
+${BEGIN}  UINT32   ${UNINIT_CNAME_DECL_UINT32}_${UNINIT_GUID_DECL_UINT32}[${UNINIT_NUMSKUS_DECL_UINT32}];
+${END}
+${BEGIN}  UINT16   ${UNINIT_CNAME_DECL_UINT16}_${UNINIT_GUID_DECL_UINT16}[${UNINIT_NUMSKUS_DECL_UINT16}];
+${END}
+${BEGIN}  UINT8    ${UNINIT_CNAME_DECL_UINT8}_${UNINIT_GUID_DECL_UINT8}[${UNINIT_NUMSKUS_DECL_UINT8}];
+${END}
+${BEGIN}  BOOLEAN  ${UNINIT_CNAME_DECL_BOOLEAN}_${UNINIT_GUID_DECL_BOOLEAN}[${UNINIT_NUMSKUS_DECL_BOOLEAN}];
+${END}
+} ${PHASE}_PCD_DATABASE_UNINIT;
+
+#define PCD_${PHASE}_SERVICE_DRIVER_VERSION         2
+
+typedef struct {
+  ${PHASE}_PCD_DATABASE_INIT    Init;
+  ${PHASE}_PCD_DATABASE_UNINIT  Uninit;
+} ${PHASE}_PCD_DATABASE;
+
+#define ${PHASE}_NEX_TOKEN_NUMBER (${PHASE}_LOCAL_TOKEN_NUMBER - ${PHASE}_EX_TOKEN_NUMBER)
+"""
+
+gEmptyPcdDatabaseAutoGenC = """
+${PHASE}_PCD_DATABASE_INIT g${PHASE}PcdDbInit = {
+  /* ExMapTable */
+  {
+    {0, 0, 0}
+  },
+  /* LocalTokenNumberTable */
+  {
+    0
+  },
+  /* GuidTable */
+  {
+    {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}
+  },
+  /* StringTable */
+  { 0 },
+  /* SizeTable */
+  {
+    0, 0
+  },
+  /* SkuIdTable */
+  { 0 },
+  ${SYSTEM_SKU_ID_VALUE}
+};
+"""
+
+gPcdDatabaseAutoGenC = """
+${PHASE}_PCD_DATABASE_INIT g${PHASE}PcdDbInit = {
+${BEGIN}  { ${INIT_VALUE_UINT64} }, /*  ${INIT_CNAME_DECL_UINT64}_${INIT_GUID_DECL_UINT64}[${INIT_NUMSKUS_DECL_UINT64}] */
+${END}
+${BEGIN}  ${VARDEF_VALUE_UINT64}, /* ${VARDEF_CNAME_UINT64}_${VARDEF_GUID_UINT64}_VariableDefault_${VARDEF_SKUID_UINT64} */
+${END}
+${BEGIN}  { ${INIT_VALUE_UINT32} }, /*  ${INIT_CNAME_DECL_UINT32}_${INIT_GUID_DECL_UINT32}[${INIT_NUMSKUS_DECL_UINT32}] */
+${END}
+${BEGIN}  ${VARDEF_VALUE_UINT32}, /* ${VARDEF_CNAME_UINT32}_${VARDEF_GUID_UINT32}_VariableDefault_${VARDEF_SKUID_UINT32} */
+${END}
+  /* VPD */
+${BEGIN}  { ${VPD_HEAD_VALUE} }, /* ${VPD_HEAD_CNAME_DECL}_${VPD_HEAD_GUID_DECL}[${VPD_HEAD_NUMSKUS_DECL}] */
+${END}
+  /* ExMapTable */
+  {
+${BEGIN}    { ${EXMAPPING_TABLE_EXTOKEN}, ${EXMAPPING_TABLE_LOCAL_TOKEN}, ${EXMAPPING_TABLE_GUID_INDEX} },
+${END}
+  },
+  /* LocalTokenNumberTable */
+  {
+${BEGIN}    offsetof(${PHASE}_PCD_DATABASE, ${TOKEN_INIT}.${TOKEN_CNAME}_${TOKEN_GUID}) | ${TOKEN_TYPE},
+${END}
+  },
+  /* GuidTable */
+  {
+${BEGIN}    ${GUID_STRUCTURE},
+${END}
+  },
+${BEGIN}  { ${STRING_HEAD_VALUE} }, /* ${STRING_HEAD_CNAME_DECL}_${STRING_HEAD_GUID_DECL}[${STRING_HEAD_NUMSKUS_DECL}] */
+${END}
+${BEGIN}  /* ${VARIABLE_HEAD_CNAME_DECL}_${VARIABLE_HEAD_GUID_DECL}[${VARIABLE_HEAD_NUMSKUS_DECL}] */
+  {
+    ${VARIABLE_HEAD_VALUE}
+  },
+${END}
+ /* StringTable */
+${BEGIN}  ${STRING_TABLE_VALUE}, /* ${STRING_TABLE_CNAME}_${STRING_TABLE_GUID} */
+${END}
+  /* SizeTable */
+  {
+${BEGIN}    ${SIZE_TABLE_MAXIMUM_LENGTH}, ${SIZE_TABLE_CURRENT_LENGTH}, /* ${SIZE_TABLE_CNAME}_${SIZE_TABLE_GUID} */
+${END}
+  },
+${BEGIN}  { ${INIT_VALUE_UINT16} }, /*  ${INIT_CNAME_DECL_UINT16}_${INIT_GUID_DECL_UINT16}[${INIT_NUMSKUS_DECL_UINT16}] */
+${END}
+${BEGIN}  ${VARDEF_VALUE_UINT16}, /* ${VARDEF_CNAME_UINT16}_${VARDEF_GUID_UINT16}_VariableDefault_${VARDEF_SKUID_UINT16} */
+${END}
+${BEGIN}  { ${INIT_VALUE_UINT8} }, /*  ${INIT_CNAME_DECL_UINT8}_${INIT_GUID_DECL_UINT8}[${INIT_NUMSKUS_DECL_UINT8}] */
+${END}
+${BEGIN}  ${VARDEF_VALUE_UINT8}, /* ${VARDEF_CNAME_UINT8}_${VARDEF_GUID_UINT8}_VariableDefault_${VARDEF_SKUID_UINT8} */
+${END}
+${BEGIN}  { ${INIT_VALUE_BOOLEAN} }, /*  ${INIT_CNAME_DECL_BOOLEAN}_${INIT_GUID_DECL_BOOLEAN}[${INIT_NUMSKUS_DECL_BOOLEAN}] */
+${END}
+${BEGIN}  ${VARDEF_VALUE_BOOLEAN}, /* ${VARDEF_CNAME_BOOLEAN}_${VARDEF_GUID_BOOLEAN}_VariableDefault_${VARDEF_SKUID_BOOLEAN} */
+${END}
+  /* SkuIdTable */
+  { ${BEGIN}${SKUID_VALUE}, ${END} },
+  ${SYSTEM_SKU_ID_VALUE}
+};
+"""
+
+
+## AutoGen File Header Templates
+gAutoGenHeaderString = """\
+/**
+  DO NOT EDIT
+  FILE auto-generated
+  Module name:
+    $FileName
+  Abstract:       Auto-generated $FileName for building module or library.
+**/
+"""
+
+gAutoGenHPrologueString = """
+#ifndef _AUTOGENH_${Guid}
+#define _AUTOGENH_${Guid}
+
+"""
+
+gAutoGenHEpilogueString = """
+#endif
+"""
+
+## PEI Core Entry Point Templates
+gPeiCoreEntryPointString = """
+${BEGIN}
+EFI_STATUS
+${Function} (
+  IN CONST  EFI_SEC_PEI_HAND_OFF    *SecCoreData,
+  IN CONST  EFI_PEI_PPI_DESCRIPTOR  *PpiList,
+  IN VOID                           *OldCoreData
+  );
+
+EFI_STATUS
+EFIAPI
+ProcessModuleEntryPointList (
+  IN CONST  EFI_SEC_PEI_HAND_OFF    *SecCoreData,
+  IN CONST  EFI_PEI_PPI_DESCRIPTOR  *PpiList,
+  IN VOID                           *OldCoreData
+  )
+
+{
+  return ${Function} (SecCoreData, PpiList, OldCoreData);
+}
+${END}
+"""
+
+
+## DXE Core Entry Point Templates
+gDxeCoreEntryPointString = """
+const UINT32 _gUefiDriverRevision = 0;
+${BEGIN}
+VOID
+${Function} (
+  IN VOID  *HobStart
+  );
+
+VOID
+EFIAPI
+ProcessModuleEntryPointList (
+  IN VOID  *HobStart
+  )
+
+{
+  ${Function} (HobStart);
+}
+${END}
+"""
+
+## PEIM Entry Point Templates
+gPeimEntryPointString = [
+"""
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = 0;
+
+EFI_STATUS
+EFIAPI
+ProcessModuleEntryPointList (
+  IN EFI_PEI_FILE_HANDLE  FileHandle,
+  IN EFI_PEI_SERVICES     **PeiServices
+  )
+
+{
+  return EFI_SUCCESS;
+}
+""",
+"""
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = 0;
+${BEGIN}
+EFI_STATUS
+${Function} (
+  IN EFI_PEI_FILE_HANDLE  FileHandle,
+  IN EFI_PEI_SERVICES     **PeiServices
+  );
+
+EFI_STATUS
+EFIAPI
+ProcessModuleEntryPointList (
+  IN EFI_PEI_FILE_HANDLE  FileHandle,
+  IN EFI_PEI_SERVICES     **PeiServices
+  )
+
+{
+  return ${Function} (FileHandle, PeiServices);
+}
+${END}
+""",
+"""
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = 0;
+
+${BEGIN}
+EFI_STATUS
+${Function} (
+  IN EFI_PEI_FILE_HANDLE  FileHandle,
+  IN EFI_PEI_SERVICES     **PeiServices
+  );
+${END}
+
+EFI_STATUS
+EFIAPI
+ProcessModuleEntryPointList (
+  IN EFI_PEI_FILE_HANDLE  FileHandle,
+  IN EFI_PEI_SERVICES     **PeiServices
+  )
+
+{
+  EFI_STATUS  Status;
+  EFI_STATUS  CombinedStatus;
+
+  CombinedStatus = EFI_LOAD_ERROR;
+${BEGIN}
+  Status = ${Function} (FileHandle, PeiServices);
+  if (!EFI_ERROR (Status) || EFI_ERROR (CombinedStatus)) {
+    CombinedStatus = Status;
+  }
+${END}
+  return CombinedStatus;
+}
+"""
+]
+
+## DXE SMM Entry Point Templates
+gDxeSmmEntryPointString = [
+"""
+EFI_STATUS
+EFIAPI
+ProcessModuleEntryPointList (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+
+{
+  return EFI_SUCCESS;
+}
+""",
+"""
+${BEGIN}
+EFI_STATUS
+${Function} (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  );
+${END}
+
+static BASE_LIBRARY_JUMP_BUFFER  mJumpContext;
+static EFI_STATUS  mDriverEntryPointStatus = EFI_LOAD_ERROR;
+
+VOID
+EFIAPI
+ExitDriver (
+  IN EFI_STATUS  Status
+  )
+{
+  if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {
+    mDriverEntryPointStatus = Status;
+  }
+  LongJump (&mJumpContext, (UINTN)-1);
+  ASSERT (FALSE);
+}
+
+EFI_STATUS
+EFIAPI
+ProcessModuleEntryPointList (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+
+{
+${BEGIN}
+  if (SetJump (&mJumpContext) == 0) {
+    ExitDriver (${Function} (ImageHandle, SystemTable));
+    ASSERT (FALSE);
+  }
+${END}
+
+  return mDriverEntryPointStatus;
+}
+"""
+]
+
+## UEFI Entry Point Templates
+gUefiEntryPointString = [
+"""
+const UINT32 _gUefiDriverRevision = 0;
+
+EFI_STATUS
+EFIAPI
+ProcessModuleEntryPointList (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  return EFI_SUCCESS;
+}
+""",
+"""
+const UINT32 _gUefiDriverRevision = 0;
+${BEGIN}
+EFI_STATUS
+${Function} (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  );
+
+EFI_STATUS
+EFIAPI
+ProcessModuleEntryPointList (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+
+{
+  return ${Function} (ImageHandle, SystemTable);
+}
+${END}
+VOID
+EFIAPI
+ExitDriver (
+  IN EFI_STATUS  Status
+  )
+{
+  if (EFI_ERROR (Status)) {
+    ProcessLibraryDestructorList (gImageHandle, gST);
+  }
+  gBS->Exit (gImageHandle, Status, 0, NULL);
+}
+""",
+"""
+const UINT32 _gUefiDriverRevision = 0;
+
+${BEGIN}
+EFI_STATUS
+${Function} (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  );
+${END}
+
+EFI_STATUS
+EFIAPI
+ProcessModuleEntryPointList (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+
+{
+  ${BEGIN}
+  if (SetJump (&mJumpContext) == 0) {
+    ExitDriver (${Function} (ImageHandle, SystemTable));
+    ASSERT (FALSE);
+  }
+  ${END}
+  return mDriverEntryPointStatus;
+}
+
+static BASE_LIBRARY_JUMP_BUFFER  mJumpContext;
+static EFI_STATUS  mDriverEntryPointStatus = EFI_LOAD_ERROR;
+
+VOID
+EFIAPI
+ExitDriver (
+  IN EFI_STATUS  Status
+  )
+{
+  if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {
+    mDriverEntryPointStatus = Status;
+  }
+  LongJump (&mJumpContext, (UINTN)-1);
+  ASSERT (FALSE);
+}
+"""
+]
+
+## UEFI Unload Image Templates
+gUefiUnloadImageString = [
+"""
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count};
+
+EFI_STATUS
+EFIAPI
+ProcessModuleUnloadList (
+  IN EFI_HANDLE        ImageHandle
+  )
+{
+  return EFI_SUCCESS;
+}
+""",
+"""
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count};
+
+${BEGIN}
+EFI_STATUS
+${Function} (
+  IN EFI_HANDLE        ImageHandle
+  );
+
+EFI_STATUS
+EFIAPI
+ProcessModuleUnloadList (
+  IN EFI_HANDLE        ImageHandle
+  )
+{
+  return ${Function} (ImageHandle);
+}
+${END}
+""",
+"""
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count};
+
+${BEGIN}
+EFI_STATUS
+${Function} (
+  IN EFI_HANDLE        ImageHandle
+  );
+${END}
+
+EFI_STATUS
+EFIAPI
+ProcessModuleUnloadList (
+  IN EFI_HANDLE        ImageHandle
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = EFI_SUCCESS;
+${BEGIN}
+  if (EFI_ERROR (Status)) {
+    ${Function} (ImageHandle);
+  } else {
+    Status = ${Function} (ImageHandle);
+  }
+${END}
+  return Status;
+}
+"""
+]
+
+gLibraryStructorPrototype = {
+'BASE'  : """${BEGIN}
+EFI_STATUS
+EFIAPI
+${Function} (
+  VOID
+  );${END}
+""",
+
+'PEI'   : """${BEGIN}
+EFI_STATUS
+EFIAPI
+${Function} (
+  IN EFI_PEI_FILE_HANDLE       FileHandle,
+  IN EFI_PEI_SERVICES          **PeiServices
+  );${END}
+""",
+
+'DXE'   : """${BEGIN}
+EFI_STATUS
+EFIAPI
+${Function} (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  );${END}
+""",
+}
+
+gLibraryStructorCall = {
+'BASE'  : """${BEGIN}
+  Status = ${Function} ();
+  ASSERT_EFI_ERROR (Status);${END}
+""",
+
+'PEI'   : """${BEGIN}
+  Status = ${Function} (FileHandle, PeiServices);
+  ASSERT_EFI_ERROR (Status);${END}
+""",
+
+'DXE'   : """${BEGIN}
+  Status = ${Function} (ImageHandle, SystemTable);
+  ASSERT_EFI_ERROR (Status);${END}
+""",
+}
+
+## Library Constructor and Destructor Templates
+gLibraryString = {
+'BASE'  :   """
+${BEGIN}${FunctionPrototype}${END}
+
+VOID
+EFIAPI
+ProcessLibrary${Type}List (
+  VOID
+  )
+{
+${BEGIN}  EFI_STATUS  Status;
+${FunctionCall}${END}
+}
+""",
+
+'PEI'   :   """
+${BEGIN}${FunctionPrototype}${END}
+
+VOID
+EFIAPI
+ProcessLibrary${Type}List (
+  IN EFI_PEI_FILE_HANDLE       FileHandle,
+  IN EFI_PEI_SERVICES          **PeiServices
+  )
+{
+${BEGIN}  EFI_STATUS  Status;
+${FunctionCall}${END}
+}
+""",
+
+'DXE'   :   """
+${BEGIN}${FunctionPrototype}${END}
+
+VOID
+EFIAPI
+ProcessLibrary${Type}List (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+${BEGIN}  EFI_STATUS  Status;
+${FunctionCall}${END}
+}
+""",
+}
+
+gSpecificationString = """
+${BEGIN}
+#undef ${SpecificationName}
+#define ${SpecificationName} ${SpecificationValue}
+${END}
+"""
+
+gBasicHeaderFile = "Base.h"
+
+gModuleTypeHeaderFile = {
+    "BASE"              :   [gBasicHeaderFile],
+    "SEC"               :   ["PiPei.h", "Library/DebugLib.h"],
+    "PEI_CORE"          :   ["PiPei.h", "Library/DebugLib.h"],
+    "PEIM"              :   ["PiPei.h", "Library/DebugLib.h"],
+    "DXE_CORE"          :   ["PiDxe.h", "Library/DebugLib.h"],
+    "DXE_DRIVER"        :   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h"],
+    "DXE_SMM_DRIVER"    :   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h"],
+    "DXE_RUNTIME_DRIVER":   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h"],
+    "DXE_SAL_DRIVER"    :   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h"],
+    "UEFI_DRIVER"       :   ["Uefi.h",  "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h"],
+    "UEFI_APPLICATION"  :   ["Uefi.h",  "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h"],
+    "USER_DEFINED"      :   [gBasicHeaderFile]
+}
+
+## Create code for module PCDs
+#
+#   @param      Info        The ModuleAutoGen object
+#   @param      AutoGenC    The TemplateString object for C code
+#   @param      AutoGenH    The TemplateString object for header file
+#   @param      Pcd         The PCD object
+#
+def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
+    TokenSpaceGuidValue = Pcd.TokenSpaceGuidValue   #Info.GuidList[Pcd.TokenSpaceGuidCName]
+    PcdTokenNumber = Info.PlatformInfo.PcdTokenNumber
+    #
+    # Write PCDs
+    #
+    PcdTokenName = '_PCD_TOKEN_' + Pcd.TokenCName
+    if Pcd.Type in gDynamicExPcd:
+        TokenNumber = int(Pcd.TokenValue, 0)
+    else:
+        if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) not in PcdTokenNumber:
+            EdkLogger.error("build", AUTOGEN_ERROR,
+                            "No generated token number for %s.%s\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                            ExtraData="[%s]" % str(Info))
+        TokenNumber = PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName]
+    AutoGenH.Append('#define %s  %d\n' % (PcdTokenName, TokenNumber))
+
+    EdkLogger.debug(EdkLogger.DEBUG_3, "Creating code for " + Pcd.TokenCName + "|" + Pcd.TokenSpaceGuidCName)
+    if Pcd.Type not in gItemTypeStringDatabase:
+        EdkLogger.error("build", AUTOGEN_ERROR,
+                        "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                        ExtraData="[%s]" % str(Info))
+    if Pcd.DatumType not in gDatumSizeStringDatabase:
+        EdkLogger.error("build", AUTOGEN_ERROR,
+                        "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                        ExtraData="[%s]" % str(Info))
+
+    DatumSize = gDatumSizeStringDatabase[Pcd.DatumType]
+    DatumSizeLib = gDatumSizeStringDatabaseLib[Pcd.DatumType]
+    GetModeName = '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName
+    SetModeName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName
+
+    if Pcd.Type in gDynamicExPcd:
+        AutoGenH.Append('#define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+        if Pcd.DatumType == 'VOID*':
+            AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+        else:
+            AutoGenH.Append('#define %s(Value)  LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+    elif Pcd.Type in gDynamicPcd:
+        AutoGenH.Append('#define %s  LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))
+        if Pcd.DatumType == 'VOID*':
+            AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))
+        else:
+            AutoGenH.Append('#define %s(Value)  LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName))
+    else:
+        PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[Pcd.Type] + '_' + Pcd.TokenCName
+        Const = 'const'
+        if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
+            Const = ''
+        Type = ''
+        Array = ''
+        Value = Pcd.DefaultValue
+        if Pcd.DatumType == 'UINT64':
+            if not Value.endswith('ULL'):
+                Value += 'ULL'
+        if Pcd.DatumType == 'VOID*':
+            if Pcd.MaxDatumSize == None or Pcd.MaxDatumSize == '':
+                EdkLogger.error("build", AUTOGEN_ERROR,
+                                "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                                ExtraData="[%s]" % str(Info))
+
+            ArraySize = int(Pcd.MaxDatumSize, 0)
+            if Value[0] == '{':
+                Type = '(VOID *)'
+            else:
+                Unicode = False
+                if Value[0] == 'L':
+                    Unicode = True
+                Value = Value.lstrip('L').strip('"')
+                NewValue = '{'
+                for Index in range(0,len(Value)):
+                    NewValue = NewValue + str(ord(Value[Index]) % 0x100) + ', '
+                    if Unicode:
+                        NewValue = NewValue + str(ord(Value[Index]) / 0x100) + ', '
+                if Unicode:
+                    if ArraySize < (len(Value)*2 + 2):
+                        ArraySize = len(Value)*2 + 2
+                    NewValue = NewValue + '0, '
+                else:
+                    if ArraySize < (len(Value) + 1):
+                        ArraySize = len(Value) + 1
+                Value = NewValue + '0 }'
+            Array = '[%d]' % ArraySize
+
+        PcdValueName = '_PCD_VALUE_' + Pcd.TokenCName
+        if Pcd.DatumType == 'VOID*' and Value[0] == '{':
+            AutoGenH.Append('#define _PCD_PATCHABLE_%s_SIZE %s\n' % (Pcd.TokenCName, Pcd.MaxDatumSize))
+            AutoGenH.Append('#define %s  %s%s\n' %(PcdValueName, Type, PcdVariableName))
+            AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s UINT8 %s%s = %s;\n' % (Const, PcdVariableName, Array, Value))
+            AutoGenH.Append('extern %s UINT8 %s%s;\n' %(Const, PcdVariableName, Array))
+            AutoGenH.Append('#define %s  %s%s\n' %(GetModeName, Type, PcdVariableName))
+        else:
+            AutoGenH.Append('#define %s  %s\n' %(PcdValueName, Value))
+            AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s %s = %s;\n' %(Const, Pcd.DatumType, PcdVariableName, PcdValueName))
+            AutoGenH.Append('extern %s  %s  %s%s;\n' % (Const, Pcd.DatumType, PcdVariableName, Array))
+            AutoGenH.Append('#define %s  %s%s\n' % (GetModeName, Type, PcdVariableName))
+
+        if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
+            if Pcd.DatumType == 'VOID*':
+                AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtr(_gPcd_BinaryPatch_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeName, Pcd.TokenCName, Pcd.TokenCName))
+            else:
+                AutoGenH.Append('#define %s(Value)  (%s = (Value))\n' % (SetModeName, PcdVariableName))
+        else:
+            AutoGenH.Append('//#define %s  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD\n' % SetModeName)
+
+## Create code for library module PCDs
+#
+#   @param      Info        The ModuleAutoGen object
+#   @param      AutoGenC    The TemplateString object for C code
+#   @param      AutoGenH    The TemplateString object for header file
+#   @param      Pcd         The PCD object
+#
+def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
+    PcdTokenNumber = Info.PlatformInfo.PcdTokenNumber
+    TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName
+    TokenCName  = Pcd.TokenCName
+    TokenSpaceGuidValue = Pcd.TokenSpaceGuidValue   #Info.GuidList[TokenSpaceGuidCName]
+    if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) not in PcdTokenNumber:
+        EdkLogger.error("build", AUTOGEN_ERROR,
+                        "No generated token number for %s|%s\n" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName),
+                        ExtraData="[%s]" % str(Info))
+    TokenNumber = PcdTokenNumber[TokenCName, TokenSpaceGuidCName]
+
+    if Pcd.Type not in gItemTypeStringDatabase:
+        EdkLogger.error("build", AUTOGEN_ERROR,
+                        "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                        ExtraData="[%s]" % str(Info))
+    if Pcd.DatumType not in gDatumSizeStringDatabase:
+        EdkLogger.error("build", AUTOGEN_ERROR,
+                        "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                        ExtraData="[%s]" % str(Info))
+
+    DatumType   = Pcd.DatumType
+    DatumSize   = gDatumSizeStringDatabaseH[DatumType]
+    DatumSizeLib= gDatumSizeStringDatabaseLib[DatumType]
+    GetModeName = '_PCD_GET_MODE_' + DatumSize + '_' + TokenCName
+    SetModeName = '_PCD_SET_MODE_' + DatumSize + '_' + TokenCName
+
+    Type = ''
+    Array = ''
+    if Pcd.DatumType == 'VOID*':
+        Type = '(VOID *)'
+        Array = '[]'
+
+    AutoGenH.Append('#define _PCD_TOKEN_%s  %d\n' % (TokenCName, TokenNumber))
+
+    PcdItemType = Pcd.Type
+    #if PcdItemType in gDynamicPcd:
+    #    PcdItemType = TAB_PCDS_FIXED_AT_BUILD
+    #    if (TokenCName, TokenSpaceGuidCName) in Info.PlatformInfo.Platform.Pcds:
+    #        PcdItemType  = Info.PlatformInfo.Platform.Pcds[TokenCName, TokenSpaceGuidCName].Type
+    if PcdItemType in gDynamicExPcd:
+        PcdTokenName = '_PCD_TOKEN_' + TokenCName
+        AutoGenH.Append('#define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, TokenSpaceGuidCName, PcdTokenName))
+        if DatumType == 'VOID*':
+            AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName,DatumSizeLib, TokenSpaceGuidCName, PcdTokenName))
+        else:
+            AutoGenH.Append('#define %s(Value)  LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, TokenSpaceGuidCName, PcdTokenName))
+    if PcdItemType in gDynamicPcd:
+        PcdTokenName = '_PCD_TOKEN_' + TokenCName
+        AutoGenH.Append('#define %s  LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))
+        if DatumType == 'VOID*':
+            AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))
+        else:
+            AutoGenH.Append('#define %s(Value)  LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName))
+    if PcdItemType == TAB_PCDS_PATCHABLE_IN_MODULE:
+        PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[TAB_PCDS_PATCHABLE_IN_MODULE] + '_' + TokenCName
+        AutoGenH.Append('extern %s _gPcd_BinaryPatch_%s%s;\n' %(DatumType, TokenCName, Array) )
+        AutoGenH.Append('#define %s  %s_gPcd_BinaryPatch_%s\n' %(GetModeName, Type, TokenCName))
+        AutoGenH.Append('#define %s(Value)  (%s = (Value))\n' % (SetModeName, PcdVariableName))
+    if PcdItemType == TAB_PCDS_FIXED_AT_BUILD or PcdItemType == TAB_PCDS_FEATURE_FLAG:
+        AutoGenH.Append('extern const %s _gPcd_FixedAtBuild_%s%s;\n' %(DatumType, TokenCName, Array))
+        #AutoGenH.Append('#define _PCD_VALUE_%s  _gPcd_FixedAtBuild_%s\n' %(TokenCName, TokenCName))
+        AutoGenH.Append('#define %s  %s_gPcd_FixedAtBuild_%s\n' %(GetModeName, Type, TokenCName))
+        AutoGenH.Append('//#define %s  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD\n' % SetModeName)
+
+## Create code for PCD database in DXE or PEI phase
+#
+#   @param      Platform    The platform object
+#   @retval     tuple       Two TemplateString objects for C code and header file,
+#                           respectively
+#
+def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
+    AutoGenC = TemplateString()
+    AutoGenH = TemplateString()
+
+    Dict = {
+        'PHASE'                         : Phase,
+        'GUID_TABLE_SIZE'               : '1',
+        'STRING_TABLE_SIZE'             : '1',
+        'SKUID_TABLE_SIZE'              : '1',
+        'LOCAL_TOKEN_NUMBER_TABLE_SIZE' : '1',
+        'LOCAL_TOKEN_NUMBER'            : '0',
+        'EXMAPPING_TABLE_SIZE'          : '1',
+        'EX_TOKEN_NUMBER'               : '0',
+        'SIZE_TABLE_SIZE'               : '2',
+        'GUID_TABLE_EMPTY'              : 'TRUE',
+        'STRING_TABLE_EMPTY'            : 'TRUE',
+        'SKUID_TABLE_EMPTY'             : 'TRUE',
+        'DATABASE_EMPTY'                : 'TRUE',
+        'EXMAP_TABLE_EMPTY'             : 'TRUE',
+        'PCD_DATABASE_UNINIT_EMPTY'     : '  UINT8  dummy; /* PCD_DATABASE_UNINIT is emptry */',
+        'SYSTEM_SKU_ID'                 : '  SKU_ID             SystemSkuId;',
+        'SYSTEM_SKU_ID_VALUE'           : '0'
+    }
+
+    for DatumType in ['UINT64','UINT32','UINT16','UINT8','BOOLEAN']:
+        Dict['VARDEF_CNAME_' + DatumType] = []
+        Dict['VARDEF_GUID_' + DatumType]  = []
+        Dict['VARDEF_SKUID_' + DatumType] = []
+        Dict['VARDEF_VALUE_' + DatumType] = []
+        for Init in ['INIT','UNINIT']:
+            Dict[Init+'_CNAME_DECL_' + DatumType]   = []
+            Dict[Init+'_GUID_DECL_' + DatumType]    = []
+            Dict[Init+'_NUMSKUS_DECL_' + DatumType] = []
+            Dict[Init+'_VALUE_' + DatumType]        = []
+
+    for Type in ['STRING_HEAD','VPD_HEAD','VARIABLE_HEAD']:
+        Dict[Type + '_CNAME_DECL']   = []
+        Dict[Type + '_GUID_DECL']    = []
+        Dict[Type + '_NUMSKUS_DECL'] = []
+        Dict[Type + '_VALUE'] = []
+
+    Dict['STRING_TABLE_INDEX'] = []
+    Dict['STRING_TABLE_LENGTH']  = []
+    Dict['STRING_TABLE_CNAME'] = []
+    Dict['STRING_TABLE_GUID']  = []
+    Dict['STRING_TABLE_VALUE'] = []
+
+    Dict['SIZE_TABLE_CNAME'] = []
+    Dict['SIZE_TABLE_GUID']  = []
+    Dict['SIZE_TABLE_CURRENT_LENGTH']  = []
+    Dict['SIZE_TABLE_MAXIMUM_LENGTH']  = []
+
+    Dict['EXMAPPING_TABLE_EXTOKEN'] = []
+    Dict['EXMAPPING_TABLE_LOCAL_TOKEN'] = []
+    Dict['EXMAPPING_TABLE_GUID_INDEX'] = []
+
+    Dict['GUID_STRUCTURE'] = []
+
+    Dict['SKUID_VALUE'] = []
+
+    if Phase == 'DXE':
+        Dict['SYSTEM_SKU_ID'] = ''
+        Dict['SYSTEM_SKU_ID_VALUE'] = ''
+
+    StringTableIndex = 0
+    StringTableSize = 0
+    NumberOfLocalTokens = 0
+    NumberOfPeiLocalTokens = 0
+    NumberOfDxeLocalTokens = 0
+    NumberOfExTokens = 0
+    NumberOfSizeItems = 0
+    GuidList = []
+
+    for Pcd in Platform.DynamicPcdList:
+        CName = Pcd.TokenCName
+        TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName
+
+        EdkLogger.debug(EdkLogger.DEBUG_3, "PCD: %s %s (%s : %s)" % (CName, TokenSpaceGuidCName, Pcd.Phase, Phase))
+        if Pcd.DatumType not in gDatumSizeStringDatabase:
+            EdkLogger.error("build", AUTOGEN_ERROR,
+                            "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                            ExtraData="[%s]" % str(Info))
+
+        if Pcd.Phase == 'PEI':
+            NumberOfPeiLocalTokens += 1
+        if Pcd.Phase == 'DXE':
+            NumberOfDxeLocalTokens += 1
+        if Pcd.Phase != Phase:
+            continue
+
+        #
+        # TODO: need GetGuidValue() definition
+        #
+        TokenSpaceGuidStructure = Pcd.TokenSpaceGuidValue
+        TokenSpaceGuid = GuidStructureStringToGuidValueName(TokenSpaceGuidStructure)
+        if Pcd.Type in gDynamicExPcd:
+            if TokenSpaceGuid not in GuidList:
+                GuidList += [TokenSpaceGuid]
+                Dict['GUID_STRUCTURE'].append(TokenSpaceGuidStructure)
+            NumberOfExTokens += 1
+
+        ValueList = []
+        StringHeadOffsetList = []
+        VpdHeadOffsetList = []
+        VariableHeadValueList = []
+        Pcd.InitString = 'UNINIT'
+
+        if Pcd.DatumType == 'VOID*':
+            Pcd.TokenTypeList = ['PCD_DATUM_TYPE_POINTER']
+        elif Pcd.DatumType == 'BOOLEAN':
+            Pcd.TokenTypeList = ['PCD_DATUM_TYPE_UINT8']
+        else:
+            Pcd.TokenTypeList = ['PCD_DATUM_TYPE_' + Pcd.DatumType]
+
+        if len(Pcd.SkuInfoList) > 1:
+            Pcd.TokenTypeList += ['PCD_TYPE_SKU_ENABLED']
+
+        for SkuName in Pcd.SkuInfoList:
+            Sku = Pcd.SkuInfoList[SkuName]
+            SkuId = Sku.SkuId
+            if SkuId == None or SkuId == '':
+                continue
+
+            if SkuId not in Dict['SKUID_VALUE']:
+                Dict['SKUID_VALUE'].append(SkuId)
+
+            SkuIdIndex =   Dict['SKUID_VALUE'].index(SkuId)
+            if len(Sku.VariableName) > 0:
+                Pcd.TokenTypeList += ['PCD_TYPE_HII']
+                Pcd.InitString = 'INIT'
+                VariableNameStructure = '{' + ', '.join(Sku.VariableName.split(" ")) + ', 0x0000}'
+                if VariableNameStructure not in Dict['STRING_TABLE_VALUE']:
+                    Dict['STRING_TABLE_CNAME'].append(CName)
+                    Dict['STRING_TABLE_GUID'].append(TokenSpaceGuid)
+                    if StringTableIndex == 0:
+                        Dict['STRING_TABLE_INDEX'].append('')
+                    else:
+                        Dict['STRING_TABLE_INDEX'].append('_%d' % StringTableIndex)
+
+                    Dict['STRING_TABLE_LENGTH'].append(len(Sku.VariableName) + 1)
+                    Dict['STRING_TABLE_VALUE'].append(VariableNameStructure)
+                    StringTableIndex += 1
+                    StringTableSize += len(Sku.VariableName) + 1
+
+                VariableHeadStringIndex = 0
+                for Index in range(Dict['STRING_TABLE_VALUE'].index(VariableNameStructure)):
+                    VariableHeadStringIndex += Dict['STRING_TABLE_LENGTH'][Index]
+
+                VariableGuidStructure = Sku.VariableGuidValue
+                VariableGuid = GuidStructureStringToGuidValueName(VariableGuidStructure)
+                if VariableGuid not in GuidList:
+                    GuidList += [VariableGuid]
+                    Dict['GUID_STRUCTURE'].append(VariableGuidStructure)
+                VariableHeadGuidIndex = GuidList.index(VariableGuid)
+
+                VariableHeadValueList.append('%d, %d, %s, offsetof(${PHASE}_PCD_DATABASE, Init.%s_%s_VariableDefault_%s)' %
+                                             (VariableHeadGuidIndex, VariableHeadStringIndex, Sku.VariableOffset, CName, TokenSpaceGuid, SkuIdIndex))
+                Dict['VARDEF_CNAME_'+Pcd.DatumType].append(CName)
+                Dict['VARDEF_GUID_'+Pcd.DatumType].append(TokenSpaceGuid)
+                Dict['VARDEF_SKUID_'+Pcd.DatumType].append(SkuIdIndex)
+                Dict['VARDEF_VALUE_'+Pcd.DatumType].append(Sku.HiiDefaultValue)
+            elif Sku.VpdOffset != '':
+                Pcd.TokenTypeList += ['PCD_TYPE_VPD']
+                Pcd.InitString = 'INIT'
+                VpdHeadOffsetList.append(Sku.VpdOffset)
+            else:
+                if Pcd.DatumType == 'VOID*':
+                    Pcd.TokenTypeList += ['PCD_TYPE_STRING']
+                    Pcd.InitString = 'INIT'
+                    if Sku.DefaultValue != '':
+                        NumberOfSizeItems += 1
+                        Dict['STRING_TABLE_CNAME'].append(CName)
+                        Dict['STRING_TABLE_GUID'].append(TokenSpaceGuid)
+
+                        if StringTableIndex == 0:
+                            Dict['STRING_TABLE_INDEX'].append('')
+                        else:
+                            Dict['STRING_TABLE_INDEX'].append('_%d' % StringTableIndex)
+                        if Sku.DefaultValue[0] == 'L':
+                            Size = (len(Sku.DefaultValue) - 3) * 2
+                            Dict['STRING_TABLE_VALUE'].append(Sku.DefaultValue)
+                        elif Sku.DefaultValue[0] == '"':
+                            Size = len(Sku.DefaultValue) - 2
+                            Dict['STRING_TABLE_VALUE'].append(Sku.DefaultValue)
+                        elif Sku.DefaultValue[0] == '{':
+                            Size = len(Sku.DefaultValue.replace(',',' ').split())
+                            Dict['STRING_TABLE_VALUE'].append('{' + Sku.DefaultValue + '}')
+
+                        StringHeadOffsetList.append(str(StringTableSize))
+                        Dict['SIZE_TABLE_CNAME'].append(CName)
+                        Dict['SIZE_TABLE_GUID'].append(TokenSpaceGuid)
+                        Dict['SIZE_TABLE_CURRENT_LENGTH'].append(Size)
+                        Dict['SIZE_TABLE_MAXIMUM_LENGTH'].append(Pcd.MaxDatumSize)
+                        if Pcd.MaxDatumSize != '':
+                            MaxDatumSize = int(Pcd.MaxDatumSize, 0)
+                            if MaxDatumSize > Size:
+                                Size = MaxDatumSize
+                        Dict['STRING_TABLE_LENGTH'].append(Size / 2 + 1)
+                        StringTableIndex += 1
+                        StringTableSize += (Size / 2 + 1)
+                else:
+                    Pcd.TokenTypeList += ['PCD_TYPE_DATA']
+                    if Sku.DefaultValue == 'TRUE':
+                        Pcd.InitString = 'INIT'
+                    else:
+                        try:
+                            if int(Sku.DefaultValue, 0) != 0:
+                                Pcd.InitString = 'INIT'
+                        except:
+                            pass
+                    ValueList.append(Sku.DefaultValue)
+
+        Pcd.TokenTypeList = list(set(Pcd.TokenTypeList))
+
+        if 'PCD_TYPE_HII' in Pcd.TokenTypeList:
+            Dict['VARIABLE_HEAD_CNAME_DECL'].append(CName)
+            Dict['VARIABLE_HEAD_GUID_DECL'].append(TokenSpaceGuid)
+            Dict['VARIABLE_HEAD_NUMSKUS_DECL'].append(len(Pcd.SkuInfoList))
+            Dict['VARIABLE_HEAD_VALUE'].append('{ %s }\n' % ' },\n    { '.join(VariableHeadValueList))
+        if 'PCD_TYPE_VPD' in Pcd.TokenTypeList:
+            Dict['VPD_HEAD_CNAME_DECL'].append(CName)
+            Dict['VPD_HEAD_GUID_DECL'].append(TokenSpaceGuid)
+            Dict['VPD_HEAD_NUMSKUS_DECL'].append(len(Pcd.SkuInfoList))
+            Dict['VPD_HEAD_VALUE'].append('{ %s }' % ' }, { '.join(VpdHeadOffsetList))
+        if 'PCD_TYPE_STRING' in Pcd.TokenTypeList:
+            Dict['STRING_HEAD_CNAME_DECL'].append(CName)
+            Dict['STRING_HEAD_GUID_DECL'].append(TokenSpaceGuid)
+            Dict['STRING_HEAD_NUMSKUS_DECL'].append(len(Pcd.SkuInfoList))
+            Dict['STRING_HEAD_VALUE'].append(', '.join(StringHeadOffsetList))
+        if 'PCD_TYPE_DATA' in Pcd.TokenTypeList:
+            Dict[Pcd.InitString+'_CNAME_DECL_'+Pcd.DatumType].append(CName)
+            Dict[Pcd.InitString+'_GUID_DECL_'+Pcd.DatumType].append(TokenSpaceGuid)
+            Dict[Pcd.InitString+'_NUMSKUS_DECL_'+Pcd.DatumType].append(len(Pcd.SkuInfoList))
+            if Pcd.InitString == 'UNINIT':
+                Dict['PCD_DATABASE_UNINIT_EMPTY'] = ''
+            else:
+                Dict[Pcd.InitString+'_VALUE_'+Pcd.DatumType].append(', '.join(ValueList))
+
+    if Phase == 'PEI':
+        NumberOfLocalTokens = NumberOfPeiLocalTokens
+    if Phase == 'DXE':
+        NumberOfLocalTokens = NumberOfDxeLocalTokens
+
+    Dict['TOKEN_INIT']       = ['' for x in range(NumberOfLocalTokens)]
+    Dict['TOKEN_CNAME']      = ['' for x in range(NumberOfLocalTokens)]
+    Dict['TOKEN_GUID']       = ['' for x in range(NumberOfLocalTokens)]
+    Dict['TOKEN_TYPE']       = ['' for x in range(NumberOfLocalTokens)]
+
+    for Pcd in Platform.DynamicPcdList:
+        CName = Pcd.TokenCName
+        TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName
+        if Pcd.Phase != Phase:
+            continue
+
+        TokenSpaceGuid = GuidStructureStringToGuidValueName(Pcd.TokenSpaceGuidValue) #(Platform.PackageList, TokenSpaceGuidCName))
+        GeneratedTokenNumber = Platform.PcdTokenNumber[CName, TokenSpaceGuidCName] - 1
+        if Phase == 'DXE':
+            GeneratedTokenNumber -= NumberOfPeiLocalTokens
+
+        EdkLogger.debug(EdkLogger.DEBUG_1, "PCD = %s | %s" % (CName, TokenSpaceGuidCName))
+        EdkLogger.debug(EdkLogger.DEBUG_1, "phase = %s" % Phase)
+        EdkLogger.debug(EdkLogger.DEBUG_1, "GeneratedTokenNumber = %s" % str(GeneratedTokenNumber))
+
+        Dict['TOKEN_INIT'][GeneratedTokenNumber] = 'Init'
+        if Pcd.InitString == 'UNINIT':
+            Dict['TOKEN_INIT'][GeneratedTokenNumber] = 'Uninit'
+        Dict['TOKEN_CNAME'][GeneratedTokenNumber] = CName
+        Dict['TOKEN_GUID'][GeneratedTokenNumber] = TokenSpaceGuid
+        Dict['TOKEN_TYPE'][GeneratedTokenNumber] = ' | '.join(Pcd.TokenTypeList)
+        if Pcd.Type in gDynamicExPcd:
+            Dict['EXMAPPING_TABLE_EXTOKEN'].append(Pcd.TokenValue)
+            if Phase == 'DXE':
+                GeneratedTokenNumber += NumberOfPeiLocalTokens
+            Dict['EXMAPPING_TABLE_LOCAL_TOKEN'].append(GeneratedTokenNumber)
+            Dict['EXMAPPING_TABLE_GUID_INDEX'].append(GuidList.index(TokenSpaceGuid))
+
+    if GuidList != []:
+        Dict['GUID_TABLE_EMPTY'] = 'FALSE'
+        Dict['GUID_TABLE_SIZE'] = len(GuidList)
+    else:
+        Dict['GUID_STRUCTURE'] = [GuidStringToGuidStructureString('00000000-0000-0000-0000-000000000000')]
+
+    if StringTableIndex == 0:
+        Dict['STRING_TABLE_INDEX'].append('')
+        Dict['STRING_TABLE_LENGTH'].append(1)
+        Dict['STRING_TABLE_CNAME'].append('')
+        Dict['STRING_TABLE_GUID'].append('')
+        Dict['STRING_TABLE_VALUE'].append('{ 0 }')
+    else:
+        Dict['STRING_TABLE_EMPTY'] = 'FALSE'
+        Dict['STRING_TABLE_SIZE'] = StringTableSize
+
+    if Dict['SIZE_TABLE_CNAME'] == []:
+        Dict['SIZE_TABLE_CNAME'].append('')
+        Dict['SIZE_TABLE_GUID'].append('')
+        Dict['SIZE_TABLE_CURRENT_LENGTH'].append(0)
+        Dict['SIZE_TABLE_MAXIMUM_LENGTH'].append(0)
+
+    if NumberOfLocalTokens != 0:
+        Dict['DATABASE_EMPTY']                = 'FALSE'
+        Dict['LOCAL_TOKEN_NUMBER_TABLE_SIZE'] = NumberOfLocalTokens
+        Dict['LOCAL_TOKEN_NUMBER']            = NumberOfLocalTokens
+
+    if NumberOfExTokens != 0:
+        Dict['EXMAP_TABLE_EMPTY']    = 'FALSE'
+        Dict['EXMAPPING_TABLE_SIZE'] = NumberOfExTokens
+        Dict['EX_TOKEN_NUMBER']      = NumberOfExTokens
+    else:
+        Dict['EXMAPPING_TABLE_EXTOKEN'].append(0)
+        Dict['EXMAPPING_TABLE_LOCAL_TOKEN'].append(0)
+        Dict['EXMAPPING_TABLE_GUID_INDEX'].append(0)
+
+    if NumberOfSizeItems != 0:
+        Dict['SIZE_TABLE_SIZE'] = NumberOfSizeItems * 2
+
+    AutoGenH.Append(gPcdDatabaseAutoGenH, Dict)
+    if NumberOfLocalTokens == 0:
+        AutoGenC.Append(gEmptyPcdDatabaseAutoGenC, Dict)
+    else:
+        AutoGenC.Append(gPcdDatabaseAutoGenC, Dict)
+
+    return AutoGenH, AutoGenC
+
+## Create code for PCD database
+#
+#   @param      Info        The ModuleAutoGen object
+#   @param      AutoGenC    The TemplateString object for C code
+#   @param      AutoGenH    The TemplateString object for header file
+#
+def CreatePcdDatabaseCode (Info, AutoGenC, AutoGenH):
+    if Info.PcdIsDriver == "":
+        return
+    if Info.PcdIsDriver not in gPcdPhaseMap:
+        EdkLogger.error("build", AUTOGEN_ERROR, "Not supported PcdIsDriver type:%s" % Info.PcdIsDriver,
+                        ExtraData="[%s]" % str(Info))
+
+    AutoGenH.Append(gPcdDatabaseCommonAutoGenH)
+    AdditionalAutoGenH, AdditionalAutoGenC = CreatePcdDatabasePhaseSpecificAutoGen (Info.PlatformInfo, 'PEI')
+    AutoGenH.Append(AdditionalAutoGenH.String)
+
+    Phase = gPcdPhaseMap[Info.PcdIsDriver]
+    if Phase == 'PEI':
+        AutoGenC.Append(AdditionalAutoGenC.String)
+
+    if Phase == 'DXE':
+        AdditionalAutoGenH, AdditionalAutoGenC = CreatePcdDatabasePhaseSpecificAutoGen (Info.PlatformInfo, Phase)
+        AutoGenH.Append(AdditionalAutoGenH.String)
+        AutoGenC.Append(AdditionalAutoGenC.String)
+        AutoGenH.Append(gPcdDatabaseEpilogueAutoGenH)
+
+## Create code for library constructor
+#
+#   @param      Info        The ModuleAutoGen object
+#   @param      AutoGenC    The TemplateString object for C code
+#   @param      AutoGenH    The TemplateString object for header file
+#
+def CreateLibraryConstructorCode(Info, AutoGenC, AutoGenH):
+    if Info.IsLibrary:
+        return
+    #
+    # Library Constructors
+    #
+    ConstructorPrototypeString = TemplateString()
+    ConstructorCallingString = TemplateString()
+    for Lib in Info.DependentLibraryList:
+        if len(Lib.ConstructorList) <= 0:
+            continue
+        Dict = {'Function':Lib.ConstructorList}
+        if Lib.ModuleType == 'BASE':
+            ConstructorPrototypeString.Append(gLibraryStructorPrototype['BASE'], Dict)
+            ConstructorCallingString.Append(gLibraryStructorCall['BASE'], Dict)
+        elif Lib.ModuleType in ['PEI_CORE','PEIM']:
+            ConstructorPrototypeString.Append(gLibraryStructorPrototype['PEI'], Dict)
+            ConstructorCallingString.Append(gLibraryStructorCall['PEI'], Dict)
+        elif Lib.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER','DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION']:
+            ConstructorPrototypeString.Append(gLibraryStructorPrototype['DXE'], Dict)
+            ConstructorCallingString.Append(gLibraryStructorCall['DXE'], Dict)
+
+    if str(ConstructorPrototypeString) == '':
+        ConstructorPrototypeList = []
+    else:
+        ConstructorPrototypeList = [str(ConstructorPrototypeString)]
+    if str(ConstructorCallingString) == '':
+        ConstructorCallingList = []
+    else:
+        ConstructorCallingList = [str(ConstructorCallingString)]
+
+    Dict = {
+        'Type'              :   'Constructor',
+        'FunctionPrototype' :   ConstructorPrototypeList,
+        'FunctionCall'      :   ConstructorCallingList
+    }
+    if Info.ModuleType == 'BASE':
+        AutoGenC.Append(gLibraryString['BASE'], Dict)
+    elif Info.ModuleType in ['PEI_CORE','PEIM']:
+        AutoGenC.Append(gLibraryString['PEI'], Dict)
+    elif Info.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER','DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION']:
+        AutoGenC.Append(gLibraryString['DXE'], Dict)
+
+## Create code for library destructor
+#
+#   @param      Info        The ModuleAutoGen object
+#   @param      AutoGenC    The TemplateString object for C code
+#   @param      AutoGenH    The TemplateString object for header file
+#
+def CreateLibraryDestructorCode(Info, AutoGenC, AutoGenH):
+    if Info.IsLibrary:
+        return
+    #
+    # Library Destructors
+    #
+    DestructorPrototypeString = TemplateString()
+    DestructorCallingString = TemplateString()
+    for Index in range(len(Info.DependentLibraryList)-1, -1, -1):
+        Lib = Info.DependentLibraryList[Index]
+        if len(Lib.DestructorList) <= 0:
+            continue
+        Dict = {'Function':Lib.DestructorList}
+        if Lib.ModuleType == 'BASE':
+            DestructorPrototypeString.Append(gLibraryStructorPrototype['BASE'], Dict)
+            DestructorCallingString.Append(gLibraryStructorCall['BASE'], Dict)
+        elif Lib.ModuleType in ['PEI_CORE','PEIM']:
+            DestructorPrototypeString.Append(gLibraryStructorPrototype['PEI'], Dict)
+            DestructorCallingString.Append(gLibraryStructorCall['PEI'], Dict)
+        elif Lib.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER','DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION']:
+            DestructorPrototypeString.Append(gLibraryStructorPrototype['DXE'], Dict)
+            DestructorCallingString.Append(gLibraryStructorCall['DXE'], Dict)
+
+    if str(DestructorPrototypeString) == '':
+        DestructorPrototypeList = []
+    else:
+        DestructorPrototypeList = [str(DestructorPrototypeString)]
+    if str(DestructorCallingString) == '':
+        DestructorCallingList = []
+    else:
+        DestructorCallingList = [str(DestructorCallingString)]
+
+    Dict = {
+        'Type'              :   'Destructor',
+        'FunctionPrototype' :   DestructorPrototypeList,
+        'FunctionCall'      :   DestructorCallingList
+    }
+    if Info.ModuleType == 'BASE':
+        AutoGenC.Append(gLibraryString['BASE'], Dict)
+    elif Info.ModuleType in ['PEI_CORE','PEIM']:
+        AutoGenC.Append(gLibraryString['PEI'], Dict)
+    elif Info.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER','DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION']:
+        AutoGenC.Append(gLibraryString['DXE'], Dict)
+
+
+## Create code for ModuleEntryPoint
+#
+#   @param      Info        The ModuleAutoGen object
+#   @param      AutoGenC    The TemplateString object for C code
+#   @param      AutoGenH    The TemplateString object for header file
+#
+def CreateModuleEntryPointCode(Info, AutoGenC, AutoGenH):
+    if Info.IsLibrary or Info.ModuleType == "USER_DEFINED":
+        return
+    #
+    # Module Entry Points
+    #
+    NumEntryPoints = len(Info.Module.ModuleEntryPointList)
+    Dict = {'Function':Info.Module.ModuleEntryPointList}
+
+    if Info.ModuleType in ['PEI_CORE', 'DXE_CORE']:
+        if NumEntryPoints != 1:
+            EdkLogger.error(
+                "build",
+                AUTOGEN_ERROR,
+                '%s must have exactly one entry point' % Info.ModuleType,
+                File=str(Info),
+                ExtraData= ", ".join(Info.Module.ModuleEntryPointList)
+                )
+    if Info.ModuleType == 'PEI_CORE':
+        AutoGenC.Append(gPeiCoreEntryPointString, Dict)
+    elif Info.ModuleType == 'DXE_CORE':
+        AutoGenC.Append(gDxeCoreEntryPointString, Dict)
+    elif Info.ModuleType == 'PEIM':
+        if NumEntryPoints < 2:
+            AutoGenC.Append(gPeimEntryPointString[NumEntryPoints], Dict)
+        else:
+            AutoGenC.Append(gPeimEntryPointString[2], Dict)
+    elif Info.ModuleType in ['DXE_RUNTIME_DRIVER','DXE_DRIVER','DXE_SMM_DRIVER', 'DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION']:
+        if Info.ModuleType == 'DXE_SMM_DRIVER':
+            if NumEntryPoints == 0:
+                AutoGenC.Append(gDxeSmmEntryPointString[0], Dict)
+            else:
+                AutoGenC.Append(gDxeSmmEntryPointString[1], Dict)
+        else:
+            if NumEntryPoints < 2:
+                AutoGenC.Append(gUefiEntryPointString[NumEntryPoints], Dict)
+            else:
+                AutoGenC.Append(gUefiEntryPointString[2], Dict)
+
+## Create code for ModuleUnloadImage
+#
+#   @param      Info        The ModuleAutoGen object
+#   @param      AutoGenC    The TemplateString object for C code
+#   @param      AutoGenH    The TemplateString object for header file
+#
+def CreateModuleUnloadImageCode(Info, AutoGenC, AutoGenH):
+    if Info.IsLibrary or Info.ModuleType == "USER_DEFINED":
+        return
+    #
+    # Unload Image Handlers
+    #
+    NumUnloadImage = len(Info.Module.ModuleUnloadImageList)
+    Dict = {'Count':NumUnloadImage, 'Function':Info.Module.ModuleUnloadImageList}
+    if NumUnloadImage < 2:
+        AutoGenC.Append(gUefiUnloadImageString[NumUnloadImage], Dict)
+    else:
+        AutoGenC.Append(gUefiUnloadImageString[2], Dict)
+
+## Create code for GUID
+#
+#   @param      Info        The ModuleAutoGen object
+#   @param      AutoGenC    The TemplateString object for C code
+#   @param      AutoGenH    The TemplateString object for header file
+#
+def CreateGuidDefinitionCode(Info, AutoGenC, AutoGenH):
+    if Info.IsLibrary:
+        return
+
+    if Info.ModuleType in ["USER_DEFINED", "BASE"]:
+        GuidType = "GUID"
+    else:
+        GuidType = "EFI_GUID"
+
+    #
+    # GUIDs
+    #
+    for Key in Info.GuidList:
+        AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.GuidList[Key]))
+
+## Create code for protocol
+#
+#   @param      Info        The ModuleAutoGen object
+#   @param      AutoGenC    The TemplateString object for C code
+#   @param      AutoGenH    The TemplateString object for header file
+#
+def CreateProtocolDefinitionCode(Info, AutoGenC, AutoGenH):
+    if Info.IsLibrary:
+        return
+
+    if Info.ModuleType in ["USER_DEFINED", "BASE"]:
+        GuidType = "GUID"
+    else:
+        GuidType = "EFI_GUID"
+
+    #
+    # Protocol GUIDs
+    #
+    for Key in Info.ProtocolList:
+        AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.ProtocolList[Key]))
+
+## Create code for PPI
+#
+#   @param      Info        The ModuleAutoGen object
+#   @param      AutoGenC    The TemplateString object for C code
+#   @param      AutoGenH    The TemplateString object for header file
+#
+def CreatePpiDefinitionCode(Info, AutoGenC, AutoGenH):
+    if Info.IsLibrary:
+        return
+
+    if Info.ModuleType in ["USER_DEFINED", "BASE"]:
+        GuidType = "GUID"
+    else:
+        GuidType = "EFI_GUID"
+
+    #
+    # PPI GUIDs
+    #
+    for Key in Info.PpiList:
+        AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.PpiList[Key]))
+
+## Create code for PCD
+#
+#   @param      Info        The ModuleAutoGen object
+#   @param      AutoGenC    The TemplateString object for C code
+#   @param      AutoGenH    The TemplateString object for header file
+#
+def CreatePcdCode(Info, AutoGenC, AutoGenH):
+    if Info.IsLibrary:
+        for Pcd in Info.PcdList:
+            CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd)
+    else:
+        for Pcd in Info.PcdList:
+            CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd)
+    CreatePcdDatabaseCode(Info, AutoGenC, AutoGenH)
+
+## Create code for unicode string definition
+#
+#   @param      Info        The ModuleAutoGen object
+#   @param      AutoGenC    The TemplateString object for C code
+#   @param      AutoGenH    The TemplateString object for header file
+#
+def CreateUnicodeStringCode(Info, AutoGenC, AutoGenH):
+    if len(Info.UnicodeFileList) == 0:
+        return
+
+    WorkingDir = os.getcwd()
+    os.chdir(Info.WorkspaceDir)
+
+    #IncList = [os.path.join(Info.WorkspaceDir, Inc) for Inc in Info.IncludePathList]
+    IncList = [Info.SourceDir]
+    SrcList = [F[0] for F in Info.SourceFileList]
+    Header, Code = GetStringFiles(Info.UnicodeFileList, SrcList, IncList, ['.uni'], Info.Name)
+    AutoGenC.Append("\n//\n//Unicode String Pack Definition\n//\n")
+    AutoGenC.Append(Code)
+    AutoGenC.Append("\n")
+    AutoGenH.Append("\n//\n//Unicode String ID\n//\n")
+    AutoGenH.Append(Header)
+    AutoGenH.Append("\n#define STRING_ARRAY_NAME %sStrings\n" % Info.Name)
+    os.chdir(WorkingDir)
+
+## Create common code
+#
+#   @param      Info        The ModuleAutoGen object
+#   @param      AutoGenC    The TemplateString object for C code
+#   @param      AutoGenH    The TemplateString object for header file
+#
+def CreateHeaderCode(Info, AutoGenC, AutoGenH):
+    # file header
+    AutoGenH.Append(gAutoGenHeaderString,   {'FileName':'AutoGen.h'})
+    # header file Prologue
+    AutoGenH.Append(gAutoGenHPrologueString,{'Guid':Info.Guid.replace('-','_')})
+    if Info.AutoGenVersion >= 0x00010005:
+        # specification macros
+        AutoGenH.Append(gSpecificationString,   {'SpecificationName':Info.Macro.keys(),
+                                                 'SpecificationValue':Info.Macro.values()})
+        # header files includes
+        AutoGenH.Append("#include <%s>\n\n" % gBasicHeaderFile)
+        AutoGenH.Append('\nextern GUID  gEfiCallerIdGuid;\n\n')
+
+        if Info.IsLibrary:
+            return
+
+        AutoGenH.Append("#define EFI_CALLER_ID_GUID \\\n  %s\n" % GuidStringToGuidStructureString(Info.Guid))
+
+    if Info.IsLibrary:
+        return
+    # C file header
+    AutoGenC.Append(gAutoGenHeaderString, {'FileName':'AutoGen.c'})
+    if Info.AutoGenVersion >= 0x00010005:
+        # C file header files includes
+        if Info.ModuleType in gModuleTypeHeaderFile:
+            for Inc in gModuleTypeHeaderFile[Info.ModuleType]:
+                AutoGenC.Append("#include <%s>\n" % Inc)
+        else:
+            AutoGenC.Append("#include <%s>\n" % gBasicHeaderFile)
+
+        #
+        # Publish the CallerId Guid
+        #
+        AutoGenC.Append('\nGLOBAL_REMOVE_IF_UNREFERENCED GUID gEfiCallerIdGuid = %s;\n' % GuidStringToGuidStructureString(Info.Guid))
+    else:
+        # R8 modules my have nothing in the AutoGen.c. So it needs following line
+        AutoGenC.Append('\nextern int __make_me_compile_correctly;\n\n')
+
+
+## Create common code for header file
+#
+#   @param      Info        The ModuleAutoGen object
+#   @param      AutoGenC    The TemplateString object for C code
+#   @param      AutoGenH    The TemplateString object for header file
+#
+def CreateFooterCode(Info, AutoGenC, AutoGenH):
+    AutoGenH.Append(gAutoGenHEpilogueString)
+
+## Create code for a module
+#
+#   @param      Info        The ModuleAutoGen object
+#   @param      AutoGenC    The TemplateString object for C code
+#   @param      AutoGenH    The TemplateString object for header file
+#
+def CreateCode(Info, AutoGenC, AutoGenH):
+    CreateHeaderCode(Info, AutoGenC, AutoGenH)
+
+    if Info.AutoGenVersion >= 0x00010005:
+        CreateLibraryConstructorCode(Info, AutoGenC, AutoGenH)
+        CreateLibraryDestructorCode(Info, AutoGenC, AutoGenH)
+        CreateModuleEntryPointCode(Info, AutoGenC, AutoGenH)
+        CreateModuleUnloadImageCode(Info, AutoGenC, AutoGenH)
+        CreateGuidDefinitionCode(Info, AutoGenC, AutoGenH)
+        CreateProtocolDefinitionCode(Info, AutoGenC, AutoGenH)
+        CreatePpiDefinitionCode(Info, AutoGenC, AutoGenH)
+        CreatePcdCode(Info, AutoGenC, AutoGenH)
+    CreateUnicodeStringCode(Info, AutoGenC, AutoGenH)
+
+    CreateFooterCode(Info, AutoGenC, AutoGenH)
+
+## Create the code file
+#
+#   @param      FilePath    The path of code file
+#   @param      Content     The content of code file
+#
+#   @retval     True        If file content is changed or file doesn't exist
+#   @retval     False       If the file exists and the content is not changed
+#
+def Generate(FilePath, Content):
+    return SaveFileOnChange(FilePath, Content)
index 71fba85..d4ddbac 100755 (executable)
@@ -162,7 +162,8 @@ class BuildFile(object):
     #
     def Generate(self, FileType=gMakeType):
         if FileType not in self._FILE_NAME_:
-            EdkLogger.error("build", PARAMETER_INVALID, "Invalid build type [%s]" % FileType)
+            EdkLogger.error("build", PARAMETER_INVALID, "Invalid build type [%s]" % FileType,
+                            ExtraData="[%s]" % str(self._AutoGenObject))
         self._FileType = FileType
         FileContent = TemplateString()
         FileContent.Append(self._TEMPLATE_, self._TemplateDict)
@@ -420,14 +421,15 @@ cleanlib:
     # Compose a dict object containing information used to do replacement in template
     def _CreateTemplateDict(self):
         if self._FileType not in self._SEP_:
-            EdkLogger.error("build", PARAMETER_INVALID, "Invalid Makefile type", ExtraData=self._FileType)
+            EdkLogger.error("build", PARAMETER_INVALID, "Invalid Makefile type [%s]" % self._FileType,
+                            ExtraData="[%s]" % str(self._AutoGenObject))
         Separator = self._SEP_[self._FileType]
 
         # break build if no source files and binary files are found
         if len(self._AutoGenObject.SourceFileList) == 0 and len(self._AutoGenObject.BinaryFileDict) == 0:
             EdkLogger.error("build", AUTOGEN_ERROR, "No files to be built in module [%s, %s, %s]"
                             % (self._AutoGenObject.BuildTarget, self._AutoGenObject.ToolChain, self._AutoGenObject.Arch),
-                            ExtraData=str(self._AutoGenObject))
+                            ExtraData="[%s]" % str(self._AutoGenObject))
         # convert source files and binary files to build target
         if len(self._AutoGenObject.SourceFileList) > 0:
             self.ProcessSourceFileList()
@@ -452,11 +454,19 @@ cleanlib:
             DefaultToolFlag = ["" for p in DefaultToolFlag]
 
         if "CC" not in self.PlatformInfo.ToolChainFamily:
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Tool [CC] is not supported [%s, %s, %s]" % (self._AutoGenObject.BuildTarget,
-                                    self._AutoGenObject.ToolChain, self._AutoGenObject.Arch))
+            EdkLogger.error(
+                "build",
+                AUTOGEN_ERROR,
+                "Tool [CC] is not supported [%s, %s, %s]" \
+                    % (self._AutoGenObject.BuildTarget, self._AutoGenObject.ToolChain, self._AutoGenObject.Arch),
+                ExtraData="[%s]" % str(self._AutoGenObject))
         if  "DLINK" not in self.PlatformInfo.ToolChainFamily:
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Tool [DLINK] is not supported [%s, %s, %s]" % (self._AutoGenObject.BuildTarget,
-                                    self._AutoGenObject.ToolChain, self._AutoGenObject.Arch))
+            EdkLogger.error(
+                "build",
+                AUTOGEN_ERROR,
+                "Tool [DLINK] is not supported [%s, %s, %s]" \
+                    % (self._AutoGenObject.BuildTarget, self._AutoGenObject.ToolChain, self._AutoGenObject.Arch),
+                ExtraData="[%s]" % str(self._AutoGenObject))
 
         if self._AutoGenObject.IsLibrary:
             if "Static-Library-File" in self.DestFileDatabase:
@@ -465,7 +475,8 @@ cleanlib:
             if "Dynamic-Library-File" in self.DestFileDatabase:
                 self.ResultFileList = self.DestFileDatabase["Dynamic-Library-File"]
         if len(self.ResultFileList) == 0:
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Nothing found for build", ExtraData=str(self._AutoGenObject))
+            EdkLogger.error("build", AUTOGEN_ERROR, "Nothing to build",
+                            ExtraData="[%s]" % str(self._AutoGenObject))
 
         SourceFileMacroNameList = []
         SourceFileMacroList = [] # macro name = file list
@@ -565,8 +576,8 @@ cleanlib:
         ExtraDenpendencies = {}
 
         if "CC" not in self.PlatformInfo.ToolChainFamily:
-            EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No CC tool found",
-                            ExtraData=str(self._AutoGenObject.Module))
+            EdkLogger.error("build", AUTOGEN_ERROR, "No CC tool found",
+                            ExtraData="[%s]" % str(self._AutoGenObject))
         Family = self.PlatformInfo.ToolChainFamily["CC"]
         BuildRule = self.PlatformInfo.BuildRule
 
@@ -854,7 +865,7 @@ cleanlib:
                 try:
                     Fd = open(F, 'r')
                 except:
-                    EdkLogger.error("AutoGen", FILE_OPEN_FAILURE, ExtraData=F)
+                    EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=F)
 
                 FileContent = Fd.read()
                 Fd.close()
@@ -1025,14 +1036,15 @@ ${BEGIN}\t-@${create_directory_command}\n${END}\
         try:
             if self._FileType not in self._AutoGenObject.CustomMakefile:
                 EdkLogger.error('build', OPTION_NOT_SUPPORTED, "No custom makefile for %s" % self._FileType,
-                                ExtraData=str(self._AutoGenObject))
+                                ExtraData="[%s]" % str(self._AutoGenObject))
             MakefilePath = os.path.join(
                                     self._AutoGenObject.WorkspaceDir,
                                     self._AutoGenObject.CustomMakefile[self._FileType]
                                     )
             CustomMakefile = open(MakefilePath, 'r').read()
         except:
-            EdkLogger.error('build', FILE_OPEN_FAILURE, ExtraData=self._AutoGenObject.CustomMakefile[self._FileType])
+            EdkLogger.error('build', FILE_OPEN_FAILURE, File=str(self._AutoGenObject),
+                            ExtraData=self._AutoGenObject.CustomMakefile[self._FileType])
 
         MakefileName = self._FILE_NAME_[self._FileType]
         MakefileTemplateDict = {
@@ -1193,7 +1205,8 @@ cleanlib:
 
         PlatformInfo = self._AutoGenObject
         if "MAKE" not in PlatformInfo.ToolPath:
-            EdkLogger.error("GenMake", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!")
+            EdkLogger.error("build", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!",
+                            ExtraData="[%s]" % str(self._AutoGenObject))
 
         self.IntermediateDirectoryList = ["$(BUILD_DIR)"]
         self.ModuleBuildDirectoryList = self.GetModuleBuildDirectoryList()
@@ -1369,7 +1382,8 @@ ${END}\t@cd $(BUILD_DIR)\n
         PlatformInfo = self._AutoGenObject
 
         if "MAKE" not in PlatformInfo.ToolPath:
-            EdkLogger.error("GenMake", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!")
+            EdkLogger.error("build", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!",
+                            ExtraData="[%s]" % str(self._AutoGenObject))
 
         for Arch in PlatformInfo.ArchList:
             self.IntermediateDirectoryList.append(Separator.join(["$(BUILD_DIR)", Arch]))
index 184ff7f..310968a 100644 (file)
@@ -51,8 +51,8 @@ _ErrorLogger = logging.getLogger("tool_error")
 _ErrorFormatter = logging.Formatter("%(message)s")
 
 # String templates for ERROR/WARN/DEBUG log message
-_ErrorMessageTemplate = '\n\n%(tool)s...\n%(file)s(%(line)s): error %(errorcode)04X: %(msg)s\n    %(extra)s'
-_ErrorMessageTemplateWithoutFile = '\n\n%(tool)s...\n : error %(errorcode)04X: %(msg)s\n    %(extra)s'
+_ErrorMessageTemplate = '\n\n%(tool)s...\n%(file)s(%(line)s): error %(errorcode)04X: %(msg)s\n\t%(extra)s'
+_ErrorMessageTemplateWithoutFile = '\n\n%(tool)s...\n : error %(errorcode)04X: %(msg)s\n\t%(extra)s'
 _WarningMessageTemplate = '%(tool)s...\n%(file)s(%(line)s): warning: %(msg)s'
 _WarningMessageTemplateWithoutFile = '%(tool)s: : warning: %(msg)s'
 _DebugMessageTemplate = '%(file)s(%(line)s): debug: %(msg)s'
index 3c614fa..5c78473 100644 (file)
-## @file\r
-# This file is used to parse meta files\r
-#\r
-# Copyright (c) 2008, 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\r
-import time\r
-\r
-import Common.EdkLogger as EdkLogger\r
-from CommonDataClass.DataClass import *\r
-from Common.DataType import *\r
-from Common.String import *\r
-from Common.Misc import Blist\r
-\r
-## Base class of parser\r
-#\r
-#  This class is used for derivation purpose. The specific parser for one kind\r
-# type file must derive this class and implement some public interfaces.\r
-#\r
-#   @param      FilePath        The path of platform description file\r
-#   @param      FileType        The raw data of DSC file\r
-#   @param      Table           Database used to retrieve module/package information\r
-#   @param      Macros          Macros used for replacement in file\r
-#   @param      Owner           Owner ID (for sub-section parsing)\r
-#   @param      From            ID from which the data comes (for !INCLUDE directive)\r
-#\r
-class MetaFileParser(object):\r
-    # data type (file content) for specific file type\r
-    DataType = {}\r
-\r
-    ## Constructor of MetaFileParser\r
-    #\r
-    #  Initialize object of MetaFileParser\r
-    #\r
-    #   @param      FilePath        The path of platform description file\r
-    #   @param      FileType        The raw data of DSC file\r
-    #   @param      Table           Database used to retrieve module/package information\r
-    #   @param      Macros          Macros used for replacement in file\r
-    #   @param      Owner           Owner ID (for sub-section parsing)\r
-    #   @param      From            ID from which the data comes (for !INCLUDE directive)\r
-    #\r
-    def __init__(self, FilePath, FileType, Table, Macros={}, Owner=-1, From=-1):\r
-        self._Table = Table\r
-        self._FileType = FileType\r
-        self._FilePath = FilePath\r
-        self._FileDir = os.path.dirname(self._FilePath)\r
-        self._Macros = Macros\r
-        # for recursive parsing \r
-        self._Owner = Owner\r
-        self._From = From\r
-\r
-        # parsr status for parsing\r
-        self._Content = None\r
-        self._ValueList = ['', '', '', '', '']\r
-        self._Scope = []\r
-        self._LineIndex = 0\r
-        self._CurrentLine = ''\r
-        self._SectionType = MODEL_UNKNOWN\r
-        self._SectionName = ''\r
-        self._InSubsection = False\r
-        self._SubsectionType = MODEL_UNKNOWN\r
-        self._SubsectionName = ''\r
-        self._LastItem = -1\r
-        self._Enabled = 0\r
-        self._Finished = False\r
-\r
-    ## Store the parsed data in table\r
-    def _Store(self, *Args):\r
-        return self._Table.Insert(*Args)\r
-\r
-    ## Virtual method for starting parse\r
-    def Start(self):\r
-        raise NotImplementedError \r
-\r
-    ## Set parsing complete flag in both class and table\r
-    def _Done(self):\r
-        self._Finished = True\r
-        self._Table.SetEndFlag()\r
-\r
-    ## Return the table containg parsed data\r
-    #\r
-    #   If the parse complete flag is not set, this method will try to parse the\r
-    # file before return the table\r
-    # \r
-    def _GetTable(self):\r
-        if not self._Finished:\r
-            self.Start()\r
-        return self._Table\r
-\r
-    ## Get the parse complete flag\r
-    def _GetFinished(self):\r
-        return self._Finished\r
-\r
-    ## Set the complete flag\r
-    def _SetFinished(self, Value):\r
-        self._Finished = Value\r
-\r
-    ## Use [] style to query data in table, just for readability\r
-    # \r
-    #   DataInfo = [data_type, scope1(arch), scope2(platform,moduletype)]\r
-    # \r
-    def __getitem__(self, DataInfo):\r
-        if type(DataInfo) != type(()):\r
-            DataInfo = (DataInfo,)\r
-        return self.Table.Query(*DataInfo)\r
-\r
-    ## Data parser for the common format in different type of file\r
-    #\r
-    #   The common format in the meatfile is like\r
-    # \r
-    #       xxx1 | xxx2 | xxx3\r
-    # \r
-    def _CommonParser(self):\r
-        TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)\r
-        self._ValueList[0:len(TokenList)] = TokenList\r
-\r
-    ## Data parser for the format in which there's path\r
-    #\r
-    #   Only path can have macro used. So we need to replace them before use.\r
-    # \r
-    def _PathParser(self):\r
-        TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)\r
-        self._ValueList[0:len(TokenList)] = TokenList\r
-        if len(self._Macros) > 0:\r
-            for Index in range(0, len(self._ValueList)):\r
-                Value = self._ValueList[Index]\r
-                if Value == None or Value == '':\r
-                    continue\r
-                self._ValueList[Index] = NormPath(Value, self._Macros)\r
-\r
-    ## Skip unsupported data\r
-    def _Skip(self):\r
-        self._ValueList[0:1] = [self._CurrentLine]\r
-\r
-    ## Section header parser\r
-    #\r
-    #   The section header is always in following format:\r
-    # \r
-    #       [section_name.arch<.platform|module_type>]\r
-    # \r
-    def _SectionHeaderParser(self):\r
-        self._Scope = []\r
-        self._SectionName = ''\r
-        ArchList = set()\r
-        for Item in GetSplitValueList(self._CurrentLine[1:-1], TAB_COMMA_SPLIT):\r
-            ItemList = GetSplitValueList(Item, TAB_SPLIT)\r
-            # different section should not mix in one section\r
-            if self._SectionName != '' and self._SectionName != ItemList[0].upper():\r
-                EdkLogger.error('Parser', FORMAT_INVALID, "Different section names in the same section",\r
-                                File=self._FilePath, Line=self._LineIndex+1, ExtraData=self._CurrentLine)\r
-            self._SectionName = ItemList[0].upper()\r
-            if self._SectionName in self.DataType:\r
-                self._SectionType = self.DataType[self._SectionName]\r
-            else:\r
-                self._SectionType = MODEL_UNKNOWN\r
-            # S1 is always Arch\r
-            if len(ItemList) > 1:\r
-                S1 = ItemList[1].upper()\r
-            else:\r
-                S1 = 'COMMON'\r
-            ArchList.add(S1)\r
-            # S2 may be Platform or ModuleType\r
-            if len(ItemList) > 2:\r
-                S2 = ItemList[2].upper()\r
-            else:\r
-                S2 = 'COMMON'\r
-            self._Scope.append([S1, S2])\r
-\r
-        # 'COMMON' must not be used with specific ARCHs at the same section\r
-        if 'COMMON' in ArchList and len(ArchList) > 1:\r
-            EdkLogger.error('Parser', FORMAT_INVALID, "'common' ARCH must not be used with specific ARCHs",\r
-                            File=self._FilePath, Line=self._LineIndex+1, ExtraData=self._CurrentLine)\r
-\r
-    ## [defines] section parser\r
-    def _DefineParser(self):\r
-        TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
-        self._ValueList[0:len(TokenList)] = TokenList\r
-        if self._ValueList[1] == '':\r
-            EdkLogger.error('Parser', FORMAT_INVALID, "No value specified",\r
-                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)\r
-\r
-    ## DEFINE name=value parser\r
-    def _MacroParser(self):\r
-        TokenList = GetSplitValueList(self._CurrentLine, ' ', 1)\r
-        if len(TokenList) < 2 or TokenList[1] == '':\r
-            EdkLogger.error('Parser', FORMAT_INVALID, "No macro name/value given",\r
-                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)\r
-        TokenList = GetSplitValueList(TokenList[1], TAB_EQUAL_SPLIT, 1)\r
-        if len(TokenList) < 1:\r
-            return\r
-        if self._Macros == None:\r
-            self._Macros = {}\r
-        # keep the macro definition for later use\r
-        self._Macros[TokenList[0]] = TokenList[1]\r
-\r
-    _SectionParser  = {}\r
-    Table           = property(_GetTable)\r
-    Finished        = property(_GetFinished, _SetFinished)\r
-\r
-\r
-## INF file parser class\r
-#\r
-#   @param      FilePath        The path of platform description file\r
-#   @param      FileType        The raw data of DSC file\r
-#   @param      Table           Database used to retrieve module/package information\r
-#   @param      Macros          Macros used for replacement in file\r
-#\r
-class InfParser(MetaFileParser):\r
-    # INF file supported data types (one type per section)\r
-    DataType = {\r
-        TAB_UNKNOWN.upper() : MODEL_UNKNOWN,\r
-        TAB_INF_DEFINES.upper() : MODEL_META_DATA_HEADER,\r
-        TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION,\r
-        TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE,\r
-        TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE,\r
-        TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS,\r
-        TAB_PACKAGES.upper() : MODEL_META_DATA_PACKAGE,\r
-        TAB_NMAKE.upper() : MODEL_META_DATA_NMAKE,\r
-        TAB_INF_FIXED_PCD.upper() : MODEL_PCD_FIXED_AT_BUILD,\r
-        TAB_INF_PATCH_PCD.upper() : MODEL_PCD_PATCHABLE_IN_MODULE,\r
-        TAB_INF_FEATURE_PCD.upper() : MODEL_PCD_FEATURE_FLAG,\r
-        TAB_INF_PCD_EX.upper() : MODEL_PCD_DYNAMIC_EX,\r
-        TAB_INF_PCD.upper() : MODEL_PCD_DYNAMIC,\r
-        TAB_SOURCES.upper() : MODEL_EFI_SOURCE_FILE,\r
-        TAB_GUIDS.upper() : MODEL_EFI_GUID,\r
-        TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL,\r
-        TAB_PPIS.upper() : MODEL_EFI_PPI,\r
-        TAB_DEPEX.upper() : MODEL_EFI_DEPEX,\r
-        TAB_BINARIES.upper() : MODEL_EFI_BINARY_FILE,\r
-        TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION\r
-    }\r
-\r
-    ## Constructor of InfParser\r
-    #\r
-    #  Initialize object of InfParser\r
-    #\r
-    #   @param      FilePath        The path of module description file\r
-    #   @param      FileType        The raw data of DSC file\r
-    #   @param      Table           Database used to retrieve module/package information\r
-    #   @param      Macros          Macros used for replacement in file\r
-    #\r
-    def __init__(self, FilePath, FileType, Table, Macros={}):\r
-        MetaFileParser.__init__(self, FilePath, FileType, Table, Macros)\r
-\r
-    ## Parser starter\r
-    def Start(self):\r
-        try:\r
-            self._Content = open(self._FilePath, 'r').readlines()\r
-        except:\r
-            EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self._FilePath)\r
-\r
-        # parse the file line by line\r
-        for Index in range(0, len(self._Content)):\r
-            Line = CleanString(self._Content[Index])\r
-            if Line == '':\r
-                continue\r
-            self._CurrentLine = Line\r
-            self._LineIndex = Index\r
-\r
-            # section header\r
-            if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:\r
-                self._SectionHeaderParser()\r
-                continue\r
-            elif Line.upper().startswith('DEFINE '):\r
-                # file private macros\r
-                self._MacroParser()\r
-                continue\r
-\r
-            # section content\r
-            self._ValueList = ['','','']\r
-            # parse current line, result will be put in self._ValueList\r
-            self._SectionParser[self._SectionType](self)\r
-            if self._ValueList == None:\r
-                continue\r
-            # \r
-            # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1, \r
-            # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1\r
-            # \r
-            for Arch, Platform in self._Scope:\r
-                self._Store(self._SectionType,\r
-                            self._ValueList[0],\r
-                            self._ValueList[1],\r
-                            self._ValueList[2],\r
-                            Arch,\r
-                            Platform,\r
-                            self._Owner,\r
-                            self._LineIndex+1,\r
-                            -1,\r
-                            self._LineIndex+1,\r
-                            -1,\r
-                            0\r
-                            )\r
-        self._Done()\r
-\r
-    ## [BuildOptions] section parser\r
-    def _BuildOptionParser(self):\r
-        TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
-        TokenList2 = GetSplitValueList(TokenList[0], ':', 1)\r
-        if len(TokenList2) == 2:\r
-            self._ValueList[0] = TokenList2[0]\r
-            self._ValueList[1] = TokenList2[1]\r
-        else:\r
-            self._ValueList[1] = TokenList[0]\r
-        self._ValueList[2] = ReplaceMacro(TokenList[1], self._Macros)\r
-\r
-    ## [nmake] section parser (R8.x style only)\r
-    def _NmakeParser(self):\r
-        TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
-        self._ValueList[0:len(TokenList)] = TokenList\r
-        # remove self-reference in macro setting\r
-        self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})\r
-\r
-    ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser\r
-    def _PcdParser(self):\r
-        TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)\r
-        self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)\r
-        if len(TokenList) > 1:\r
-            self._ValueList[2] = TokenList[1]\r
-        if self._ValueList[0] == '' or self._ValueList[1] == '':\r
-            EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",\r
-                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)\r
-\r
-    ## [depex] section parser\r
-    def _DepexParser(self):\r
-        self._ValueList[0:1] = [self._CurrentLine]\r
-\r
-    _SectionParser = {\r
-        MODEL_UNKNOWN                   :   MetaFileParser._Skip,\r
-        MODEL_META_DATA_HEADER          :   MetaFileParser._DefineParser,\r
-        MODEL_META_DATA_BUILD_OPTION    :   _BuildOptionParser,\r
-        MODEL_EFI_INCLUDE               :   MetaFileParser._PathParser,     # for R8.x modules\r
-        MODEL_EFI_LIBRARY_INSTANCE      :   MetaFileParser._CommonParser,   # for R8.x modules\r
-        MODEL_EFI_LIBRARY_CLASS         :   MetaFileParser._PathParser,\r
-        MODEL_META_DATA_PACKAGE         :   MetaFileParser._PathParser,\r
-        MODEL_META_DATA_NMAKE           :   _NmakeParser,                   # for R8.x modules\r
-        MODEL_PCD_FIXED_AT_BUILD        :   _PcdParser,\r
-        MODEL_PCD_PATCHABLE_IN_MODULE   :   _PcdParser,\r
-        MODEL_PCD_FEATURE_FLAG          :   _PcdParser,\r
-        MODEL_PCD_DYNAMIC_EX            :   _PcdParser,\r
-        MODEL_PCD_DYNAMIC               :   _PcdParser,\r
-        MODEL_EFI_SOURCE_FILE           :   MetaFileParser._PathParser,\r
-        MODEL_EFI_GUID                  :   MetaFileParser._CommonParser,\r
-        MODEL_EFI_PROTOCOL              :   MetaFileParser._CommonParser,\r
-        MODEL_EFI_PPI                   :   MetaFileParser._CommonParser,\r
-        MODEL_EFI_DEPEX                 :   _DepexParser,\r
-        MODEL_EFI_BINARY_FILE           :   MetaFileParser._PathParser,\r
-        MODEL_META_DATA_USER_EXTENSION  :   MetaFileParser._Skip,\r
-    }\r
-\r
-## DSC file parser class\r
-#\r
-#   @param      FilePath        The path of platform description file\r
-#   @param      FileType        The raw data of DSC file\r
-#   @param      Table           Database used to retrieve module/package information\r
-#   @param      Macros          Macros used for replacement in file\r
-#   @param      Owner           Owner ID (for sub-section parsing)\r
-#   @param      From            ID from which the data comes (for !INCLUDE directive)\r
-#\r
-class DscParser(MetaFileParser):\r
-    # DSC file supported data types (one type per section)\r
-    DataType = {\r
-        TAB_SKUIDS.upper()                          :   MODEL_EFI_SKU_ID,\r
-        TAB_LIBRARIES.upper()                       :   MODEL_EFI_LIBRARY_INSTANCE,\r
-        TAB_LIBRARY_CLASSES.upper()                 :   MODEL_EFI_LIBRARY_CLASS,\r
-        TAB_BUILD_OPTIONS.upper()                   :   MODEL_META_DATA_BUILD_OPTION,\r
-        TAB_PCDS_FIXED_AT_BUILD_NULL.upper()        :   MODEL_PCD_FIXED_AT_BUILD,\r
-        TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper()   :   MODEL_PCD_PATCHABLE_IN_MODULE,\r
-        TAB_PCDS_FEATURE_FLAG_NULL.upper()          :   MODEL_PCD_FEATURE_FLAG,\r
-        TAB_PCDS_DYNAMIC_DEFAULT_NULL.upper()       :   MODEL_PCD_DYNAMIC_DEFAULT,\r
-        TAB_PCDS_DYNAMIC_HII_NULL.upper()           :   MODEL_PCD_DYNAMIC_HII,\r
-        TAB_PCDS_DYNAMIC_VPD_NULL.upper()           :   MODEL_PCD_DYNAMIC_VPD,\r
-        TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL.upper()    :   MODEL_PCD_DYNAMIC_EX_DEFAULT,\r
-        TAB_PCDS_DYNAMIC_EX_HII_NULL.upper()        :   MODEL_PCD_DYNAMIC_EX_HII,\r
-        TAB_PCDS_DYNAMIC_EX_VPD_NULL.upper()        :   MODEL_PCD_DYNAMIC_EX_VPD,\r
-        TAB_COMPONENTS.upper()                      :   MODEL_META_DATA_COMPONENT,\r
-        TAB_DSC_DEFINES.upper()                     :   MODEL_META_DATA_HEADER,\r
-        TAB_INCLUDE.upper()                         :   MODEL_META_DATA_INCLUDE,\r
-        TAB_IF.upper()                              :   MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,\r
-        TAB_IF_DEF.upper()                          :   MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,\r
-        TAB_IF_N_DEF.upper()                        :   MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF,\r
-        TAB_ELSE_IF.upper()                         :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF,\r
-        TAB_ELSE.upper()                            :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE,\r
-        TAB_END_IF.upper()                          :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF,\r
-    }\r
-\r
-    # sections which allow "!include" directive\r
-    _IncludeAllowedSection = [\r
-        TAB_LIBRARIES.upper(), \r
-        TAB_LIBRARY_CLASSES.upper(), \r
-        TAB_SKUIDS.upper(),\r
-        TAB_COMPONENTS.upper(),\r
-        TAB_BUILD_OPTIONS.upper(),\r
-        TAB_PCDS_FIXED_AT_BUILD_NULL.upper(),\r
-        TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper(),\r
-        TAB_PCDS_FEATURE_FLAG_NULL.upper(),\r
-        TAB_PCDS_DYNAMIC_DEFAULT_NULL.upper(),\r
-        TAB_PCDS_DYNAMIC_HII_NULL.upper(),\r
-        TAB_PCDS_DYNAMIC_VPD_NULL.upper(),\r
-        TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL.upper(),\r
-        TAB_PCDS_DYNAMIC_EX_HII_NULL.upper(),\r
-        TAB_PCDS_DYNAMIC_EX_VPD_NULL.upper(),\r
-        ]\r
-\r
-    # operators which can be used in "!if/!ifdef/!ifndef" directives\r
-    _OP_ = {\r
-        "!"     :   lambda a:   not a,\r
-        "!="    :   lambda a,b: a!=b,\r
-        "=="    :   lambda a,b: a==b,\r
-        ">"     :   lambda a,b: a>b,\r
-        "<"     :   lambda a,b: a<b,\r
-        "=>"    :   lambda a,b: a>=b,\r
-        ">="    :   lambda a,b: a>=b,\r
-        "<="    :   lambda a,b: a<=b,\r
-        "=<"    :   lambda a,b: a<=b,\r
-    }\r
-\r
-    ## Constructor of DscParser\r
-    #\r
-    #  Initialize object of DscParser\r
-    #\r
-    #   @param      FilePath        The path of platform description file\r
-    #   @param      FileType        The raw data of DSC file\r
-    #   @param      Table           Database used to retrieve module/package information\r
-    #   @param      Macros          Macros used for replacement in file\r
-    #   @param      Owner           Owner ID (for sub-section parsing)\r
-    #   @param      From            ID from which the data comes (for !INCLUDE directive)\r
-    #\r
-    def __init__(self, FilePath, FileType, Table, Macros={}, Owner=-1, From=-1):\r
-        MetaFileParser.__init__(self, FilePath, FileType, Table, Macros, Owner, From)\r
-        # to store conditional directive evaluation result\r
-        self._Eval = Blist()\r
-\r
-    ## Parser starter\r
-    def Start(self):\r
-        try:\r
-            if self._Content == None:\r
-                self._Content = open(self._FilePath, 'r').readlines()\r
-        except:\r
-            EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self._FilePath)\r
-\r
-        for Index in range(0, len(self._Content)):\r
-            Line = CleanString(self._Content[Index])\r
-            # skip empty line\r
-            if Line == '':\r
-                continue\r
-            self._CurrentLine = Line\r
-            self._LineIndex = Index\r
-\r
-            # section header\r
-            if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:\r
-                self._SectionHeaderParser()\r
-                continue\r
-            # subsection ending\r
-            elif Line[0] == '}':\r
-                self._InSubsection = False\r
-                self._Owner = -1\r
-                continue\r
-            # subsection header\r
-            elif Line[0] == TAB_OPTION_START and Line[-1] == TAB_OPTION_END:\r
-                self._SubsectionHeaderParser()\r
-                continue\r
-            # directive line\r
-            elif Line[0] == '!':\r
-                self._DirectiveParser()\r
-                continue\r
-            # file private macros\r
-            elif Line.upper().startswith('DEFINE '):\r
-                self._MacroParser()\r
-                continue\r
-\r
-            # section content\r
-            if self._InSubsection:\r
-                SectionType = self._SubsectionType\r
-                SectionName = self._SubsectionName\r
-                if self._Owner == -1:\r
-                    self._Owner = self._LastItem\r
-            else:\r
-                SectionType = self._SectionType\r
-                SectionName = self._SectionName\r
-            self._ValueList = ['', '', '']\r
-            self._SectionParser[SectionType](self)\r
-            if self._ValueList == None:\r
-                continue\r
-\r
-            # \r
-            # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1, \r
-            # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1\r
-            # \r
-            for Arch, ModuleType in self._Scope:\r
-                self._LastItem = self._Store(\r
-                    SectionType,\r
-                    self._ValueList[0],\r
-                    self._ValueList[1],\r
-                    self._ValueList[2],\r
-                    Arch,\r
-                    ModuleType,\r
-                    self._Owner,\r
-                    self._From,\r
-                    self._LineIndex+1,\r
-                    -1,\r
-                    self._LineIndex+1,\r
-                    -1,\r
-                    self._Enabled\r
-                    )\r
-        self._Done()\r
-\r
-    ## [defines] section parser\r
-    def _DefineParser(self):\r
-        TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
-        if len(TokenList) < 2:\r
-            EdkLogger.error('Parser', FORMAT_INVALID, "No value specified",\r
-                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)\r
-        # 'FLASH_DEFINITION', 'OUTPUT_DIRECTORY' need special processing\r
-        if TokenList[0] in ['FLASH_DEFINITION', 'OUTPUT_DIRECTORY']:\r
-            TokenList[1] = NormPath(TokenList[1], self._Macros)\r
-        self._ValueList[0:len(TokenList)] = TokenList    \r
-\r
-    ## <subsection_header> parser\r
-    def _SubsectionHeaderParser(self):\r
-        self._SubsectionName = self._CurrentLine[1:-1].upper()\r
-        if self._SubsectionName in self.DataType:\r
-            self._SubsectionType = self.DataType[self._SubsectionName]\r
-        else:\r
-            self._SubsectionType = MODEL_UNKNOWN\r
-\r
-    ## Directive statement parser\r
-    def _DirectiveParser(self):\r
-        self._ValueList = ['','','']\r
-        TokenList = GetSplitValueList(self._CurrentLine, ' ', 1)\r
-        self._ValueList[0:len(TokenList)] = TokenList\r
-        if self._ValueList[1] == '':\r
-            EdkLogger.error("Parser", FORMAT_INVALID, "Missing expression", \r
-                            File=self._FilePath, Line=self._LineIndex+1,\r
-                            ExtraData=self._CurrentLine)\r
-        DirectiveName = self._ValueList[0].upper()\r
-        # keep the directive in database first\r
-        self._LastItem = self._Store(\r
-            self.DataType[DirectiveName],\r
-            self._ValueList[0],\r
-            self._ValueList[1],\r
-            self._ValueList[2],\r
-            'COMMON',\r
-            'COMMON',\r
-            self._Owner,\r
-            self._LineIndex + 1,\r
-            -1,\r
-            self._LineIndex + 1,\r
-            -1,\r
-            0\r
-            )\r
-        # process the directive\r
-        if DirectiveName == "!INCLUDE":\r
-            if not self._SectionName in self._IncludeAllowedSection:\r
-                EdkLogger.error("Parser", FORMAT_INVALID, File=self._FilePath, Line=self._LineIndex+1,\r
-                                ExtraData="'!include' is not allowed under section [%s]" % self._SectionName)\r
-            # the included file must be relative to the parsing file\r
-            IncludedFile = os.path.join(self._FileDir, self._ValueList[1])\r
-            Parser = DscParser(IncludedFile, self._FileType, self._Table, self._Macros, From=self._LastItem)\r
-            # set the parser status with current status\r
-            Parser._SectionName = self._SectionName\r
-            Parser._SectionType = self._SectionType\r
-            Parser._Scope = self._Scope\r
-            Parser._Enabled = self._Enabled\r
-            try:\r
-                Parser.Start()\r
-            except:\r
-                EdkLogger.error("Parser", PARSER_ERROR, File=self._FilePath, Line=self._LineIndex+1,\r
-                                ExtraData="Failed to parse content in file %s" % IncludedFile)\r
-            # update current status with sub-parser's status\r
-            self._SectionName = Parser._SectionName\r
-            self._SectionType = Parser._SectionType\r
-            self._Scope       = Parser._Scope\r
-            self._Enabled     = Parser._Enabled\r
-        else:\r
-            if DirectiveName in ["!IF", "!IFDEF", "!IFNDEF"]:\r
-                # evaluate the expression\r
-                Result = self._Evaluate(self._ValueList[1])\r
-                if DirectiveName == "!IFNDEF":\r
-                    Result = not Result\r
-                self._Eval.append(Result)\r
-            elif DirectiveName in ["!ELSEIF"]:\r
-                # evaluate the expression\r
-                self._Eval[-1] = (not self._Eval[-1]) & self._Evaluate(self._ValueList[1])\r
-            elif DirectiveName in ["!ELSE"]:\r
-                self._Eval[-1] = not self._Eval[-1]\r
-            elif DirectiveName in ["!ENDIF"]:\r
-                if len(self._Eval) > 0:\r
-                    self._Eval.pop()\r
-                else:\r
-                    EdkLogger.error("Parser", FORMAT_INVALID, "!IF..[!ELSE]..!ENDIF doesn't match",\r
-                                    File=self._FilePath, Line=self._LineIndex+1)\r
-            if self._Eval.Result == False:\r
-                self._Enabled = 0 - len(self._Eval)\r
-            else:\r
-                self._Enabled = len(self._Eval)\r
-\r
-    ## Evaludate the value of expression in "if/ifdef/ifndef" directives\r
-    def _Evaluate(self, Expression):\r
-        TokenList = Expression.split()\r
-        TokenNumber = len(TokenList)\r
-        # one operand, guess it's just a macro name\r
-        if TokenNumber == 1:\r
-            return TokenList[0] in self._Macros\r
-        # two operands, suppose it's "!xxx" format\r
-        elif TokenNumber == 2:\r
-            Op = TokenList[0]\r
-            if Op not in self._OP_:\r
-                EdkLogger.error('Parser', FORMAT_INVALID, "Unsupported operator", File=self._FilePath,\r
-                                Line=self._LineIndex+1, ExtraData=Expression)\r
-            if TokenList[1].upper() == 'TRUE':\r
-                Value = True\r
-            else:\r
-                Value = False\r
-            return self._OP_[Op](Value)\r
-        # three operands\r
-        elif TokenNumber == 3:\r
-            Name = TokenList[0]\r
-            if Name not in self._Macros:\r
-                return False\r
-            Value = TokenList[2]\r
-            if Value[0] in ["'", '"']:\r
-                Value = Value[1:-1]\r
-            Op = TokenList[1]\r
-            return self._OP_[Op](self._Macros[Macro], Value)\r
-        else:\r
-            EdkLogger.error('Parser', FORMAT_INVALID, File=self._FilePath, Line=self._LineIndex+1,\r
-                            ExtraData=Expression)\r
-\r
-    ## [BuildOptions] section parser\r
-    def _BuildOptionParser(self):\r
-        TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
-        TokenList2 = GetSplitValueList(TokenList[0], ':', 1)\r
-        if len(TokenList2) == 2:\r
-            self._ValueList[0] = TokenList2[0]\r
-            self._ValueList[1] = TokenList2[1]\r
-        else:\r
-            self._ValueList[1] = TokenList[0]\r
-        self._ValueList[2] = ReplaceMacro(TokenList[1], self._Macros)\r
-\r
-    ## PCD sections parser \r
-    # \r
-    #   [PcdsFixedAtBuild]\r
-    #   [PcdsPatchableInModule]\r
-    #   [PcdsFeatureFlag]\r
-    #   [PcdsDynamicEx\r
-    #   [PcdsDynamicExDefault]\r
-    #   [PcdsDynamicExVpd]\r
-    #   [PcdsDynamicExHii]\r
-    #   [PcdsDynamic]\r
-    #   [PcdsDynamicDefault]\r
-    #   [PcdsDynamicVpd]\r
-    #   [PcdsDynamicHii]\r
-    # \r
-    def _PcdParser(self):\r
-        TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)\r
-        self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)\r
-        self._ValueList[2] = TokenList[1]\r
-        if self._ValueList[0] == '' or self._ValueList[1] == '':\r
-            EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",\r
-                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)\r
-        if self._ValueList[2] == '':\r
-            EdkLogger.error('Parser', FORMAT_INVALID, "No PCD value given",\r
-                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)\r
-\r
-    ## [components] section parser\r
-    def _ComponentParser(self):        \r
-        if self._CurrentLine[-1] == '{':\r
-            self._InSubsection = True\r
-            self._ValueList[0] = self._CurrentLine[0:-1].strip()\r
-        else:\r
-            self._ValueList[0] = self._CurrentLine\r
-        if len(self._Macros) > 0:\r
-            self._ValueList[0] = NormPath(self._ValueList[0], self._Macros)\r
-\r
-    _SectionParser = {\r
-        MODEL_META_DATA_HEADER          :   MetaFileParser._DefineParser,\r
-        MODEL_EFI_SKU_ID                :   MetaFileParser._CommonParser,\r
-        MODEL_EFI_LIBRARY_INSTANCE      :   MetaFileParser._PathParser,\r
-        MODEL_EFI_LIBRARY_CLASS         :   MetaFileParser._PathParser,\r
-        MODEL_PCD_FIXED_AT_BUILD        :   _PcdParser,\r
-        MODEL_PCD_PATCHABLE_IN_MODULE   :   _PcdParser,\r
-        MODEL_PCD_FEATURE_FLAG          :   _PcdParser,\r
-        MODEL_PCD_DYNAMIC_DEFAULT       :   _PcdParser,\r
-        MODEL_PCD_DYNAMIC_HII           :   _PcdParser,\r
-        MODEL_PCD_DYNAMIC_VPD           :   _PcdParser,\r
-        MODEL_PCD_DYNAMIC_EX_DEFAULT    :   _PcdParser,\r
-        MODEL_PCD_DYNAMIC_EX_HII        :   _PcdParser,\r
-        MODEL_PCD_DYNAMIC_EX_VPD        :   _PcdParser,\r
-        MODEL_META_DATA_COMPONENT       :   _ComponentParser,\r
-        MODEL_META_DATA_BUILD_OPTION    :   _BuildOptionParser,\r
-        MODEL_UNKNOWN                   :   MetaFileParser._Skip,\r
-        MODEL_META_DATA_USER_EXTENSION  :   MetaFileParser._Skip,\r
-    }\r
-\r
-## DEC file parser class\r
-#\r
-#   @param      FilePath        The path of platform description file\r
-#   @param      FileType        The raw data of DSC file\r
-#   @param      Table           Database used to retrieve module/package information\r
-#   @param      Macros          Macros used for replacement in file\r
-#\r
-class DecParser(MetaFileParser):\r
-    # DEC file supported data types (one type per section)\r
-    DataType = {\r
-        TAB_DEC_DEFINES.upper()                     :   MODEL_META_DATA_HEADER,\r
-        TAB_INCLUDES.upper()                        :   MODEL_EFI_INCLUDE,\r
-        TAB_LIBRARY_CLASSES.upper()                 :   MODEL_EFI_LIBRARY_CLASS,\r
-        TAB_GUIDS.upper()                           :   MODEL_EFI_GUID,\r
-        TAB_PPIS.upper()                            :   MODEL_EFI_PPI,\r
-        TAB_PROTOCOLS.upper()                       :   MODEL_EFI_PROTOCOL,\r
-        TAB_PCDS_FIXED_AT_BUILD_NULL.upper()        :   MODEL_PCD_FIXED_AT_BUILD,\r
-        TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper()   :   MODEL_PCD_PATCHABLE_IN_MODULE,\r
-        TAB_PCDS_FEATURE_FLAG_NULL.upper()          :   MODEL_PCD_FEATURE_FLAG,\r
-        TAB_PCDS_DYNAMIC_NULL.upper()               :   MODEL_PCD_DYNAMIC,\r
-        TAB_PCDS_DYNAMIC_EX_NULL.upper()            :   MODEL_PCD_DYNAMIC_EX,\r
-    }\r
-\r
-    ## Constructor of DecParser\r
-    #\r
-    #  Initialize object of DecParser\r
-    #\r
-    #   @param      FilePath        The path of platform description file\r
-    #   @param      FileType        The raw data of DSC file\r
-    #   @param      Table           Database used to retrieve module/package information\r
-    #   @param      Macros          Macros used for replacement in file\r
-    #\r
-    def __init__(self, FilePath, FileType, Table, Macro={}):\r
-        MetaFileParser.__init__(self, FilePath, FileType, Table, Macro, -1)\r
-\r
-    ## Parser starter\r
-    def Start(self):\r
-        try:\r
-            if self._Content == None:\r
-                self._Content = open(self._FilePath, 'r').readlines()\r
-        except:\r
-            EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self._FilePath)\r
-\r
-        for Index in range(0, len(self._Content)):\r
-            Line = CleanString(self._Content[Index])\r
-            # skip empty line\r
-            if Line == '':\r
-                continue\r
-            self._CurrentLine = Line\r
-            self._LineIndex = Index\r
-\r
-            # section header\r
-            if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:\r
-                self._SectionHeaderParser()\r
-                continue\r
-            elif Line.startswith('DEFINE '):\r
-                self._MacroParser()\r
-                continue\r
-\r
-            # section content\r
-            self._ValueList = ['','','']\r
-            self._SectionParser[self._SectionType](self)\r
-            if self._ValueList == None:\r
-                continue\r
-\r
-            # \r
-            # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1, \r
-            # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1\r
-            # \r
-            for Arch, ModuleType in self._Scope:\r
-                self._LastItem = self._Store(\r
-                    self._SectionType,\r
-                    self._ValueList[0],\r
-                    self._ValueList[1],\r
-                    self._ValueList[2],\r
-                    Arch,\r
-                    ModuleType,\r
-                    self._Owner,\r
-                    self._LineIndex+1,\r
-                    -1,\r
-                    self._LineIndex+1,\r
-                    -1,\r
-                    0\r
-                    )\r
-        self._Done()\r
-\r
-    ## [guids], [ppis] and [protocols] section parser\r
-    def _GuidParser(self):\r
-        TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
-        if len(TokenList) < 2:\r
-            EdkLogger.error('Parser', FORMAT_INVALID, "No value specified",\r
-                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)\r
-        self._ValueList[0] = TokenList[0]\r
-        self._ValueList[1] = TokenList[1]\r
-\r
-    ## PCD sections parser \r
-    # \r
-    #   [PcdsFixedAtBuild]\r
-    #   [PcdsPatchableInModule]\r
-    #   [PcdsFeatureFlag]\r
-    #   [PcdsDynamicEx\r
-    #   [PcdsDynamic]\r
-    # \r
-    def _PcdParser(self):\r
-        TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)\r
-        self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)\r
-        self._ValueList[2] = TokenList[1]\r
-        if self._ValueList[0] == '' or self._ValueList[1] == '':\r
-            EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",\r
-                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)\r
-        if self._ValueList[2] == '':\r
-            EdkLogger.error('Parser', FORMAT_INVALID, "No PCD Datum information given",\r
-                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)\r
-\r
-    _SectionParser = {\r
-        MODEL_META_DATA_HEADER          :   MetaFileParser._DefineParser,\r
-        MODEL_EFI_INCLUDE               :   MetaFileParser._PathParser,\r
-        MODEL_EFI_LIBRARY_CLASS         :   MetaFileParser._PathParser,\r
-        MODEL_EFI_GUID                  :   _GuidParser,\r
-        MODEL_EFI_PPI                   :   _GuidParser,\r
-        MODEL_EFI_PROTOCOL              :   _GuidParser,\r
-        MODEL_PCD_FIXED_AT_BUILD        :   _PcdParser,\r
-        MODEL_PCD_PATCHABLE_IN_MODULE   :   _PcdParser,\r
-        MODEL_PCD_FEATURE_FLAG          :   _PcdParser,\r
-        MODEL_PCD_DYNAMIC               :   _PcdParser,\r
-        MODEL_PCD_DYNAMIC_EX            :   _PcdParser,\r
-        MODEL_UNKNOWN                   :   MetaFileParser._Skip,\r
-        MODEL_META_DATA_USER_EXTENSION  :   MetaFileParser._Skip,\r
-    }\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
-\r
+## @file
+# This file is used to parse meta files
+#
+# Copyright (c) 2008, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+##
+# Import Modules
+#
+import os
+import time
+
+import Common.EdkLogger as EdkLogger
+from CommonDataClass.DataClass import *
+from Common.DataType import *
+from Common.String import *
+from Common.Misc import Blist
+
+## Base class of parser
+#
+#  This class is used for derivation purpose. The specific parser for one kind
+# type file must derive this class and implement some public interfaces.
+#
+#   @param      FilePath        The path of platform description file
+#   @param      FileType        The raw data of DSC file
+#   @param      Table           Database used to retrieve module/package information
+#   @param      Macros          Macros used for replacement in file
+#   @param      Owner           Owner ID (for sub-section parsing)
+#   @param      From            ID from which the data comes (for !INCLUDE directive)
+#
+class MetaFileParser(object):
+    # data type (file content) for specific file type
+    DataType = {}
+
+    ## Constructor of MetaFileParser
+    #
+    #  Initialize object of MetaFileParser
+    #
+    #   @param      FilePath        The path of platform description file
+    #   @param      FileType        The raw data of DSC file
+    #   @param      Table           Database used to retrieve module/package information
+    #   @param      Macros          Macros used for replacement in file
+    #   @param      Owner           Owner ID (for sub-section parsing)
+    #   @param      From            ID from which the data comes (for !INCLUDE directive)
+    #
+    def __init__(self, FilePath, FileType, Table, Macros=None, Owner=-1, From=-1):
+        self._Table = Table
+        self._FileType = FileType
+        self._FilePath = FilePath
+        self._FileDir = os.path.dirname(self._FilePath)
+        if Macros == None:
+            self._Macros = {}
+        else:
+            self._Macros = Macros
+        # for recursive parsing
+        self._Owner = Owner
+        self._From = From
+
+        # parsr status for parsing
+        self._Content = None
+        self._ValueList = ['', '', '', '', '']
+        self._Scope = []
+        self._LineIndex = 0
+        self._CurrentLine = ''
+        self._SectionType = MODEL_UNKNOWN
+        self._SectionName = ''
+        self._InSubsection = False
+        self._SubsectionType = MODEL_UNKNOWN
+        self._SubsectionName = ''
+        self._LastItem = -1
+        self._Enabled = 0
+        self._Finished = False
+
+    ## Store the parsed data in table
+    def _Store(self, *Args):
+        return self._Table.Insert(*Args)
+
+    ## Virtual method for starting parse
+    def Start(self):
+        raise NotImplementedError
+
+    ## Set parsing complete flag in both class and table
+    def _Done(self):
+        self._Finished = True
+        self._Table.SetEndFlag()
+
+    ## Return the table containg parsed data
+    #
+    #   If the parse complete flag is not set, this method will try to parse the
+    # file before return the table
+    #
+    def _GetTable(self):
+        if not self._Finished:
+            self.Start()
+        return self._Table
+
+    ## Get the parse complete flag
+    def _GetFinished(self):
+        return self._Finished
+
+    ## Set the complete flag
+    def _SetFinished(self, Value):
+        self._Finished = Value
+
+    ## Use [] style to query data in table, just for readability
+    #
+    #   DataInfo = [data_type, scope1(arch), scope2(platform,moduletype)]
+    #
+    def __getitem__(self, DataInfo):
+        if type(DataInfo) != type(()):
+            DataInfo = (DataInfo,)
+        return self.Table.Query(*DataInfo)
+
+    ## Data parser for the common format in different type of file
+    #
+    #   The common format in the meatfile is like
+    #
+    #       xxx1 | xxx2 | xxx3
+    #
+    def _CommonParser(self):
+        TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
+        self._ValueList[0:len(TokenList)] = TokenList
+
+    ## Data parser for the format in which there's path
+    #
+    #   Only path can have macro used. So we need to replace them before use.
+    #
+    def _PathParser(self):
+        TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
+        self._ValueList[0:len(TokenList)] = TokenList
+        if len(self._Macros) > 0:
+            for Index in range(0, len(self._ValueList)):
+                Value = self._ValueList[Index]
+                if Value == None or Value == '':
+                    continue
+                self._ValueList[Index] = NormPath(Value, self._Macros)
+
+    ## Skip unsupported data
+    def _Skip(self):
+        self._ValueList[0:1] = [self._CurrentLine]
+
+    ## Section header parser
+    #
+    #   The section header is always in following format:
+    #
+    #       [section_name.arch<.platform|module_type>]
+    #
+    def _SectionHeaderParser(self):
+        self._Scope = []
+        self._SectionName = ''
+        ArchList = set()
+        for Item in GetSplitValueList(self._CurrentLine[1:-1], TAB_COMMA_SPLIT):
+            if Item == '':
+                continue
+            ItemList = GetSplitValueList(Item, TAB_SPLIT)
+            # different section should not mix in one section
+            if self._SectionName != '' and self._SectionName != ItemList[0].upper():
+                EdkLogger.error('Parser', FORMAT_INVALID, "Different section names in the same section",
+                                File=self._FilePath, Line=self._LineIndex+1, ExtraData=self._CurrentLine)
+            self._SectionName = ItemList[0].upper()
+            if self._SectionName in self.DataType:
+                self._SectionType = self.DataType[self._SectionName]
+            else:
+                self._SectionType = MODEL_UNKNOWN
+                EdkLogger.warn("Parser", "Unrecognized section", File=self._FilePath,
+                                Line=self._LineIndex+1, ExtraData=self._CurrentLine)
+            # S1 is always Arch
+            if len(ItemList) > 1:
+                S1 = ItemList[1].upper()
+            else:
+                S1 = 'COMMON'
+            ArchList.add(S1)
+            # S2 may be Platform or ModuleType
+            if len(ItemList) > 2:
+                S2 = ItemList[2].upper()
+            else:
+                S2 = 'COMMON'
+            self._Scope.append([S1, S2])
+
+        # 'COMMON' must not be used with specific ARCHs at the same section
+        if 'COMMON' in ArchList and len(ArchList) > 1:
+            EdkLogger.error('Parser', FORMAT_INVALID, "'common' ARCH must not be used with specific ARCHs",
+                            File=self._FilePath, Line=self._LineIndex+1, ExtraData=self._CurrentLine)
+
+    ## [defines] section parser
+    def _DefineParser(self):
+        TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
+        self._ValueList[0:len(TokenList)] = TokenList
+        if self._ValueList[1] == '':
+            EdkLogger.error('Parser', FORMAT_INVALID, "No value specified",
+                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)
+
+    ## DEFINE name=value parser
+    def _MacroParser(self):
+        TokenList = GetSplitValueList(self._CurrentLine, ' ', 1)
+        if len(TokenList) < 2 or TokenList[1] == '':
+            EdkLogger.error('Parser', FORMAT_INVALID, "No macro name/value given",
+                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)
+        TokenList = GetSplitValueList(TokenList[1], TAB_EQUAL_SPLIT, 1)
+        if TokenList[0] == '':
+            EdkLogger.error('Parser', FORMAT_INVALID, "No macro name given",
+                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)
+        if len(TokenList) == 1:
+            self._Macros[TokenList[0]] = ''
+        else:
+            # keep the macro definition for later use
+            self._Macros[TokenList[0]] = TokenList[1]
+
+    ## [BuildOptions] section parser
+    def _BuildOptionParser(self):
+        TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
+        TokenList2 = GetSplitValueList(TokenList[0], ':', 1)
+        if len(TokenList2) == 2:
+            self._ValueList[0] = TokenList2[0]  # toolchain family
+            self._ValueList[1] = TokenList2[1]  # keys
+        else:
+            self._ValueList[1] = TokenList[0]
+        if len(TokenList) == 2:                 # value
+            self._ValueList[2] = ReplaceMacro(TokenList[1], self._Macros)
+
+        if self._ValueList[1].count('_') != 4:
+            EdkLogger.error(
+                'Parser',
+                FORMAT_INVALID,
+                "'%s' must be in format of TARGET_TOOLCHAIN_ARCH_TOOL_ATTR" % self._ValueList[1],
+                ExtraData=self._CurrentLine,
+                File=self._FilePath,
+                Line=self._LineIndex+1
+                )
+
+    _SectionParser  = {}
+    Table           = property(_GetTable)
+    Finished        = property(_GetFinished, _SetFinished)
+
+
+## INF file parser class
+#
+#   @param      FilePath        The path of platform description file
+#   @param      FileType        The raw data of DSC file
+#   @param      Table           Database used to retrieve module/package information
+#   @param      Macros          Macros used for replacement in file
+#
+class InfParser(MetaFileParser):
+    # INF file supported data types (one type per section)
+    DataType = {
+        TAB_UNKNOWN.upper() : MODEL_UNKNOWN,
+        TAB_INF_DEFINES.upper() : MODEL_META_DATA_HEADER,
+        TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION,
+        TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE,
+        TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE,
+        TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS,
+        TAB_PACKAGES.upper() : MODEL_META_DATA_PACKAGE,
+        TAB_NMAKE.upper() : MODEL_META_DATA_NMAKE,
+        TAB_INF_FIXED_PCD.upper() : MODEL_PCD_FIXED_AT_BUILD,
+        TAB_INF_PATCH_PCD.upper() : MODEL_PCD_PATCHABLE_IN_MODULE,
+        TAB_INF_FEATURE_PCD.upper() : MODEL_PCD_FEATURE_FLAG,
+        TAB_INF_PCD_EX.upper() : MODEL_PCD_DYNAMIC_EX,
+        TAB_INF_PCD.upper() : MODEL_PCD_DYNAMIC,
+        TAB_SOURCES.upper() : MODEL_EFI_SOURCE_FILE,
+        TAB_GUIDS.upper() : MODEL_EFI_GUID,
+        TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL,
+        TAB_PPIS.upper() : MODEL_EFI_PPI,
+        TAB_DEPEX.upper() : MODEL_EFI_DEPEX,
+        TAB_BINARIES.upper() : MODEL_EFI_BINARY_FILE,
+        TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION
+    }
+
+    ## Constructor of InfParser
+    #
+    #  Initialize object of InfParser
+    #
+    #   @param      FilePath        The path of module description file
+    #   @param      FileType        The raw data of DSC file
+    #   @param      Table           Database used to retrieve module/package information
+    #   @param      Macros          Macros used for replacement in file
+    #
+    def __init__(self, FilePath, FileType, Table, Macros=None):
+        MetaFileParser.__init__(self, FilePath, FileType, Table, Macros)
+
+    ## Parser starter
+    def Start(self):
+        try:
+            self._Content = open(self._FilePath, 'r').readlines()
+        except:
+            EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self._FilePath)
+
+        # parse the file line by line
+        for Index in range(0, len(self._Content)):
+            Line = CleanString(self._Content[Index])
+            if Line == '':
+                continue
+            self._CurrentLine = Line
+            self._LineIndex = Index
+
+            # section header
+            if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:
+                self._SectionHeaderParser()
+                continue
+            elif Line.upper().startswith('DEFINE '):
+                # file private macros
+                self._MacroParser()
+                continue
+
+            # section content
+            self._ValueList = ['','','']
+            # parse current line, result will be put in self._ValueList
+            self._SectionParser[self._SectionType](self)
+            if self._ValueList == None:
+                continue
+            #
+            # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
+            # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
+            #
+            for Arch, Platform in self._Scope:
+                self._Store(self._SectionType,
+                            self._ValueList[0],
+                            self._ValueList[1],
+                            self._ValueList[2],
+                            Arch,
+                            Platform,
+                            self._Owner,
+                            self._LineIndex+1,
+                            -1,
+                            self._LineIndex+1,
+                            -1,
+                            0
+                            )
+        self._Done()
+
+    ## [nmake] section parser (R8.x style only)
+    def _NmakeParser(self):
+        TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
+        self._ValueList[0:len(TokenList)] = TokenList
+        # remove self-reference in macro setting
+        self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
+
+    ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
+    def _PcdParser(self):
+        TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)
+        self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)
+        if len(TokenList) > 1:
+            self._ValueList[2] = TokenList[1]
+        if self._ValueList[0] == '' or self._ValueList[1] == '':
+            EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",
+                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)
+
+    ## [depex] section parser
+    def _DepexParser(self):
+        self._ValueList[0:1] = [self._CurrentLine]
+
+    _SectionParser = {
+        MODEL_UNKNOWN                   :   MetaFileParser._Skip,
+        MODEL_META_DATA_HEADER          :   MetaFileParser._DefineParser,
+        MODEL_META_DATA_BUILD_OPTION    :   MetaFileParser._BuildOptionParser,
+        MODEL_EFI_INCLUDE               :   MetaFileParser._PathParser,     # for R8.x modules
+        MODEL_EFI_LIBRARY_INSTANCE      :   MetaFileParser._CommonParser,   # for R8.x modules
+        MODEL_EFI_LIBRARY_CLASS         :   MetaFileParser._PathParser,
+        MODEL_META_DATA_PACKAGE         :   MetaFileParser._PathParser,
+        MODEL_META_DATA_NMAKE           :   _NmakeParser,                   # for R8.x modules
+        MODEL_PCD_FIXED_AT_BUILD        :   _PcdParser,
+        MODEL_PCD_PATCHABLE_IN_MODULE   :   _PcdParser,
+        MODEL_PCD_FEATURE_FLAG          :   _PcdParser,
+        MODEL_PCD_DYNAMIC_EX            :   _PcdParser,
+        MODEL_PCD_DYNAMIC               :   _PcdParser,
+        MODEL_EFI_SOURCE_FILE           :   MetaFileParser._PathParser,
+        MODEL_EFI_GUID                  :   MetaFileParser._CommonParser,
+        MODEL_EFI_PROTOCOL              :   MetaFileParser._CommonParser,
+        MODEL_EFI_PPI                   :   MetaFileParser._CommonParser,
+        MODEL_EFI_DEPEX                 :   _DepexParser,
+        MODEL_EFI_BINARY_FILE           :   MetaFileParser._PathParser,
+        MODEL_META_DATA_USER_EXTENSION  :   MetaFileParser._Skip,
+    }
+
+## DSC file parser class
+#
+#   @param      FilePath        The path of platform description file
+#   @param      FileType        The raw data of DSC file
+#   @param      Table           Database used to retrieve module/package information
+#   @param      Macros          Macros used for replacement in file
+#   @param      Owner           Owner ID (for sub-section parsing)
+#   @param      From            ID from which the data comes (for !INCLUDE directive)
+#
+class DscParser(MetaFileParser):
+    # DSC file supported data types (one type per section)
+    DataType = {
+        TAB_SKUIDS.upper()                          :   MODEL_EFI_SKU_ID,
+        TAB_LIBRARIES.upper()                       :   MODEL_EFI_LIBRARY_INSTANCE,
+        TAB_LIBRARY_CLASSES.upper()                 :   MODEL_EFI_LIBRARY_CLASS,
+        TAB_BUILD_OPTIONS.upper()                   :   MODEL_META_DATA_BUILD_OPTION,
+        TAB_PCDS_FIXED_AT_BUILD_NULL.upper()        :   MODEL_PCD_FIXED_AT_BUILD,
+        TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper()   :   MODEL_PCD_PATCHABLE_IN_MODULE,
+        TAB_PCDS_FEATURE_FLAG_NULL.upper()          :   MODEL_PCD_FEATURE_FLAG,
+        TAB_PCDS_DYNAMIC_DEFAULT_NULL.upper()       :   MODEL_PCD_DYNAMIC_DEFAULT,
+        TAB_PCDS_DYNAMIC_HII_NULL.upper()           :   MODEL_PCD_DYNAMIC_HII,
+        TAB_PCDS_DYNAMIC_VPD_NULL.upper()           :   MODEL_PCD_DYNAMIC_VPD,
+        TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL.upper()    :   MODEL_PCD_DYNAMIC_EX_DEFAULT,
+        TAB_PCDS_DYNAMIC_EX_HII_NULL.upper()        :   MODEL_PCD_DYNAMIC_EX_HII,
+        TAB_PCDS_DYNAMIC_EX_VPD_NULL.upper()        :   MODEL_PCD_DYNAMIC_EX_VPD,
+        TAB_COMPONENTS.upper()                      :   MODEL_META_DATA_COMPONENT,
+        TAB_DSC_DEFINES.upper()                     :   MODEL_META_DATA_HEADER,
+        TAB_INCLUDE.upper()                         :   MODEL_META_DATA_INCLUDE,
+        TAB_IF.upper()                              :   MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,
+        TAB_IF_DEF.upper()                          :   MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,
+        TAB_IF_N_DEF.upper()                        :   MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF,
+        TAB_ELSE_IF.upper()                         :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF,
+        TAB_ELSE.upper()                            :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE,
+        TAB_END_IF.upper()                          :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF,
+    }
+
+    # sections which allow "!include" directive
+    _IncludeAllowedSection = [
+        TAB_LIBRARIES.upper(),
+        TAB_LIBRARY_CLASSES.upper(),
+        TAB_SKUIDS.upper(),
+        TAB_COMPONENTS.upper(),
+        TAB_BUILD_OPTIONS.upper(),
+        TAB_PCDS_FIXED_AT_BUILD_NULL.upper(),
+        TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper(),
+        TAB_PCDS_FEATURE_FLAG_NULL.upper(),
+        TAB_PCDS_DYNAMIC_DEFAULT_NULL.upper(),
+        TAB_PCDS_DYNAMIC_HII_NULL.upper(),
+        TAB_PCDS_DYNAMIC_VPD_NULL.upper(),
+        TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL.upper(),
+        TAB_PCDS_DYNAMIC_EX_HII_NULL.upper(),
+        TAB_PCDS_DYNAMIC_EX_VPD_NULL.upper(),
+        ]
+
+    # operators which can be used in "!if/!ifdef/!ifndef" directives
+    _OP_ = {
+        "!"     :   lambda a:   not a,
+        "!="    :   lambda a,b: a!=b,
+        "=="    :   lambda a,b: a==b,
+        ">"     :   lambda a,b: a>b,
+        "<"     :   lambda a,b: a<b,
+        "=>"    :   lambda a,b: a>=b,
+        ">="    :   lambda a,b: a>=b,
+        "<="    :   lambda a,b: a<=b,
+        "=<"    :   lambda a,b: a<=b,
+    }
+
+    ## Constructor of DscParser
+    #
+    #  Initialize object of DscParser
+    #
+    #   @param      FilePath        The path of platform description file
+    #   @param      FileType        The raw data of DSC file
+    #   @param      Table           Database used to retrieve module/package information
+    #   @param      Macros          Macros used for replacement in file
+    #   @param      Owner           Owner ID (for sub-section parsing)
+    #   @param      From            ID from which the data comes (for !INCLUDE directive)
+    #
+    def __init__(self, FilePath, FileType, Table, Macros=None, Owner=-1, From=-1):
+        MetaFileParser.__init__(self, FilePath, FileType, Table, Macros, Owner, From)
+        # to store conditional directive evaluation result
+        self._Eval = Blist()
+
+    ## Parser starter
+    def Start(self):
+        try:
+            if self._Content == None:
+                self._Content = open(self._FilePath, 'r').readlines()
+        except:
+            EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self._FilePath)
+
+        for Index in range(0, len(self._Content)):
+            Line = CleanString(self._Content[Index])
+            # skip empty line
+            if Line == '':
+                continue
+            self._CurrentLine = Line
+            self._LineIndex = Index
+
+            # section header
+            if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:
+                self._SectionHeaderParser()
+                continue
+            # subsection ending
+            elif Line[0] == '}':
+                self._InSubsection = False
+                self._SubsectionType = MODEL_UNKNOWN
+                self._SubsectionName = ''
+                self._Owner = -1
+                continue
+            # subsection header
+            elif Line[0] == TAB_OPTION_START and Line[-1] == TAB_OPTION_END:
+                self._SubsectionHeaderParser()
+                continue
+            # directive line
+            elif Line[0] == '!':
+                self._DirectiveParser()
+                continue
+            # file private macros
+            elif Line.upper().startswith('DEFINE '):
+                self._MacroParser()
+                continue
+
+            # section content
+            if self._InSubsection:
+                SectionType = self._SubsectionType
+                SectionName = self._SubsectionName
+                if self._Owner == -1:
+                    self._Owner = self._LastItem
+            else:
+                SectionType = self._SectionType
+                SectionName = self._SectionName
+
+            self._ValueList = ['', '', '']
+            self._SectionParser[SectionType](self)
+            if self._ValueList == None:
+                continue
+
+            #
+            # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
+            # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
+            #
+            for Arch, ModuleType in self._Scope:
+                self._LastItem = self._Store(
+                    SectionType,
+                    self._ValueList[0],
+                    self._ValueList[1],
+                    self._ValueList[2],
+                    Arch,
+                    ModuleType,
+                    self._Owner,
+                    self._From,
+                    self._LineIndex+1,
+                    -1,
+                    self._LineIndex+1,
+                    -1,
+                    self._Enabled
+                    )
+        self._Done()
+
+    ## [defines] section parser
+    def _DefineParser(self):
+        TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
+        if len(TokenList) < 2:
+            EdkLogger.error('Parser', FORMAT_INVALID, "No value specified",
+                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)
+        # 'FLASH_DEFINITION', 'OUTPUT_DIRECTORY' need special processing
+        if TokenList[0] in ['FLASH_DEFINITION', 'OUTPUT_DIRECTORY']:
+            TokenList[1] = NormPath(TokenList[1], self._Macros)
+        self._ValueList[0:len(TokenList)] = TokenList
+
+    ## <subsection_header> parser
+    def _SubsectionHeaderParser(self):
+        self._SubsectionName = self._CurrentLine[1:-1].upper()
+        if self._SubsectionName in self.DataType:
+            self._SubsectionType = self.DataType[self._SubsectionName]
+        else:
+            self._SubsectionType = MODEL_UNKNOWN
+            EdkLogger.warn("Parser", "Unrecognized sub-section", File=self._FilePath,
+                            Line=self._LineIndex+1, ExtraData=self._CurrentLine)
+
+    ## Directive statement parser
+    def _DirectiveParser(self):
+        self._ValueList = ['','','']
+        TokenList = GetSplitValueList(self._CurrentLine, ' ', 1)
+        self._ValueList[0:len(TokenList)] = TokenList
+        DirectiveName = self._ValueList[0].upper()
+        if DirectiveName not in self.DataType:
+            EdkLogger.error("Parser", FORMAT_INVALID, "Unknown directive [%s]" % DirectiveName,
+                            File=self._FilePath, Line=self._LineIndex+1)
+        if DirectiveName in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self._ValueList[1] == '':
+            EdkLogger.error("Parser", FORMAT_INVALID, "Missing expression",
+                            File=self._FilePath, Line=self._LineIndex+1,
+                            ExtraData=self._CurrentLine)
+        # keep the directive in database first
+        self._LastItem = self._Store(
+            self.DataType[DirectiveName],
+            self._ValueList[0],
+            self._ValueList[1],
+            self._ValueList[2],
+            'COMMON',
+            'COMMON',
+            self._Owner,
+            self._From,
+            self._LineIndex + 1,
+            -1,
+            self._LineIndex + 1,
+            -1,
+            0
+            )
+
+        # process the directive
+        if DirectiveName == "!INCLUDE":
+            if not self._SectionName in self._IncludeAllowedSection:
+                EdkLogger.error("Parser", FORMAT_INVALID, File=self._FilePath, Line=self._LineIndex+1,
+                                ExtraData="'!include' is not allowed under section [%s]" % self._SectionName)
+            # the included file must be relative to the parsing file
+            IncludedFile = os.path.join(self._FileDir, self._ValueList[1])
+            Parser = DscParser(IncludedFile, self._FileType, self._Table, self._Macros, From=self._LastItem)
+            # set the parser status with current status
+            Parser._SectionName = self._SectionName
+            Parser._SectionType = self._SectionType
+            Parser._Scope = self._Scope
+            Parser._Enabled = self._Enabled
+            try:
+                Parser.Start()
+            except:
+                EdkLogger.error("Parser", PARSER_ERROR, File=self._FilePath, Line=self._LineIndex+1,
+                                ExtraData="Failed to parse content in file %s" % IncludedFile)
+            # update current status with sub-parser's status
+            self._SectionName = Parser._SectionName
+            self._SectionType = Parser._SectionType
+            self._Scope       = Parser._Scope
+            self._Enabled     = Parser._Enabled
+        else:
+            if DirectiveName in ["!IF", "!IFDEF", "!IFNDEF"]:
+                # evaluate the expression
+                Result = self._Evaluate(self._ValueList[1])
+                if DirectiveName == "!IFNDEF":
+                    Result = not Result
+                self._Eval.append(Result)
+            elif DirectiveName in ["!ELSEIF"]:
+                # evaluate the expression
+                self._Eval[-1] = (not self._Eval[-1]) & self._Evaluate(self._ValueList[1])
+            elif DirectiveName in ["!ELSE"]:
+                self._Eval[-1] = not self._Eval[-1]
+            elif DirectiveName in ["!ENDIF"]:
+                if len(self._Eval) > 0:
+                    self._Eval.pop()
+                else:
+                    EdkLogger.error("Parser", FORMAT_INVALID, "!IF..[!ELSE]..!ENDIF doesn't match",
+                                    File=self._FilePath, Line=self._LineIndex+1)
+            if self._Eval.Result == False:
+                self._Enabled = 0 - len(self._Eval)
+            else:
+                self._Enabled = len(self._Eval)
+
+    ## Evaludate the value of expression in "if/ifdef/ifndef" directives
+    def _Evaluate(self, Expression):
+        TokenList = Expression.split()
+        TokenNumber = len(TokenList)
+        # one operand, guess it's just a macro name
+        if TokenNumber == 1:
+            return TokenList[0] in self._Macros
+        # two operands, suppose it's "!xxx" format
+        elif TokenNumber == 2:
+            Op = TokenList[0]
+            if Op not in self._OP_:
+                EdkLogger.error('Parser', FORMAT_INVALID, "Unsupported operator [%s]" % Op, File=self._FilePath,
+                                Line=self._LineIndex+1, ExtraData=Expression)
+            if TokenList[1].upper() == 'TRUE':
+                Value = True
+            else:
+                Value = False
+            return self._OP_[Op](Value)
+        # three operands
+        elif TokenNumber == 3:
+            Name = TokenList[0]
+            if Name not in self._Macros:
+                return False
+            Value = TokenList[2]
+            if Value[0] in ["'", '"'] and Value[-1] in ["'", '"']:
+                Value = Value[1:-1]
+            Op = TokenList[1]
+            if Op not in self._OP_:
+                EdkLogger.error('Parser', FORMAT_INVALID, "Unsupported operator [%s]" % Op, File=self._FilePath,
+                                Line=self._LineIndex+1, ExtraData=Expression)
+            return self._OP_[Op](self._Macros[Name], Value)
+        else:
+            EdkLogger.error('Parser', FORMAT_INVALID, File=self._FilePath, Line=self._LineIndex+1,
+                            ExtraData=Expression)
+
+    ## PCD sections parser
+    #
+    #   [PcdsFixedAtBuild]
+    #   [PcdsPatchableInModule]
+    #   [PcdsFeatureFlag]
+    #   [PcdsDynamicEx
+    #   [PcdsDynamicExDefault]
+    #   [PcdsDynamicExVpd]
+    #   [PcdsDynamicExHii]
+    #   [PcdsDynamic]
+    #   [PcdsDynamicDefault]
+    #   [PcdsDynamicVpd]
+    #   [PcdsDynamicHii]
+    #
+    def _PcdParser(self):
+        TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)
+        self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)
+        if len(TokenList) == 2:
+            self._ValueList[2] = TokenList[1]
+        if self._ValueList[0] == '' or self._ValueList[1] == '':
+            EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",
+                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)
+        if self._ValueList[2] == '':
+            EdkLogger.error('Parser', FORMAT_INVALID, "No PCD value given",
+                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)
+
+    ## [components] section parser
+    def _ComponentParser(self):
+        if self._CurrentLine[-1] == '{':
+            self._ValueList[0] = self._CurrentLine[0:-1].strip()
+            self._InSubsection = True
+        else:
+            self._ValueList[0] = self._CurrentLine
+        if len(self._Macros) > 0:
+            self._ValueList[0] = NormPath(self._ValueList[0], self._Macros)
+
+    def _LibraryClassParser(self):
+        TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
+        if len(TokenList) < 2:
+            EdkLogger.error('Parser', FORMAT_INVALID, "No library class or instance specified",
+                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)
+        if TokenList[0] == '':
+            EdkLogger.error('Parser', FORMAT_INVALID, "No library class specified",
+                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)
+        if TokenList[1] == '':
+            EdkLogger.error('Parser', FORMAT_INVALID, "No library instance specified",
+                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)
+        self._ValueList[0:len(TokenList)] = TokenList
+        if len(self._Macros) > 0:
+            self._ValueList[1] = NormPath(self._ValueList[1], self._Macros)
+
+    _SectionParser = {
+        MODEL_META_DATA_HEADER          :   MetaFileParser._DefineParser,
+        MODEL_EFI_SKU_ID                :   MetaFileParser._CommonParser,
+        MODEL_EFI_LIBRARY_INSTANCE      :   MetaFileParser._PathParser,
+        MODEL_EFI_LIBRARY_CLASS         :   _LibraryClassParser,
+        MODEL_PCD_FIXED_AT_BUILD        :   _PcdParser,
+        MODEL_PCD_PATCHABLE_IN_MODULE   :   _PcdParser,
+        MODEL_PCD_FEATURE_FLAG          :   _PcdParser,
+        MODEL_PCD_DYNAMIC_DEFAULT       :   _PcdParser,
+        MODEL_PCD_DYNAMIC_HII           :   _PcdParser,
+        MODEL_PCD_DYNAMIC_VPD           :   _PcdParser,
+        MODEL_PCD_DYNAMIC_EX_DEFAULT    :   _PcdParser,
+        MODEL_PCD_DYNAMIC_EX_HII        :   _PcdParser,
+        MODEL_PCD_DYNAMIC_EX_VPD        :   _PcdParser,
+        MODEL_META_DATA_COMPONENT       :   _ComponentParser,
+        MODEL_META_DATA_BUILD_OPTION    :   MetaFileParser._BuildOptionParser,
+        MODEL_UNKNOWN                   :   MetaFileParser._Skip,
+        MODEL_META_DATA_USER_EXTENSION  :   MetaFileParser._Skip,
+    }
+
+## DEC file parser class
+#
+#   @param      FilePath        The path of platform description file
+#   @param      FileType        The raw data of DSC file
+#   @param      Table           Database used to retrieve module/package information
+#   @param      Macros          Macros used for replacement in file
+#
+class DecParser(MetaFileParser):
+    # DEC file supported data types (one type per section)
+    DataType = {
+        TAB_DEC_DEFINES.upper()                     :   MODEL_META_DATA_HEADER,
+        TAB_INCLUDES.upper()                        :   MODEL_EFI_INCLUDE,
+        TAB_LIBRARY_CLASSES.upper()                 :   MODEL_EFI_LIBRARY_CLASS,
+        TAB_GUIDS.upper()                           :   MODEL_EFI_GUID,
+        TAB_PPIS.upper()                            :   MODEL_EFI_PPI,
+        TAB_PROTOCOLS.upper()                       :   MODEL_EFI_PROTOCOL,
+        TAB_PCDS_FIXED_AT_BUILD_NULL.upper()        :   MODEL_PCD_FIXED_AT_BUILD,
+        TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper()   :   MODEL_PCD_PATCHABLE_IN_MODULE,
+        TAB_PCDS_FEATURE_FLAG_NULL.upper()          :   MODEL_PCD_FEATURE_FLAG,
+        TAB_PCDS_DYNAMIC_NULL.upper()               :   MODEL_PCD_DYNAMIC,
+        TAB_PCDS_DYNAMIC_EX_NULL.upper()            :   MODEL_PCD_DYNAMIC_EX,
+    }
+
+    ## Constructor of DecParser
+    #
+    #  Initialize object of DecParser
+    #
+    #   @param      FilePath        The path of platform description file
+    #   @param      FileType        The raw data of DSC file
+    #   @param      Table           Database used to retrieve module/package information
+    #   @param      Macros          Macros used for replacement in file
+    #
+    def __init__(self, FilePath, FileType, Table, Macro=None):
+        MetaFileParser.__init__(self, FilePath, FileType, Table, Macro, -1)
+
+    ## Parser starter
+    def Start(self):
+        try:
+            if self._Content == None:
+                self._Content = open(self._FilePath, 'r').readlines()
+        except:
+            EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self._FilePath)
+
+        for Index in range(0, len(self._Content)):
+            Line = CleanString(self._Content[Index])
+            # skip empty line
+            if Line == '':
+                continue
+            self._CurrentLine = Line
+            self._LineIndex = Index
+
+            # section header
+            if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:
+                self._SectionHeaderParser()
+                continue
+            elif Line.startswith('DEFINE '):
+                self._MacroParser()
+                continue
+
+            # section content
+            self._ValueList = ['','','']
+            self._SectionParser[self._SectionType](self)
+            if self._ValueList == None:
+                continue
+
+            #
+            # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,
+            # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1
+            #
+            for Arch, ModuleType in self._Scope:
+                self._LastItem = self._Store(
+                    self._SectionType,
+                    self._ValueList[0],
+                    self._ValueList[1],
+                    self._ValueList[2],
+                    Arch,
+                    ModuleType,
+                    self._Owner,
+                    self._LineIndex+1,
+                    -1,
+                    self._LineIndex+1,
+                    -1,
+                    0
+                    )
+        self._Done()
+
+    ## [guids], [ppis] and [protocols] section parser
+    def _GuidParser(self):
+        TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
+        if len(TokenList) < 2:
+            EdkLogger.error('Parser', FORMAT_INVALID, "No GUID name or value specified",
+                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)
+        if TokenList[0] == '':
+            EdkLogger.error('Parser', FORMAT_INVALID, "No GUID name specified",
+                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)
+        if TokenList[1] == '':
+            EdkLogger.error('Parser', FORMAT_INVALID, "No GUID value specified",
+                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)
+        self._ValueList[0] = TokenList[0]
+        self._ValueList[1] = TokenList[1]
+
+    ## PCD sections parser
+    #
+    #   [PcdsFixedAtBuild]
+    #   [PcdsPatchableInModule]
+    #   [PcdsFeatureFlag]
+    #   [PcdsDynamicEx
+    #   [PcdsDynamic]
+    #
+    def _PcdParser(self):
+        TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)
+        self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)
+        if self._ValueList[0] == '' or self._ValueList[1] == '':
+            EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",
+                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)
+        if len(TokenList) < 2 or TokenList[1] == '':
+            EdkLogger.error('Parser', FORMAT_INVALID, "No PCD Datum information given",
+                            ExtraData=self._CurrentLine, File=self._FilePath, Line=self._LineIndex+1)
+        self._ValueList[2] = TokenList[1]
+
+    _SectionParser = {
+        MODEL_META_DATA_HEADER          :   MetaFileParser._DefineParser,
+        MODEL_EFI_INCLUDE               :   MetaFileParser._PathParser,
+        MODEL_EFI_LIBRARY_CLASS         :   MetaFileParser._PathParser,
+        MODEL_EFI_GUID                  :   _GuidParser,
+        MODEL_EFI_PPI                   :   _GuidParser,
+        MODEL_EFI_PROTOCOL              :   _GuidParser,
+        MODEL_PCD_FIXED_AT_BUILD        :   _PcdParser,
+        MODEL_PCD_PATCHABLE_IN_MODULE   :   _PcdParser,
+        MODEL_PCD_FEATURE_FLAG          :   _PcdParser,
+        MODEL_PCD_DYNAMIC               :   _PcdParser,
+        MODEL_PCD_DYNAMIC_EX            :   _PcdParser,
+        MODEL_UNKNOWN                   :   MetaFileParser._Skip,
+        MODEL_META_DATA_USER_EXTENSION  :   MetaFileParser._Skip,
+    }
+
+##
+#
+# This acts like the main() function for the script, unless it is 'import'ed into another
+# script.
+#
+if __name__ == '__main__':
+    pass
+
index 5c86604..98663a8 100644 (file)
-## @file\r
-# This file is used to create a database used by build tool\r
-#\r
-# Copyright (c) 2008, 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 sqlite3\r
-import os\r
-import os.path\r
-\r
-import Common.EdkLogger as EdkLogger\r
-from CommonDataClass.DataClass import *\r
-from CommonDataClass.ModuleClass import *\r
-from Common.String import *\r
-from Common.DataType import *\r
-from Common.Misc import *\r
-\r
-from MetaDataTable import *\r
-from MetaFileTable import *\r
-from MetaFileParser import *\r
-from BuildClassObject import *\r
-\r
-## Platform build information from DSC file\r
-#\r
-#  This class is used to retrieve information stored in database and convert them\r
-# into PlatformBuildClassObject form for easier use for AutoGen.\r
-#\r
-class DscBuildData(PlatformBuildClassObject):\r
-    # dict used to convert PCD type in database to string used by build tool\r
-    _PCD_TYPE_STRING_ = {\r
-        MODEL_PCD_FIXED_AT_BUILD        :   "FixedAtBuild",\r
-        MODEL_PCD_PATCHABLE_IN_MODULE   :   "PatchableInModule",\r
-        MODEL_PCD_FEATURE_FLAG          :   "FeatureFlag",\r
-        MODEL_PCD_DYNAMIC               :   "Dynamic",\r
-        MODEL_PCD_DYNAMIC_DEFAULT       :   "Dynamic",\r
-        MODEL_PCD_DYNAMIC_HII           :   "DynamicHii",\r
-        MODEL_PCD_DYNAMIC_VPD           :   "DynamicVpd",\r
-        MODEL_PCD_DYNAMIC_EX            :   "DynamicEx",\r
-        MODEL_PCD_DYNAMIC_EX_DEFAULT    :   "DynamicEx",\r
-        MODEL_PCD_DYNAMIC_EX_HII        :   "DynamicExHii",\r
-        MODEL_PCD_DYNAMIC_EX_VPD        :   "DynamicExVpd",\r
-    }\r
-\r
-    # dict used to convert part of [Defines] to members of DscBuildData directly\r
-    _PROPERTY_ = {\r
-        #\r
-        # Required Fields\r
-        #\r
-        TAB_DSC_DEFINES_PLATFORM_NAME           :   "_PlatformName",\r
-        TAB_DSC_DEFINES_PLATFORM_GUID           :   "_Guid",\r
-        TAB_DSC_DEFINES_PLATFORM_VERSION        :   "_Version",\r
-        TAB_DSC_DEFINES_DSC_SPECIFICATION       :   "_DscSpecification",\r
-        #TAB_DSC_DEFINES_OUTPUT_DIRECTORY        :   "_OutputDirectory",\r
-        #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES :   "_SupArchList",\r
-        #TAB_DSC_DEFINES_BUILD_TARGETS           :   "_BuildTargets",\r
-        #TAB_DSC_DEFINES_SKUID_IDENTIFIER        :   "_SkuName",\r
-        #TAB_DSC_DEFINES_FLASH_DEFINITION        :   "_FlashDefinition",\r
-        TAB_DSC_DEFINES_BUILD_NUMBER            :   "_BuildNumber",\r
-        TAB_DSC_DEFINES_MAKEFILE_NAME           :   "_MakefileName",\r
-        TAB_DSC_DEFINES_BS_BASE_ADDRESS         :   "_BsBaseAddress",\r
-        TAB_DSC_DEFINES_RT_BASE_ADDRESS         :   "_RtBaseAddress",\r
-    }\r
-\r
-    # used to compose dummy library class name for those forced library instances\r
-    _NullLibraryNumber = 0\r
-\r
-    ## Constructor of DscBuildData\r
-    #\r
-    #  Initialize object of DscBuildData\r
-    #\r
-    #   @param      FilePath        The path of platform description file\r
-    #   @param      RawData         The raw data of DSC file\r
-    #   @param      BuildDataBase   Database used to retrieve module/package information\r
-    #   @param      Arch            The target architecture\r
-    #   @param      Platform        (not used for DscBuildData)\r
-    #   @param      Macros          Macros used for replacement in DSC file\r
-    #\r
-    def __init__(self, FilePath, RawData, BuildDataBase, Arch='COMMON', Platform='DUMMY', Macros={}):\r
-        self.DescFilePath = FilePath\r
-        self._RawData = RawData\r
-        self._Bdb = BuildDataBase\r
-        self._Arch = Arch\r
-        self._Macros = Macros\r
-        self._Clear()\r
-\r
-    ## XXX[key] = value\r
-    def __setitem__(self, key, value):\r
-        self.__dict__[self._PROPERTY_[key]] = value\r
-\r
-    ## value = XXX[key]\r
-    def __getitem__(self, key):\r
-        return self.__dict__[self._PROPERTY_[key]]\r
-\r
-    ## "in" test support\r
-    def __contains__(self, key):\r
-        return key in self._PROPERTY_\r
-\r
-    ## Set all internal used members of DscBuildData to None\r
-    def _Clear(self):\r
-        self._Header            = None\r
-        self._PlatformName      = None\r
-        self._Guid              = None\r
-        self._Version           = None\r
-        self._DscSpecification  = None\r
-        self._OutputDirectory   = None\r
-        self._SupArchList       = None\r
-        self._BuildTargets      = None\r
-        self._SkuName           = None\r
-        self._FlashDefinition   = None\r
-        self._BuildNumber       = None\r
-        self._MakefileName      = None\r
-        self._BsBaseAddress     = None\r
-        self._RtBaseAddress     = None\r
-        self._SkuIds            = None\r
-        self._Modules           = None\r
-        self._LibraryInstances  = None\r
-        self._LibraryClasses    = None\r
-        self._Pcds              = None\r
-        self._BuildOptions      = None\r
-\r
-    ## Get architecture\r
-    def _GetArch(self):\r
-        return self._Arch\r
-\r
-    ## Set architecture\r
-    #\r
-    #   Changing the default ARCH to another may affect all other information\r
-    # because all information in a platform may be ARCH-related. That's\r
-    # why we need to clear all internal used members, in order to cause all\r
-    # information to be re-retrieved.\r
-    #\r
-    #   @param  Value   The value of ARCH\r
-    #\r
-    def _SetArch(self, Value):\r
-        if self._Arch == Value:\r
-            return\r
-        self._Arch = Value\r
-        self._Clear()\r
-\r
-    ## Retrieve all information in [Defines] section\r
-    #\r
-    #   (Retriving all [Defines] information in one-shot is just to save time.)\r
-    #\r
-    def _GetHeaderInfo(self):\r
-        RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]\r
-        for Record in RecordList:\r
-            Name = Record[0]\r
-            # items defined _PROPERTY_ don't need additional processing\r
-            if Name in self:\r
-                self[Name] = Record[1]\r
-            # some special items in [Defines] section need special treatment\r
-            elif Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:\r
-                self._OutputDirectory = NormPath(Record[1], self._Macros)\r
-            elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION:\r
-                self._FlashDefinition = NormPath(Record[1], self._Macros)\r
-            elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:\r
-                self._SupArchList = GetSplitValueList(Record[1], TAB_VALUE_SPLIT)\r
-            elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:\r
-                self._BuildTargets = GetSplitValueList(Record[1])\r
-            elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER:\r
-                if self._SkuName == None:\r
-                    self._SkuName = Record[1]\r
-        # set _Header to non-None in order to avoid database re-querying\r
-        self._Header = 'DUMMY'\r
-\r
-    ## Retrieve platform name\r
-    def _GetPlatformName(self):\r
-        if self._PlatformName == None:\r
-            if self._Header == None:\r
-                self._GetHeaderInfo()\r
-            if self._PlatformName == None:\r
-                EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_NAME", File=self.DescFilePath)\r
-        return self._PlatformName\r
-\r
-    ## Retrieve file guid\r
-    def _GetFileGuid(self):\r
-        if self._Guid == None:\r
-            if self._Header == None:\r
-                self._GetHeaderInfo()\r
-            if self._Guid == None:\r
-                EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No FILE_GUID", File=self.DescFilePath)\r
-        return self._Guid\r
-\r
-    ## Retrieve platform version\r
-    def _GetVersion(self):\r
-        if self._Version == None:\r
-            if self._Header == None:\r
-                self._GetHeaderInfo()\r
-            if self._Version == None:\r
-                self._Version = ''\r
-        return self._Version\r
-\r
-    ## Retrieve platform description file version\r
-    def _GetDscSpec(self):\r
-        if self._DscSpecification == None:\r
-            if self._Header == None:\r
-                self._GetHeaderInfo()\r
-            if self._DscSpecification == None:\r
-                self._DscSpecification = ''\r
-        return self._DscSpecification\r
-\r
-    ## Retrieve OUTPUT_DIRECTORY\r
-    def _GetOutpuDir(self):\r
-        if self._OutputDirectory == None:\r
-            if self._Header == None:\r
-                self._GetHeaderInfo()\r
-            if self._OutputDirectory == None:\r
-                self._OutputDirectory = os.path.join("Build", self._PlatformName)\r
-        return self._OutputDirectory\r
-\r
-    ## Retrieve SUPPORTED_ARCHITECTURES\r
-    def _GetSupArch(self):\r
-        if self._SupArchList == None:\r
-            if self._Header == None:\r
-                self._GetHeaderInfo()\r
-            if self._SupArchList == None:\r
-                self._SupArchList = ARCH_LIST\r
-        return self._SupArchList\r
-\r
-    ## Retrieve BUILD_TARGETS\r
-    def _GetBuildTarget(self):\r
-        if self._BuildTargets == None:\r
-            if self._Header == None:\r
-                self._GetHeaderInfo()\r
-            if self._BuildTargets == None:\r
-                self._BuildTargets = ['DEBUG', 'RELEASE']\r
-        return self._BuildTargets\r
-\r
-    ## Retrieve SKUID_IDENTIFIER\r
-    def _GetSkuName(self):\r
-        if self._SkuName == None:\r
-            if self._Header == None:\r
-                self._GetHeaderInfo()\r
-            if self._SkuName == None or self._SkuName not in self.SkuIds:\r
-                self._SkuName = 'DEFAULT'\r
-        return self._SkuName\r
-\r
-    ## Override SKUID_IDENTIFIER\r
-    def _SetSkuName(self, Value):\r
-        if Value in self.SkuIds:\r
-            self._SkuName = Value\r
-\r
-    def _GetFdfFile(self):\r
-        if self._FlashDefinition == None:\r
-            if self._Header == None:\r
-                self._GetHeaderInfo()\r
-            if self._FlashDefinition == None:\r
-                self._FlashDefinition = ''\r
-        return self._FlashDefinition\r
-\r
-    ## Retrieve FLASH_DEFINITION\r
-    def _GetBuildNumber(self):\r
-        if self._BuildNumber == None:\r
-            if self._Header == None:\r
-                self._GetHeaderInfo()\r
-            if self._BuildNumber == None:\r
-                self._BuildNumber = ''\r
-        return self._BuildNumber\r
-\r
-    ## Retrieve MAKEFILE_NAME\r
-    def _GetMakefileName(self):\r
-        if self._MakefileName == None:\r
-            if self._Header == None:\r
-                self._GetHeaderInfo()\r
-            if self._MakefileName == None:\r
-                self._MakefileName = ''\r
-        return self._MakefileName\r
-\r
-    ## Retrieve BsBaseAddress\r
-    def _GetBsBaseAddress(self):\r
-        if self._BsBaseAddress == None:\r
-            if self._Header == None:\r
-                self._GetHeaderInfo()\r
-            if self._BsBaseAddress == None:\r
-                self._BsBaseAddress = ''\r
-        return self._BsBaseAddress\r
-\r
-    ## Retrieve RtBaseAddress\r
-    def _GetRtBaseAddress(self):\r
-        if self._RtBaseAddress == None:\r
-            if self._Header == None:\r
-                self._GetHeaderInfo()\r
-            if self._RtBaseAddress == None:\r
-                self._RtBaseAddress = ''\r
-        return self._RtBaseAddress\r
-\r
-    ## Retrieve [SkuIds] section information\r
-    def _GetSkuIds(self):\r
-        if self._SkuIds == None:\r
-            self._SkuIds = {}\r
-            RecordList = self._RawData[MODEL_EFI_SKU_ID]\r
-            for Record in RecordList:\r
-                if Record[0] in [None, '']:\r
-                    EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID number',\r
-                                    File=self.DescFilePath, Line=Record[-1])\r
-                if Record[1] in [None, '']:\r
-                    EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID name',\r
-                                    File=self.DescFilePath, Line=Record[-1])\r
-                self._SkuIds[Record[1]] = Record[0]\r
-            if 'DEFAULT' not in self._SkuIds:\r
-                self._SkuIds['DEFAULT'] = 0\r
-        return self._SkuIds\r
-\r
-    ## Retrieve [Components] section information\r
-    def _GetModules(self):\r
-        if self._Modules != None:\r
-            return self._Modules\r
-\r
-        self._Modules = sdict()\r
-        RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]\r
-        for Record in RecordList:\r
-            ModuleFile = NormPath(Record[0], self._Macros)\r
-            ModuleId = Record[5]\r
-            LineNo = Record[6]\r
-            # check the file existence\r
-            if not ValidFile(ModuleFile, '.inf'):\r
-                EdkLogger.error('build', FORMAT_INVALID, "Invalid or non-existent module",\r
-                                File=self.DescFilePath, ExtraData=ModuleFile, Line=LineNo)\r
-            if ModuleFile in self._Modules:\r
-                continue\r
-            Module = ModuleBuildClassObject()\r
-            Module.DescFilePath = ModuleFile\r
-\r
-            # get module private library instance\r
-            RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, ModuleId]\r
-            for Record in RecordList:\r
-                LibraryClass = Record[0]\r
-                LibraryPath = NormPath(Record[1], self._Macros)\r
-                LineNo = Record[-1]\r
-                if not ValidFile(LibraryPath, '.inf'):\r
-                    EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=LibraryPath,\r
-                                    File=self.DescFilePath, Line=LineNo)\r
-                if LibraryClass == '' or LibraryClass == 'NULL':\r
-                    self._NullLibraryNumber += 1\r
-                    LibraryClass = 'NULL%d' % self._NullLibraryNumber\r
-                    EdkLogger.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass))\r
-                Module.LibraryClasses[LibraryClass] = LibraryPath\r
-                if LibraryPath not in self.LibraryInstances:\r
-                    self.LibraryInstances.append(LibraryPath)\r
-\r
-            # get module private PCD setting\r
-            for Type in [MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, \\r
-                         MODEL_PCD_FEATURE_FLAG, MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]:\r
-                RecordList = self._RawData[Type, self._Arch, None, ModuleId]\r
-                for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
-                    TokenList = GetSplitValueList(Setting)\r
-                    DefaultValue = TokenList[0]\r
-                    if len(TokenList) > 1:\r
-                        MaxDatumSize = TokenList[1]\r
-                    else:\r
-                        MaxDatumSize = ''\r
-                    Type = self._PCD_TYPE_STRING_[Type]\r
-                    Pcd = PcdClassObject(\r
-                            PcdCName,\r
-                            TokenSpaceGuid,\r
-                            Type,\r
-                            '',\r
-                            DefaultValue,\r
-                            '',\r
-                            MaxDatumSize,\r
-                            {},\r
-                            None\r
-                            )\r
-                    Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd\r
-\r
-            # get module private build options\r
-            RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None, ModuleId]\r
-            for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
-                if (ToolChainFamily, ToolChain) not in Module.BuildOptions:\r
-                    Module.BuildOptions[ToolChainFamily, ToolChain] = Option\r
-                else:\r
-                    OptionString = Module.BuildOptions[ToolChainFamily, ToolChain]\r
-                    Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r
-\r
-            self._Modules[ModuleFile] = Module\r
-        return self._Modules\r
-\r
-    ## Retrieve all possible library instances used in this platform\r
-    def _GetLibraryInstances(self):\r
-        if self._LibraryInstances == None:\r
-            self._GetLibraryClasses()\r
-        return self._LibraryInstances\r
-\r
-    ## Retrieve [LibraryClasses] information\r
-    def _GetLibraryClasses(self):\r
-        if self._LibraryClasses == None:\r
-            self._LibraryInstances = []\r
-            #\r
-            # tdict is a special dict kind of type, used for selecting correct\r
-            # library instance for given library class and module type\r
-            #\r
-            LibraryClassDict = tdict(True, 3)\r
-            # track all library class names\r
-            LibraryClassSet = set()\r
-            RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]\r
-            for LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy, LineNo in RecordList:\r
-                LibraryClassSet.add(LibraryClass)\r
-                LibraryInstance = NormPath(LibraryInstance, self._Macros)\r
-                if not ValidFile(LibraryInstance, '.inf'):\r
-                    EdkLogger.error('build', FILE_NOT_FOUND, File=self.DescFilePath,\r
-                                    ExtraData=LibraryInstance, Line=LineNo)\r
-                LibraryClassDict[Arch, ModuleType, LibraryClass] = LibraryInstance\r
-                if LibraryInstance not in self._LibraryInstances:\r
-                    self._LibraryInstances.append(LibraryInstance)\r
-\r
-            # resolve the specific library instance for each class and each module type\r
-            self._LibraryClasses = tdict(True)\r
-            for LibraryClass in LibraryClassSet:\r
-                # try all possible module types\r
-                for ModuleType in SUP_MODULE_LIST:\r
-                    LibraryInstance = LibraryClassDict[self._Arch, ModuleType, LibraryClass]\r
-                    if LibraryInstance == None:\r
-                        continue\r
-                    self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance\r
-\r
-            # for R8 style library instances, which are listed in different section\r
-            RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch]\r
-            for Record in RecordList:\r
-                File = NormPath(Record[0], self._Macros)\r
-                LineNo = Record[-1]\r
-                if not ValidFile(File, '.inf'):\r
-                    EdkLogger.error('build', FILE_NOT_FOUND, ExtraData=File,\r
-                                    File=self.DescFilePath, Line=LineNo)\r
-                if File not in self._LibraryInstances:\r
-                    self._LibraryInstances.append(File)\r
-                #\r
-                # we need the module name as the library class name, so we have\r
-                # to parse it here. (self._Bdb[] will trigger a file parse if it\r
-                # hasn't been parsed)\r
-                #\r
-                Library = self._Bdb[File, self._Arch]\r
-                self._LibraryClasses[Library.BaseName, ':dummy:'] = Library\r
-        return self._LibraryClasses\r
-\r
-    ## Retrieve all PCD settings in platform\r
-    def _GetPcds(self):\r
-        if self._Pcds == None:\r
-            self._Pcds = {}\r
-            self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
-            self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
-            self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
-            self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))\r
-            self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))\r
-            self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))\r
-            self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))\r
-            self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))\r
-            self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))\r
-        return self._Pcds\r
-\r
-    ## Retrieve [BuildOptions]\r
-    def _GetBuildOptions(self):\r
-        if self._BuildOptions == None:\r
-            self._BuildOptions = {}\r
-            RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION]\r
-            for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
-                self._BuildOptions[ToolChainFamily, ToolChain] = Option\r
-        return self._BuildOptions\r
-\r
-    ## Retrieve non-dynamic PCD settings\r
-    #\r
-    #   @param  Type    PCD type\r
-    #\r
-    #   @retval a dict object contains settings of given PCD type\r
-    #\r
-    def _GetPcd(self, Type):\r
-        Pcds = {}\r
-        #\r
-        # tdict is a special dict kind of type, used for selecting correct\r
-        # PCD settings for certain ARCH\r
-        #\r
-        PcdDict = tdict(True, 3)\r
-        PcdSet = set()\r
-        # Find out all possible PCD candidates for self._Arch\r
-        RecordList = self._RawData[Type, self._Arch]\r
-        for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
-            PcdSet.add((PcdCName, TokenSpaceGuid))\r
-            PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting\r
-        # Remove redundant PCD candidates\r
-        for PcdCName, TokenSpaceGuid in PcdSet:\r
-            ValueList = ['', '', '']\r
-            Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]\r
-            if Setting == None:\r
-                continue\r
-            TokenList = Setting.split(TAB_VALUE_SPLIT)\r
-            ValueList[0:len(TokenList)] = TokenList\r
-            PcdValue, DatumType, MaxDatumSize = ValueList\r
-            Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
-                                                PcdCName,\r
-                                                TokenSpaceGuid,\r
-                                                self._PCD_TYPE_STRING_[Type],\r
-                                                DatumType,\r
-                                                PcdValue,\r
-                                                '',\r
-                                                MaxDatumSize,\r
-                                                {},\r
-                                                None\r
-                                                )\r
-        return Pcds\r
-\r
-    ## Retrieve dynamic PCD settings\r
-    #\r
-    #   @param  Type    PCD type\r
-    #\r
-    #   @retval a dict object contains settings of given PCD type\r
-    #\r
-    def _GetDynamicPcd(self, Type):\r
-        Pcds = {}\r
-        #\r
-        # tdict is a special dict kind of type, used for selecting correct\r
-        # PCD settings for certain ARCH and SKU\r
-        #\r
-        PcdDict = tdict(True, 4)\r
-        PcdSet = set()\r
-        # Find out all possible PCD candidates for self._Arch\r
-        RecordList = self._RawData[Type, self._Arch]\r
-        for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
-            PcdSet.add((PcdCName, TokenSpaceGuid))\r
-            PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
-        # Remove redundant PCD candidates, per the ARCH and SKU\r
-        for PcdCName, TokenSpaceGuid in PcdSet:\r
-            ValueList = ['', '', '']\r
-            Setting = PcdDict[self._Arch, self.SkuName, PcdCName, TokenSpaceGuid]\r
-            if Setting == None:\r
-                continue\r
-            TokenList = Setting.split(TAB_VALUE_SPLIT)\r
-            ValueList[0:len(TokenList)] = TokenList\r
-            PcdValue, DatumType, MaxDatumSize = ValueList\r
-\r
-            SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], '', '', '', '', '', PcdValue)\r
-            Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
-                                                PcdCName,\r
-                                                TokenSpaceGuid,\r
-                                                self._PCD_TYPE_STRING_[Type],\r
-                                                DatumType,\r
-                                                PcdValue,\r
-                                                '',\r
-                                                MaxDatumSize,\r
-                                                {self.SkuName : SkuInfo},\r
-                                                None\r
-                                                )\r
-        return Pcds\r
-\r
-    ## Retrieve dynamic HII PCD settings\r
-    #\r
-    #   @param  Type    PCD type\r
-    #\r
-    #   @retval a dict object contains settings of given PCD type\r
-    #\r
-    def _GetDynamicHiiPcd(self, Type):\r
-        Pcds = {}\r
-        #\r
-        # tdict is a special dict kind of type, used for selecting correct\r
-        # PCD settings for certain ARCH and SKU\r
-        #\r
-        PcdDict = tdict(True, 4)\r
-        PcdSet = set()\r
-        RecordList = self._RawData[Type, self._Arch]\r
-        # Find out all possible PCD candidates for self._Arch\r
-        for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
-            PcdSet.add((PcdCName, TokenSpaceGuid))\r
-            PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
-        # Remove redundant PCD candidates, per the ARCH and SKU\r
-        for PcdCName, TokenSpaceGuid in PcdSet:\r
-            ValueList = ['', '', '', '']\r
-            Setting = PcdDict[self._Arch, self.SkuName, PcdCName, TokenSpaceGuid]\r
-            if Setting == None:\r
-                continue\r
-            TokenList = Setting.split(TAB_VALUE_SPLIT)\r
-            ValueList[0:len(TokenList)] = TokenList\r
-            VariableName, VariableGuid, VariableOffset, DefaultValue = ValueList\r
-            SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue)\r
-            Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
-                                                PcdCName,\r
-                                                TokenSpaceGuid,\r
-                                                self._PCD_TYPE_STRING_[Type],\r
-                                                '',\r
-                                                DefaultValue,\r
-                                                '',\r
-                                                '',\r
-                                                {self.SkuName : SkuInfo},\r
-                                                None\r
-                                                )\r
-        return Pcds\r
-\r
-    ## Retrieve dynamic VPD PCD settings\r
-    #\r
-    #   @param  Type    PCD type\r
-    #\r
-    #   @retval a dict object contains settings of given PCD type\r
-    #\r
-    def _GetDynamicVpdPcd(self, Type):\r
-        Pcds = {}\r
-        #\r
-        # tdict is a special dict kind of type, used for selecting correct\r
-        # PCD settings for certain ARCH and SKU\r
-        #\r
-        PcdDict = tdict(True, 4)\r
-        PcdSet = set()\r
-        # Find out all possible PCD candidates for self._Arch\r
-        RecordList = self._RawData[Type, self._Arch]\r
-        for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
-            PcdSet.add((PcdCName, TokenSpaceGuid))\r
-            PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
-        # Remove redundant PCD candidates, per the ARCH and SKU\r
-        for PcdCName, TokenSpaceGuid in PcdSet:\r
-            ValueList = ['', '']\r
-            Setting = PcdDict[self._Arch, self.SkuName, PcdCName, TokenSpaceGuid]\r
-            if Setting == None:\r
-                continue\r
-            TokenList = Setting.split(TAB_VALUE_SPLIT)\r
-            ValueList[0:len(TokenList)] = TokenList\r
-            VpdOffset, MaxDatumSize = ValueList\r
-\r
-            SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], '', '', '', '', VpdOffset)\r
-            Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
-                                                PcdCName,\r
-                                                TokenSpaceGuid,\r
-                                                self._PCD_TYPE_STRING_[Type],\r
-                                                '',\r
-                                                '',\r
-                                                '',\r
-                                                MaxDatumSize,\r
-                                                {self.SkuName : SkuInfo},\r
-                                                None\r
-                                                )\r
-        return Pcds\r
-\r
-    ## Add external modules\r
-    #\r
-    #   The external modules are mostly those listed in FDF file, which don't\r
-    # need "build".\r
-    #\r
-    #   @param  FilePath    The path of module description file\r
-    #\r
-    def AddModule(self, FilePath):\r
-        FilePath = NormPath(FilePath)\r
-        if FilePath not in self.Modules:\r
-            Module = ModuleBuildClassObject()\r
-            Module.DescFilePath = FilePath\r
-            self.Modules.append(Module)\r
-\r
-    ## Add external PCDs\r
-    #\r
-    #   The external PCDs are mostly those listed in FDF file to specify address\r
-    # or offset information.\r
-    #\r
-    #   @param  Name    Name of the PCD\r
-    #   @param  Guid    Token space guid of the PCD\r
-    #   @param  Value   Value of the PCD\r
-    #\r
-    def AddPcd(self, Name, Guid, Value):\r
-        if (Name, Guid) not in self.Pcds:\r
-            self.Pcds[Name, Guid] = PcdClassObject(\r
-                                        Name,\r
-                                        Guid,\r
-                                        '',\r
-                                        '',\r
-                                        '',\r
-                                        '',\r
-                                        '',\r
-                                        {},\r
-                                        None\r
-                                        )\r
-        self.Pcds[Name, Guid].DefaultValue = Value\r
-\r
-    Arch                = property(_GetArch, _SetArch)\r
-    Platform            = property(_GetPlatformName)\r
-    PlatformName        = property(_GetPlatformName)\r
-    Guid                = property(_GetFileGuid)\r
-    Version             = property(_GetVersion)\r
-    DscSpecification    = property(_GetDscSpec)\r
-    OutputDirectory     = property(_GetOutpuDir)\r
-    SupArchList         = property(_GetSupArch)\r
-    BuildTargets        = property(_GetBuildTarget)\r
-    SkuName             = property(_GetSkuName, _SetSkuName)\r
-    FlashDefinition     = property(_GetFdfFile)\r
-    BuildNumber         = property(_GetBuildNumber)\r
-    MakefileName        = property(_GetMakefileName)\r
-    BsBaseAddress       = property(_GetBsBaseAddress)\r
-    RtBaseAddress       = property(_GetRtBaseAddress)\r
-\r
-    SkuIds              = property(_GetSkuIds)\r
-    Modules             = property(_GetModules)\r
-    LibraryInstances    = property(_GetLibraryInstances)\r
-    LibraryClasses      = property(_GetLibraryClasses)\r
-    Pcds                = property(_GetPcds)\r
-    BuildOptions        = property(_GetBuildOptions)\r
-\r
-## Platform build information from DSC file\r
-#\r
-#  This class is used to retrieve information stored in database and convert them\r
-# into PackageBuildClassObject form for easier use for AutoGen.\r
-#\r
-class DecBuildData(PackageBuildClassObject):\r
-    # dict used to convert PCD type in database to string used by build tool\r
-    _PCD_TYPE_STRING_ = {\r
-        MODEL_PCD_FIXED_AT_BUILD        :   "FixedAtBuild",\r
-        MODEL_PCD_PATCHABLE_IN_MODULE   :   "PatchableInModule",\r
-        MODEL_PCD_FEATURE_FLAG          :   "FeatureFlag",\r
-        MODEL_PCD_DYNAMIC               :   "Dynamic",\r
-        MODEL_PCD_DYNAMIC_DEFAULT       :   "Dynamic",\r
-        MODEL_PCD_DYNAMIC_HII           :   "DynamicHii",\r
-        MODEL_PCD_DYNAMIC_VPD           :   "DynamicVpd",\r
-        MODEL_PCD_DYNAMIC_EX            :   "DynamicEx",\r
-        MODEL_PCD_DYNAMIC_EX_DEFAULT    :   "DynamicEx",\r
-        MODEL_PCD_DYNAMIC_EX_HII        :   "DynamicExHii",\r
-        MODEL_PCD_DYNAMIC_EX_VPD        :   "DynamicExVpd",\r
-    }\r
-\r
-    # dict used to convert part of [Defines] to members of DecBuildData directly\r
-    _PROPERTY_ = {\r
-        #\r
-        # Required Fields\r
-        #\r
-        TAB_DEC_DEFINES_PACKAGE_NAME                : "_PackageName",\r
-        TAB_DEC_DEFINES_PACKAGE_GUID                : "_Guid",\r
-        TAB_DEC_DEFINES_PACKAGE_VERSION             : "_Version",\r
-    }\r
-\r
-\r
-    ## Constructor of DecBuildData\r
-    #\r
-    #  Initialize object of DecBuildData\r
-    #\r
-    #   @param      FilePath        The path of package description file\r
-    #   @param      RawData         The raw data of DEC file\r
-    #   @param      BuildDataBase   Database used to retrieve module information\r
-    #   @param      Arch            The target architecture\r
-    #   @param      Platform        (not used for DecBuildData)\r
-    #   @param      Macros          Macros used for replacement in DSC file\r
-    #\r
-    def __init__(self, FilePath, RawData, BuildDataBase, Arch='COMMON', Platform='DUMMY', Macros={}):\r
-        self.DescFilePath = FilePath\r
-        self._PackageDir = os.path.dirname(FilePath)\r
-        self._RawData = RawData\r
-        self._Bdb = BuildDataBase\r
-        self._Arch = Arch\r
-        self._Macros = Macros\r
-        self._Clear()\r
-\r
-    ## XXX[key] = value\r
-    def __setitem__(self, key, value):\r
-        self.__dict__[self._PROPERTY_[key]] = value\r
-\r
-    ## value = XXX[key]\r
-    def __getitem__(self, key):\r
-        return self.__dict__[self._PROPERTY_[key]]\r
-\r
-    ## "in" test support\r
-    def __contains__(self, key):\r
-        return key in self._PROPERTY_\r
-\r
-    ## Set all internal used members of DecBuildData to None\r
-    def _Clear(self):\r
-        self._Header            = None\r
-        self._PackageName       = None\r
-        self._Guid              = None\r
-        self._Version           = None\r
-        self._Protocols         = None\r
-        self._Ppis              = None\r
-        self._Guids             = None\r
-        self._Includes          = None\r
-        self._LibraryClasses    = None\r
-        self._Pcds              = None\r
-\r
-    ## Get architecture\r
-    def _GetArch(self):\r
-        return self._Arch\r
-\r
-    ## Set architecture\r
-    #\r
-    #   Changing the default ARCH to another may affect all other information\r
-    # because all information in a platform may be ARCH-related. That's\r
-    # why we need to clear all internal used members, in order to cause all\r
-    # information to be re-retrieved.\r
-    #\r
-    #   @param  Value   The value of ARCH\r
-    #\r
-    def _SetArch(self, Value):\r
-        if self._Arch == Value:\r
-            return\r
-        self._Arch = Value\r
-        self._Clear()\r
-\r
-    ## Retrieve all information in [Defines] section\r
-    #\r
-    #   (Retriving all [Defines] information in one-shot is just to save time.)\r
-    #\r
-    def _GetHeaderInfo(self):\r
-        RecordList = self._RawData[MODEL_META_DATA_HEADER]\r
-        for Record in RecordList:\r
-            Name = Record[0]\r
-            if Name in self:\r
-                self[Name] = Record[1]\r
-        self._Header = 'DUMMY'\r
-\r
-    ## Retrieve package name\r
-    def _GetPackageName(self):\r
-        if self._PackageName == None:\r
-            if self._Header == None:\r
-                self._GetHeaderInfo()\r
-            if self._PackageName == None:\r
-                EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_NAME", File=self.DescFilePath)\r
-        return self._PackageName\r
-\r
-    ## Retrieve file guid\r
-    def _GetFileGuid(self):\r
-        if self._Guid == None:\r
-            if self._Header == None:\r
-                self._GetHeaderInfo()\r
-            if self._Guid == None:\r
-                EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_GUID", File=self.DescFilePath)\r
-        return self._Guid\r
-\r
-    ## Retrieve package version\r
-    def _GetVersion(self):\r
-        if self._Version == None:\r
-            if self._Header == None:\r
-                self._GetHeaderInfo()\r
-            if self._Version == None:\r
-                self._Version = ''\r
-        return self._Version\r
-