]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
Sync BaseTools Branch (version r2271) to EDKII main trunk.
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / WorkspaceDatabase.py
index 12c3324b8dfa834321116cc11e10007219308821..f923129c5429bc1d749eea5265a289f585b15f87 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # This file is used to create a database used by build tool\r
 #\r
-# Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>\r
 # 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
@@ -18,6 +18,7 @@ import sqlite3
 import os\r
 import os.path\r
 import pickle\r
+import uuid\r
 \r
 import Common.EdkLogger as EdkLogger\r
 import Common.GlobalData as GlobalData\r
@@ -73,6 +74,8 @@ class DscBuildData(PlatformBuildClassObject):
         TAB_DSC_DEFINES_MAKEFILE_NAME           :   "_MakefileName",\r
         TAB_DSC_DEFINES_BS_BASE_ADDRESS         :   "_BsBaseAddress",\r
         TAB_DSC_DEFINES_RT_BASE_ADDRESS         :   "_RtBaseAddress",\r
+        #TAB_DSC_DEFINES_RFC_LANGUAGES           :   "_RFCLanguages",\r
+        #TAB_DSC_DEFINES_ISO_LANGUAGES           :   "_ISOLanguages",\r
     }\r
 \r
     # used to compose dummy library class name for those forced library instances\r
@@ -99,6 +102,10 @@ class DscBuildData(PlatformBuildClassObject):
         RecordList = self._RawData[MODEL_META_DATA_DEFINE, self._Arch]\r
         for Record in RecordList:\r
             GlobalData.gEdkGlobal[Record[0]] = Record[1]\r
+        \r
+        RecordList = self._RawData[MODEL_META_DATA_GLOBAL_DEFINE, self._Arch]\r
+        for Record in RecordList:\r
+            GlobalData.gGlobalDefines[Record[0]] = Record[1]\r
 \r
     ## XXX[key] = value\r
     def __setitem__(self, key, value):\r
@@ -135,6 +142,9 @@ class DscBuildData(PlatformBuildClassObject):
         self._Pcds              = None\r
         self._BuildOptions      = None\r
         self._LoadFixAddress    = None\r
+        self._RFCLanguages      = None\r
+        self._ISOLanguages      = None\r
+        self._VpdToolGuid       = None\r
 \r
     ## Get architecture\r
     def _GetArch(self):\r
@@ -188,6 +198,45 @@ class DscBuildData(PlatformBuildClassObject):
                     self._SkuName = Record[1]\r
             elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS:\r
                 self._LoadFixAddress = Record[1]\r
+            elif Name == TAB_DSC_DEFINES_RFC_LANGUAGES:\r
+                if not Record[1] or Record[1][0] != '"' or Record[1][-1] != '"' or len(Record[1]) == 1:\r
+                    EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = "en-us;zh-hans"',\r
+                                    File=self.MetaFile, Line=Record[-1])\r
+                LanguageCodes = Record[1][1:-1]\r
+                if not LanguageCodes:\r
+                    EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',\r
+                                    File=self.MetaFile, Line=Record[-1])                \r
+                LanguageList = GetSplitValueList(LanguageCodes, TAB_SEMI_COLON_SPLIT)\r
+                # check whether there is empty entries in the list\r
+                if None in LanguageList:\r
+                    EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more empty language code is in RFC_LANGUAGES statement',\r
+                                    File=self.MetaFile, Line=Record[-1])                      \r
+                self._RFCLanguages = LanguageList\r
+            elif Name == TAB_DSC_DEFINES_ISO_LANGUAGES:\r
+                if not Record[1] or Record[1][0] != '"' or Record[1][-1] != '"' or len(Record[1]) == 1:\r
+                    EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',\r
+                                    File=self.MetaFile, Line=Record[-1])\r
+                LanguageCodes = Record[1][1:-1]\r
+                if not LanguageCodes:\r
+                    EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',\r
+                                    File=self.MetaFile, Line=Record[-1])                    \r
+                if len(LanguageCodes)%3:\r
+                    EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'bad ISO639-2 format for ISO_LANGUAGES',\r
+                                    File=self.MetaFile, Line=Record[-1])\r
+                LanguageList = []\r
+                for i in range(0, len(LanguageCodes), 3):\r
+                    LanguageList.append(LanguageCodes[i:i+3])\r
+                self._ISOLanguages = LanguageList               \r
+            elif Name == TAB_DSC_DEFINES_VPD_TOOL_GUID:\r
+                #\r
+                # try to convert GUID to a real UUID value to see whether the GUID is format \r
+                # for VPD_TOOL_GUID is correct.\r
+                #\r
+                try:\r
+                    uuid.UUID(Record[1])\r
+                except:\r
+                    EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile)\r
+                self._VpdToolGuid = Record[1]                   \r
         # set _Header to non-None in order to avoid database re-querying\r
         self._Header = 'DUMMY'\r
 \r
@@ -267,6 +316,8 @@ class DscBuildData(PlatformBuildClassObject):
     def _SetSkuName(self, Value):\r
         if Value in self.SkuIds:\r
             self._SkuName = Value\r
+            # Needs to re-retrieve the PCD information\r
+            self._Pcds = None\r
 \r
     def _GetFdfFile(self):\r
         if self._FlashDefinition == None:\r
@@ -321,6 +372,33 @@ class DscBuildData(PlatformBuildClassObject):
                 self._LoadFixAddress = ''\r
         return self._LoadFixAddress\r
 \r
+    ## Retrieve RFCLanguage filter\r
+    def _GetRFCLanguages(self):\r
+        if self._RFCLanguages == None:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._RFCLanguages == None:\r
+                self._RFCLanguages = []\r
+        return self._RFCLanguages\r
+\r
+    ## Retrieve ISOLanguage filter\r
+    def _GetISOLanguages(self):\r
+        if self._ISOLanguages == None:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._ISOLanguages == None:\r
+                self._ISOLanguages = []\r
+        return self._ISOLanguages\r
+\r
+    ## Retrieve the GUID string for VPD tool\r
+    def _GetVpdToolGuid(self):\r
+        if self._VpdToolGuid == None:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._VpdToolGuid == None:\r
+                self._VpdToolGuid = ''\r
+        return self._VpdToolGuid\r
+      \r
     ## Retrieve [SkuIds] section information\r
     def _GetSkuIds(self):\r
         if self._SkuIds == None:\r
@@ -418,6 +496,7 @@ class DscBuildData(PlatformBuildClassObject):
                             '',\r
                             MaxDatumSize,\r
                             {},\r
+                            False,\r
                             None\r
                             )\r
                     Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd\r
@@ -560,13 +639,10 @@ class DscBuildData(PlatformBuildClassObject):
             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
+            PcdValue, DatumType, MaxDatumSize = AnalyzePcdData(Setting)\r
             Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
                                                 PcdCName,\r
                                                 TokenSpaceGuid,\r
@@ -576,6 +652,7 @@ class DscBuildData(PlatformBuildClassObject):
                                                 '',\r
                                                 MaxDatumSize,\r
                                                 {},\r
+                                                False,\r
                                                 None\r
                                                 )\r
         return Pcds\r
@@ -593,22 +670,20 @@ class DscBuildData(PlatformBuildClassObject):
         # PCD settings for certain ARCH and SKU\r
         #\r
         PcdDict = tdict(True, 4)\r
-        PcdSet = set()\r
+        PcdList = []\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
+            PcdList.append((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
+        for PcdCName, TokenSpaceGuid in PcdList:\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
+                      \r
+            PcdValue, DatumType, MaxDatumSize = AnalyzePcdData(Setting)\r
+                \r
             SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], '', '', '', '', '', PcdValue)\r
             Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
                                                 PcdCName,\r
@@ -619,6 +694,7 @@ class DscBuildData(PlatformBuildClassObject):
                                                 '',\r
                                                 MaxDatumSize,\r
                                                 {self.SkuName : SkuInfo},\r
+                                                False,\r
                                                 None\r
                                                 )\r
         return Pcds\r
@@ -644,13 +720,10 @@ class DscBuildData(PlatformBuildClassObject):
             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
+            VariableName, VariableGuid, VariableOffset, DefaultValue = AnalyzeHiiPcdData(Setting)\r
             SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue)\r
             Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
                                                 PcdCName,\r
@@ -661,6 +734,7 @@ class DscBuildData(PlatformBuildClassObject):
                                                 '',\r
                                                 '',\r
                                                 {self.SkuName : SkuInfo},\r
+                                                False,\r
                                                 None\r
                                                 )\r
         return Pcds\r
@@ -678,23 +752,26 @@ class DscBuildData(PlatformBuildClassObject):
         # PCD settings for certain ARCH and SKU\r
         #\r
         PcdDict = tdict(True, 4)\r
-        PcdSet = set()\r
+        PcdList = []\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
+            PcdList.append((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
+        for PcdCName, TokenSpaceGuid in PcdList:\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
+            #\r
+            # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue\r
+            # For the Integer & Boolean type, the optional data can only be InitialValue.\r
+            # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype\r
+            # until the DEC parser has been called.\r
+            # \r
+            VpdOffset, MaxDatumSize, InitialValue = AnalyzeVpdPcdData(Setting)\r
+\r
+            SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], '', '', '', '', VpdOffset, InitialValue)\r
             Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
                                                 PcdCName,\r
                                                 TokenSpaceGuid,\r
@@ -704,6 +781,7 @@ class DscBuildData(PlatformBuildClassObject):
                                                 '',\r
                                                 MaxDatumSize,\r
                                                 {self.SkuName : SkuInfo},\r
+                                                False,\r
                                                 None\r
                                                 )\r
         return Pcds\r
@@ -733,7 +811,7 @@ class DscBuildData(PlatformBuildClassObject):
     #\r
     def AddPcd(self, Name, Guid, Value):\r
         if (Name, Guid) not in self.Pcds:\r
-            self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, None)\r
+            self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)\r
         self.Pcds[Name, Guid].DefaultValue = Value\r
 \r
     Arch                = property(_GetArch, _SetArch)\r
@@ -752,7 +830,9 @@ class DscBuildData(PlatformBuildClassObject):
     BsBaseAddress       = property(_GetBsBaseAddress)\r
     RtBaseAddress       = property(_GetRtBaseAddress)\r
     LoadFixAddress      = property(_GetLoadFixAddress)\r
-\r
+    RFCLanguages        = property(_GetRFCLanguages)\r
+    ISOLanguages        = property(_GetISOLanguages)\r
+    VpdToolGuid         = property(_GetVpdToolGuid)   \r
     SkuIds              = property(_GetSkuIds)\r
     Modules             = property(_GetModules)\r
     LibraryInstances    = property(_GetLibraryInstances)\r
@@ -760,7 +840,7 @@ class DscBuildData(PlatformBuildClassObject):
     Pcds                = property(_GetPcds)\r
     BuildOptions        = property(_GetBuildOptions)\r
 \r
-## Platform build information from DSC file\r
+## Platform build information from DEC 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
@@ -789,6 +869,7 @@ class DecBuildData(PackageBuildClassObject):
         TAB_DEC_DEFINES_PACKAGE_NAME                : "_PackageName",\r
         TAB_DEC_DEFINES_PACKAGE_GUID                : "_Guid",\r
         TAB_DEC_DEFINES_PACKAGE_VERSION             : "_Version",\r
+        TAB_DEC_DEFINES_PKG_UNI_FILE                : "_PkgUniFile",\r
     }\r
 \r
 \r
@@ -830,6 +911,7 @@ class DecBuildData(PackageBuildClassObject):
         self._PackageName       = None\r
         self._Guid              = None\r
         self._Version           = None\r
+        self._PkgUniFile        = None\r
         self._Protocols         = None\r
         self._Ppis              = None\r
         self._Guids             = None\r
@@ -1043,7 +1125,6 @@ class DecBuildData(PackageBuildClassObject):
             PcdSet.add((PcdCName, TokenSpaceGuid))\r
 \r
         for PcdCName, TokenSpaceGuid in PcdSet:\r
-            ValueList = ['', '', '']\r
             #\r
             # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
             # will automatically turn to 'common' ARCH and try again\r
@@ -1051,9 +1132,9 @@ class DecBuildData(PackageBuildClassObject):
             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
-            DefaultValue, DatumType, TokenNumber = ValueList\r
+\r
+            DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting)\r
+                                       \r
             Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdClassObject(\r
                                                                             PcdCName,\r
                                                                             TokenSpaceGuid,\r
@@ -1063,6 +1144,7 @@ class DecBuildData(PackageBuildClassObject):
                                                                             TokenNumber,\r
                                                                             '',\r
                                                                             {},\r
+                                                                            False,\r
                                                                             None\r
                                                                             )\r
         return Pcds\r
@@ -1276,18 +1358,16 @@ class InfBuildData(ModuleBuildClassObject):
             if Name in self:\r
                 self[Name] = Record[1]\r
             # some special items in [Defines] section need special treatment\r
-            elif Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):\r
+            elif Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):\r
+                if Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):\r
+                    Name = 'UEFI_SPECIFICATION_VERSION'\r
                 if self._Specification == None:\r
                     self._Specification = sdict()\r
-                self._Specification['UEFI_SPECIFICATION_VERSION'] = Record[1]\r
-            elif Name == 'EDK_RELEASE_VERSION':\r
-                if self._Specification == None:\r
-                    self._Specification = sdict()\r
-                self._Specification[Name] = Record[1]\r
-            elif Name == 'PI_SPECIFICATION_VERSION':\r
-                if self._Specification == None:\r
-                    self._Specification = sdict()\r
-                self._Specification[Name] = Record[1]\r
+                self._Specification[Name] = GetHexVerValue(Record[1])\r
+                if self._Specification[Name] == None:\r
+                    EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
+                                    "'%s' format is not supported for %s" % (Record[1], Name),\r
+                                    File=self.MetaFile, Line=Record[-1])\r
             elif Name == 'LIBRARY_CLASS':\r
                 if self._LibraryClass == None:\r
                     self._LibraryClass = []\r
@@ -1345,7 +1425,17 @@ class InfBuildData(ModuleBuildClassObject):
             if not self._ModuleType:\r
                 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
                                 "MODULE_TYPE is not given", File=self.MetaFile)\r
-            if (self._Specification == None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (self._Specification['PI_SPECIFICATION_VERSION'] < 0x0001000A):\r
+            if self._ModuleType not in SUP_MODULE_LIST:\r
+                RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
+                for Record in RecordList:\r
+                    Name = Record[0]\r
+                    if Name == "MODULE_TYPE":\r
+                        LineNo = Record[6]\r
+                        break\r
+                EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
+                                "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self._ModuleType,' '.join(l for l in SUP_MODULE_LIST)), \r
+                                File=self.MetaFile, Line=LineNo)             \r
+            if (self._Specification == None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):\r
                 if self._ModuleType == SUP_MODULE_SMM_CORE:\r
                     EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.MetaFile)                \r
             if self._Defs and 'PCI_DEVICE_ID' in self._Defs and 'PCI_VENDOR_ID' in self._Defs \\r
@@ -1814,7 +1904,12 @@ class InfBuildData(ModuleBuildClassObject):
         if self._Depex == None:\r
             self._Depex = tdict(False, 2)\r
             RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\r
-\r
+            \r
+            # If the module has only Binaries and no Sources, then ignore [Depex] \r
+            if self.Sources == None or self.Sources == []:\r
+              if self.Binaries <> None and self.Binaries <> []:\r
+                return self._Depex\r
+                \r
             # PEIM and DXE drivers must have a valid [Depex] section\r
             if len(self.LibraryClass) == 0 and len(RecordList) == 0:\r
                 if self.ModuleType == 'DXE_DRIVER' or self.ModuleType == 'PEIM' or self.ModuleType == 'DXE_SMM_DRIVER' or \\r
@@ -1881,11 +1976,11 @@ class InfBuildData(ModuleBuildClassObject):
     def _GetPcd(self, Type):\r
         Pcds = {}\r
         PcdDict = tdict(True, 4)\r
-        PcdSet = set()\r
+        PcdList = []\r
         RecordList = self._RawData[Type, self._Arch, self._Platform]\r
         for TokenSpaceGuid, PcdCName, Setting, Arch, Platform, Dummy1, LineNo in RecordList:\r
             PcdDict[Arch, Platform, PcdCName, TokenSpaceGuid] = (Setting, LineNo)\r
-            PcdSet.add((PcdCName, TokenSpaceGuid))\r
+            PcdList.append((PcdCName, TokenSpaceGuid))\r
             # get the guid value\r
             if TokenSpaceGuid not in self.Guids:\r
                 Value = GuidValue(TokenSpaceGuid, self.Packages)\r
@@ -1897,13 +1992,11 @@ class InfBuildData(ModuleBuildClassObject):
                 self.Guids[TokenSpaceGuid] = Value\r
 \r
         # resolve PCD type, value, datum info, etc. by getting its definition from package\r
-        for PcdCName, TokenSpaceGuid in PcdSet:\r
-            ValueList = ['', '']\r
+        for PcdCName, TokenSpaceGuid in PcdList:\r
             Setting, LineNo = PcdDict[self._Arch, self.Platform, PcdCName, TokenSpaceGuid]\r
             if Setting == None:\r
                 continue\r
-            TokenList = Setting.split(TAB_VALUE_SPLIT)\r
-            ValueList[0:len(TokenList)] = TokenList\r
+            ValueList = AnalyzePcdData(Setting)\r
             DefaultValue = ValueList[0]\r
             Pcd = PcdClassObject(\r
                     PcdCName,\r
@@ -1914,6 +2007,7 @@ class InfBuildData(ModuleBuildClassObject):
                     '',\r
                     '',\r
                     {},\r
+                    False,\r
                     self.Guids[TokenSpaceGuid]\r
                     )\r
 \r
@@ -1927,7 +2021,7 @@ class InfBuildData(ModuleBuildClassObject):
                 #   "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"\r
                 #\r
                 PcdType = self._PCD_TYPE_STRING_[Type]\r
-                if Type in [MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]:\r
+                if Type == MODEL_PCD_DYNAMIC:\r
                     Pcd.Pending = True\r
                     for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:\r
                         if (PcdCName, TokenSpaceGuid, T) in Package.Pcds:\r
@@ -1940,6 +2034,64 @@ class InfBuildData(ModuleBuildClassObject):
                     PcdInPackage = Package.Pcds[PcdCName, TokenSpaceGuid, PcdType]\r
                     Pcd.Type = PcdType\r
                     Pcd.TokenValue = PcdInPackage.TokenValue\r
+                    \r
+                    #\r
+                    # Check whether the token value exist or not.\r
+                    #\r
+                    if Pcd.TokenValue == None or Pcd.TokenValue == "":\r
+                        EdkLogger.error(\r
+                                'build',\r
+                                FORMAT_INVALID,\r
+                                "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid, PcdCName, str(Package)),\r
+                                File =self.MetaFile, Line=LineNo,\r
+                                ExtraData=None\r
+                                )                        \r
+                    #\r
+                    # Check hexadecimal token value length and format.\r
+                    #\r
+                    if Pcd.TokenValue.startswith("0x") or Pcd.TokenValue.startswith("0X"):\r
+                        if len(Pcd.TokenValue) < 3 or len(Pcd.TokenValue) > 10:\r
+                            EdkLogger.error(\r
+                                    'build',\r
+                                    FORMAT_INVALID,\r
+                                    "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),\r
+                                    File =self.MetaFile, Line=LineNo,\r
+                                    ExtraData=None\r
+                                    )                          \r
+                        try:\r
+                            int (Pcd.TokenValue, 16)\r
+                        except:\r
+                            EdkLogger.error(\r
+                                    'build',\r
+                                    FORMAT_INVALID,\r
+                                    "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),\r
+                                    File =self.MetaFile, Line=LineNo,\r
+                                    ExtraData=None\r
+                                    )\r
+                            \r
+                    #\r
+                    # Check decimal token value length and format.\r
+                    #                            \r
+                    else:\r
+                        try:\r
+                            TokenValueInt = int (Pcd.TokenValue, 10)\r
+                            if (TokenValueInt < 0 or TokenValueInt > 4294967295):\r
+                                EdkLogger.error(\r
+                                            'build',\r
+                                            FORMAT_INVALID,\r
+                                            "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, as a decimal it should between: 0 - 4294967295!"% (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),\r
+                                            File =self.MetaFile, Line=LineNo,\r
+                                            ExtraData=None\r
+                                            )                                \r
+                        except:\r
+                            EdkLogger.error(\r
+                                        'build',\r
+                                        FORMAT_INVALID,\r
+                                        "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, it should be hexadecimal or decimal!"% (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),\r
+                                        File =self.MetaFile, Line=LineNo,\r
+                                        ExtraData=None\r
+                                        )\r
+                    \r
                     Pcd.DatumType = PcdInPackage.DatumType\r
                     Pcd.MaxDatumSize = PcdInPackage.MaxDatumSize\r
                     Pcd.InfDefaultValue = Pcd.DefaultValue\r
@@ -1949,12 +2101,13 @@ class InfBuildData(ModuleBuildClassObject):
             else:\r
                 EdkLogger.error(\r
                             'build',\r
-                            PARSER_ERROR,\r
+                            FORMAT_INVALID,\r
                             "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdCName, self.MetaFile),\r
                             File =self.MetaFile, Line=LineNo,\r
                             ExtraData="\t%s" % '\n\t'.join([str(P) for P in self.Packages])\r
                             )\r
             Pcds[PcdCName, TokenSpaceGuid] = Pcd\r
+\r
         return Pcds\r
 \r
     Arch                    = property(_GetArch, _SetArch)\r
@@ -1994,7 +2147,7 @@ class InfBuildData(ModuleBuildClassObject):
 \r
 ## Database\r
 #\r
-#   This class defined the build databse for all modules, packages and platform.\r
+#   This class defined the build database for all modules, packages and platform.\r
 # It will call corresponding parser for the given file if it cannot find it in\r
 # the database.\r
 #\r
@@ -2108,6 +2261,7 @@ class WorkspaceDatabase(object):
     # @prarm RenewDb=False      Create new database file if it's already there\r
     #\r
     def __init__(self, DbPath, GlobalMacros={}, RenewDb=False):\r
+        self._DbClosedFlag = False\r
         self._GlobalMacros = GlobalMacros\r
 \r
         if DbPath == None or DbPath == '':\r
@@ -2261,9 +2415,11 @@ determine whether database file is out of date!\n")
     # Close the connection and cursor\r
     #\r
     def Close(self):\r
-        self.Conn.commit()\r
-        self.Cur.close()\r
-        self.Conn.close()\r
+        if not self._DbClosedFlag:\r
+            self.Conn.commit()\r
+            self.Cur.close()\r
+            self.Conn.close()\r
+            self._DbClosedFlag = True\r
 \r
     ## Get unique file ID for the gvien file\r
     def GetFileId(self, FilePath):\r
@@ -2287,6 +2443,13 @@ determine whether database file is out of date!\n")
             Result = self.Cur.execute("select min(ID) from %s" % (TableName)).fetchall()\r
             if Result[0][0] != -1:\r
                 return False\r
+            #\r
+            # Check whether the meta data file has external dependency by comparing the time stamp\r
+            #\r
+            Sql = "select Value1, Value2 from %s where Model=%d" % (TableName, MODEL_EXTERNAL_DEPENDENCY)\r
+            for Dependency in self.Cur.execute(Sql).fetchall():\r
+                if str(os.stat(Dependency[0])[8]) != Dependency[1]:\r
+                    return False\r
         except:\r
             return False\r
         return True\r