]> git.proxmox.com Git - mirror_edk2.git/commitdiff
BaseTools: Support Structure PCD value assignment in DEC/DSC
authorLiming Gao <liming.gao@intel.com>
Fri, 24 Nov 2017 06:30:11 +0000 (14:30 +0800)
committerLiming Gao <liming.gao@intel.com>
Mon, 25 Dec 2017 03:05:45 +0000 (11:05 +0800)
https://bugzilla.tianocore.org/show_bug.cgi?id=542
This is pure BaseTools enhancement to support PCD with one structure.
User can specify PCD value based on its structure field.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Liming Gao <liming.gao@intel.com>
Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
15 files changed:
BaseTools/Source/Python/AutoGen/AutoGen.py
BaseTools/Source/Python/AutoGen/GenC.py
BaseTools/Source/Python/AutoGen/GenPcdDb.py
BaseTools/Source/Python/Common/BuildToolError.py
BaseTools/Source/Python/Common/GlobalData.py
BaseTools/Source/Python/Common/Misc.py
BaseTools/Source/Python/Common/ToolDefClassObject.py
BaseTools/Source/Python/CommonDataClass/DataClass.py
BaseTools/Source/Python/Workspace/BuildClassObject.py
BaseTools/Source/Python/Workspace/DecBuildData.py [new file with mode: 0644]
BaseTools/Source/Python/Workspace/DscBuildData.py [new file with mode: 0644]
BaseTools/Source/Python/Workspace/InfBuildData.py [new file with mode: 0644]
BaseTools/Source/Python/Workspace/MetaFileParser.py
BaseTools/Source/Python/Workspace/WorkspaceCommon.py
BaseTools/Source/Python/Workspace/WorkspaceDatabase.py

index b00390ce7dd48d44717660d7764ac1abc4b657d3..12861399ac8623e8f05ed06f970f56695da8257b 100644 (file)
@@ -316,8 +316,8 @@ class WorkspaceAutoGen(AutoGen):
 \r
         EdkLogger.verbose("\nFLASH_DEFINITION = %s" % self.FdfFile)\r
 \r
 \r
         EdkLogger.verbose("\nFLASH_DEFINITION = %s" % self.FdfFile)\r
 \r
-        if Progress:\r
-            Progress.Start("\nProcessing meta-data")\r
+        if Progress:\r
+            Progress.Start("\nProcessing meta-data")\r
 \r
         if self.FdfFile:\r
             #\r
 \r
         if self.FdfFile:\r
             #\r
@@ -1557,12 +1557,19 @@ class PlatformAutoGen(AutoGen):
             if pcd not in self._PlatformPcds.keys():\r
                 self._PlatformPcds[pcd] = self.Platform.Pcds[pcd]\r
 \r
             if pcd not in self._PlatformPcds.keys():\r
                 self._PlatformPcds[pcd] = self.Platform.Pcds[pcd]\r
 \r
+        for item in self._PlatformPcds:\r
+            if self._PlatformPcds[item].DatumType and self._PlatformPcds[item].DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]:\r
+                self._PlatformPcds[item].DatumType = "VOID*"\r
+\r
         if (self.Workspace.ArchList[-1] == self.Arch): \r
             for Pcd in self._DynamicPcdList:\r
                 # just pick the a value to determine whether is unicode string type\r
                 Sku = Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]]\r
                 Sku.VpdOffset = Sku.VpdOffset.strip()\r
 \r
         if (self.Workspace.ArchList[-1] == self.Arch): \r
             for Pcd in self._DynamicPcdList:\r
                 # just pick the a value to determine whether is unicode string type\r
                 Sku = Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]]\r
                 Sku.VpdOffset = Sku.VpdOffset.strip()\r
 \r
+                if Pcd.DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]:\r
+                    Pcd.DatumType = "VOID*"\r
+\r
                 PcdValue = Sku.DefaultValue\r
                 if Pcd.DatumType == 'VOID*' and PcdValue.startswith("L"):\r
                     # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex\r
                 PcdValue = Sku.DefaultValue\r
                 if Pcd.DatumType == 'VOID*' and PcdValue.startswith("L"):\r
                     # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex\r
@@ -4059,7 +4066,7 @@ class ModuleAutoGen(AutoGen):
                     elif BoolValue == 'FALSE':\r
                         Pcd.DefaultValue = '0'\r
 \r
                     elif BoolValue == 'FALSE':\r
                         Pcd.DefaultValue = '0'\r
 \r
-                if Pcd.DatumType != 'VOID*':\r
+                if Pcd.DatumType in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:\r
                     HexFormat = '0x%02x'\r
                     if Pcd.DatumType == 'UINT16':\r
                         HexFormat = '0x%04x'\r
                     HexFormat = '0x%02x'\r
                     if Pcd.DatumType == 'UINT16':\r
                         HexFormat = '0x%04x'\r
index 7aa2016196d487125886ce6bce4e8314da323058..2bc4fbdb6e4047524ea66c540c0f347bec20f273 100644 (file)
@@ -869,7 +869,7 @@ def DynExPcdTokenNumberMapping(Info, AutoGenH):
                 TokenCNameList.append(TokenCName)\r
 \r
 def GetPcdSize(Pcd):\r
                 TokenCNameList.append(TokenCName)\r
 \r
 def GetPcdSize(Pcd):\r
-    if Pcd.DatumType == 'VOID*':\r
+    if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:\r
         Value = Pcd.DefaultValue\r
         if Value in [None, '']:\r
             return 1\r
         Value = Pcd.DefaultValue\r
         if Value in [None, '']:\r
             return 1\r
@@ -889,6 +889,8 @@ def GetPcdSize(Pcd):
         return 1\r
     if Pcd.DatumType == 'BOOLEAN':\r
         return 1\r
         return 1\r
     if Pcd.DatumType == 'BOOLEAN':\r
         return 1\r
+    else:\r
+        return Pcd.MaxDatumSize\r
 \r
 \r
 ## Create code for module PCDs\r
 \r
 \r
 ## Create code for module PCDs\r
@@ -951,16 +953,12 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
         EdkLogger.error("build", AUTOGEN_ERROR,\r
                         "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, TokenCName),\r
                         ExtraData="[%s]" % str(Info))\r
         EdkLogger.error("build", AUTOGEN_ERROR,\r
                         "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, TokenCName),\r
                         ExtraData="[%s]" % str(Info))\r
-    if Pcd.DatumType not in gDatumSizeStringDatabase:\r
-        EdkLogger.error("build", AUTOGEN_ERROR,\r
-                        "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, TokenCName),\r
-                        ExtraData="[%s]" % str(Info))\r
 \r
 \r
-    DatumSize = gDatumSizeStringDatabase[Pcd.DatumType]\r
-    DatumSizeLib = gDatumSizeStringDatabaseLib[Pcd.DatumType]\r
-    GetModeName = '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + TokenCName\r
-    SetModeName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + TokenCName\r
-    SetModeStatusName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_S_' + TokenCName\r
+    DatumSize = gDatumSizeStringDatabase[Pcd.DatumType] if Pcd.DatumType in gDatumSizeStringDatabase else gDatumSizeStringDatabase['VOID*']\r
+    DatumSizeLib = gDatumSizeStringDatabaseLib[Pcd.DatumType] if Pcd.DatumType in gDatumSizeStringDatabaseLib else gDatumSizeStringDatabaseLib['VOID*']\r
+    GetModeName = '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + TokenCName if Pcd.DatumType in gDatumSizeStringDatabaseH else '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH['VOID*'] + '_' + TokenCName\r
+    SetModeName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + TokenCName if Pcd.DatumType in gDatumSizeStringDatabaseH else '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH['VOID*'] + '_' + TokenCName\r
+    SetModeStatusName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_S_' + TokenCName if Pcd.DatumType in gDatumSizeStringDatabaseH else '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH['VOID*'] + '_S_' + TokenCName\r
     GetModeSizeName = '_PCD_GET_MODE_SIZE' + '_' + TokenCName\r
     \r
     PcdExCNameList  = []\r
     GetModeSizeName = '_PCD_GET_MODE_SIZE' + '_' + TokenCName\r
     \r
     PcdExCNameList  = []\r
@@ -980,7 +978,7 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
             AutoGenH.Append('// #define %s  %s\n' % (PcdTokenName, PcdExTokenName))\r
             AutoGenH.Append('// #define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             AutoGenH.Append('// #define %s  LibPcdGetExSize(&%s, %s)\n' % (GetModeSizeName,Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             AutoGenH.Append('// #define %s  %s\n' % (PcdTokenName, PcdExTokenName))\r
             AutoGenH.Append('// #define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             AutoGenH.Append('// #define %s  LibPcdGetExSize(&%s, %s)\n' % (GetModeSizeName,Pcd.TokenSpaceGuidCName, PcdTokenName))\r
-            if Pcd.DatumType == 'VOID*':\r
+            if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:\r
                 AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
                 AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             else:\r
                 AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
                 AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             else:\r
@@ -990,7 +988,7 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
             AutoGenH.Append('#define %s  %s\n' % (PcdTokenName, PcdExTokenName))\r
             AutoGenH.Append('#define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             AutoGenH.Append('#define %s LibPcdGetExSize(&%s, %s)\n' % (GetModeSizeName,Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             AutoGenH.Append('#define %s  %s\n' % (PcdTokenName, PcdExTokenName))\r
             AutoGenH.Append('#define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             AutoGenH.Append('#define %s LibPcdGetExSize(&%s, %s)\n' % (GetModeSizeName,Pcd.TokenSpaceGuidCName, PcdTokenName))\r
-            if Pcd.DatumType == 'VOID*':\r
+            if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             else:\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             else:\r
@@ -1009,7 +1007,7 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
         else:\r
             AutoGenH.Append('#define %s  LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))\r
             AutoGenH.Append('#define %s  LibPcdGetSize(%s)\n' % (GetModeSizeName, PcdTokenName))\r
         else:\r
             AutoGenH.Append('#define %s  LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))\r
             AutoGenH.Append('#define %s  LibPcdGetSize(%s)\n' % (GetModeSizeName, PcdTokenName))\r
-            if Pcd.DatumType == 'VOID*':\r
+            if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%sS(%s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))\r
             else:\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%sS(%s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))\r
             else:\r
@@ -1087,7 +1085,7 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
                                     ExtraData="[%s]" % str(Info))\r
                 if not Value.endswith('U'):\r
                     Value += 'U'\r
                                     ExtraData="[%s]" % str(Info))\r
                 if not Value.endswith('U'):\r
                     Value += 'U'\r
-        if Pcd.DatumType == 'VOID*':\r
+        if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:\r
             if Pcd.MaxDatumSize == None or Pcd.MaxDatumSize == '':\r
                 EdkLogger.error("build", AUTOGEN_ERROR,\r
                                 "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, TokenCName),\r
             if Pcd.MaxDatumSize == None or Pcd.MaxDatumSize == '':\r
                 EdkLogger.error("build", AUTOGEN_ERROR,\r
                                 "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, TokenCName),\r
@@ -1120,15 +1118,25 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
         # skip casting for fixed at build since it breaks ARM assembly.\r
         # Long term we need PCD macros that work in assembly\r
         #\r
         # skip casting for fixed at build since it breaks ARM assembly.\r
         # Long term we need PCD macros that work in assembly\r
         #\r
-        elif Pcd.Type != TAB_PCDS_FIXED_AT_BUILD:\r
+        elif Pcd.Type != TAB_PCDS_FIXED_AT_BUILD and Pcd.DatumType in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN', 'VOID*']:\r
             Value = "((%s)%s)" % (Pcd.DatumType, Value)\r
 \r
             Value = "((%s)%s)" % (Pcd.DatumType, Value)\r
 \r
+        if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN', 'VOID*']:\r
+            # handle structure PCD\r
+            if Pcd.MaxDatumSize == None or Pcd.MaxDatumSize == '':\r
+                EdkLogger.error("build", AUTOGEN_ERROR,\r
+                                "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, TokenCName),\r
+                                ExtraData="[%s]" % str(Info))\r
+\r
+            ArraySize = int(Pcd.MaxDatumSize, 0)\r
+            Array = '[%d]' % ArraySize\r
+\r
         if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:\r
             PcdValueName = '_PCD_PATCHABLE_VALUE_' + TokenCName\r
         else:\r
             PcdValueName = '_PCD_VALUE_' + TokenCName\r
             \r
         if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:\r
             PcdValueName = '_PCD_PATCHABLE_VALUE_' + TokenCName\r
         else:\r
             PcdValueName = '_PCD_VALUE_' + TokenCName\r
             \r
-        if Pcd.DatumType == 'VOID*':\r
+        if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:\r
             #\r
             # For unicode, UINT16 array will be generated, so the alignment of unicode is guaranteed.\r
             #\r
             #\r
             # For unicode, UINT16 array will be generated, so the alignment of unicode is guaranteed.\r
             #\r
@@ -1176,7 +1184,7 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
             AutoGenH.Append('#define %s  %s%s\n' % (GetModeName, Type, PcdVariableName))\r
 \r
         if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:\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
+            if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtrAndSize((VOID *)_gPcd_BinaryPatch_%s, &_gPcd_BinaryPatch_Size_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeName, Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName))\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtrAndSizeS((VOID *)_gPcd_BinaryPatch_%s, &_gPcd_BinaryPatch_Size_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName))\r
             else:\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtrAndSize((VOID *)_gPcd_BinaryPatch_%s, &_gPcd_BinaryPatch_Size_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeName, Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName))\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtrAndSizeS((VOID *)_gPcd_BinaryPatch_%s, &_gPcd_BinaryPatch_Size_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName))\r
             else:\r
@@ -1239,22 +1247,18 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
         EdkLogger.error("build", AUTOGEN_ERROR,\r
                         "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, TokenCName),\r
                         ExtraData="[%s]" % str(Info))\r
         EdkLogger.error("build", AUTOGEN_ERROR,\r
                         "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, TokenCName),\r
                         ExtraData="[%s]" % str(Info))\r
-    if Pcd.DatumType not in gDatumSizeStringDatabase:\r
-        EdkLogger.error("build", AUTOGEN_ERROR,\r
-                        "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, TokenCName),\r
-                        ExtraData="[%s]" % str(Info))\r
 \r
     DatumType   = Pcd.DatumType\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
-    SetModeStatusName = '_PCD_SET_MODE_' + DatumSize + '_S_' + TokenCName\r
+    DatumSize = gDatumSizeStringDatabase[Pcd.DatumType] if Pcd.DatumType in gDatumSizeStringDatabase else gDatumSizeStringDatabase['VOID*']\r
+    DatumSizeLib = gDatumSizeStringDatabaseLib[Pcd.DatumType] if Pcd.DatumType in gDatumSizeStringDatabaseLib else gDatumSizeStringDatabaseLib['VOID*']\r
+    GetModeName = '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + TokenCName if Pcd.DatumType in gDatumSizeStringDatabaseH else '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH['VOID*'] + '_' + TokenCName\r
+    SetModeName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + TokenCName if Pcd.DatumType in gDatumSizeStringDatabaseH else '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH['VOID*'] + '_' + TokenCName\r
+    SetModeStatusName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_S_' + TokenCName if Pcd.DatumType in gDatumSizeStringDatabaseH else '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH['VOID*'] + '_S_' + TokenCName\r
     GetModeSizeName = '_PCD_GET_MODE_SIZE' + '_' + TokenCName\r
 \r
     Type = ''\r
     Array = ''\r
     GetModeSizeName = '_PCD_GET_MODE_SIZE' + '_' + TokenCName\r
 \r
     Type = ''\r
     Array = ''\r
-    if Pcd.DatumType == 'VOID*':\r
+    if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:\r
         if Pcd.DefaultValue[0]== '{':\r
             Type = '(VOID *)'\r
         Array = '[]'\r
         if Pcd.DefaultValue[0]== '{':\r
             Type = '(VOID *)'\r
         Array = '[]'\r
@@ -1279,7 +1283,7 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
             AutoGenH.Append('// #define %s  %s\n' % (PcdTokenName, PcdExTokenName))\r
             AutoGenH.Append('// #define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             AutoGenH.Append('// #define %s  LibPcdGetExSize(&%s, %s)\n' % (GetModeSizeName,Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             AutoGenH.Append('// #define %s  %s\n' % (PcdTokenName, PcdExTokenName))\r
             AutoGenH.Append('// #define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             AutoGenH.Append('// #define %s  LibPcdGetExSize(&%s, %s)\n' % (GetModeSizeName,Pcd.TokenSpaceGuidCName, PcdTokenName))\r
-            if Pcd.DatumType == 'VOID*':\r
+            if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:\r
                 AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
                 AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             else:\r
                 AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
                 AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             else:\r
@@ -1289,7 +1293,7 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
             AutoGenH.Append('#define %s  %s\n' % (PcdTokenName, PcdExTokenName))\r
             AutoGenH.Append('#define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             AutoGenH.Append('#define %s LibPcdGetExSize(&%s, %s)\n' % (GetModeSizeName,Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             AutoGenH.Append('#define %s  %s\n' % (PcdTokenName, PcdExTokenName))\r
             AutoGenH.Append('#define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             AutoGenH.Append('#define %s LibPcdGetExSize(&%s, %s)\n' % (GetModeSizeName,Pcd.TokenSpaceGuidCName, PcdTokenName))\r
-            if Pcd.DatumType == 'VOID*':\r
+            if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             else:\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))\r
             else:\r
@@ -1310,7 +1314,7 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
         else:\r
             AutoGenH.Append('#define %s  LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))\r
             AutoGenH.Append('#define %s  LibPcdGetSize(%s)\n' % (GetModeSizeName, PcdTokenName))\r
         else:\r
             AutoGenH.Append('#define %s  LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))\r
             AutoGenH.Append('#define %s  LibPcdGetSize(%s)\n' % (GetModeSizeName, PcdTokenName))\r
-            if DatumType == 'VOID*':\r
+            if DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%sS(%s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))\r
             else:\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))\r
                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%sS(%s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))\r
             else:\r
@@ -1318,7 +1322,7 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
                 AutoGenH.Append('#define %s(Value)  LibPcdSet%sS(%s, (Value))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))\r
     if PcdItemType == TAB_PCDS_PATCHABLE_IN_MODULE:\r
         PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[TAB_PCDS_PATCHABLE_IN_MODULE] + '_' + TokenCName\r
                 AutoGenH.Append('#define %s(Value)  LibPcdSet%sS(%s, (Value))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))\r
     if PcdItemType == TAB_PCDS_PATCHABLE_IN_MODULE:\r
         PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[TAB_PCDS_PATCHABLE_IN_MODULE] + '_' + TokenCName\r
-        if DatumType == 'VOID*':\r
+        if DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:\r
             ArraySize = int(Pcd.MaxDatumSize, 0)\r
             if Pcd.DefaultValue[0] == 'L':\r
                 ArraySize = ArraySize / 2\r
             ArraySize = int(Pcd.MaxDatumSize, 0)\r
             if Pcd.DefaultValue[0] == 'L':\r
                 ArraySize = ArraySize / 2\r
@@ -1329,7 +1333,7 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
             AutoGenH.Append('extern volatile  %s  %s%s;\n' % (DatumType, PcdVariableName, Array))\r
         AutoGenH.Append('#define %s  %s_gPcd_BinaryPatch_%s\n' %(GetModeName, Type, TokenCName))\r
         PcdDataSize = GetPcdSize(Pcd)\r
             AutoGenH.Append('extern volatile  %s  %s%s;\n' % (DatumType, PcdVariableName, Array))\r
         AutoGenH.Append('#define %s  %s_gPcd_BinaryPatch_%s\n' %(GetModeName, Type, TokenCName))\r
         PcdDataSize = GetPcdSize(Pcd)\r
-        if Pcd.DatumType == 'VOID*':\r
+        if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:\r
             AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtrAndSize((VOID *)_gPcd_BinaryPatch_%s, &_gPcd_BinaryPatch_Size_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeName, TokenCName, TokenCName, TokenCName))\r
             AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtrAndSizeS((VOID *)_gPcd_BinaryPatch_%s, &_gPcd_BinaryPatch_Size_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, TokenCName, TokenCName, TokenCName))\r
             AutoGenH.Append('#define %s %s\n' % (PatchPcdSizeTokenName, Pcd.MaxDatumSize))\r
             AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtrAndSize((VOID *)_gPcd_BinaryPatch_%s, &_gPcd_BinaryPatch_Size_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeName, TokenCName, TokenCName, TokenCName))\r
             AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtrAndSizeS((VOID *)_gPcd_BinaryPatch_%s, &_gPcd_BinaryPatch_Size_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, TokenCName, TokenCName, TokenCName))\r
             AutoGenH.Append('#define %s %s\n' % (PatchPcdSizeTokenName, Pcd.MaxDatumSize))\r
@@ -1346,12 +1350,14 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
         PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[Pcd.Type] + '_' + TokenCName\r
         if DatumType == 'VOID*' and Array == '[]':\r
             DatumType = ['UINT8', 'UINT16'][Pcd.DefaultValue[0] == 'L']\r
         PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[Pcd.Type] + '_' + TokenCName\r
         if DatumType == 'VOID*' and Array == '[]':\r
             DatumType = ['UINT8', 'UINT16'][Pcd.DefaultValue[0] == 'L']\r
+        if DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN', 'VOID*']:\r
+            DatumType = 'UINT8'\r
         AutoGenH.Append('extern const %s _gPcd_FixedAtBuild_%s%s;\n' %(DatumType, TokenCName, Array))\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
         if PcdItemType == TAB_PCDS_FIXED_AT_BUILD and (key in Info.ConstPcd or (Info.IsLibrary and not Info._ReferenceModules)):\r
         AutoGenH.Append('extern const %s _gPcd_FixedAtBuild_%s%s;\n' %(DatumType, TokenCName, Array))\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
         if PcdItemType == TAB_PCDS_FIXED_AT_BUILD and (key in Info.ConstPcd or (Info.IsLibrary and not Info._ReferenceModules)):\r
-            if  Pcd.DatumType == 'VOID*':\r
+            if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:\r
                 AutoGenH.Append('#define _PCD_VALUE_%s %s%s\n' %(TokenCName, Type, PcdVariableName))\r
             else:\r
                 AutoGenH.Append('#define _PCD_VALUE_%s %s\n' %(TokenCName, Pcd.DefaultValue))\r
                 AutoGenH.Append('#define _PCD_VALUE_%s %s%s\n' %(TokenCName, Type, PcdVariableName))\r
             else:\r
                 AutoGenH.Append('#define _PCD_VALUE_%s %s\n' %(TokenCName, Pcd.DefaultValue))\r
index fc9ac7178f61a91defdaf787956a63589009ecbd..ddbfe281b857cf5604619fdf952561173ac2007a 100644 (file)
@@ -1158,6 +1158,9 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
     VarCheckTab = VAR_CHECK_PCD_VARIABLE_TAB_CONTAINER()\r
     i = 0\r
     ReorderedDynPcdList = GetOrderedDynamicPcdList(Platform.DynamicPcdList, Platform.PcdTokenNumber)\r
     VarCheckTab = VAR_CHECK_PCD_VARIABLE_TAB_CONTAINER()\r
     i = 0\r
     ReorderedDynPcdList = GetOrderedDynamicPcdList(Platform.DynamicPcdList, Platform.PcdTokenNumber)\r
+    for item in ReorderedDynPcdList:\r
+        if item.DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]:\r
+            item.DatumType = "VOID*"\r
     for Pcd in ReorderedDynPcdList:\r
         VoidStarTypeCurrSize = []\r
         i += 1\r
     for Pcd in ReorderedDynPcdList:\r
         VoidStarTypeCurrSize = []\r
         i += 1\r
index bee5850fc5ab071fa36788ff335392695da12177..2ee899ac4437f958cd106f24e393cb0088f6a09e 100644 (file)
@@ -86,6 +86,7 @@ MIGRATION_ERROR = 0xF010
 PCD_VALIDATION_INFO_ERROR = 0xF011\r
 PCD_VARIABLE_ATTRIBUTES_ERROR = 0xF012\r
 PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR = 0xF013\r
 PCD_VALIDATION_INFO_ERROR = 0xF011\r
 PCD_VARIABLE_ATTRIBUTES_ERROR = 0xF012\r
 PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR = 0xF013\r
+PCD_STRUCTURE_PCD_ERROR = 0xF014\r
 ABORT_ERROR = 0xFFFE\r
 UNKNOWN_ERROR = 0xFFFF\r
 \r
 ABORT_ERROR = 0xFFFE\r
 UNKNOWN_ERROR = 0xFFFF\r
 \r
index 8b7562daa130ccfc71b3820b4f691b79a6e195c0..57ba0546ed3b46d3616f0be28c15b56e84cbb023 100644 (file)
@@ -86,6 +86,9 @@ BuildOptionPcd = []
 #\r
 MixedPcd = {}\r
 \r
 #\r
 MixedPcd = {}\r
 \r
+# Structure Pcd dict\r
+gStructurePcd = {}\r
+\r
 # Pcd name for the Pcd which used in the Conditional directives\r
 gConditionalPcds = []\r
 \r
 # Pcd name for the Pcd which used in the Conditional directives\r
 gConditionalPcds = []\r
 \r
index 2a5125d72da8c08f943bb0ac4fbdc113f49ba043..2bbd9945fc0ad702cd2272fbe88b068dceb124c1 100644 (file)
@@ -36,6 +36,7 @@ from CommonDataClass.DataClass import *
 from Parsing import GetSplitValueList\r
 from Common.LongFilePathSupport import OpenLongFilePath as open\r
 from Common.MultipleWorkspace import MultipleWorkspace as mws\r
 from Parsing import GetSplitValueList\r
 from Common.LongFilePathSupport import OpenLongFilePath as open\r
 from Common.MultipleWorkspace import MultipleWorkspace as mws\r
+import uuid\r
 \r
 ## Regular expression used to find out place holders in string template\r
 gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE | re.UNICODE)\r
 \r
 ## Regular expression used to find out place holders in string template\r
 gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE | re.UNICODE)\r
@@ -1471,6 +1472,100 @@ def AnalyzePcdExpression(Setting):
 \r
     return FieldList\r
 \r
 \r
     return FieldList\r
 \r
+def ParseFieldValue (Value):\r
+  if type(Value) == type(0):\r
+    return Value, (Value.bit_length() + 7) / 8\r
+  if type(Value) <> type(''):\r
+    raise ValueError\r
+  Value = Value.strip()\r
+  if Value.startswith('UINT8') and Value.endswith(')'):\r
+    Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])\r
+    if Size > 1:\r
+      raise ValueError\r
+    return Value, 1\r
+  if Value.startswith('UINT16') and Value.endswith(')'):\r
+    Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])\r
+    if Size > 2:\r
+      raise ValueError\r
+    return Value, 2\r
+  if Value.startswith('UINT32') and Value.endswith(')'):\r
+    Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])\r
+    if Size > 4:\r
+      raise ValueError\r
+    return Value, 4\r
+  if Value.startswith('UINT64') and Value.endswith(')'):\r
+    Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])\r
+    if Size > 8:\r
+      raise ValueError\r
+    return Value, 8\r
+  if Value.startswith('GUID') and Value.endswith(')'):\r
+    Value = Value.split('(', 1)[1][:-1].strip()\r
+    if Value[0] == '{' and Value[-1] == '}':\r
+      Value = Value[1:-1].strip()\r
+      Value = Value.split('{', 1)\r
+      Value = [Item.strip()[2:] for Item in (Value[0] + Value[1][:-1]).split(',')]\r
+      Value = '-'.join(Value[0:3]) + '-' + ''.join(Value[3:5]) + '-' + ''.join(Value[5:11])\r
+    if Value[0] == '"' and Value[-1] == '"':\r
+      Value = Value[1:-1]\r
+    Value = "'" + uuid.UUID(Value).get_bytes_le() + "'"\r
+    Value, Size = ParseFieldValue(Value)\r
+    return Value, 16\r
+  if Value.startswith('L"') and Value.endswith('"'):\r
+    # Unicode String\r
+    List = list(Value[2:-1])\r
+    List.reverse()\r
+    Value = 0\r
+    for Char in List:\r
+      Value = (Value << 16) | ord(Char)\r
+    return Value, (len(List) + 1) * 2\r
+  if Value.startswith('"') and Value.endswith('"'):\r
+    # ASCII String\r
+    List = list(Value[1:-1])\r
+    List.reverse()\r
+    Value = 0\r
+    for Char in List:\r
+      Value = (Value << 8) | ord(Char)\r
+    return Value, len(List) + 1\r
+  if Value.startswith("L'") and Value.endswith("'"):\r
+    # Unicode Character Constant\r
+    List = list(Value[2:-1])\r
+    List.reverse()\r
+    Value = 0\r
+    for Char in List:\r
+      Value = (Value << 16) | ord(Char)\r
+    return Value, len(List) * 2\r
+  if Value.startswith("'") and Value.endswith("'"):\r
+    # Character constant\r
+    List = list(Value[1:-1])\r
+    List.reverse()\r
+    Value = 0\r
+    for Char in List:\r
+      Value = (Value << 8) | ord(Char)\r
+    return Value, len(List)\r
+  if Value.startswith('{') and Value.endswith('}'):\r
+    # Byte array\r
+    Value = Value[1:-1]\r
+    List = [Item.strip() for Item in Value.split(',')]\r
+    List.reverse()\r
+    Value = 0\r
+    for Item in List:\r
+      ItemValue, Size = ParseFieldValue(Item)\r
+      if Size > 1:\r
+        raise ValueError\r
+      Value = (Value << 8) | ItemValue\r
+    return Value, len(List)\r
+  if Value.lower().startswith('0x'):\r
+    Value = int(Value, 16)\r
+    return Value, (Value.bit_length() + 7) / 8\r
+  if Value[0].isdigit():\r
+    Value = int(Value, 10)\r
+    return Value, (Value.bit_length() + 7) / 8\r
+  if Value.lower() == 'true':\r
+    return 1, 1\r
+  if Value.lower() == 'false':\r
+    return 0, 1\r
+  return Value, 1\r
+\r
 ## AnalyzeDscPcd\r
 #\r
 #  Analyze DSC PCD value, since there is no data type info in DSC\r
 ## AnalyzeDscPcd\r
 #\r
 #  Analyze DSC PCD value, since there is no data type info in DSC\r
@@ -1504,19 +1599,19 @@ def AnalyzeDscPcd(Setting, PcdType, DataType=''):
         Value = FieldList[0]\r
         Size = ''\r
         if len(FieldList) > 1:\r
         Value = FieldList[0]\r
         Size = ''\r
         if len(FieldList) > 1:\r
-            Type = FieldList[1]\r
-            # Fix the PCD type when no DataType input\r
-            if Type == 'VOID*':\r
-                DataType = 'VOID*'\r
-            else:\r
+            if FieldList[1].upper().startswith("0X") or FieldList[1].isdigit():\r
                 Size = FieldList[1]\r
                 Size = FieldList[1]\r
+            else:\r
+                DataType = FieldList[1]\r
+\r
         if len(FieldList) > 2:\r
             Size = FieldList[2]\r
         if len(FieldList) > 2:\r
             Size = FieldList[2]\r
-        if DataType == 'VOID*':\r
-            IsValid = (len(FieldList) <= 3)\r
-        else:\r
+        if DataType == "":\r
             IsValid = (len(FieldList) <= 1)\r
             IsValid = (len(FieldList) <= 1)\r
-        return [Value, '', Size], IsValid, 0\r
+        else:\r
+            IsValid = (len(FieldList) <= 3)\r
+#         Value, Size = ParseFieldValue(Value)\r
+        return [str(Value), '', str(Size)], IsValid, 0\r
     elif PcdType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT):\r
         Value = FieldList[0]\r
         Size = Type = ''\r
     elif PcdType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT):\r
         Value = FieldList[0]\r
         Size = Type = ''\r
@@ -1534,10 +1629,10 @@ def AnalyzeDscPcd(Setting, PcdType, DataType=''):
                     Size = str(len(Value.split(",")))\r
                 else:\r
                     Size = str(len(Value) -2 + 1 )\r
                     Size = str(len(Value.split(",")))\r
                 else:\r
                     Size = str(len(Value) -2 + 1 )\r
-        if DataType == 'VOID*':\r
-            IsValid = (len(FieldList) <= 3)\r
-        else:\r
+        if DataType == "":\r
             IsValid = (len(FieldList) <= 1)\r
             IsValid = (len(FieldList) <= 1)\r
+        else:\r
+            IsValid = (len(FieldList) <= 3)\r
         return [Value, Type, Size], IsValid, 0\r
     elif PcdType in (MODEL_PCD_DYNAMIC_VPD, MODEL_PCD_DYNAMIC_EX_VPD):\r
         VpdOffset = FieldList[0]\r
         return [Value, Type, Size], IsValid, 0\r
     elif PcdType in (MODEL_PCD_DYNAMIC_VPD, MODEL_PCD_DYNAMIC_EX_VPD):\r
         VpdOffset = FieldList[0]\r
@@ -1550,10 +1645,11 @@ def AnalyzeDscPcd(Setting, PcdType, DataType=''):
                 Size = FieldList[1]\r
             if len(FieldList) > 2:\r
                 Value = FieldList[2]\r
                 Size = FieldList[1]\r
             if len(FieldList) > 2:\r
                 Value = FieldList[2]\r
-        if DataType == 'VOID*':\r
-            IsValid = (len(FieldList) <= 3)\r
+        if DataType == "":\r
+            IsValid = (len(FieldList) <= 1)\r
         else:\r
         else:\r
-            IsValid = (len(FieldList) <= 2)\r
+            IsValid = (len(FieldList) <= 3)\r
+\r
         return [VpdOffset, Size, Value], IsValid, 2\r
     elif PcdType in (MODEL_PCD_DYNAMIC_HII, MODEL_PCD_DYNAMIC_EX_HII):\r
         HiiString = FieldList[0]\r
         return [VpdOffset, Size, Value], IsValid, 2\r
     elif PcdType in (MODEL_PCD_DYNAMIC_HII, MODEL_PCD_DYNAMIC_EX_HII):\r
         HiiString = FieldList[0]\r
@@ -1682,7 +1778,7 @@ def CheckPcdDatum(Type, Value):
             return False, "Invalid value [%s] of type [%s];"\\r
                           " must be a hexadecimal, decimal or octal in C language format." % (Value, Type)\r
     else:\r
             return False, "Invalid value [%s] of type [%s];"\\r
                           " must be a hexadecimal, decimal or octal in C language format." % (Value, Type)\r
     else:\r
-        return False, "Invalid type [%s]; must be one of VOID*, BOOLEAN, UINT8, UINT16, UINT32, UINT64." % (Type)\r
+        return True, "StructurePcd"\r
 \r
     return True, ""\r
 \r
 \r
     return True, ""\r
 \r
index c65cb8a36d5af129fb2b9a70514da90ce574ab4f..dc90b4783f2f57ef150d22180578bd435db17aa6 100644 (file)
@@ -246,7 +246,6 @@ class ToolDefClassObject(object):
                     Value = Value.replace(Ref, self.MacroDictionary[Ref])\r
                 else:\r
                     Value = Value.replace(Ref, self.MacroDictionary[Ref.upper()])\r
                     Value = Value.replace(Ref, self.MacroDictionary[Ref])\r
                 else:\r
                     Value = Value.replace(Ref, self.MacroDictionary[Ref.upper()])\r
-\r
         MacroReference = gMacroRefPattern.findall(Value)\r
         for Ref in MacroReference:\r
             if Ref not in self.MacroDictionary:\r
         MacroReference = gMacroRefPattern.findall(Value)\r
         for Ref in MacroReference:\r
             if Ref not in self.MacroDictionary:\r
index 3be369a0f472d15cded1d1f4679e42e3acbe219e..efeba3e5dc2a4c74044874403cba6efc41cdad72 100644 (file)
@@ -77,6 +77,16 @@ MODEL_PCD_DYNAMIC = 4008
 MODEL_PCD_DYNAMIC_DEFAULT = 4009\r
 MODEL_PCD_DYNAMIC_VPD = 4010\r
 MODEL_PCD_DYNAMIC_HII = 4011\r
 MODEL_PCD_DYNAMIC_DEFAULT = 4009\r
 MODEL_PCD_DYNAMIC_VPD = 4010\r
 MODEL_PCD_DYNAMIC_HII = 4011\r
+MODEL_PCD_TYPE_LIST = [MODEL_PCD_FIXED_AT_BUILD,\r
+                        MODEL_PCD_PATCHABLE_IN_MODULE,\r
+                        MODEL_PCD_FEATURE_FLAG,\r
+                        MODEL_PCD_DYNAMIC_DEFAULT,\r
+                        MODEL_PCD_DYNAMIC_HII,\r
+                        MODEL_PCD_DYNAMIC_VPD,\r
+                        MODEL_PCD_DYNAMIC_EX_DEFAULT,\r
+                        MODEL_PCD_DYNAMIC_EX_HII,\r
+                        MODEL_PCD_DYNAMIC_EX_VPD\r
+                       ]\r
 \r
 MODEL_META_DATA_HEADER_COMMENT = 5000\r
 MODEL_META_DATA_HEADER = 5001\r
 \r
 MODEL_META_DATA_HEADER_COMMENT = 5000\r
 MODEL_META_DATA_HEADER = 5001\r
index 5fa497b803d4e93e1c5db85b310c8389432badd1..da265b68f1af510e844dc3d804e53e1c3ff2c446 100644 (file)
@@ -16,6 +16,7 @@ import Common.LongFilePathOs as os
 from Common.Misc import sdict\r
 from Common.Misc import RealPath2\r
 from Common.BuildToolError import *\r
 from Common.Misc import sdict\r
 from Common.Misc import RealPath2\r
 from Common.BuildToolError import *\r
+import collections\r
 \r
 ## PcdClassObject\r
 #\r
 \r
 ## PcdClassObject\r
 #\r
@@ -106,6 +107,63 @@ class PcdClassObject(object):
     def __hash__(self):\r
         return hash((self.TokenCName, self.TokenSpaceGuidCName))\r
 \r
     def __hash__(self):\r
         return hash((self.TokenCName, self.TokenSpaceGuidCName))\r
 \r
+class StructurePcd(PcdClassObject):\r
+    def __init__(self, StructuredPcdIncludeFile="", Packages=None, Name=None, Guid=None, Type=None, DatumType=None, Value=None, Token=None, MaxDatumSize=None, SkuInfoList={}, IsOverrided=False, GuidValue=None, validateranges=[], validlists=[], expressions=[]):\r
+        super(StructurePcd, self).__init__(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, IsOverrided, GuidValue, validateranges, validlists, expressions)\r
+        self.StructuredPcdIncludeFile = StructuredPcdIncludeFile\r
+        self.PackageDecs = Packages\r
+        self.DefaultStoreName = ['STANDARD']\r
+        self.DefaultValues = collections.OrderedDict({})\r
+        self.PcdMode = None\r
+        self.SkuOverrideValues = collections.OrderedDict({})\r
+        self.FlexibleFieldName = None\r
+\r
+    def __repr__(self):\r
+        return self.TypeName\r
+\r
+    def AddDefaultValue (self, FieldName, Value, FileName="", LineNo=0):\r
+        self.DefaultValues[FieldName] = [Value.strip(), FileName, LineNo]\r
+        return self.DefaultValues[FieldName]\r
+\r
+    def AddOverrideValue (self, FieldName, Value, SkuName, FileName="", LineNo=0):\r
+        if SkuName not in self.SkuOverrideValues:\r
+            self.SkuOverrideValues[SkuName] = collections.OrderedDict({})\r
+        self.SkuOverrideValues[SkuName][FieldName] = [Value.strip(), FileName, LineNo]\r
+        return self.SkuOverrideValues[SkuName][FieldName]\r
+\r
+    def SetPcdMode (self, PcdMode):\r
+        self.PcdMode = PcdMode\r
+\r
+    def SetFlexibleFieldName (self, FlexibleFieldName):\r
+        self.FlexibleFieldName = FlexibleFieldName\r
+\r
+    def copy(self, PcdObject):\r
+        self.TokenCName = PcdObject.TokenCName if PcdObject.TokenCName else self.TokenCName\r
+        self.TokenSpaceGuidCName = PcdObject.TokenSpaceGuidCName if PcdObject.TokenSpaceGuidCName else PcdObject.TokenSpaceGuidCName\r
+        self.TokenSpaceGuidValue = PcdObject.TokenSpaceGuidValue if PcdObject.TokenSpaceGuidValue else self.TokenSpaceGuidValue\r
+        self.Type = PcdObject.Type if PcdObject.Type else self.Type\r
+        self.DatumType = PcdObject.DatumType if PcdObject.DatumType else self.DatumType\r
+        self.DefaultValue = PcdObject.DefaultValue if  PcdObject.DefaultValue else self.DefaultValue\r
+        self.TokenValue = PcdObject.TokenValue if PcdObject.TokenValue else self.TokenValue\r
+        self.MaxDatumSize = PcdObject.MaxDatumSize if PcdObject.MaxDatumSize else self.MaxDatumSize\r
+        self.SkuInfoList = PcdObject.SkuInfoList if PcdObject.SkuInfoList else self.SkuInfoList\r
+        self.Phase = PcdObject.Phase if PcdObject.Phase else self.Phase\r
+        self.Pending = PcdObject.Pending if PcdObject.Pending else self.Pending\r
+        self.IsOverrided = PcdObject.IsOverrided if PcdObject.IsOverrided else self.IsOverrided\r
+        self.IsFromBinaryInf = PcdObject.IsFromBinaryInf if PcdObject.IsFromBinaryInf else self.IsFromBinaryInf\r
+        self.IsFromDsc = PcdObject.IsFromDsc if PcdObject.IsFromDsc else self.IsFromDsc\r
+        self.validateranges = PcdObject.validateranges if PcdObject.validateranges else self.validateranges\r
+        self.validlists = PcdObject.validlists if PcdObject.validlists else self.validlists\r
+        self.expressions = PcdObject.expressions if PcdObject.expressions else self.expressions\r
+        if type(PcdObject) is StructurePcd:\r
+            self.StructuredPcdIncludeFile = PcdObject.StructuredPcdIncludeFile if PcdObject.StructuredPcdIncludeFile else self.StructuredPcdIncludeFile\r
+            self.PackageDecs = PcdObject.PackageDecs if PcdObject.PackageDecs else self.PackageDecs\r
+            self.DefaultValues = PcdObject.DefaultValues if PcdObject.DefaultValues else self.DefaultValues\r
+            self.PcdMode = PcdObject.PcdMode if PcdObject.PcdMode else self.PcdMode\r
+            self.DefaultFromDSC=None\r
+            self.OverrideValues = PcdObject.SkuOverrideValues if PcdObject.SkuOverrideValues else self.SkuOverrideValues\r
+            self.FlexibleFieldName = PcdObject.FlexibleFieldName if PcdObject.FlexibleFieldName else self.FlexibleFieldName\r
+\r
 ## LibraryClassObject\r
 #\r
 # This Class defines LibraryClassObject used in BuildDatabase\r
 ## LibraryClassObject\r
 #\r
 # This Class defines LibraryClassObject used in BuildDatabase\r
diff --git a/BaseTools/Source/Python/Workspace/DecBuildData.py b/BaseTools/Source/Python/Workspace/DecBuildData.py
new file mode 100644 (file)
index 0000000..d0e77fa
--- /dev/null
@@ -0,0 +1,462 @@
+## @file\r
+# This file is used to create a database used by build tool\r
+#\r
+# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
+# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<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
+# 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
+from Common.String import *\r
+from Common.DataType import *\r
+from Common.Misc import *\r
+from types import *\r
+\r
+from Workspace.BuildClassObject import PackageBuildClassObject, StructurePcd, PcdClassObject\r
+\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
+#\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
+        TAB_DEC_DEFINES_PKG_UNI_FILE                : "_PkgUniFile",\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, File, RawData, BuildDataBase, Arch='COMMON', Target=None, Toolchain=None):\r
+        self.MetaFile = File\r
+        self._PackageDir = File.Dir\r
+        self._RawData = RawData\r
+        self._Bdb = BuildDataBase\r
+        self._Arch = Arch\r
+        self._Target = Target\r
+        self._Toolchain = Toolchain\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._PkgUniFile        = 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
+        self.__Macros           = None\r
+        self._PrivateProtocols  = None\r
+        self._PrivatePpis       = None\r
+        self._PrivateGuids      = None\r
+        self._PrivateIncludes   = None\r
+\r
+    ## Get current effective macros\r
+    def _GetMacros(self):\r
+        if self.__Macros == None:\r
+            self.__Macros = {}\r
+            self.__Macros.update(GlobalData.gGlobalDefines)\r
+        return self.__Macros\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[1]\r
+            if Name in self:\r
+                self[Name] = Record[2]\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.MetaFile)\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.MetaFile)\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
+\r
+    ## Retrieve protocol definitions (name/value pairs)\r
+    def _GetProtocol(self):\r
+        if self._Protocols == None:\r
+            #\r
+            # tdict is a special kind of dict, used for selecting correct\r
+            # protocol defition for given ARCH\r
+            #\r
+            ProtocolDict = tdict(True)\r
+            PrivateProtocolDict = tdict(True)\r
+            NameList = []\r
+            PrivateNameList = []\r
+            PublicNameList = []\r
+            # find out all protocol definitions for specific and 'common' arch\r
+            RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch]\r
+            for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:\r
+                if PrivateFlag == 'PRIVATE':\r
+                    if Name not in PrivateNameList:\r
+                        PrivateNameList.append(Name)\r
+                        PrivateProtocolDict[Arch, Name] = Guid\r
+                    if Name in PublicNameList:\r
+                        EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)\r
+                else:\r
+                    if Name not in PublicNameList:\r
+                        PublicNameList.append(Name)\r
+                    if Name in PrivateNameList:\r
+                        EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)\r
+                if Name not in NameList:\r
+                    NameList.append(Name)\r
+                ProtocolDict[Arch, Name] = Guid\r
+            # use sdict to keep the order\r
+            self._Protocols = sdict()\r
+            self._PrivateProtocols = sdict()\r
+            for Name in NameList:\r
+                #\r
+                # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
+                # will automatically turn to 'common' ARCH for trying\r
+                #\r
+                self._Protocols[Name] = ProtocolDict[self._Arch, Name]\r
+            for Name in PrivateNameList:\r
+                self._PrivateProtocols[Name] = PrivateProtocolDict[self._Arch, Name]\r
+        return self._Protocols\r
+\r
+    ## Retrieve PPI definitions (name/value pairs)\r
+    def _GetPpi(self):\r
+        if self._Ppis == None:\r
+            #\r
+            # tdict is a special kind of dict, used for selecting correct\r
+            # PPI defition for given ARCH\r
+            #\r
+            PpiDict = tdict(True)\r
+            PrivatePpiDict = tdict(True)\r
+            NameList = []\r
+            PrivateNameList = []\r
+            PublicNameList = []\r
+            # find out all PPI definitions for specific arch and 'common' arch\r
+            RecordList = self._RawData[MODEL_EFI_PPI, self._Arch]\r
+            for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:\r
+                if PrivateFlag == 'PRIVATE':\r
+                    if Name not in PrivateNameList:\r
+                        PrivateNameList.append(Name)\r
+                        PrivatePpiDict[Arch, Name] = Guid\r
+                    if Name in PublicNameList:\r
+                        EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)\r
+                else:\r
+                    if Name not in PublicNameList:\r
+                        PublicNameList.append(Name)\r
+                    if Name in PrivateNameList:\r
+                        EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)\r
+                if Name not in NameList:\r
+                    NameList.append(Name)\r
+                PpiDict[Arch, Name] = Guid\r
+            # use sdict to keep the order\r
+            self._Ppis = sdict()\r
+            self._PrivatePpis = sdict()\r
+            for Name in NameList:\r
+                #\r
+                # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
+                # will automatically turn to 'common' ARCH for trying\r
+                #\r
+                self._Ppis[Name] = PpiDict[self._Arch, Name]\r
+            for Name in PrivateNameList:\r
+                self._PrivatePpis[Name] = PrivatePpiDict[self._Arch, Name]\r
+        return self._Ppis\r
+\r
+    ## Retrieve GUID definitions (name/value pairs)\r
+    def _GetGuid(self):\r
+        if self._Guids == None:\r
+            #\r
+            # tdict is a special kind of dict, used for selecting correct\r
+            # GUID defition for given ARCH\r
+            #\r
+            GuidDict = tdict(True)\r
+            PrivateGuidDict = tdict(True)\r
+            NameList = []\r
+            PrivateNameList = []\r
+            PublicNameList = []\r
+            # find out all protocol definitions for specific and 'common' arch\r
+            RecordList = self._RawData[MODEL_EFI_GUID, self._Arch]\r
+            for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:\r
+                if PrivateFlag == 'PRIVATE':\r
+                    if Name not in PrivateNameList:\r
+                        PrivateNameList.append(Name)\r
+                        PrivateGuidDict[Arch, Name] = Guid\r
+                    if Name in PublicNameList:\r
+                        EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)\r
+                else:\r
+                    if Name not in PublicNameList:\r
+                        PublicNameList.append(Name)\r
+                    if Name in PrivateNameList:\r
+                        EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)\r
+                if Name not in NameList:\r
+                    NameList.append(Name)\r
+                GuidDict[Arch, Name] = Guid\r
+            # use sdict to keep the order\r
+            self._Guids = sdict()\r
+            self._PrivateGuids = sdict()\r
+            for Name in NameList:\r
+                #\r
+                # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
+                # will automatically turn to 'common' ARCH for trying\r
+                #\r
+                self._Guids[Name] = GuidDict[self._Arch, Name]\r
+            for Name in PrivateNameList:\r
+                self._PrivateGuids[Name] = PrivateGuidDict[self._Arch, Name]\r
+        return self._Guids\r
+\r
+    ## Retrieve public include paths declared in this package\r
+    def _GetInclude(self):\r
+        if self._Includes == None:\r
+            self._Includes = []\r
+            self._PrivateIncludes = []\r
+            PublicInclues = []\r
+            RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch]\r
+            Macros = self._Macros\r
+            Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
+            for Record in RecordList:\r
+                File = PathClass(NormPath(Record[0], Macros), self._PackageDir, Arch=self._Arch)\r
+                LineNo = Record[-1]\r
+                # validate the path\r
+                ErrorCode, ErrorInfo = File.Validate()\r
+                if ErrorCode != 0:\r
+                    EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
+\r
+                # avoid duplicate include path\r
+                if File not in self._Includes:\r
+                    self._Includes.append(File)\r
+                if Record[4] == 'PRIVATE':\r
+                    if File not in self._PrivateIncludes:\r
+                        self._PrivateIncludes.append(File)\r
+                    if File in PublicInclues:\r
+                        EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % File, File=self.MetaFile, Line=LineNo)\r
+                else:\r
+                    if File not in PublicInclues:\r
+                        PublicInclues.append(File)\r
+                    if File in self._PrivateIncludes:\r
+                        EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % File, File=self.MetaFile, Line=LineNo)\r
+\r
+        return self._Includes\r
+\r
+    ## Retrieve library class declarations (not used in build at present)\r
+    def _GetLibraryClass(self):\r
+        if self._LibraryClasses == None:\r
+            #\r
+            # tdict is a special kind of dict, used for selecting correct\r
+            # library class declaration for given ARCH\r
+            #\r
+            LibraryClassDict = tdict(True)\r
+            LibraryClassSet = set()\r
+            RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]\r
+            Macros = self._Macros\r
+            for LibraryClass, File, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:\r
+                File = PathClass(NormPath(File, Macros), self._PackageDir, Arch=self._Arch)\r
+                # check the file validation\r
+                ErrorCode, ErrorInfo = File.Validate()\r
+                if ErrorCode != 0:\r
+                    EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
+                LibraryClassSet.add(LibraryClass)\r
+                LibraryClassDict[Arch, LibraryClass] = File\r
+            self._LibraryClasses = sdict()\r
+            for LibraryClass in LibraryClassSet:\r
+                self._LibraryClasses[LibraryClass] = LibraryClassDict[self._Arch, LibraryClass]\r
+        return self._LibraryClasses\r
+\r
+    ## Retrieve PCD declarations\r
+    def _GetPcds(self):\r
+        if self._Pcds == None:\r
+            self._Pcds = sdict()\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._GetPcd(MODEL_PCD_DYNAMIC))\r
+            self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))\r
+        return self._Pcds\r
+\r
+\r
+    def ProcessStructurePcd(self, StructurePcdRawDataSet):\r
+        s_pcd_set = dict()\r
+        for s_pcd,LineNo in StructurePcdRawDataSet:\r
+            if s_pcd.TokenSpaceGuidCName not in s_pcd_set:\r
+                s_pcd_set[s_pcd.TokenSpaceGuidCName] = []\r
+            s_pcd_set[s_pcd.TokenSpaceGuidCName].append((s_pcd,LineNo))\r
+\r
+        str_pcd_set = []\r
+        for pcdname in s_pcd_set:\r
+            dep_pkgs = []\r
+            struct_pcd = StructurePcd()\r
+            for item,LineNo in s_pcd_set[pcdname]:\r
+                if "<HeaderFiles>" in item.TokenCName:\r
+                    struct_pcd.StructuredPcdIncludeFile = item.DefaultValue\r
+                elif "<Packages>" in item.TokenCName:\r
+                    dep_pkgs.append(item.DefaultValue)\r
+                elif item.DatumType == item.TokenCName:\r
+                    struct_pcd.copy(item)\r
+                    struct_pcd.TokenValue = struct_pcd.TokenValue.strip("{").strip()\r
+                    struct_pcd.TokenSpaceGuidCName, struct_pcd.TokenCName = pcdname.split(".")\r
+                else:\r
+                    struct_pcd.AddDefaultValue(item.TokenCName, item.DefaultValue,self.MetaFile.File,LineNo)\r
+\r
+            struct_pcd.PackageDecs = dep_pkgs\r
+\r
+            str_pcd_set.append(struct_pcd)\r
+\r
+        return str_pcd_set\r
+\r
+    ## Retrieve PCD declarations for given type\r
+    def _GetPcd(self, Type):\r
+        Pcds = sdict()\r
+        #\r
+        # tdict is a special kind of dict, used for selecting correct\r
+        # PCD declaration for given ARCH\r
+        #\r
+        PcdDict = tdict(True, 3)\r
+        # for summarizing PCD\r
+        PcdSet = set()\r
+        # find out all PCDs of the 'type'\r
+\r
+        StrPcdSet = []\r
+        RecordList = self._RawData[Type, self._Arch]\r
+        for TokenSpaceGuid, PcdCName, Setting, Arch, PrivateFlag, Dummy1, Dummy2 in RecordList:\r
+            PcdDict[Arch, PcdCName, TokenSpaceGuid] = (Setting,Dummy2)\r
+            PcdSet.add((PcdCName, TokenSpaceGuid))\r
+\r
+        for PcdCName, TokenSpaceGuid in PcdSet:\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
+            #\r
+            Setting,LineNo = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]\r
+            if Setting == None:\r
+                continue\r
+\r
+            DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting)\r
+            validateranges, validlists, expressions = self._RawData.GetValidExpression(TokenSpaceGuid, PcdCName)\r
+            PcdObj = PcdClassObject(\r
+                                        PcdCName,\r
+                                        TokenSpaceGuid,\r
+                                        self._PCD_TYPE_STRING_[Type],\r
+                                        DatumType,\r
+                                        DefaultValue,\r
+                                        TokenNumber,\r
+                                        '',\r
+                                        {},\r
+                                        False,\r
+                                        None,\r
+                                        list(validateranges),\r
+                                        list(validlists),\r
+                                        list(expressions)\r
+                                        )\r
+            if "." in TokenSpaceGuid:\r
+                StrPcdSet.append((PcdObj,LineNo))\r
+            else:\r
+                Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdObj\r
+\r
+        StructurePcds = self.ProcessStructurePcd(StrPcdSet)\r
+        for pcd in StructurePcds:\r
+            Pcds[pcd.TokenCName, pcd.TokenSpaceGuidCName, self._PCD_TYPE_STRING_[Type]] = pcd\r
+\r
+        return Pcds\r
+\r
+\r
+    _Macros = property(_GetMacros)\r
+    Arch = property(_GetArch, _SetArch)\r
+    PackageName = property(_GetPackageName)\r
+    Guid = property(_GetFileGuid)\r
+    Version = property(_GetVersion)\r
+\r
+    Protocols = property(_GetProtocol)\r
+    Ppis = property(_GetPpi)\r
+    Guids = property(_GetGuid)\r
+    Includes = property(_GetInclude)\r
+    LibraryClasses = property(_GetLibraryClass)\r
+    Pcds = property(_GetPcds)\r
diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py
new file mode 100644 (file)
index 0000000..302de72
--- /dev/null
@@ -0,0 +1,1740 @@
+## @file\r
+# This file is used to create a database used by build tool\r
+#\r
+# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
+# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<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
+# 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
+## 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
+from Common.String import *\r
+from Common.DataType import *\r
+from Common.Misc import *\r
+from types import *\r
+\r
+from CommonDataClass.CommonClass import SkuInfoClass\r
+\r
+from MetaDataTable import *\r
+from MetaFileTable import *\r
+from MetaFileParser import *\r
+\r
+from WorkspaceCommon import GetDeclaredPcd\r
+from Common.Misc import AnalyzeDscPcd\r
+from Common.Misc import ProcessDuplicatedInf\r
+import re\r
+from Common.Parsing import IsValidWord\r
+from Common.VariableAttributes import VariableAttributes\r
+import Common.GlobalData as GlobalData\r
+import subprocess\r
+from Workspace.BuildClassObject import PlatformBuildClassObject, StructurePcd, PcdClassObject, ModuleBuildClassObject\r
+\r
+#\r
+# Treat CHAR16 as a synonym for UINT16.  CHAR16 support is required for VFR C structs\r
+#\r
+PcdValueInitName = 'PcdValueInit'\r
+PcdSupportedBaseTypes = ['BOOLEAN', 'UINT8', 'UINT16', 'UINT32', 'UINT64', 'CHAR16']\r
+PcdSupportedBaseTypeWidth = {'BOOLEAN':8, 'UINT8':8, 'UINT16':16, 'UINT32':32, 'UINT64':64}\r
+PcdUnsupportedBaseTypes = ['INT8', 'INT16', 'INT32', 'INT64', 'CHAR8', 'UINTN', 'INTN', 'VOID']\r
+\r
+PcdMainCHeader = '''\r
+/**\r
+  DO NOT EDIT\r
+  FILE auto-generated\r
+**/\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <PcdValueCommon.h>\r
+'''\r
+\r
+PcdMainCEntry = '''\r
+int\r
+main (\r
+  int   argc,\r
+  char  *argv[]\r
+  )\r
+{\r
+  return PcdValueMain (argc, argv);\r
+}\r
+'''\r
+\r
+PcdMakefileHeader = '''\r
+#\r
+# DO NOT EDIT\r
+# This file is auto-generated by build utility\r
+#\r
+\r
+'''\r
+\r
+PcdMakefileEnd = '''\r
+!INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.common\r
+\r
+CFLAGS = $(CFLAGS) /wd4200 /wd4034 /wd4101\r
+\r
+LIBS = $(LIB_PATH)\Common.lib\r
+\r
+!INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.app\r
+'''\r
+\r
+PcdGccMakefile = '''\r
+ARCH ?= IA32\r
+MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C\r
+LIBS = -lCommon\r
+'''\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
+        # 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
+    _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', Target=None, Toolchain=None):\r
+        self.MetaFile = FilePath\r
+        self._RawData = RawData\r
+        self._Bdb = BuildDataBase\r
+        self._Arch = Arch\r
+        self._Target = Target\r
+        self._Toolchain = Toolchain\r
+        self._Clear()\r
+        self._HandleOverridePath()\r
+        if os.getenv("WORKSPACE"):\r
+            self.OutputPath = os.path.join(os.getenv("WORKSPACE"), 'Build', PcdValueInitName)\r
+        else:\r
+            self.OutputPath = os.path.dirname(self.DscFile)\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._SkuIdentifier     = None\r
+        self._AvilableSkuIds    = None\r
+        self._PcdInfoFlag       = None\r
+        self._VarCheckFlag      = None\r
+        self._FlashDefinition   = None\r
+        self._Prebuild          = None\r
+        self._Postbuild         = 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._DecPcds           = None\r
+        self._BuildOptions      = None\r
+        self._ModuleTypeOptions = None\r
+        self._LoadFixAddress    = None\r
+        self._RFCLanguages      = None\r
+        self._ISOLanguages      = None\r
+        self._VpdToolGuid       = None\r
+        self.__Macros           = None\r
+\r
+\r
+    ## handle Override Path of Module\r
+    def _HandleOverridePath(self):\r
+        RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]\r
+        Macros = self._Macros\r
+        Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
+        for Record in RecordList:\r
+            ModuleId = Record[5]\r
+            LineNo = Record[6]\r
+            ModuleFile = PathClass(NormPath(Record[0]), GlobalData.gWorkspace, Arch=self._Arch)\r
+            RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId]\r
+            if RecordList != []:\r
+                SourceOverridePath = mws.join(GlobalData.gWorkspace, NormPath(RecordList[0][0]))\r
+\r
+                # Check if the source override path exists\r
+                if not os.path.isdir(SourceOverridePath):\r
+                    EdkLogger.error('build', FILE_NOT_FOUND, Message='Source override path does not exist:', File=self.MetaFile, ExtraData=SourceOverridePath, Line=LineNo)\r
+\r
+                # Add to GlobalData Variables\r
+                GlobalData.gOverrideDir[ModuleFile.Key] = SourceOverridePath\r
+\r
+    ## Get current effective macros\r
+    def _GetMacros(self):\r
+        if self.__Macros == None:\r
+            self.__Macros = {}\r
+            self.__Macros.update(GlobalData.gPlatformDefines)\r
+            self.__Macros.update(GlobalData.gGlobalDefines)\r
+            self.__Macros.update(GlobalData.gCommandLineDefines)\r
+        return self.__Macros\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[1]\r
+            # items defined _PROPERTY_ don't need additional processing\r
+\r
+            # some special items in [Defines] section need special treatment\r
+            if Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:\r
+                self._OutputDirectory = NormPath(Record[2], self._Macros)\r
+                if ' ' in self._OutputDirectory:\r
+                    EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in OUTPUT_DIRECTORY",\r
+                                    File=self.MetaFile, Line=Record[-1],\r
+                                    ExtraData=self._OutputDirectory)\r
+            elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION:\r
+                self._FlashDefinition = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)\r
+                ErrorCode, ErrorInfo = self._FlashDefinition.Validate('.fdf')\r
+                if ErrorCode != 0:\r
+                    EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1],\r
+                                    ExtraData=ErrorInfo)\r
+            elif Name == TAB_DSC_PREBUILD:\r
+                PrebuildValue = Record[2]\r
+                if Record[2][0] == '"':\r
+                    if Record[2][-1] != '"':\r
+                        EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_PREBUILD,\r
+                                    File=self.MetaFile, Line=Record[-1])\r
+                    PrebuildValue = Record[2][1:-1]\r
+                self._Prebuild = PrebuildValue\r
+            elif Name == TAB_DSC_POSTBUILD:\r
+                PostbuildValue = Record[2]\r
+                if Record[2][0] == '"':\r
+                    if Record[2][-1] != '"':\r
+                        EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_POSTBUILD,\r
+                                    File=self.MetaFile, Line=Record[-1])\r
+                    PostbuildValue = Record[2][1:-1]\r
+                self._Postbuild = PostbuildValue\r
+            elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:\r
+                self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)\r
+            elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:\r
+                self._BuildTargets = GetSplitValueList(Record[2])\r
+            elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER:\r
+                if self._SkuName == None:\r
+                    self._SkuName = Record[2]\r
+                self._SkuIdentifier = Record[2]\r
+                self._AvilableSkuIds = Record[2]\r
+            elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION:\r
+                self._PcdInfoFlag = Record[2]\r
+            elif Name == TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION:\r
+                self._VarCheckFlag = Record[2]\r
+            elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS:\r
+                try:\r
+                    self._LoadFixAddress = int (Record[2], 0)\r
+                except:\r
+                    EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record[2]))\r
+            elif Name == TAB_DSC_DEFINES_RFC_LANGUAGES:\r
+                if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 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[2][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[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 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[2][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[2])\r
+                except:\r
+                    EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile)\r
+                self._VpdToolGuid = Record[2]\r
+            elif Name in self:\r
+                self[Name] = Record[2]\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.MetaFile)\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 PLATFORM_GUID", File=self.MetaFile)\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
+                EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_VERSION", File=self.MetaFile)\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
+                EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No DSC_SPECIFICATION", File=self.MetaFile)\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
+                EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No SUPPORTED_ARCHITECTURES", File=self.MetaFile)\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
+                EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BUILD_TARGETS", File=self.MetaFile)\r
+        return self._BuildTargets\r
+\r
+    def _GetPcdInfoFlag(self):\r
+        if self._PcdInfoFlag == None or self._PcdInfoFlag.upper() == 'FALSE':\r
+            return False\r
+        elif self._PcdInfoFlag.upper() == 'TRUE':\r
+            return True\r
+        else:\r
+            return False\r
+    def _GetVarCheckFlag(self):\r
+        if self._VarCheckFlag == None or self._VarCheckFlag.upper() == 'FALSE':\r
+            return False\r
+        elif self._VarCheckFlag.upper() == 'TRUE':\r
+            return True\r
+        else:\r
+            return False\r
+    def _GetAviableSkuIds(self):\r
+        if self._AvilableSkuIds:\r
+            return self._AvilableSkuIds\r
+        return self.SkuIdentifier\r
+    def _GetSkuIdentifier(self):\r
+        if self._SkuName:\r
+            return self._SkuName\r
+        if self._SkuIdentifier == None:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+        return self._SkuIdentifier\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
+        self._SkuName = Value\r
+        self._Pcds = None\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
+    def _GetPrebuild(self):\r
+        if self._Prebuild == None:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._Prebuild == None:\r
+                self._Prebuild = ''\r
+        return self._Prebuild\r
+\r
+    def _GetPostbuild(self):\r
+        if self._Postbuild == None:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._Postbuild == None:\r
+                self._Postbuild = ''\r
+        return self._Postbuild\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 the top address for the load fix address\r
+    def _GetLoadFixAddress(self):\r
+        if self._LoadFixAddress == None:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+\r
+            if self._LoadFixAddress == None:\r
+                self._LoadFixAddress = self._Macros.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS, '0')\r
+\r
+            try:\r
+                self._LoadFixAddress = int (self._LoadFixAddress, 0)\r
+            except:\r
+                EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self._LoadFixAddress))\r
+\r
+        #\r
+        # If command line defined, should override the value in DSC file.\r
+        #\r
+        if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData.gCommandLineDefines.keys():\r
+            try:\r
+                self._LoadFixAddress = int(GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)\r
+            except:\r
+                EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS']))\r
+\r
+        if self._LoadFixAddress < 0:\r
+            EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self._LoadFixAddress))\r
+        if self._LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self._LoadFixAddress % 0x1000 != 0:\r
+            EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self._LoadFixAddress))\r
+\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
+    ## 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
+            self._SkuIds = sdict()\r
+            RecordList = self._RawData[MODEL_EFI_SKU_ID, self._Arch]\r
+            for Record in RecordList:\r
+                if Record[0] in [None, '']:\r
+                    EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID number',\r
+                                    File=self.MetaFile, Line=Record[-1])\r
+                if Record[1] in [None, '']:\r
+                    EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID name',\r
+                                    File=self.MetaFile, Line=Record[-1])\r
+                self._SkuIds[Record[1]] = Record[0]\r
+            if 'DEFAULT' not in self._SkuIds:\r
+                self._SkuIds['DEFAULT'] = '0'\r
+            if 'COMMON' not in self._SkuIds:\r
+                self._SkuIds['COMMON'] = '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
+        Macros = self._Macros\r
+        Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
+        for Record in RecordList:\r
+            DuplicatedFile = False\r
+\r
+            ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
+            ModuleId = Record[5]\r
+            LineNo = Record[6]\r
+\r
+            # check the file validation\r
+            ErrorCode, ErrorInfo = ModuleFile.Validate('.inf')\r
+            if ErrorCode != 0:\r
+                EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
+                                ExtraData=ErrorInfo)\r
+            # Check duplication\r
+            # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected\r
+            if self._Arch != 'COMMON' and ModuleFile in self._Modules:\r
+                DuplicatedFile = True\r
+\r
+            Module = ModuleBuildClassObject()\r
+            Module.MetaFile = 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 = PathClass(NormPath(Record[1], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
+                LineNo = Record[-1]\r
+\r
+                # check the file validation\r
+                ErrorCode, ErrorInfo = LibraryPath.Validate('.inf')\r
+                if ErrorCode != 0:\r
+                    EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
+                                    ExtraData=ErrorInfo)\r
+\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
+                    TypeString = self._PCD_TYPE_STRING_[Type]\r
+                    Pcd = PcdClassObject(\r
+                            PcdCName,\r
+                            TokenSpaceGuid,\r
+                            TypeString,\r
+                            '',\r
+                            DefaultValue,\r
+                            '',\r
+                            MaxDatumSize,\r
+                            {},\r
+                            False,\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
+            RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, None, ModuleId]\r
+            if DuplicatedFile and not RecordList:\r
+                EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)\r
+            if RecordList:\r
+                if len(RecordList) != 1:\r
+                    EdkLogger.error('build', OPTION_UNKNOWN, 'Only FILE_GUID can be listed in <Defines> section.',\r
+                                    File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)\r
+                ModuleFile = ProcessDuplicatedInf(ModuleFile, RecordList[0][2], GlobalData.gWorkspace)\r
+                ModuleFile.Arch = self._Arch\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, None, -1]\r
+            Macros = self._Macros\r
+            for Record in RecordList:\r
+                LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy, LineNo = Record\r
+                if LibraryClass == '' or LibraryClass == 'NULL':\r
+                    self._NullLibraryNumber += 1\r
+                    LibraryClass = 'NULL%d' % self._NullLibraryNumber\r
+                    EdkLogger.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch, LibraryInstance, LibraryClass))\r
+                LibraryClassSet.add(LibraryClass)\r
+                LibraryInstance = PathClass(NormPath(LibraryInstance, Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
+                # check the file validation\r
+                ErrorCode, ErrorInfo = LibraryInstance.Validate('.inf')\r
+                if ErrorCode != 0:\r
+                    EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
+                                    ExtraData=ErrorInfo)\r
+\r
+                if ModuleType != 'COMMON' and ModuleType not in SUP_MODULE_LIST:\r
+                    EdkLogger.error('build', OPTION_UNKNOWN, "Unknown module type [%s]" % ModuleType,\r
+                                    File=self.MetaFile, 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 Edk style library instances, which are listed in different section\r
+            Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
+            RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch]\r
+            for Record in RecordList:\r
+                File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
+                LineNo = Record[-1]\r
+                # check the file validation\r
+                ErrorCode, ErrorInfo = File.Validate('.inf')\r
+                if ErrorCode != 0:\r
+                    EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
+                                    ExtraData=ErrorInfo)\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, self._Target, self._Toolchain]\r
+                self._LibraryClasses[Library.BaseName, ':dummy:'] = Library\r
+        return self._LibraryClasses\r
+\r
+    def _ValidatePcd(self, PcdCName, TokenSpaceGuid, Setting, PcdType, LineNo):\r
+        if self._DecPcds == None:\r
+            self._DecPcds = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain)\r
+            FdfInfList = []\r
+            if GlobalData.gFdfParser:\r
+                FdfInfList = GlobalData.gFdfParser.Profile.InfList\r
+\r
+            PkgSet = set()\r
+            for Inf in FdfInfList:\r
+                ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)\r
+                if ModuleFile in self._Modules:\r
+                    continue\r
+                ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]\r
+                PkgSet.update(ModuleData.Packages)\r
+            DecPcds = {}\r
+            for Pkg in PkgSet:\r
+                for Pcd in Pkg.Pcds:\r
+                    DecPcds[Pcd[0], Pcd[1]] = Pkg.Pcds[Pcd]\r
+            self._DecPcds.update(DecPcds)\r
+\r
+        if (PcdCName, TokenSpaceGuid) not in self._DecPcds and "." in TokenSpaceGuid and (TokenSpaceGuid.split(".")[1], TokenSpaceGuid.split(".")[0]) not in self._DecPcds:\r
+            EdkLogger.error('build', PARSER_ERROR,\r
+                            "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid, PcdCName, self._Arch),\r
+                            File=self.MetaFile, Line=LineNo)\r
+        ValueList, IsValid, Index = AnalyzeDscPcd(Setting, PcdType, self._DecPcds[PcdCName, TokenSpaceGuid].DatumType)\r
+        if not IsValid and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:\r
+            EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,\r
+                            ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))\r
+        if ValueList[Index] and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:\r
+            try:\r
+                ValueList[Index] = ValueExpression(ValueList[Index], GlobalData.gPlatformPcds)(True)\r
+            except WrnExpression, Value:\r
+                ValueList[Index] = Value.result\r
+            except EvaluationException, Excpt:\r
+                if hasattr(Excpt, 'Pcd'):\r
+                    if Excpt.Pcd in GlobalData.gPlatformOtherPcds:\r
+                        EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"\r
+                                        " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"\r
+                                        " of the DSC file" % Excpt.Pcd,\r
+                                        File=self.MetaFile, Line=LineNo)\r
+                    else:\r
+                        EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,\r
+                                        File=self.MetaFile, Line=LineNo)\r
+                else:\r
+                    EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),\r
+                                    File=self.MetaFile, Line=LineNo)\r
+            if ValueList[Index] == 'True':\r
+                ValueList[Index] = '1'\r
+            elif ValueList[Index] == 'False':\r
+                ValueList[Index] = '0'\r
+        if ValueList[Index]:\r
+            Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index])\r
+            if not Valid:\r
+                EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo,\r
+                                ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName))\r
+        return ValueList\r
+\r
+    ## Retrieve all PCD settings in platform\r
+    def _GetPcds(self):\r
+        if self._Pcds == None:\r
+            self._Pcds = sdict()\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
+\r
+            self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds)\r
+        return self._Pcds\r
+\r
+    ## Retrieve [BuildOptions]\r
+    def _GetBuildOptions(self):\r
+        if self._BuildOptions == None:\r
+            self._BuildOptions = sdict()\r
+            #\r
+            # Retrieve build option for EDKII and EDK style module\r
+            #\r
+            for CodeBase in (EDKII_NAME, EDK_NAME):\r
+                RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]\r
+                for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
+                    CurKey = (ToolChainFamily, ToolChain, CodeBase)\r
+                    #\r
+                    # Only flags can be appended\r
+                    #\r
+                    if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
+                        self._BuildOptions[CurKey] = Option\r
+                    else:\r
+                        self._BuildOptions[CurKey] += ' ' + Option\r
+        return self._BuildOptions\r
+\r
+    def GetBuildOptionsByModuleType(self, Edk, ModuleType):\r
+        if self._ModuleTypeOptions == None:\r
+            self._ModuleTypeOptions = sdict()\r
+        if (Edk, ModuleType) not in self._ModuleTypeOptions:\r
+            options = sdict()\r
+            self._ModuleTypeOptions[Edk, ModuleType] = options\r
+            DriverType = '%s.%s' % (Edk, ModuleType)\r
+            CommonDriverType = '%s.%s' % ('COMMON', ModuleType)\r
+            RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, DriverType]\r
+            for ToolChainFamily, ToolChain, Option, Arch, Type, Dummy3, Dummy4 in RecordList:\r
+                if Type == DriverType or Type == CommonDriverType:\r
+                    Key = (ToolChainFamily, ToolChain, Edk)\r
+                    if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
+                        options[Key] = Option\r
+                    else:\r
+                        options[Key] += ' ' + Option\r
+        return self._ModuleTypeOptions[Edk, ModuleType]\r
+\r
+    def GetStructurePcdInfo(self, PcdSet):\r
+        structure_pcd_data = {}\r
+        for item in PcdSet:\r
+            if item[1] not in structure_pcd_data:\r
+                structure_pcd_data[item[1]] = []\r
+            structure_pcd_data[item[1]].append(item)\r
+\r
+        return structure_pcd_data\r
+\r
+    def UpdateStructuredPcds(self, TypeList, AllPcds):\r
+        Pcds = AllPcds\r
+        SkuObj = SkuClass(self.SkuIdentifier, self.SkuIds)\r
+\r
+        S_PcdSet = []\r
+        # Find out all possible PCD candidates for self._Arch\r
+        RecordList = []\r
+        for Type in TypeList:\r
+            RecordList.extend(self._RawData[Type, self._Arch])\r
+\r
+        for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
+            SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r
+            if SkuName in SkuObj.SkuIdSet and "." in TokenSpaceGuid:\r
+                S_PcdSet.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4, AnalyzePcdExpression(Setting)[0]))\r
+\r
+        # handle pcd value override\r
+        StrPcdSet = self.GetStructurePcdInfo(S_PcdSet)\r
+        S_pcd_set = {}\r
+        for str_pcd in StrPcdSet:\r
+            str_pcd_obj = Pcds.get((str_pcd.split(".")[1], str_pcd.split(".")[0]), None)\r
+            str_pcd_dec = self._DecPcds.get((str_pcd.split(".")[1], str_pcd.split(".")[0]), None)\r
+            if str_pcd_dec:\r
+                str_pcd_obj_str = StructurePcd()\r
+                str_pcd_obj_str.copy(str_pcd_dec)\r
+                if str_pcd_obj:\r
+                    str_pcd_obj_str.copy(str_pcd_obj)\r
+                    if str_pcd_obj.DefaultValue:\r
+                        str_pcd_obj_str.DefaultFromDSC = str_pcd_obj.DefaultValue\r
+                for str_pcd_data in StrPcdSet[str_pcd]:\r
+                    if str_pcd_data[2] in SkuObj.SkuIdSet:\r
+                        str_pcd_obj_str.AddOverrideValue(str_pcd_data[0], str(str_pcd_data[4]), 'DEFAULT' if str_pcd_data[2] == 'COMMON' else str_pcd_data[2],self.MetaFile.File,LineNo=str_pcd_data[3])\r
+                S_pcd_set[str_pcd.split(".")[1], str_pcd.split(".")[0]] = str_pcd_obj_str\r
+        # Add the Structure PCD that only defined in DEC, don't have override in DSC file\r
+        for Pcd in self._DecPcds:\r
+            if type (self._DecPcds[Pcd]) is StructurePcd:\r
+                if Pcd not in S_pcd_set:\r
+                    str_pcd_obj_str = StructurePcd()\r
+                    str_pcd_obj_str.copy(self._DecPcds[Pcd])\r
+                    str_pcd_obj = Pcds.get(Pcd, None)\r
+                    if str_pcd_obj:\r
+                        str_pcd_obj_str.copy(str_pcd_obj)\r
+                        if str_pcd_obj.DefaultValue:\r
+                            str_pcd_obj_str.DefaultFromDSC = str_pcd_obj.DefaultValue\r
+                    S_pcd_set[Pcd] = str_pcd_obj_str\r
+        if S_pcd_set:\r
+            GlobalData.gStructurePcd[self.Arch] = S_pcd_set\r
+        Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)\r
+        if Str_Pcd_Values:\r
+            for item in Str_Pcd_Values:\r
+                str_pcd_obj = S_pcd_set.get((item[2], item[1]))\r
+                if str_pcd_obj is None:\r
+                    raise\r
+                if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
+                                        self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
+                    if item[0] not in str_pcd_obj.SkuInfoList:\r
+                        str_pcd_obj.SkuInfoList[item[0]] = SkuInfoClass(SkuIdName=item[0], SkuId=self.SkuIds[item[0]], HiiDefaultValue=item[3])\r
+                    else:\r
+                        str_pcd_obj.SkuInfoList[item[0]].HiiDefaultValue = item[3]\r
+                elif str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r
+                                        self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r
+                    if item[0] in (SkuObj.SystemSkuId, 'DEFAULT', 'COMMON'):\r
+                        str_pcd_obj.DefaultValue = item[3]\r
+                else:\r
+                    if item[0] not in str_pcd_obj.SkuInfoList:\r
+                        str_pcd_obj.SkuInfoList[item[0]] = SkuInfoClass(SkuIdName=item[0], SkuId=self.SkuIds[item[0]], DefaultValue=item[3])\r
+                    else:\r
+                        str_pcd_obj.SkuInfoList[item[0]].DefaultValue = item[3]\r
+\r
+            for str_pcd_obj in S_pcd_set.values():\r
+                str_pcd_obj.MaxDatumSize = self.GetStructurePcdMaxSize(str_pcd_obj)\r
+                Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj\r
+\r
+        return Pcds\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 = sdict()\r
+        #\r
+        # tdict is a special dict kind of type, used for selecting correct\r
+        # PCD settings for certain ARCH\r
+        #\r
+\r
+        SkuObj = SkuClass(self.SkuIdentifier, self.SkuIds)\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
+        AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()\r
+        AvailableSkuIdSet.update({'DEFAULT':0, 'COMMON':0})\r
+        PcdValueDict = sdict()\r
+        for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
+            if SkuName not in AvailableSkuIdSet:\r
+                EdkLogger.error('Build', OPTION_VALUE_INVALID, "The SKUID name %s is not supported by the platform." % SkuName)\r
+            if "." not in TokenSpaceGuid:\r
+                PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy4))\r
+                PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting\r
+            else:\r
+                TokenSpaceGuid, PcdCName = TokenSpaceGuid.split('.')\r
+                Flag = True\r
+                for PcdItem in RecordList:\r
+                    if (TokenSpaceGuid, PcdCName) == (PcdItem[0], PcdItem[1]):\r
+                        Flag = False\r
+                        break\r
+                if Flag:\r
+                    PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, 0))\r
+                    PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = ''\r
+\r
+        for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet:\r
+            Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName]\r
+            if Setting == None:\r
+                continue\r
+            PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
+            if (PcdCName, TokenSpaceGuid) in PcdValueDict:\r
+                PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize)\r
+            else:\r
+                PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize)}\r
+\r
+        PcdsKeys = PcdValueDict.keys()\r
+        for PcdCName, TokenSpaceGuid in PcdsKeys:\r
+\r
+            PcdSetting = PcdValueDict[PcdCName, TokenSpaceGuid]\r
+            PcdValue = None\r
+            DatumType = None\r
+            MaxDatumSize = None\r
+            if 'COMMON' in PcdSetting:\r
+                PcdValue, DatumType, MaxDatumSize = PcdSetting['COMMON']\r
+            if 'DEFAULT' in PcdSetting:\r
+                PcdValue, DatumType, MaxDatumSize = PcdSetting['DEFAULT']\r
+            if SkuObj.SystemSkuId in PcdSetting:\r
+                PcdValue, DatumType, MaxDatumSize = PcdSetting[SkuObj.SystemSkuId]\r
+\r
+            Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
+                                                PcdCName,\r
+                                                TokenSpaceGuid,\r
+                                                self._PCD_TYPE_STRING_[Type],\r
+                                                DatumType,\r
+                                                PcdValue,\r
+                                                '',\r
+                                                MaxDatumSize,\r
+                                                {},\r
+                                                False,\r
+                                                None,\r
+                                                IsDsc=True)\r
+\r
+\r
+        return Pcds\r
+\r
+    def GetStructurePcdMaxSize(self, str_pcd):\r
+        pcd_default_value = str_pcd.DefaultValue\r
+        sku_values = [skuobj.HiiDefaultValue if str_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]] else skuobj.DefaultValue for skuobj in str_pcd.SkuInfoList.values()]\r
+        sku_values.append(pcd_default_value)\r
+\r
+        def get_length(value):\r
+            Value = value.strip()\r
+            if Value.startswith('GUID') and Value.endswith(')'):\r
+                return 16\r
+            if Value.startswith('L"') and Value.endswith('"'):\r
+                return len(Value[2:-1])\r
+            if Value[0] == '"' and Value[-1] == '"':\r
+                return len(Value) - 2\r
+            if Value[0] == '{' and Value[-1] == '}':\r
+                return len(Value.split(","))\r
+            if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:\r
+                return  len(list(Value[2:-1]))\r
+            if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:\r
+                return len(Value) - 2\r
+            return len(Value)\r
+\r
+        return str(max([pcd_size for pcd_size in [get_length(item) for item in sku_values]]))\r
+\r
+    def IsFieldValueAnArray (self, Value):\r
+        Value = Value.strip()\r
+        if Value.startswith('GUID') and Value.endswith(')'):\r
+            return True\r
+        if Value.startswith('L"') and Value.endswith('"')  and len(list(Value[2:-1])) > 1:\r
+            return True\r
+        if Value[0] == '"' and Value[-1] == '"' and len(list(Value[1:-1])) > 1:\r
+            return True\r
+        if Value[0] == '{' and Value[-1] == '}':\r
+            return True\r
+        if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:\r
+            print 'foo = ', list(Value[2:-1])\r
+            return True\r
+        if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:\r
+            print 'bar = ', list(Value[1:-1])\r
+            return True\r
+        return False\r
+\r
+    def ExecuteCommand (self, Command):\r
+        try:\r
+            Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\r
+        except:\r
+            print 'ERROR: Can not execute command:', Command\r
+            sys.exit(1)\r
+        Result = Process.communicate()\r
+        if Process.returncode <> 0:\r
+            print 'ERROR: Can not collect output from command:', Command\r
+        return Result[0], Result[1]\r
+\r
+    def IntToCString(self, Value, ValueSize):\r
+        Result = '"'\r
+        if not isinstance (Value, str):\r
+            for Index in range(0, ValueSize):\r
+                Result = Result + '\\x%02x' % (Value & 0xff)\r
+                Value = Value >> 8\r
+        Result = Result + '"'\r
+        return Result\r
+\r
+    def GenerateInitializeFunc(self, SkuName, DefaultStoreName, Pcd, InitByteValue, CApp):\r
+        OverrideValues = None\r
+        if Pcd.SkuOverrideValues:\r
+            OverrideValues = Pcd.SkuOverrideValues[SkuName]\r
+        CApp = CApp + 'void\n'\r
+        CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
+        CApp = CApp + '  void\n'\r
+        CApp = CApp + '  )\n'\r
+        CApp = CApp + '{\n'\r
+        CApp = CApp + '  UINT32  Size;\n'\r
+        CApp = CApp + '  UINT32  FieldSize;\n'\r
+        CApp = CApp + '  UINT8   *Value;\n'\r
+        CApp = CApp + '  UINT32  OriginalSize;\n'\r
+        CApp = CApp + '  VOID    *OriginalPcd;\n'\r
+        CApp = CApp + '  %s  *Pcd;\n' % (Pcd.DatumType)\r
+        CApp = CApp + '\n'\r
+        InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, Pcd.DefaultValue)\r
+\r
+        #\r
+        # Get current PCD value and size\r
+        #\r
+        CApp = CApp + '  OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
+\r
+        #\r
+        # Determine the size of the PCD.  For simple structures, sizeof(TYPE) provides\r
+        # the correct value.  For structures with a flexible array member, the flexible\r
+        # array member is detected, and the size is based on the highest index used with\r
+        # the flexible array member.  The flexible array member must be the last field\r
+        # in a structure.  The size formula for this case is:\r
+        # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)\r
+        #\r
+        CApp = CApp + '  Size = sizeof(%s);\n' % (Pcd.DatumType)\r
+        for FieldList in [Pcd.DefaultValues, OverrideValues]:\r
+            if not FieldList:\r
+                continue\r
+            for FieldName in FieldList:\r
+                FieldName = "." + FieldName\r
+                IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])\r
+                if IsArray:\r
+                    Value, ValueSize = ParseFieldValue (FieldList[FieldName.strip(".")][0])\r
+                        CApp = CApp + '  __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0));\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."))\r
+                else:\r
+                    NewFieldName = ''\r
+                    while '[' in  FieldName:\r
+                        NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'\r
+                        ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])\r
+                        FieldName = FieldName.split(']', 1)[1]\r
+                    FieldName = NewFieldName + FieldName\r
+                    while '[' in FieldName:\r
+                        FieldName = FieldName.rsplit('[', 1)[0]\r
+                        CApp = CApp + '  __FLEXIBLE_SIZE(Size, %s, %s, %d);\n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1)\r
+\r
+        #\r
+        # Allocate and zero buffer for the PCD\r
+        # Must handle cases where current value is smaller, larger, or same size\r
+        # Always keep that larger one as the current size\r
+        #\r
+        CApp = CApp + '  Size = (OriginalSize > Size ? OriginalSize : Size);\n'\r
+        CApp = CApp + '  Pcd     = (%s *)malloc (Size);\n' % (Pcd.DatumType)\r
+        CApp = CApp + '  memset (Pcd, 0, Size);\n'\r
+\r
+        #\r
+        # Copy current PCD value into allocated buffer.\r
+        #\r
+        CApp = CApp + '  memcpy (Pcd, OriginalPcd, OriginalSize);\n'\r
+            CApp = CApp + '  free (OriginalPcd);\n'\r
+\r
+        #\r
+        # Assign field values in PCD\r
+        #\r
+        for FieldList in [Pcd.DefaultValues, Pcd.DefaultFromDSC, OverrideValues]:\r
+            if not FieldList:\r
+                continue\r
+            if Pcd.DefaultFromDSC and FieldList == Pcd.DefaultFromDSC:\r
+                IsArray = self.IsFieldValueAnArray(FieldList)\r
+                Value, ValueSize = ParseFieldValue (FieldList)\r
+                if isinstance(Value, str):\r
+                    CApp = CApp + '  Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC)\r
+                elif IsArray:\r
+                    #\r
+                    # Use memcpy() to copy value into field\r
+                    #\r
+                    CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC)\r
+                    CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)\r
+                continue\r
+\r
+            for FieldName in FieldList:\r
+                IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])\r
+                Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])\r
+                if isinstance(Value, str):\r
+                    CApp = CApp + '  Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
+                elif IsArray:\r
+                    #\r
+                    # Use memcpy() to copy value into field\r
+                    #\r
+                    CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)\r
+                    CApp = CApp + '  Value     = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
+                    CApp = CApp + '  memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)\r
+                else:\r
+                    if ValueSize > 4:\r
+                        CApp = CApp + '  Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
+                    else:\r
+                        CApp = CApp + '  Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
+\r
+        #\r
+        # Set new PCD value and size\r
+        #\r
+        CApp = CApp + '  PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
+\r
+        #\r
+        # Free PCD\r
+        #\r
+        CApp = CApp + '  free (Pcd);\n'\r
+        CApp = CApp + '}\n'\r
+        CApp = CApp + '\n'\r
+        return InitByteValue, CApp\r
+\r
+    def GenerateByteArrayValue (self, StructuredPcds):\r
+        #\r
+        # Generate/Compile/Run C application to determine if there are any flexible array members\r
+        #\r
+        if not StructuredPcds:\r
+            return\r
+\r
+        InitByteValue = ""\r
+        CApp = PcdMainCHeader\r
+\r
+        Includes = {}\r
+        for PcdName in StructuredPcds:\r
+            Pcd = StructuredPcds[PcdName]\r
+            IncludeFile = Pcd.StructuredPcdIncludeFile\r
+            if IncludeFile not in Includes:\r
+                Includes[IncludeFile] = True\r
+                CApp = CApp + '#include <%s>\n' % (IncludeFile)\r
+        CApp = CApp + '\n'\r
+\r
+        for PcdName in StructuredPcds:\r
+            Pcd = StructuredPcds[PcdName]\r
+            if not Pcd.SkuOverrideValues:\r
+                InitByteValue, CApp = self.GenerateInitializeFunc('DEFAULT', 'STANDARD', Pcd, InitByteValue, CApp)\r
+            else:\r
+                for SkuName in Pcd.SkuOverrideValues:\r
+                    for DefaultStoreName in Pcd.DefaultStoreName:\r
+                        Pcd = StructuredPcds[PcdName]\r
+                        InitByteValue, CApp = self.GenerateInitializeFunc(SkuName, DefaultStoreName, Pcd, InitByteValue, CApp)\r
+\r
+        CApp = CApp + 'VOID\n'\r
+        CApp = CApp + 'PcdEntryPoint(\n'\r
+        CApp = CApp + '  VOID\n'\r
+        CApp = CApp + '  )\n'\r
+        CApp = CApp + '{\n'\r
+        for Pcd in StructuredPcds.values():\r
+            if not Pcd.SkuOverrideValues:\r
+                CApp = CApp + '  Initialize_%s_%s_%s_%s();\n' % ('DEFAULT', 'STANDARD', Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
+            else:\r
+                for SkuName in Pcd.SkuOverrideValues:\r
+                    for DefaultStoreName in Pcd.DefaultStoreName:\r
+                        CApp = CApp + '  Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
+        CApp = CApp + '}\n'\r
+\r
+        CApp = CApp + PcdMainCEntry + '\n'\r
+\r
+        if not os.path.exists(self.OutputPath):\r
+            os.makedirs(self.OutputPath)\r
+        CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)\r
+        File = open (CAppBaseFileName + '.c', 'w')\r
+        File.write(CApp)\r
+        File.close()\r
+\r
+        MakeApp = PcdMakefileHeader\r
+        if sys.platform == "win32":\r
+            MakeApp = MakeApp + 'ARCH = IA32\nAPPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = '\r
+        else:\r
+            MakeApp = MakeApp + PcdGccMakefile\r
+            MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o\n' % (self.OutputPath, PcdValueInitName) + \\r
+                      'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'BUILD_CFLAGS += -Wno-error\n' + 'INCLUDE +='\r
+\r
+        PlatformInc = {}\r
+        for Cache in self._Bdb._CACHE_.values():\r
+            if Cache.MetaFile.Ext.lower() != '.dec':\r
+                continue\r
+            if Cache.Includes:\r
+                if str(Cache.MetaFile.Path) not in PlatformInc:\r
+                    PlatformInc[str(Cache.MetaFile.Path)] = Cache.Includes\r
+\r
+        PcdDependDEC = []\r
+        for Pcd in StructuredPcds.values():\r
+            for PackageDec in Pcd.PackageDecs:\r
+                Package = os.path.normpath(mws.join(GlobalData.gWorkspace, PackageDec))\r
+                if not os.path.exists(Package):\r
+                    EdkLogger.error('Build', RESOURCE_NOT_AVAILABLE, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))\r
+                if Package not in PcdDependDEC:\r
+                    PcdDependDEC.append(Package)\r
+\r
+        if PlatformInc and PcdDependDEC:\r
+            for pkg in PcdDependDEC:\r
+                if pkg in PlatformInc:\r
+                    for inc in PlatformInc[pkg]:\r
+                        MakeApp += '-I'  + str(inc) + ' '\r
+        MakeApp = MakeApp + '\n'\r
+        if sys.platform == "win32":\r
+            MakeApp = MakeApp + PcdMakefileEnd\r
+        MakeFileName = os.path.join(self.OutputPath, 'Makefile')\r
+        File = open (MakeFileName, 'w')\r
+        File.write(MakeApp)\r
+        File.close()\r
+\r
+        InputValueFile = os.path.join(self.OutputPath, 'Input.txt')\r
+        OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')\r
+        File = open (InputValueFile, 'w')\r
+        File.write(InitByteValue)\r
+        File.close()\r
+\r
+        if sys.platform == "win32":\r
+            StdOut, StdErr = self.ExecuteCommand ('nmake clean & nmake -f %s' % (MakeFileName))\r
+        else:\r
+            StdOut, StdErr = self.ExecuteCommand ('make clean & make -f %s' % (MakeFileName))\r
+        Messages = StdOut.split('\r')\r
+        for Message in Messages:\r
+            if " error " in Message:\r
+                FileInfo = Message.strip().split('(')\r
+                if len (FileInfo) > 0:\r
+                    FileName = FileInfo [0]\r
+                    FileLine = FileInfo [1].split (')')[0]\r
+                else:\r
+                    FileInfo = Message.strip().split(':')\r
+                    FileName = FileInfo [0]\r
+                    FileLine = FileInfo [1]\r
+\r
+                File = open (FileName, 'r')\r
+                FileData = File.readlines()\r
+                File.close()\r
+                error_line = FileData[int (FileLine) - 1]\r
+                if r"//" in error_line:\r
+                    c_line,dsc_line = error_line.split(r"//")\r
+                else:\r
+                    dsc_line = error_line\r
+\r
+                message_itmes = Message.split(":")\r
+                for item in message_itmes:\r
+                    if "PcdValueInit.c" in item:\r
+                        message_itmes[message_itmes.index(item)] = dsc_line.strip()\r
+\r
+                EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, ":".join(message_itmes[1:]))\r
+\r
+        PcdValueInitExe = PcdValueInitName\r
+        if not sys.platform == "win32":\r
+            PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName)\r
+\r
+        StdOut, StdErr = self.ExecuteCommand (PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile))\r
+        File = open (OutputValueFile, 'r')\r
+        FileBuffer = File.readlines()\r
+        File.close()\r
+\r
+        StructurePcdSet = []\r
+        for Pcd in FileBuffer:\r
+            PcdValue = Pcd.split ('|')\r
+            PcdInfo = PcdValue[0].split ('.')\r
+            StructurePcdSet.append((PcdInfo[0], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))\r
+        return StructurePcdSet\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
+\r
+        SkuObj = SkuClass(self.SkuIdentifier, self.SkuIds)\r
+\r
+        Pcds = sdict()\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
+        PcdList = []\r
+        # Find out all possible PCD candidates for self._Arch\r
+        RecordList = self._RawData[Type, self._Arch]\r
+        AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()\r
+\r
+        AvailableSkuIdSet.update({'DEFAULT':0, 'COMMON':0})\r
+\r
+        for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
+            if SkuName not in AvailableSkuIdSet:\r
+                EdkLogger.error('Build', OPTION_VALUE_INVALID, "The SKUID name %s is not supported by the platform." % SkuName)\r
+            if "." not in TokenSpaceGuid:\r
+                PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4))\r
+            PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
+\r
+        # Remove redundant PCD candidates, per the ARCH and SKU\r
+        for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:\r
+\r
+            Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
+            if Setting == None:\r
+                continue\r
+\r
+            PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
+            SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', '', PcdValue)\r
+            if (PcdCName, TokenSpaceGuid) in Pcds.keys():\r
+                pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r
+                pcdObject.SkuInfoList[SkuName] = SkuInfo\r
+                if MaxDatumSize.strip():\r
+                    CurrentMaxSize = int(MaxDatumSize.strip(), 0)\r
+                else:\r
+                    CurrentMaxSize = 0\r
+                if pcdObject.MaxDatumSize:\r
+                    PcdMaxSize = int(pcdObject.MaxDatumSize, 0)\r
+                else:\r
+                    PcdMaxSize = 0\r
+                if CurrentMaxSize > PcdMaxSize:\r
+                    pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
+            else:\r
+                Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
+                                                    PcdCName,\r
+                                                    TokenSpaceGuid,\r
+                                                    self._PCD_TYPE_STRING_[Type],\r
+                                                    DatumType,\r
+                                                    PcdValue,\r
+                                                    '',\r
+                                                    MaxDatumSize,\r
+                                                    {SkuName : SkuInfo},\r
+                                                    False,\r
+                                                    None,\r
+                                                    IsDsc=True)\r
+\r
+        for pcd in Pcds.values():\r
+            pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r
+            if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
+                valuefromDec = pcdDecObject.DefaultValue\r
+                SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec)\r
+                pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
+            elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
+                pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
+                del(pcd.SkuInfoList['COMMON'])\r
+            elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
+                del(pcd.SkuInfoList['COMMON'])\r
+            if SkuObj.SkuUsageType == SkuObj.SINGLE:\r
+                if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():\r
+                    pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
+                del(pcd.SkuInfoList['DEFAULT'])\r
+\r
+        return Pcds\r
+\r
+    def CompareVarAttr(self, Attr1, Attr2):\r
+        if not Attr1 or not Attr2:  # for empty string\r
+            return True\r
+        Attr1s = [attr.strip() for attr in Attr1.split(",")]\r
+        Attr1Set = set(Attr1s)\r
+        Attr2s = [attr.strip() for attr in Attr2.split(",")]\r
+        Attr2Set = set(Attr2s)\r
+        if Attr2Set == Attr1Set:\r
+            return True\r
+        else:\r
+            return False\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
+\r
+        SkuObj = SkuClass(self.SkuIdentifier, self.SkuIds)\r
+        VariableAttrs = {}\r
+\r
+        Pcds = sdict()\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
+        AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()\r
+\r
+        AvailableSkuIdSet.update({'DEFAULT':0, 'COMMON':0})\r
+        for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
+            if SkuName not in AvailableSkuIdSet:\r
+                EdkLogger.error('Build', OPTION_VALUE_INVALID, "The SKUID name %s is not supported by the platform." % SkuName)\r
+            if "." not in TokenSpaceGuid:\r
+                PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy4))\r
+            PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
+\r
+\r
+        # Remove redundant PCD candidates, per the ARCH and SKU\r
+        for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet:\r
+\r
+            Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
+            if Setting == None:\r
+                continue\r
+            VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
+\r
+            rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)\r
+            if not rt:\r
+                EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),\r
+                        ExtraData="[%s]" % VarAttribute)\r
+            ExceedMax = False\r
+            FormatCorrect = True\r
+            if VariableOffset.isdigit():\r
+                if int(VariableOffset, 10) > 0xFFFF:\r
+                    ExceedMax = True\r
+            elif re.match(r'[\t\s]*0[xX][a-fA-F0-9]+$', VariableOffset):\r
+                if int(VariableOffset, 16) > 0xFFFF:\r
+                    ExceedMax = True\r
+            # For Offset written in "A.B"\r
+            elif VariableOffset.find('.') > -1:\r
+                VariableOffsetList = VariableOffset.split(".")\r
+                if not (len(VariableOffsetList) == 2\r
+                        and IsValidWord(VariableOffsetList[0])\r
+                        and IsValidWord(VariableOffsetList[1])):\r
+                    FormatCorrect = False\r
+            else:\r
+                FormatCorrect = False\r
+            if not FormatCorrect:\r
+                EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid, PcdCName)))\r
+\r
+            if ExceedMax:\r
+                EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)))\r
+            if (VariableName, VariableGuid) not in VariableAttrs:\r
+                VariableAttrs[(VariableName, VariableGuid)] = VarAttribute\r
+            else:\r
+                if not self.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):\r
+                    EdkLogger.error('Build', PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR, "The variable %s.%s for DynamicHii PCDs has conflicting attributes [%s] and [%s] " % (VariableGuid, VariableName, VarAttribute, VariableAttrs[(VariableName, VariableGuid)]))\r
+\r
+            SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute)\r
+            pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]\r
+            if (PcdCName, TokenSpaceGuid) in Pcds.keys():\r
+                pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r
+                pcdObject.SkuInfoList[SkuName] = SkuInfo\r
+            else:\r
+                Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
+                                                PcdCName,\r
+                                                TokenSpaceGuid,\r
+                                                self._PCD_TYPE_STRING_[Type],\r
+                                                '',\r
+                                                DefaultValue,\r
+                                                '',\r
+                                                '',\r
+                                                {SkuName : SkuInfo},\r
+                                                False,\r
+                                                None,\r
+                                                pcdDecObject.validateranges,\r
+                                                pcdDecObject.validlists,\r
+                                                pcdDecObject.expressions,\r
+                                                IsDsc=True)\r
+\r
+\r
+        for pcd in Pcds.values():\r
+            SkuInfoObj = pcd.SkuInfoList.values()[0]\r
+            pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r
+            # Only fix the value while no value provided in DSC file.\r
+            for sku in pcd.SkuInfoList.values():\r
+                if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue == None):\r
+                    sku.HiiDefaultValue = pcdDecObject.DefaultValue\r
+            if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
+                valuefromDec = pcdDecObject.DefaultValue\r
+                SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec)\r
+                pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
+            elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
+                pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
+                del(pcd.SkuInfoList['COMMON'])\r
+            elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
+                del(pcd.SkuInfoList['COMMON'])\r
+\r
+            if SkuObj.SkuUsageType == SkuObj.SINGLE:\r
+                if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():\r
+                    pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
+                del(pcd.SkuInfoList['DEFAULT'])\r
+\r
+            if pcd.MaxDatumSize.strip():\r
+                MaxSize = int(pcd.MaxDatumSize, 0)\r
+            else:\r
+                MaxSize = 0\r
+            if pcdDecObject.DatumType == 'VOID*':\r
+                for (skuname, skuobj) in pcd.SkuInfoList.items():\r
+                    datalen = 0\r
+                    if skuobj.HiiDefaultValue.startswith("L"):\r
+                        datalen = (len(skuobj.HiiDefaultValue) - 3 + 1) * 2\r
+                    elif skuobj.HiiDefaultValue.startswith("{"):\r
+                        datalen = len(skuobj.HiiDefaultValue.split(","))\r
+                    else:\r
+                        datalen = len(skuobj.HiiDefaultValue) - 2 + 1\r
+                    if datalen > MaxSize:\r
+                        MaxSize = datalen\r
+                pcd.MaxDatumSize = str(MaxSize)\r
+        return Pcds\r
+\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
+\r
+        SkuObj = SkuClass(self.SkuIdentifier, self.SkuIds)\r
+\r
+        Pcds = sdict()\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
+        PcdList = []\r
+\r
+        # Find out all possible PCD candidates for self._Arch\r
+        RecordList = self._RawData[Type, self._Arch]\r
+        AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()\r
+\r
+        AvailableSkuIdSet.update({'DEFAULT':0, 'COMMON':0})\r
+        for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
+            if SkuName not in AvailableSkuIdSet:\r
+                EdkLogger.error('Build', OPTION_VALUE_INVALID, "The SKUID name %s is not supported by the platform." % SkuName)\r
+            if "." not in TokenSpaceGuid:\r
+                PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4))\r
+            PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
+\r
+        # Remove redundant PCD candidates, per the ARCH and SKU\r
+        for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:\r
+            Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
+            if Setting == None:\r
+                continue\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 = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
+            SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', VpdOffset, InitialValue)\r
+            if (PcdCName, TokenSpaceGuid) in Pcds.keys():\r
+                pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r
+                pcdObject.SkuInfoList[SkuName] = SkuInfo\r
+                if MaxDatumSize.strip():\r
+                    CurrentMaxSize = int(MaxDatumSize.strip(), 0)\r
+                else:\r
+                    CurrentMaxSize = 0\r
+                if pcdObject.MaxDatumSize:\r
+                    PcdMaxSize = int(pcdObject.MaxDatumSize, 0)\r
+                else:\r
+                    PcdMaxSize = 0\r
+                if CurrentMaxSize > PcdMaxSize:\r
+                    pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
+            else:\r
+                Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
+                                                PcdCName,\r
+                                                TokenSpaceGuid,\r
+                                                self._PCD_TYPE_STRING_[Type],\r
+                                                '',\r
+                                                InitialValue,\r
+                                                '',\r
+                                                MaxDatumSize,\r
+                                                {SkuName : SkuInfo},\r
+                                                False,\r
+                                                None,\r
+                                                IsDsc=True)\r
+        for pcd in Pcds.values():\r
+            SkuInfoObj = pcd.SkuInfoList.values()[0]\r
+            pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r
+            if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
+                valuefromDec = pcdDecObject.DefaultValue\r
+                SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', SkuInfoObj.VpdOffset, valuefromDec)\r
+                pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
+            elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
+                pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
+                del(pcd.SkuInfoList['COMMON'])\r
+            elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
+                del(pcd.SkuInfoList['COMMON'])\r
+            if SkuObj.SkuUsageType == SkuObj.SINGLE:\r
+                if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():\r
+                    pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
+                del(pcd.SkuInfoList['DEFAULT'])\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.MetaFile = 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(Name, Guid, '', '', '', '', '', {}, False, None)\r
+        self.Pcds[Name, Guid].DefaultValue = Value\r
+\r
+    _Macros             = property(_GetMacros)\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
+    SkuIdentifier       = property(_GetSkuIdentifier)\r
+    AvilableSkuIds      = property(_GetAviableSkuIds)\r
+    PcdInfoFlag         = property(_GetPcdInfoFlag)\r
+    VarCheckFlag        = property(_GetVarCheckFlag)\r
+    FlashDefinition     = property(_GetFdfFile)\r
+    Prebuild            = property(_GetPrebuild)\r
+    Postbuild           = property(_GetPostbuild)\r
+    BuildNumber         = property(_GetBuildNumber)\r
+    MakefileName        = property(_GetMakefileName)\r
+    BsBaseAddress       = property(_GetBsBaseAddress)\r
+    RtBaseAddress       = property(_GetRtBaseAddress)\r
+    LoadFixAddress      = property(_GetLoadFixAddress)\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
+    LibraryClasses      = property(_GetLibraryClasses)\r
+    Pcds                = property(_GetPcds)\r
+    BuildOptions        = property(_GetBuildOptions)\r
diff --git a/BaseTools/Source/Python/Workspace/InfBuildData.py b/BaseTools/Source/Python/Workspace/InfBuildData.py
new file mode 100644 (file)
index 0000000..7115140
--- /dev/null
@@ -0,0 +1,1212 @@
+## @file\r
+# This file is used to create a database used by build tool\r
+#\r
+# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
+# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<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
+# 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
+from Common.String import *\r
+from Common.DataType import *\r
+from Common.Misc import *\r
+from types import *\r
+\r
+from Workspace.BuildClassObject import ModuleBuildClassObject, LibraryClassObject, PcdClassObject\r
+## Module build information from INF file\r
+#\r
+#  This class is used to retrieve information stored in database and convert them\r
+# into ModuleBuildClassObject form for easier use for AutoGen.\r
+#\r
+class InfBuildData(ModuleBuildClassObject):\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 InfBuildData directly\r
+    _PROPERTY_ = {\r
+        #\r
+        # Required Fields\r
+        #\r
+        TAB_INF_DEFINES_BASE_NAME                   : "_BaseName",\r
+        TAB_INF_DEFINES_FILE_GUID                   : "_Guid",\r
+        TAB_INF_DEFINES_MODULE_TYPE                 : "_ModuleType",\r
+        #\r
+        # Optional Fields\r
+        #\r
+        # TAB_INF_DEFINES_INF_VERSION                 : "_AutoGenVersion",\r
+        TAB_INF_DEFINES_COMPONENT_TYPE              : "_ComponentType",\r
+        TAB_INF_DEFINES_MAKEFILE_NAME               : "_MakefileName",\r
+        # TAB_INF_DEFINES_CUSTOM_MAKEFILE             : "_CustomMakefile",\r
+        TAB_INF_DEFINES_DPX_SOURCE                  :"_DxsFile",\r
+        TAB_INF_DEFINES_VERSION_NUMBER              : "_Version",\r
+        TAB_INF_DEFINES_VERSION_STRING              : "_Version",\r
+        TAB_INF_DEFINES_VERSION                     : "_Version",\r
+        TAB_INF_DEFINES_PCD_IS_DRIVER               : "_PcdIsDriver",\r
+        TAB_INF_DEFINES_SHADOW                      : "_Shadow",\r
+\r
+        TAB_COMPONENTS_SOURCE_OVERRIDE_PATH         : "_SourceOverridePath",\r
+    }\r
+\r
+    # dict used to convert Component type to Module type\r
+    _MODULE_TYPE_ = {\r
+        "LIBRARY"               :   "BASE",\r
+        "SECURITY_CORE"         :   "SEC",\r
+        "PEI_CORE"              :   "PEI_CORE",\r
+        "COMBINED_PEIM_DRIVER"  :   "PEIM",\r
+        "PIC_PEIM"              :   "PEIM",\r
+        "RELOCATABLE_PEIM"      :   "PEIM",\r
+        "PE32_PEIM"             :   "PEIM",\r
+        "BS_DRIVER"             :   "DXE_DRIVER",\r
+        "RT_DRIVER"             :   "DXE_RUNTIME_DRIVER",\r
+        "SAL_RT_DRIVER"         :   "DXE_SAL_DRIVER",\r
+        "DXE_SMM_DRIVER"        :   "DXE_SMM_DRIVER",\r
+    #    "SMM_DRIVER"            :   "DXE_SMM_DRIVER",\r
+    #    "BS_DRIVER"             :   "DXE_SMM_DRIVER",\r
+    #    "BS_DRIVER"             :   "UEFI_DRIVER",\r
+        "APPLICATION"           :   "UEFI_APPLICATION",\r
+        "LOGO"                  :   "BASE",\r
+    }\r
+\r
+    # regular expression for converting XXX_FLAGS in [nmake] section to new type\r
+    _NMAKE_FLAG_PATTERN_ = re.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re.UNICODE)\r
+    # dict used to convert old tool name used in [nmake] section to new ones\r
+    _TOOL_CODE_ = {\r
+        "C"         :   "CC",\r
+        "LIB"       :   "SLINK",\r
+        "LINK"      :   "DLINK",\r
+    }\r
+\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        The name of platform employing this module\r
+    #   @param      Macros          Macros used for replacement in DSC file\r
+    #\r
+    def __init__(self, FilePath, RawData, BuildDatabase, Arch='COMMON', Target=None, Toolchain=None):\r
+        self.MetaFile = FilePath\r
+        self._ModuleDir = FilePath.Dir\r
+        self._RawData = RawData\r
+        self._Bdb = BuildDatabase\r
+        self._Arch = Arch\r
+        self._Target = Target\r
+        self._Toolchain = Toolchain\r
+        self._Platform = 'COMMON'\r
+        self._SourceOverridePath = None\r
+        if FilePath.Key in GlobalData.gOverrideDir:\r
+            self._SourceOverridePath = GlobalData.gOverrideDir[FilePath.Key]\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 InfBuildData to None\r
+    def _Clear(self):\r
+        self._HeaderComments = None\r
+        self._TailComments = None\r
+        self._Header_               = None\r
+        self._AutoGenVersion        = None\r
+        self._BaseName              = None\r
+        self._DxsFile               = None\r
+        self._ModuleType            = None\r
+        self._ComponentType         = None\r
+        self._BuildType             = None\r
+        self._Guid                  = None\r
+        self._Version               = None\r
+        self._PcdIsDriver           = None\r
+        self._BinaryModule          = None\r
+        self._Shadow                = None\r
+        self._MakefileName          = None\r
+        self._CustomMakefile        = None\r
+        self._Specification         = None\r
+        self._LibraryClass          = None\r
+        self._ModuleEntryPointList  = None\r
+        self._ModuleUnloadImageList = None\r
+        self._ConstructorList       = None\r
+        self._DestructorList        = None\r
+        self._Defs                  = None\r
+        self._Binaries              = None\r
+        self._Sources               = None\r
+        self._LibraryClasses        = None\r
+        self._Libraries             = None\r
+        self._Protocols             = None\r
+        self._ProtocolComments      = None\r
+        self._Ppis                  = None\r
+        self._PpiComments           = None\r
+        self._Guids                 = None\r
+        self._GuidsUsedByPcd        = sdict()\r
+        self._GuidComments          = None\r
+        self._Includes              = None\r
+        self._Packages              = None\r
+        self._Pcds                  = None\r
+        self._PcdComments           = None\r
+        self._BuildOptions          = None\r
+        self._Depex                 = None\r
+        self._DepexExpression       = None\r
+        self.__Macros               = None\r
+\r
+    ## Get current effective macros\r
+    def _GetMacros(self):\r
+        if self.__Macros == None:\r
+            self.__Macros = {}\r
+            # EDK_GLOBAL defined macros can be applied to EDK module\r
+            if self.AutoGenVersion < 0x00010005:\r
+                self.__Macros.update(GlobalData.gEdkGlobal)\r
+                self.__Macros.update(GlobalData.gGlobalDefines)\r
+        return self.__Macros\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
+    ## Return the name of platform employing this module\r
+    def _GetPlatform(self):\r
+        return self._Platform\r
+\r
+    ## Change the name of platform employing this module\r
+    #\r
+    #   Changing the default name of platform to another may affect some information\r
+    # because they may be PLATFORM-related. That's why we need to clear all internal\r
+    # used members, in order to cause all information to be re-retrieved.\r
+    #\r
+    def _SetPlatform(self, Value):\r
+        if self._Platform == Value:\r
+            return\r
+        self._Platform = Value\r
+        self._Clear()\r
+    def _GetHeaderComments(self):\r
+        if not self._HeaderComments:\r
+            self._HeaderComments = []\r
+            RecordList = self._RawData[MODEL_META_DATA_HEADER_COMMENT]\r
+            for Record in RecordList:\r
+                self._HeaderComments.append(Record[0])\r
+        return self._HeaderComments\r
+    def _GetTailComments(self):\r
+        if not self._TailComments:\r
+            self._TailComments = []\r
+            RecordList = self._RawData[MODEL_META_DATA_TAIL_COMMENT]\r
+            for Record in RecordList:\r
+                self._TailComments.append(Record[0])\r
+        return self._TailComments\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, self._Platform]\r
+        for Record in RecordList:\r
+            Name, Value = Record[1], ReplaceMacro(Record[2], self._Macros, False)\r
+            # items defined _PROPERTY_ don't need additional processing\r
+            if Name in self:\r
+                self[Name] = Value\r
+                if self._Defs == None:\r
+                    self._Defs = sdict()\r
+                self._Defs[Name] = Value\r
+                self._Macros[Name] = Value\r
+            # some special items in [Defines] section need special treatment\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[Name] = GetHexVerValue(Value)\r
+                if self._Specification[Name] == None:\r
+                    EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
+                                    "'%s' format is not supported for %s" % (Value, Name),\r
+                                    File=self.MetaFile, Line=Record[-1])\r
+            elif Name == 'LIBRARY_CLASS':\r
+                if self._LibraryClass == None:\r
+                    self._LibraryClass = []\r
+                ValueList = GetSplitValueList(Value)\r
+                LibraryClass = ValueList[0]\r
+                if len(ValueList) > 1:\r
+                    SupModuleList = GetSplitValueList(ValueList[1], ' ')\r
+                else:\r
+                    SupModuleList = SUP_MODULE_LIST\r
+                self._LibraryClass.append(LibraryClassObject(LibraryClass, SupModuleList))\r
+            elif Name == 'ENTRY_POINT':\r
+                if self._ModuleEntryPointList == None:\r
+                    self._ModuleEntryPointList = []\r
+                self._ModuleEntryPointList.append(Value)\r
+            elif Name == 'UNLOAD_IMAGE':\r
+                if self._ModuleUnloadImageList == None:\r
+                    self._ModuleUnloadImageList = []\r
+                if not Value:\r
+                    continue\r
+                self._ModuleUnloadImageList.append(Value)\r
+            elif Name == 'CONSTRUCTOR':\r
+                if self._ConstructorList == None:\r
+                    self._ConstructorList = []\r
+                if not Value:\r
+                    continue\r
+                self._ConstructorList.append(Value)\r
+            elif Name == 'DESTRUCTOR':\r
+                if self._DestructorList == None:\r
+                    self._DestructorList = []\r
+                if not Value:\r
+                    continue\r
+                self._DestructorList.append(Value)\r
+            elif Name == TAB_INF_DEFINES_CUSTOM_MAKEFILE:\r
+                TokenList = GetSplitValueList(Value)\r
+                if self._CustomMakefile == None:\r
+                    self._CustomMakefile = {}\r
+                if len(TokenList) < 2:\r
+                    self._CustomMakefile['MSFT'] = TokenList[0]\r
+                    self._CustomMakefile['GCC'] = TokenList[0]\r
+                else:\r
+                    if TokenList[0] not in ['MSFT', 'GCC']:\r
+                        EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
+                                        "No supported family [%s]" % TokenList[0],\r
+                                        File=self.MetaFile, Line=Record[-1])\r
+                    self._CustomMakefile[TokenList[0]] = TokenList[1]\r
+            else:\r
+                if self._Defs == None:\r
+                    self._Defs = sdict()\r
+                self._Defs[Name] = Value\r
+                self._Macros[Name] = Value\r
+\r
+        #\r
+        # Retrieve information in sections specific to Edk.x modules\r
+        #\r
+        if self.AutoGenVersion >= 0x00010005:\r
+            if not self._ModuleType:\r
+                EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
+                                "MODULE_TYPE is not given", File=self.MetaFile)\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[1]\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._Specification == None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x00010032):\r
+                if self._ModuleType == SUP_MODULE_MM_CORE_STANDALONE:\r
+                    EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "MM_CORE_STANDALONE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x00010032", File=self.MetaFile)\r
+                if self._ModuleType == SUP_MODULE_MM_STANDALONE:\r
+                    EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "MM_STANDALONE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x00010032", File=self.MetaFile)\r
+            if self._Defs and 'PCI_DEVICE_ID' in self._Defs and 'PCI_VENDOR_ID' in self._Defs \\r
+               and 'PCI_CLASS_CODE' in self._Defs and 'PCI_REVISION' in self._Defs:\r
+                self._BuildType = 'UEFI_OPTIONROM'\r
+                if 'PCI_COMPRESS' in self._Defs:\r
+                    if self._Defs['PCI_COMPRESS'] not in ('TRUE', 'FALSE'):\r
+                        EdkLogger.error("build", FORMAT_INVALID, "Expected TRUE/FALSE for PCI_COMPRESS: %s" % self.MetaFile)\r
+\r
+            elif self._Defs and 'UEFI_HII_RESOURCE_SECTION' in self._Defs \\r
+               and self._Defs['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':\r
+                self._BuildType = 'UEFI_HII'\r
+            else:\r
+                self._BuildType = self._ModuleType.upper()\r
+\r
+            if self._DxsFile:\r
+                File = PathClass(NormPath(self._DxsFile), self._ModuleDir, Arch=self._Arch)\r
+                # check the file validation\r
+                ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)\r
+                if ErrorCode != 0:\r
+                    EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,\r
+                                    File=self.MetaFile, Line=LineNo)\r
+                if self.Sources == None:\r
+                    self._Sources = []\r
+                self._Sources.append(File)\r
+        else:\r
+            if not self._ComponentType:\r
+                EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
+                                "COMPONENT_TYPE is not given", File=self.MetaFile)\r
+            self._BuildType = self._ComponentType.upper()\r
+            if self._ComponentType in self._MODULE_TYPE_:\r
+                self._ModuleType = self._MODULE_TYPE_[self._ComponentType]\r
+            if self._ComponentType == 'LIBRARY':\r
+                self._LibraryClass = [LibraryClassObject(self._BaseName, SUP_MODULE_LIST)]\r
+            # make use some [nmake] section macros\r
+            Macros = self._Macros\r
+            Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
+            Macros['PROCESSOR'] = self._Arch\r
+            RecordList = self._RawData[MODEL_META_DATA_NMAKE, self._Arch, self._Platform]\r
+            for Name, Value, Dummy, Arch, Platform, ID, LineNo in RecordList:\r
+                Value = ReplaceMacro(Value, Macros, True)\r
+                if Name == "IMAGE_ENTRY_POINT":\r
+                    if self._ModuleEntryPointList == None:\r
+                        self._ModuleEntryPointList = []\r
+                    self._ModuleEntryPointList.append(Value)\r
+                elif Name == "DPX_SOURCE":\r
+                    File = PathClass(NormPath(Value), self._ModuleDir, Arch=self._Arch)\r
+                    # check the file validation\r
+                    ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)\r
+                    if ErrorCode != 0:\r
+                        EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,\r
+                                        File=self.MetaFile, Line=LineNo)\r
+                    if self.Sources == None:\r
+                        self._Sources = []\r
+                    self._Sources.append(File)\r
+                else:\r
+                    ToolList = self._NMAKE_FLAG_PATTERN_.findall(Name)\r
+                    if len(ToolList) == 0 or len(ToolList) != 1:\r
+                        pass\r
+#                        EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,\r
+#                                       File=self.MetaFile, Line=LineNo)\r
+                    else:\r
+                        if self._BuildOptions == None:\r
+                            self._BuildOptions = sdict()\r
+\r
+                        if ToolList[0] in self._TOOL_CODE_:\r
+                            Tool = self._TOOL_CODE_[ToolList[0]]\r
+                        else:\r
+                            Tool = ToolList[0]\r
+                        ToolChain = "*_*_*_%s_FLAGS" % Tool\r
+                        ToolChainFamily = 'MSFT'  # Edk.x only support MSFT tool chain\r
+                        # ignore not replaced macros in value\r
+                        ValueList = GetSplitList(' ' + Value, '/D')\r
+                        Dummy = ValueList[0]\r
+                        for Index in range(1, len(ValueList)):\r
+                            if ValueList[Index][-1] == '=' or ValueList[Index] == '':\r
+                                continue\r
+                            Dummy = Dummy + ' /D ' + ValueList[Index]\r
+                        Value = Dummy.strip()\r
+                        if (ToolChainFamily, ToolChain) not in self._BuildOptions:\r
+                            self._BuildOptions[ToolChainFamily, ToolChain] = Value\r
+                        else:\r
+                            OptionString = self._BuildOptions[ToolChainFamily, ToolChain]\r
+                            self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Value\r
+        # set _Header to non-None in order to avoid database re-querying\r
+        self._Header_ = 'DUMMY'\r
+\r
+    ## Retrieve file version\r
+    def _GetInfVersion(self):\r
+        if self._AutoGenVersion == None:\r
+            RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
+            for Record in RecordList:\r
+                if Record[1] == TAB_INF_DEFINES_INF_VERSION:\r
+                    if '.' in Record[2]:\r
+                        ValueList = Record[2].split('.')\r
+                        Major = '%04o' % int(ValueList[0], 0)\r
+                        Minor = '%04o' % int(ValueList[1], 0)\r
+                        self._AutoGenVersion = int('0x' + Major + Minor, 0)\r
+                    else:\r
+                        self._AutoGenVersion = int(Record[2], 0)\r
+                    break\r
+            if self._AutoGenVersion == None:\r
+                self._AutoGenVersion = 0x00010000\r
+        return self._AutoGenVersion\r
+\r
+    ## Retrieve BASE_NAME\r
+    def _GetBaseName(self):\r
+        if self._BaseName == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._BaseName == None:\r
+                EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BASE_NAME name", File=self.MetaFile)\r
+        return self._BaseName\r
+\r
+    ## Retrieve DxsFile\r
+    def _GetDxsFile(self):\r
+        if self._DxsFile == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._DxsFile == None:\r
+                self._DxsFile = ''\r
+        return self._DxsFile\r
+\r
+    ## Retrieve MODULE_TYPE\r
+    def _GetModuleType(self):\r
+        if self._ModuleType == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._ModuleType == None:\r
+                self._ModuleType = 'BASE'\r
+            if self._ModuleType not in SUP_MODULE_LIST:\r
+                self._ModuleType = "USER_DEFINED"\r
+        return self._ModuleType\r
+\r
+    ## Retrieve COMPONENT_TYPE\r
+    def _GetComponentType(self):\r
+        if self._ComponentType == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._ComponentType == None:\r
+                self._ComponentType = 'USER_DEFINED'\r
+        return self._ComponentType\r
+\r
+    ## Retrieve "BUILD_TYPE"\r
+    def _GetBuildType(self):\r
+        if self._BuildType == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if not self._BuildType:\r
+                self._BuildType = "BASE"\r
+        return self._BuildType\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
+                self._Guid = '00000000-0000-0000-0000-000000000000'\r
+        return self._Guid\r
+\r
+    ## Retrieve module 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 = '0.0'\r
+        return self._Version\r
+\r
+    ## Retrieve PCD_IS_DRIVER\r
+    def _GetPcdIsDriver(self):\r
+        if self._PcdIsDriver == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._PcdIsDriver == None:\r
+                self._PcdIsDriver = ''\r
+        return self._PcdIsDriver\r
+\r
+    ## Retrieve SHADOW\r
+    def _GetShadow(self):\r
+        if self._Shadow == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._Shadow != None and self._Shadow.upper() == 'TRUE':\r
+                self._Shadow = True\r
+            else:\r
+                self._Shadow = False\r
+        return self._Shadow\r
+\r
+    ## Retrieve CUSTOM_MAKEFILE\r
+    def _GetMakefile(self):\r
+        if self._CustomMakefile == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._CustomMakefile == None:\r
+                self._CustomMakefile = {}\r
+        return self._CustomMakefile\r
+\r
+    ## Retrieve EFI_SPECIFICATION_VERSION\r
+    def _GetSpec(self):\r
+        if self._Specification == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._Specification == None:\r
+                self._Specification = {}\r
+        return self._Specification\r
+\r
+    ## Retrieve LIBRARY_CLASS\r
+    def _GetLibraryClass(self):\r
+        if self._LibraryClass == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._LibraryClass == None:\r
+                self._LibraryClass = []\r
+        return self._LibraryClass\r
+\r
+    ## Retrieve ENTRY_POINT\r
+    def _GetEntryPoint(self):\r
+        if self._ModuleEntryPointList == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._ModuleEntryPointList == None:\r
+                self._ModuleEntryPointList = []\r
+        return self._ModuleEntryPointList\r
+\r
+    ## Retrieve UNLOAD_IMAGE\r
+    def _GetUnloadImage(self):\r
+        if self._ModuleUnloadImageList == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._ModuleUnloadImageList == None:\r
+                self._ModuleUnloadImageList = []\r
+        return self._ModuleUnloadImageList\r
+\r
+    ## Retrieve CONSTRUCTOR\r
+    def _GetConstructor(self):\r
+        if self._ConstructorList == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._ConstructorList == None:\r
+                self._ConstructorList = []\r
+        return self._ConstructorList\r
+\r
+    ## Retrieve DESTRUCTOR\r
+    def _GetDestructor(self):\r
+        if self._DestructorList == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._DestructorList == None:\r
+                self._DestructorList = []\r
+        return self._DestructorList\r
+\r
+    ## Retrieve definies other than above ones\r
+    def _GetDefines(self):\r
+        if self._Defs == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._Defs == None:\r
+                self._Defs = sdict()\r
+        return self._Defs\r
+\r
+    ## Retrieve binary files\r
+    def _GetBinaries(self):\r
+        if self._Binaries == None:\r
+            self._Binaries = []\r
+            RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform]\r
+            Macros = self._Macros\r
+            Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
+            Macros['PROCESSOR'] = self._Arch\r
+            for Record in RecordList:\r
+                FileType = Record[0]\r
+                LineNo = Record[-1]\r
+                Target = 'COMMON'\r
+                FeatureFlag = []\r
+                if Record[2]:\r
+                    TokenList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)\r
+                    if TokenList:\r
+                        Target = TokenList[0]\r
+                    if len(TokenList) > 1:\r
+                        FeatureFlag = Record[1:]\r
+\r
+                File = PathClass(NormPath(Record[1], Macros), self._ModuleDir, '', FileType, True, self._Arch, '', Target)\r
+                # check the file validation\r
+                ErrorCode, ErrorInfo = File.Validate()\r
+                if ErrorCode != 0:\r
+                    EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
+                self._Binaries.append(File)\r
+        return self._Binaries\r
+\r
+    ## Retrieve binary files with error check.\r
+    def _GetBinaryFiles(self):\r
+        Binaries = self._GetBinaries()\r
+        if GlobalData.gIgnoreSource and Binaries == []:\r
+            ErrorInfo = "The INF file does not contain any Binaries to use in creating the image\n"\r
+            EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, ExtraData=ErrorInfo, File=self.MetaFile)\r
+\r
+        return Binaries\r
+    ## Check whether it exists the binaries with current ARCH in AsBuild INF\r
+    def _IsSupportedArch(self):\r
+        if self._GetBinaries() and not self._GetSourceFiles():\r
+            return True\r
+        else:\r
+            return False\r
+    ## Retrieve source files\r
+    def _GetSourceFiles(self):\r
+        # Ignore all source files in a binary build mode\r
+        if GlobalData.gIgnoreSource:\r
+            self._Sources = []\r
+            return self._Sources\r
+\r
+        if self._Sources == None:\r
+            self._Sources = []\r
+            RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform]\r
+            Macros = self._Macros\r
+            for Record in RecordList:\r
+                LineNo = Record[-1]\r
+                ToolChainFamily = Record[1]\r
+                TagName = Record[2]\r
+                ToolCode = Record[3]\r
+                FeatureFlag = Record[4]\r
+                if self.AutoGenVersion < 0x00010005:\r
+                    Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
+                    Macros['PROCESSOR'] = self._Arch\r
+                    SourceFile = NormPath(Record[0], Macros)\r
+                    if SourceFile[0] == os.path.sep:\r
+                        SourceFile = mws.join(GlobalData.gWorkspace, SourceFile[1:])\r
+                    # old module source files (Edk)\r
+                    File = PathClass(SourceFile, self._ModuleDir, self._SourceOverridePath,\r
+                                     '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)\r
+                    # check the file validation\r
+                    ErrorCode, ErrorInfo = File.Validate(CaseSensitive=False)\r
+                    if ErrorCode != 0:\r
+                        if File.Ext.lower() == '.h':\r
+                            EdkLogger.warn('build', 'Include file not found', ExtraData=ErrorInfo,\r
+                                           File=self.MetaFile, Line=LineNo)\r
+                            continue\r
+                        else:\r
+                            EdkLogger.error('build', ErrorCode, ExtraData=File, File=self.MetaFile, Line=LineNo)\r
+                else:\r
+                    File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, '',\r
+                                     '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)\r
+                    # check the file validation\r
+                    ErrorCode, ErrorInfo = File.Validate()\r
+                    if ErrorCode != 0:\r
+                        EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
+\r
+                self._Sources.append(File)\r
+        return self._Sources\r
+\r
+    ## Retrieve library classes employed by this module\r
+    def _GetLibraryClassUses(self):\r
+        if self._LibraryClasses == None:\r
+            self._LibraryClasses = sdict()\r
+            RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, self._Platform]\r
+            for Record in RecordList:\r
+                Lib = Record[0]\r
+                Instance = Record[1]\r
+                if Instance:\r
+                    Instance = NormPath(Instance, self._Macros)\r
+                self._LibraryClasses[Lib] = Instance\r
+        return self._LibraryClasses\r
+\r
+    ## Retrieve library names (for Edk.x style of modules)\r
+    def _GetLibraryNames(self):\r
+        if self._Libraries == None:\r
+            self._Libraries = []\r
+            RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch, self._Platform]\r
+            for Record in RecordList:\r
+                LibraryName = ReplaceMacro(Record[0], self._Macros, False)\r
+                # in case of name with '.lib' extension, which is unusual in Edk.x inf\r
+                LibraryName = os.path.splitext(LibraryName)[0]\r
+                if LibraryName not in self._Libraries:\r
+                    self._Libraries.append(LibraryName)\r
+        return self._Libraries\r
+\r
+    def _GetProtocolComments(self):\r
+        self._GetProtocols()\r
+        return self._ProtocolComments\r
+    ## Retrieve protocols consumed/produced by this module\r
+    def _GetProtocols(self):\r
+        if self._Protocols == None:\r
+            self._Protocols = sdict()\r
+            self._ProtocolComments = sdict()\r
+            RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]\r
+            for Record in RecordList:\r
+                CName = Record[0]\r
+                Value = ProtocolValue(CName, self.Packages, self.MetaFile.Path)\r
+                if Value == None:\r
+                    PackageList = "\n\t".join([str(P) for P in self.Packages])\r
+                    EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
+                                    "Value of Protocol [%s] is not found under [Protocols] section in" % CName,\r
+                                    ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
+                self._Protocols[CName] = Value\r
+                CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
+                Comments = []\r
+                for CmtRec in CommentRecords:\r
+                    Comments.append(CmtRec[0])\r
+                self._ProtocolComments[CName] = Comments\r
+        return self._Protocols\r
+\r
+    def _GetPpiComments(self):\r
+        self._GetPpis()\r
+        return self._PpiComments\r
+    ## Retrieve PPIs consumed/produced by this module\r
+    def _GetPpis(self):\r
+        if self._Ppis == None:\r
+            self._Ppis = sdict()\r
+            self._PpiComments = sdict()\r
+            RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]\r
+            for Record in RecordList:\r
+                CName = Record[0]\r
+                Value = PpiValue(CName, self.Packages, self.MetaFile.Path)\r
+                if Value == None:\r
+                    PackageList = "\n\t".join([str(P) for P in self.Packages])\r
+                    EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
+                                    "Value of PPI [%s] is not found under [Ppis] section in " % CName,\r
+                                    ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
+                self._Ppis[CName] = Value\r
+                CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
+                Comments = []\r
+                for CmtRec in CommentRecords:\r
+                    Comments.append(CmtRec[0])\r
+                self._PpiComments[CName] = Comments\r
+        return self._Ppis\r
+\r
+    def _GetGuidComments(self):\r
+        self._GetGuids()\r
+        return self._GuidComments\r
+    ## Retrieve GUIDs consumed/produced by this module\r
+    def _GetGuids(self):\r
+        if self._Guids == None:\r
+            self._Guids = sdict()\r
+            self._GuidComments = sdict()\r
+            RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]\r
+            for Record in RecordList:\r
+                CName = Record[0]\r
+                Value = GuidValue(CName, self.Packages, self.MetaFile.Path)\r
+                if Value == None:\r
+                    PackageList = "\n\t".join([str(P) for P in self.Packages])\r
+                    EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
+                                    "Value of Guid [%s] is not found under [Guids] section in" % CName,\r
+                                    ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
+                self._Guids[CName] = Value\r
+                CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
+                Comments = []\r
+                for CmtRec in CommentRecords:\r
+                    Comments.append(CmtRec[0])\r
+                self._GuidComments[CName] = Comments\r
+        return self._Guids\r
+\r
+    ## Retrieve include paths necessary for this module (for Edk.x style of modules)\r
+    def _GetIncludes(self):\r
+        if self._Includes == None:\r
+            self._Includes = []\r
+            if self._SourceOverridePath:\r
+                self._Includes.append(self._SourceOverridePath)\r
+\r
+            Macros = self._Macros\r
+            if 'PROCESSOR' in GlobalData.gEdkGlobal.keys():\r
+                Macros['PROCESSOR'] = GlobalData.gEdkGlobal['PROCESSOR']\r
+            else:\r
+                Macros['PROCESSOR'] = self._Arch\r
+            RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch, self._Platform]\r
+            for Record in RecordList:\r
+                if Record[0].find('EDK_SOURCE') > -1:\r
+                    Macros['EDK_SOURCE'] = GlobalData.gEcpSource\r
+                    File = NormPath(Record[0], self._Macros)\r
+                    if File[0] == '.':\r
+                        File = os.path.join(self._ModuleDir, File)\r
+                    else:\r
+                        File = os.path.join(GlobalData.gWorkspace, File)\r
+                    File = RealPath(os.path.normpath(File))\r
+                    if File:\r
+                        self._Includes.append(File)\r
+\r
+                    # TRICK: let compiler to choose correct header file\r
+                    Macros['EDK_SOURCE'] = GlobalData.gEdkSource\r
+                    File = NormPath(Record[0], self._Macros)\r
+                    if File[0] == '.':\r
+                        File = os.path.join(self._ModuleDir, File)\r
+                    else:\r
+                        File = os.path.join(GlobalData.gWorkspace, File)\r
+                    File = RealPath(os.path.normpath(File))\r
+                    if File:\r
+                        self._Includes.append(File)\r
+                else:\r
+                    File = NormPath(Record[0], Macros)\r
+                    if File[0] == '.':\r
+                        File = os.path.join(self._ModuleDir, File)\r
+                    else:\r
+                        File = mws.join(GlobalData.gWorkspace, File)\r
+                    File = RealPath(os.path.normpath(File))\r
+                    if File:\r
+                        self._Includes.append(File)\r
+                    if not File and Record[0].find('EFI_SOURCE') > -1:\r
+                        # tricky to regard WorkSpace as EFI_SOURCE\r
+                        Macros['EFI_SOURCE'] = GlobalData.gWorkspace\r
+                        File = NormPath(Record[0], Macros)\r
+                        if File[0] == '.':\r
+                            File = os.path.join(self._ModuleDir, File)\r
+                        else:\r
+                            File = os.path.join(GlobalData.gWorkspace, File)\r
+                        File = RealPath(os.path.normpath(File))\r
+                        if File:\r
+                            self._Includes.append(File)\r
+        return self._Includes\r
+\r
+    ## Retrieve packages this module depends on\r
+    def _GetPackages(self):\r
+        if self._Packages == None:\r
+            self._Packages = []\r
+            RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform]\r
+            Macros = self._Macros\r
+            Macros['EDK_SOURCE'] = GlobalData.gEcpSource\r
+            for Record in RecordList:\r
+                File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
+                LineNo = Record[-1]\r
+                # check the file validation\r
+                ErrorCode, ErrorInfo = File.Validate('.dec')\r
+                if ErrorCode != 0:\r
+                    EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
+                # parse this package now. we need it to get protocol/ppi/guid value\r
+                Package = self._Bdb[File, self._Arch, self._Target, self._Toolchain]\r
+                self._Packages.append(Package)\r
+        return self._Packages\r
+\r
+    ## Retrieve PCD comments\r
+    def _GetPcdComments(self):\r
+        self._GetPcds()\r
+        return self._PcdComments\r
+    ## Retrieve PCDs used in this module\r
+    def _GetPcds(self):\r
+        if self._Pcds == None:\r
+            self._Pcds = sdict()\r
+            self._PcdComments = sdict()\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._GetPcd(MODEL_PCD_DYNAMIC))\r
+            self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))\r
+        return self._Pcds\r
+\r
+    ## Retrieve build options specific to this module\r
+    def _GetBuildOptions(self):\r
+        if self._BuildOptions == None:\r
+            self._BuildOptions = sdict()\r
+            RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, self._Platform]\r
+            for Record in RecordList:\r
+                ToolChainFamily = Record[0]\r
+                ToolChain = Record[1]\r
+                Option = Record[2]\r
+                if (ToolChainFamily, ToolChain) not in self._BuildOptions or Option.startswith('='):\r
+                    self._BuildOptions[ToolChainFamily, ToolChain] = Option\r
+                else:\r
+                    # concatenate the option string if they're for the same tool\r
+                    OptionString = self._BuildOptions[ToolChainFamily, ToolChain]\r
+                    self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r
+        return self._BuildOptions\r
+\r
+    ## Retrieve dependency expression\r
+    def _GetDepex(self):\r
+        if self._Depex == None:\r
+            self._Depex = tdict(False, 2)\r
+            RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\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
+                    self.ModuleType == 'DXE_SAL_DRIVER' or self.ModuleType == 'DXE_RUNTIME_DRIVER':\r
+                    EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \\r
+                                    % self.ModuleType, File=self.MetaFile)\r
+\r
+            if len(RecordList) != 0 and self.ModuleType == 'USER_DEFINED':\r
+                for Record in RecordList:\r
+                    if Record[4] not in ['PEIM', 'DXE_DRIVER', 'DXE_SMM_DRIVER']:\r
+                        EdkLogger.error('build', FORMAT_INVALID,\r
+                                        "'%s' module must specify the type of [Depex] section" % self.ModuleType,\r
+                                        File=self.MetaFile)\r
+\r
+            Depex = sdict()\r
+            for Record in RecordList:\r
+                DepexStr = ReplaceMacro(Record[0], self._Macros, False)\r
+                Arch = Record[3]\r
+                ModuleType = Record[4]\r
+                TokenList = DepexStr.split()\r
+                if (Arch, ModuleType) not in Depex:\r
+                    Depex[Arch, ModuleType] = []\r
+                DepexList = Depex[Arch, ModuleType]\r
+                for Token in TokenList:\r
+                    if Token in DEPEX_SUPPORTED_OPCODE:\r
+                        DepexList.append(Token)\r
+                    elif Token.endswith(".inf"):  # module file name\r
+                        ModuleFile = os.path.normpath(Token)\r
+                        Module = self.BuildDatabase[ModuleFile]\r
+                        if Module == None:\r
+                            EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "Module is not found in active platform",\r
+                                            ExtraData=Token, File=self.MetaFile, Line=Record[-1])\r
+                        DepexList.append(Module.Guid)\r
+                    else:\r
+                        # get the GUID value now\r
+                        Value = ProtocolValue(Token, self.Packages, self.MetaFile.Path)\r
+                        if Value == None:\r
+                            Value = PpiValue(Token, self.Packages, self.MetaFile.Path)\r
+                            if Value == None:\r
+                                Value = GuidValue(Token, self.Packages, self.MetaFile.Path)\r
+                        if Value == None:\r
+                            PackageList = "\n\t".join([str(P) for P in self.Packages])\r
+                            EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
+                                            "Value of [%s] is not found in" % Token,\r
+                                            ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
+                        DepexList.append(Value)\r
+            for Arch, ModuleType in Depex:\r
+                self._Depex[Arch, ModuleType] = Depex[Arch, ModuleType]\r
+        return self._Depex\r
+\r
+    ## Retrieve depedency expression\r
+    def _GetDepexExpression(self):\r
+        if self._DepexExpression == None:\r
+            self._DepexExpression = tdict(False, 2)\r
+            RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\r
+            DepexExpression = sdict()\r
+            for Record in RecordList:\r
+                DepexStr = ReplaceMacro(Record[0], self._Macros, False)\r
+                Arch = Record[3]\r
+                ModuleType = Record[4]\r
+                TokenList = DepexStr.split()\r
+                if (Arch, ModuleType) not in DepexExpression:\r
+                    DepexExpression[Arch, ModuleType] = ''\r
+                for Token in TokenList:\r
+                    DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType] + Token.strip() + ' '\r
+            for Arch, ModuleType in DepexExpression:\r
+                self._DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType]\r
+        return self._DepexExpression\r
+\r
+    def GetGuidsUsedByPcd(self):\r
+        return self._GuidsUsedByPcd\r
+    ## Retrieve PCD for given type\r
+    def _GetPcd(self, Type):\r
+        Pcds = sdict()\r
+        PcdDict = tdict(True, 4)\r
+        PcdList = []\r
+        RecordList = self._RawData[Type, self._Arch, self._Platform]\r
+        for TokenSpaceGuid, PcdCName, Setting, Arch, Platform, Id, LineNo in RecordList:\r
+            PcdDict[Arch, Platform, PcdCName, TokenSpaceGuid] = (Setting, LineNo)\r
+            PcdList.append((PcdCName, TokenSpaceGuid))\r
+            # get the guid value\r
+            if TokenSpaceGuid not in self.Guids:\r
+                Value = GuidValue(TokenSpaceGuid, self.Packages, self.MetaFile.Path)\r
+                if Value == None:\r
+                    PackageList = "\n\t".join([str(P) for P in self.Packages])\r
+                    EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
+                                    "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid,\r
+                                    ExtraData=PackageList, File=self.MetaFile, Line=LineNo)\r
+                self.Guids[TokenSpaceGuid] = Value\r
+                self._GuidsUsedByPcd[TokenSpaceGuid] = Value\r
+            CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Id]\r
+            Comments = []\r
+            for CmtRec in CommentRecords:\r
+                Comments.append(CmtRec[0])\r
+            self._PcdComments[TokenSpaceGuid, PcdCName] = Comments\r
+\r
+        # resolve PCD type, value, datum info, etc. by getting its definition from package\r
+        for PcdCName, TokenSpaceGuid in PcdList:\r
+            PcdRealName = PcdCName\r
+            Setting, LineNo = PcdDict[self._Arch, self.Platform, PcdCName, TokenSpaceGuid]\r
+            if Setting == None:\r
+                continue\r
+            ValueList = AnalyzePcdData(Setting)\r
+            DefaultValue = ValueList[0]\r
+            Pcd = PcdClassObject(\r
+                    PcdCName,\r
+                    TokenSpaceGuid,\r
+                    '',\r
+                    '',\r
+                    DefaultValue,\r
+                    '',\r
+                    '',\r
+                    {},\r
+                    False,\r
+                    self.Guids[TokenSpaceGuid]\r
+                    )\r
+            if Type == MODEL_PCD_PATCHABLE_IN_MODULE and ValueList[1]:\r
+                # Patch PCD: TokenSpace.PcdCName|Value|Offset\r
+                Pcd.Offset = ValueList[1]\r
+\r
+            if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:\r
+                for Package in self.Packages:\r
+                    for key in Package.Pcds:\r
+                        if (Package.Pcds[key].TokenCName, Package.Pcds[key].TokenSpaceGuidCName) == (PcdRealName, TokenSpaceGuid):\r
+                            for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:\r
+                                Pcd_Type = item[0].split('_')[-1]\r
+                                if Pcd_Type == Package.Pcds[key].Type:\r
+                                    Value = Package.Pcds[key]\r
+                                    Value.TokenCName = Package.Pcds[key].TokenCName + '_' + Pcd_Type\r
+                                    if len(key) == 2:\r
+                                        newkey = (Value.TokenCName, key[1])\r
+                                    elif len(key) == 3:\r
+                                        newkey = (Value.TokenCName, key[1], key[2])\r
+                                    del Package.Pcds[key]\r
+                                    Package.Pcds[newkey] = Value\r
+                                    break\r
+                                else:\r
+                                    pass\r
+                        else:\r
+                            pass\r
+\r
+            # get necessary info from package declaring this PCD\r
+            for Package in self.Packages:\r
+                #\r
+                # 'dynamic' in INF means its type is determined by platform;\r
+                # if platform doesn't give its type, use 'lowest' one in the\r
+                # following order, if any\r
+                #\r
+                #   "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"\r
+                #\r
+                PcdType = self._PCD_TYPE_STRING_[Type]\r
+                if Type == MODEL_PCD_DYNAMIC:\r
+                    Pcd.Pending = True\r
+                    for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:\r
+                        if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:\r
+                            for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:\r
+                                if str(item[0]).endswith(T) and (item[0], item[1], T) in Package.Pcds:\r
+                                    PcdType = T\r
+                                    PcdCName = item[0]\r
+                                    break\r
+                                else:\r
+                                    pass\r
+                            break\r
+                        else:\r
+                            if (PcdRealName, TokenSpaceGuid, T) in Package.Pcds:\r
+                                PcdType = T\r
+                                break\r
+\r
+                else:\r
+                    Pcd.Pending = False\r
+                    if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:\r
+                        for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:\r
+                            Pcd_Type = item[0].split('_')[-1]\r
+                            if Pcd_Type == PcdType:\r
+                                PcdCName = item[0]\r
+                                break\r
+                            else:\r
+                                pass\r
+                    else:\r
+                        pass\r
+\r
+                if (PcdCName, TokenSpaceGuid, PcdType) in Package.Pcds:\r
+                    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, PcdRealName, str(Package)),\r
+                                File=self.MetaFile, Line=LineNo,\r
+                                ExtraData=None\r
+                                )\r
+                    #\r
+                    # Check hexadecimal token value length and format.\r
+                    #\r
+                    ReIsValidPcdTokenValue = re.compile(r"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re.DOTALL)\r
+                    if Pcd.TokenValue.startswith("0x") or Pcd.TokenValue.startswith("0X"):\r
+                        if ReIsValidPcdTokenValue.match(Pcd.TokenValue) == None:\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, PcdRealName, 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, PcdRealName, 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, PcdRealName, 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
+                    if Pcd.DefaultValue in [None, '']:\r
+                        Pcd.DefaultValue = PcdInPackage.DefaultValue\r
+                    break\r
+            else:\r
+                EdkLogger.error(\r
+                            'build',\r
+                            FORMAT_INVALID,\r
+                            "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdRealName, 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
+    ## check whether current module is binary module\r
+    def _IsBinaryModule(self):\r
+        if self.Binaries and not self.Sources:\r
+            return True\r
+        elif GlobalData.gIgnoreSource:\r
+            return True\r
+        else:\r
+            return False\r
+\r
+    _Macros = property(_GetMacros)\r
+    Arch = property(_GetArch, _SetArch)\r
+    Platform = property(_GetPlatform, _SetPlatform)\r
+\r
+    HeaderComments = property(_GetHeaderComments)\r
+    TailComments = property(_GetTailComments)\r
+    AutoGenVersion          = property(_GetInfVersion)\r
+    BaseName                = property(_GetBaseName)\r
+    ModuleType              = property(_GetModuleType)\r
+    ComponentType           = property(_GetComponentType)\r
+    BuildType               = property(_GetBuildType)\r
+    Guid                    = property(_GetFileGuid)\r
+    Version                 = property(_GetVersion)\r
+    PcdIsDriver             = property(_GetPcdIsDriver)\r
+    Shadow                  = property(_GetShadow)\r
+    CustomMakefile          = property(_GetMakefile)\r
+    Specification           = property(_GetSpec)\r
+    LibraryClass            = property(_GetLibraryClass)\r
+    ModuleEntryPointList    = property(_GetEntryPoint)\r
+    ModuleUnloadImageList   = property(_GetUnloadImage)\r
+    ConstructorList         = property(_GetConstructor)\r
+    DestructorList          = property(_GetDestructor)\r
+    Defines                 = property(_GetDefines)\r
+    DxsFile                 = property(_GetDxsFile)\r
+\r
+    Binaries                = property(_GetBinaryFiles)\r
+    Sources                 = property(_GetSourceFiles)\r
+    LibraryClasses          = property(_GetLibraryClassUses)\r
+    Libraries               = property(_GetLibraryNames)\r
+    Protocols               = property(_GetProtocols)\r
+    ProtocolComments        = property(_GetProtocolComments)\r
+    Ppis                    = property(_GetPpis)\r
+    PpiComments             = property(_GetPpiComments)\r
+    Guids                   = property(_GetGuids)\r
+    GuidComments            = property(_GetGuidComments)\r
+    Includes                = property(_GetIncludes)\r
+    Packages                = property(_GetPackages)\r
+    Pcds                    = property(_GetPcds)\r
+    PcdComments             = property(_GetPcdComments)\r
+    BuildOptions            = property(_GetBuildOptions)\r
+    Depex                   = property(_GetDepex)\r
+    DepexExpression         = property(_GetDepexExpression)\r
+    IsBinaryModule          = property(_IsBinaryModule)\r
+    IsSupportedArch         = property(_IsSupportedArch)\r
index b756361afd7aca6d72a36487ff8d90384a86ae31..6a30d45b3dbf7059cd21309776769ae1ef1e3d81 100644 (file)
@@ -19,6 +19,7 @@ import Common.LongFilePathOs as os
 import re\r
 import time\r
 import copy\r
 import re\r
 import time\r
 import copy\r
+import md5\r
 \r
 import Common.EdkLogger as EdkLogger\r
 import Common.GlobalData as GlobalData\r
 \r
 import Common.EdkLogger as EdkLogger\r
 import Common.GlobalData as GlobalData\r
@@ -1116,6 +1117,11 @@ class DscParser(MetaFileParser):
     def _PcdParser(self):\r
         TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)\r
         self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)\r
     def _PcdParser(self):\r
         TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)\r
         self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)\r
+        PcdNameTockens = GetSplitValueList(TokenList[0], TAB_SPLIT)\r
+        if len(PcdNameTockens) == 2:\r
+            self._ValueList[0], self._ValueList[1] = PcdNameTockens[0], PcdNameTockens[1]\r
+        elif len(PcdNameTockens) == 3:\r
+            self._ValueList[0], self._ValueList[1] = ".".join((PcdNameTockens[0], PcdNameTockens[1])), PcdNameTockens[2]\r
         if len(TokenList) == 2:\r
             self._ValueList[2] = TokenList[1]\r
         if self._ValueList[0] == '' or self._ValueList[1] == '':\r
         if len(TokenList) == 2:\r
             self._ValueList[2] = TokenList[1]\r
         if self._ValueList[0] == '' or self._ValueList[1] == '':\r
@@ -1134,7 +1140,7 @@ class DscParser(MetaFileParser):
 \r
         # Validate the datum type of Dynamic Defaul PCD and DynamicEx Default PCD\r
         ValueList = GetSplitValueList(self._ValueList[2])\r
 \r
         # Validate the datum type of Dynamic Defaul PCD and DynamicEx Default PCD\r
         ValueList = GetSplitValueList(self._ValueList[2])\r
-        if len(ValueList) > 1 and ValueList[1] != TAB_VOID \\r
+        if len(ValueList) > 1 and ValueList[1] in [TAB_UINT8 , TAB_UINT16, TAB_UINT32 , TAB_UINT64] \\r
                               and self._ItemType in [MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT]:\r
             EdkLogger.error('Parser', FORMAT_INVALID, "The datum type '%s' of PCD is wrong" % ValueList[1],\r
                             ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
                               and self._ItemType in [MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT]:\r
             EdkLogger.error('Parser', FORMAT_INVALID, "The datum type '%s' of PCD is wrong" % ValueList[1],\r
                             ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
@@ -1560,7 +1566,7 @@ class DscParser(MetaFileParser):
             EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self._FileWithError, Line=self._LineIndex + 1,\r
                             ExtraData="%s.%s|%s" % (self._ValueList[0], self._ValueList[1], self._ValueList[2]))\r
         PcdValue = ValList[Index]\r
             EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self._FileWithError, Line=self._LineIndex + 1,\r
                             ExtraData="%s.%s|%s" % (self._ValueList[0], self._ValueList[1], self._ValueList[2]))\r
         PcdValue = ValList[Index]\r
-        if PcdValue:\r
+        if PcdValue and "." not in self._ValueList[0]:\r
             try:\r
                 ValList[Index] = ValueExpression(PcdValue, self._Macros)(True)\r
             except WrnExpression, Value:\r
             try:\r
                 ValList[Index] = ValueExpression(PcdValue, self._Macros)(True)\r
             except WrnExpression, Value:\r
@@ -1574,7 +1580,10 @@ class DscParser(MetaFileParser):
         if (not self._DirectiveEvalStack) or (False not in self._DirectiveEvalStack):\r
             GlobalData.gPlatformPcds[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue\r
             self._Symbols[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue\r
         if (not self._DirectiveEvalStack) or (False not in self._DirectiveEvalStack):\r
             GlobalData.gPlatformPcds[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue\r
             self._Symbols[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue\r
-        self._ValueList[2] = '|'.join(ValList)\r
+        try:\r
+            self._ValueList[2] = '|'.join(ValList)\r
+        except Exception:\r
+            print ValList\r
 \r
     def __ProcessComponent(self):\r
         self._ValueList[0] = ReplaceMacro(self._ValueList[0], self._Macros)\r
 \r
     def __ProcessComponent(self):\r
         self._ValueList[0] = ReplaceMacro(self._ValueList[0], self._Macros)\r
@@ -1655,6 +1664,10 @@ class DecParser(MetaFileParser):
         self._AllPCDs = [] # Only for check duplicate PCD\r
         self._AllPcdDict = {}\r
 \r
         self._AllPCDs = [] # Only for check duplicate PCD\r
         self._AllPcdDict = {}\r
 \r
+        self._CurrentStructurePcdName = ""\r
+        self._include_flag = False\r
+        self._package_flag = False\r
+\r
     ## Parser starter\r
     def Start(self):\r
         Content = ''\r
     ## Parser starter\r
     def Start(self):\r
         Content = ''\r
@@ -1847,105 +1860,143 @@ class DecParser(MetaFileParser):
     #\r
     @ParseMacro\r
     def _PcdParser(self):\r
     #\r
     @ParseMacro\r
     def _PcdParser(self):\r
-        TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)\r
-        self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)\r
-        ValueRe = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*')\r
-        # check PCD information\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 + \\r
-                                      " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
-                            File=self.MetaFile, Line=self._LineIndex + 1)\r
-        # check format of token space GUID CName\r
-        if not ValueRe.match(self._ValueList[0]):\r
-            EdkLogger.error('Parser', FORMAT_INVALID, "The format of the token space GUID CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",\r
-                            ExtraData=self._CurrentLine + \\r
-                                      " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
-                            File=self.MetaFile, Line=self._LineIndex + 1)\r
-        # check format of PCD CName\r
-        if not ValueRe.match(self._ValueList[1]):\r
-            EdkLogger.error('Parser', FORMAT_INVALID, "The format of the PCD CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",\r
-                            ExtraData=self._CurrentLine + \\r
-                                      " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
-                            File=self.MetaFile, Line=self._LineIndex + 1)\r
-        # check PCD datum information\r
-        if len(TokenList) < 2 or TokenList[1] == '':\r
-            EdkLogger.error('Parser', FORMAT_INVALID, "No PCD Datum information given",\r
-                            ExtraData=self._CurrentLine + \\r
-                                      " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
-                            File=self.MetaFile, Line=self._LineIndex + 1)\r
-\r
-\r
-        ValueRe = re.compile(r'^\s*L?\".*\|.*\"')\r
-        PtrValue = ValueRe.findall(TokenList[1])\r
-\r
-        # Has VOID* type string, may contain "|" character in the string. \r
-        if len(PtrValue) != 0:\r
-            ptrValueList = re.sub(ValueRe, '', TokenList[1])\r
-            ValueList = AnalyzePcdExpression(ptrValueList)\r
-            ValueList[0] = PtrValue[0]\r
-        else:\r
-            ValueList = AnalyzePcdExpression(TokenList[1])\r
-\r
-\r
-        # check if there's enough datum information given\r
-        if len(ValueList) != 3:\r
-            EdkLogger.error('Parser', FORMAT_INVALID, "Invalid PCD Datum information given",\r
-                            ExtraData=self._CurrentLine + \\r
-                                      " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
-                            File=self.MetaFile, Line=self._LineIndex + 1)\r
-        # check default value\r
-        if ValueList[0] == '':\r
-            EdkLogger.error('Parser', FORMAT_INVALID, "Missing DefaultValue in PCD Datum information",\r
-                            ExtraData=self._CurrentLine + \\r
-                                      " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
-                            File=self.MetaFile, Line=self._LineIndex + 1)\r
-        # check datum type\r
-        if ValueList[1] == '':\r
-            EdkLogger.error('Parser', FORMAT_INVALID, "Missing DatumType in PCD Datum information",\r
-                            ExtraData=self._CurrentLine + \\r
-                                      " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
-                            File=self.MetaFile, Line=self._LineIndex + 1)\r
-        # check token of the PCD\r
-        if ValueList[2] == '':\r
-            EdkLogger.error('Parser', FORMAT_INVALID, "Missing Token in PCD Datum information",\r
-                            ExtraData=self._CurrentLine + \\r
-                                      " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
-                            File=self.MetaFile, Line=self._LineIndex + 1)\r
-\r
-        PcdValue = ValueList[0]\r
-        if PcdValue:\r
-            try:\r
-                ValueList[0] = ValueExpression(PcdValue, self._AllPcdDict)(True)\r
-            except WrnExpression, Value:\r
-                ValueList[0] = Value.result\r
-\r
-        if ValueList[0] == 'True':\r
-            ValueList[0] = '1'\r
-        if ValueList[0] == 'False':\r
-            ValueList[0] = '0'\r
-\r
-        # check format of default value against the datum type\r
-        IsValid, Cause = CheckPcdDatum(ValueList[1], ValueList[0])\r
-        if not IsValid:\r
-            EdkLogger.error('Parser', FORMAT_INVALID, Cause, ExtraData=self._CurrentLine,\r
-                            File=self.MetaFile, Line=self._LineIndex + 1)\r
-\r
-        if ValueList[0] in ['True', 'true', 'TRUE']:\r
-            ValueList[0] = '1'\r
-        elif ValueList[0] in ['False', 'false', 'FALSE']:\r
-            ValueList[0] = '0'\r
-\r
-        # check for duplicate PCD definition\r
-        if (self._Scope[0], self._ValueList[0], self._ValueList[1]) in self._AllPCDs:\r
-            EdkLogger.error('Parser', FORMAT_INVALID,\r
-                            "The same PCD name and GUID have been already defined",\r
-                            ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
-        else:\r
-            self._AllPCDs.append((self._Scope[0], self._ValueList[0], self._ValueList[1]))\r
-            self._AllPcdDict[TAB_SPLIT.join(self._ValueList[0:2])] = ValueList[0]\r
+        if self._CurrentStructurePcdName:\r
+            self._ValueList[0] = self._CurrentStructurePcdName\r
+\r
+            if "|" not in self._CurrentLine:\r
+                if "<HeaderFiles>" == self._CurrentLine:\r
+                    self._include_flag = True\r
+                    self._ValueList = None\r
+                    return\r
+                if "<Packages>" == self._CurrentLine:\r
+                    self._package_flag = True\r
+                    self._ValueList = None\r
+                    return\r
+\r
+                if self._include_flag:\r
+                    self._ValueList[1] = "<HeaderFiles>_" + md5.new(self._CurrentLine).hexdigest()\r
+                    self._ValueList[2] = self._CurrentLine\r
+                    self._include_flag = False\r
+                if self._package_flag and "}" != self._CurrentLine:\r
+                    self._ValueList[1] = "<Packages>_" + md5.new(self._CurrentLine).hexdigest()\r
+                    self._ValueList[2] = self._CurrentLine\r
+                if self._CurrentLine == "}":\r
+                    self._package_flag = False\r
+                    self._ValueList = None\r
+                    return\r
+            else:\r
+                PcdTockens = self._CurrentLine.split(TAB_VALUE_SPLIT)\r
+                PcdNames = PcdTockens[0].split(TAB_SPLIT)\r
+                if len(PcdNames) == 2:\r
+                    self._CurrentStructurePcdName = ""\r
+                else:\r
+                    self._ValueList[1] = PcdNames[2]\r
+                    self._ValueList[2] = PcdTockens[1]\r
+        if not self._CurrentStructurePcdName:\r
+            TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)\r
+            self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)\r
+            ValueRe = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*')\r
+            # check PCD information\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 + \\r
+                                          " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
+                                File=self.MetaFile, Line=self._LineIndex + 1)\r
+            # check format of token space GUID CName\r
+            if not ValueRe.match(self._ValueList[0]):\r
+                EdkLogger.error('Parser', FORMAT_INVALID, "The format of the token space GUID CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",\r
+                                ExtraData=self._CurrentLine + \\r
+                                          " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
+                                File=self.MetaFile, Line=self._LineIndex + 1)\r
+            # check format of PCD CName\r
+            if not ValueRe.match(self._ValueList[1]):\r
+                EdkLogger.error('Parser', FORMAT_INVALID, "The format of the PCD CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",\r
+                                ExtraData=self._CurrentLine + \\r
+                                          " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
+                                File=self.MetaFile, Line=self._LineIndex + 1)\r
+            # check PCD datum information\r
+            if len(TokenList) < 2 or TokenList[1] == '':\r
+                EdkLogger.error('Parser', FORMAT_INVALID, "No PCD Datum information given",\r
+                                ExtraData=self._CurrentLine + \\r
+                                          " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
+                                File=self.MetaFile, Line=self._LineIndex + 1)\r
+\r
+\r
+            ValueRe = re.compile(r'^\s*L?\".*\|.*\"')\r
+            PtrValue = ValueRe.findall(TokenList[1])\r
+\r
+            # Has VOID* type string, may contain "|" character in the string.\r
+            if len(PtrValue) != 0:\r
+                ptrValueList = re.sub(ValueRe, '', TokenList[1])\r
+                ValueList = AnalyzePcdExpression(ptrValueList)\r
+                ValueList[0] = PtrValue[0]\r
+            else:\r
+                ValueList = AnalyzePcdExpression(TokenList[1])\r
+\r
+\r
+            # check if there's enough datum information given\r
+            if len(ValueList) != 3:\r
+                EdkLogger.error('Parser', FORMAT_INVALID, "Invalid PCD Datum information given",\r
+                                ExtraData=self._CurrentLine + \\r
+                                          " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
+                                File=self.MetaFile, Line=self._LineIndex + 1)\r
+            # check default value\r
+            if ValueList[0] == '':\r
+                EdkLogger.error('Parser', FORMAT_INVALID, "Missing DefaultValue in PCD Datum information",\r
+                                ExtraData=self._CurrentLine + \\r
+                                          " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
+                                File=self.MetaFile, Line=self._LineIndex + 1)\r
+            # check datum type\r
+            if ValueList[1] == '':\r
+                EdkLogger.error('Parser', FORMAT_INVALID, "Missing DatumType in PCD Datum information",\r
+                                ExtraData=self._CurrentLine + \\r
+                                          " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
+                                File=self.MetaFile, Line=self._LineIndex + 1)\r
+            # check token of the PCD\r
+            if ValueList[2] == '':\r
+                EdkLogger.error('Parser', FORMAT_INVALID, "Missing Token in PCD Datum information",\r
+                                ExtraData=self._CurrentLine + \\r
+                                          " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
+                                File=self.MetaFile, Line=self._LineIndex + 1)\r
+\r
+            PcdValue = ValueList[0]\r
+            if PcdValue:\r
+                try:\r
+                    ValueList[0] = ValueExpression(PcdValue, self._AllPcdDict)(True)\r
+                except WrnExpression, Value:\r
+                    ValueList[0] = Value.result\r
+\r
+            if ValueList[0] == 'True':\r
+                ValueList[0] = '1'\r
+            if ValueList[0] == 'False':\r
+                ValueList[0] = '0'\r
+\r
+            # check format of default value against the datum type\r
+            IsValid, Cause = CheckPcdDatum(ValueList[1], ValueList[0])\r
+            if not IsValid:\r
+                EdkLogger.error('Parser', FORMAT_INVALID, Cause, ExtraData=self._CurrentLine,\r
+                                File=self.MetaFile, Line=self._LineIndex + 1)\r
+\r
+            if Cause == "StructurePcd":\r
+                self._CurrentStructurePcdName = TAB_SPLIT.join(self._ValueList[0:2])\r
+                self._ValueList[0] = self._CurrentStructurePcdName\r
+                self._ValueList[1] = ValueList[1].strip()\r
+\r
+            if ValueList[0] in ['True', 'true', 'TRUE']:\r
+                ValueList[0] = '1'\r
+            elif ValueList[0] in ['False', 'false', 'FALSE']:\r
+                ValueList[0] = '0'\r
+\r
+            # check for duplicate PCD definition\r
+            if (self._Scope[0], self._ValueList[0], self._ValueList[1]) in self._AllPCDs:\r
+                EdkLogger.error('Parser', FORMAT_INVALID,\r
+                                "The same PCD name and GUID have been already defined",\r
+                                ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
+            else:\r
+                self._AllPCDs.append((self._Scope[0], self._ValueList[0], self._ValueList[1]))\r
+                self._AllPcdDict[TAB_SPLIT.join(self._ValueList[0:2])] = ValueList[0]\r
 \r
 \r
-        self._ValueList[2] = ValueList[0].strip() + '|' + ValueList[1].strip() + '|' + ValueList[2].strip()\r
+            self._ValueList[2] = ValueList[0].strip() + '|' + ValueList[1].strip() + '|' + ValueList[2].strip()\r
 \r
     _SectionParser = {\r
         MODEL_META_DATA_HEADER          :   MetaFileParser._DefineParser,\r
 \r
     _SectionParser = {\r
         MODEL_META_DATA_HEADER          :   MetaFileParser._DefineParser,\r
index c224b8e0e631863299f828e273f6cb60e4f0ce28..67aa530526274cc0f7a640144a92fc7a29a3eb04 100644 (file)
@@ -15,6 +15,7 @@ from Common.Misc import sdict
 from Common.DataType import SUP_MODULE_USER_DEFINED\r
 from BuildClassObject import LibraryClassObject\r
 import Common.GlobalData as GlobalData\r
 from Common.DataType import SUP_MODULE_USER_DEFINED\r
 from BuildClassObject import LibraryClassObject\r
 import Common.GlobalData as GlobalData\r
+from Workspace.BuildClassObject import StructurePcd\r
 \r
 ## Get all packages from platform for specified arch, target and toolchain\r
 #\r
 \r
 ## Get all packages from platform for specified arch, target and toolchain\r
 #\r
index 2c4b973901a9b92982d4856a540a413031739d89..a3407d113e0f437dbb2b6a5af65cd65d1a3969d8 100644 (file)
 # Import Modules\r
 #\r
 import sqlite3\r
 # Import Modules\r
 #\r
 import sqlite3\r
-import Common.LongFilePathOs as os\r
-import pickle\r
-import uuid\r
-\r
-import Common.EdkLogger as EdkLogger\r
-import Common.GlobalData as GlobalData\r
-from Common.MultipleWorkspace import MultipleWorkspace as mws\r
-\r
 from Common.String import *\r
 from Common.DataType import *\r
 from Common.Misc import *\r
 from types import *\r
 \r
 from Common.String import *\r
 from Common.DataType import *\r
 from Common.Misc import *\r
 from types import *\r
 \r
-from CommonDataClass.CommonClass import SkuInfoClass\r
-\r
 from MetaDataTable import *\r
 from MetaFileTable import *\r
 from MetaFileParser import *\r
 from MetaDataTable import *\r
 from MetaFileTable import *\r
 from MetaFileParser import *\r
-from BuildClassObject import *\r
-from WorkspaceCommon import GetDeclaredPcd\r
-from Common.Misc import AnalyzeDscPcd\r
-from Common.Misc import ProcessDuplicatedInf\r
-import re\r
-from Common.Parsing import IsValidWord\r
-from Common.VariableAttributes import VariableAttributes\r
-import Common.GlobalData as GlobalData\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
-        #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
-    _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', Target=None, Toolchain=None):\r
-        self.MetaFile = FilePath\r
-        self._RawData = RawData\r
-        self._Bdb = BuildDataBase\r
-        self._Arch = Arch\r
-        self._Target = Target\r
-        self._Toolchain = Toolchain\r
-        self._Clear()\r
-        self._HandleOverridePath()\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._SkuIdentifier     = None\r
-        self._AvilableSkuIds = None\r
-        self._PcdInfoFlag       = None\r
-        self._VarCheckFlag = None\r
-        self._FlashDefinition   = None\r
-        self._Prebuild          = None\r
-        self._Postbuild         = 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._DecPcds           = None\r
-        self._BuildOptions      = None\r
-        self._ModuleTypeOptions = None\r
-        self._LoadFixAddress    = None\r
-        self._RFCLanguages      = None\r
-        self._ISOLanguages      = None\r
-        self._VpdToolGuid       = None\r
-        self.__Macros            = None\r
-\r
-\r
-    ## handle Override Path of Module\r
-    def _HandleOverridePath(self):\r
-        RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]\r
-        Macros = self._Macros\r
-        Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
-        for Record in RecordList:\r
-            ModuleId = Record[5]\r
-            LineNo = Record[6]\r
-            ModuleFile = PathClass(NormPath(Record[0]), GlobalData.gWorkspace, Arch=self._Arch)\r
-            RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId]\r
-            if RecordList != []:\r
-                SourceOverridePath = mws.join(GlobalData.gWorkspace, NormPath(RecordList[0][0]))\r
-\r
-                # Check if the source override path exists\r
-                if not os.path.isdir(SourceOverridePath):\r
-                    EdkLogger.error('build', FILE_NOT_FOUND, Message='Source override path does not exist:', File=self.MetaFile, ExtraData=SourceOverridePath, Line=LineNo)\r
-\r
-                #Add to GlobalData Variables\r
-                GlobalData.gOverrideDir[ModuleFile.Key] = SourceOverridePath\r
-\r
-    ## Get current effective macros\r
-    def _GetMacros(self):\r
-        if self.__Macros == None:\r
-            self.__Macros = {}\r
-            self.__Macros.update(GlobalData.gPlatformDefines)\r
-            self.__Macros.update(GlobalData.gGlobalDefines)\r
-            self.__Macros.update(GlobalData.gCommandLineDefines)\r
-        return self.__Macros\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[1]\r
-            # items defined _PROPERTY_ don't need additional processing\r
-            \r
-            # some special items in [Defines] section need special treatment\r
-            if Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:\r
-                self._OutputDirectory = NormPath(Record[2], self._Macros)\r
-                if ' ' in self._OutputDirectory:\r
-                    EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in OUTPUT_DIRECTORY",\r
-                                    File=self.MetaFile, Line=Record[-1],\r
-                                    ExtraData=self._OutputDirectory)\r
-            elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION:\r
-                self._FlashDefinition = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)\r
-                ErrorCode, ErrorInfo = self._FlashDefinition.Validate('.fdf')\r
-                if ErrorCode != 0:\r
-                    EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1],\r
-                                    ExtraData=ErrorInfo)\r
-            elif Name == TAB_DSC_PREBUILD:\r
-                PrebuildValue = Record[2]\r
-                if Record[2][0] == '"':\r
-                    if Record[2][-1] != '"':\r
-                        EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_PREBUILD,\r
-                                    File=self.MetaFile, Line=Record[-1])\r
-                    PrebuildValue = Record[2][1:-1]\r
-                self._Prebuild = PrebuildValue\r
-            elif Name == TAB_DSC_POSTBUILD:\r
-                PostbuildValue = Record[2]\r
-                if Record[2][0] == '"':\r
-                    if Record[2][-1] != '"':\r
-                        EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_POSTBUILD,\r
-                                    File=self.MetaFile, Line=Record[-1])\r
-                    PostbuildValue = Record[2][1:-1]\r
-                self._Postbuild = PostbuildValue\r
-            elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:\r
-                self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)\r
-            elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:\r
-                self._BuildTargets = GetSplitValueList(Record[2])\r
-            elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER:\r
-                if self._SkuName == None:\r
-                    self._SkuName = Record[2]\r
-                self._SkuIdentifier = Record[2]\r
-                self._AvilableSkuIds = Record[2]\r
-            elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION:\r
-                self._PcdInfoFlag = Record[2]\r
-            elif Name == TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION:\r
-                self._VarCheckFlag = Record[2]\r
-            elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS:\r
-                try:\r
-                    self._LoadFixAddress = int (Record[2], 0)\r
-                except:\r
-                    EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record[2]))\r
-            elif Name == TAB_DSC_DEFINES_RFC_LANGUAGES:\r
-                if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 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[2][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[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 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[2][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[2])\r
-                except:\r
-                    EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile)\r
-                self._VpdToolGuid = Record[2]                   \r
-            elif Name in self:\r
-                self[Name] = Record[2]                 \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.MetaFile)\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 PLATFORM_GUID", File=self.MetaFile)\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
-                EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_VERSION", File=self.MetaFile)\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
-                EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No DSC_SPECIFICATION", File=self.MetaFile)                \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
-                EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No SUPPORTED_ARCHITECTURES", File=self.MetaFile)\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
-                EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BUILD_TARGETS", File=self.MetaFile)\r
-        return self._BuildTargets\r
-    \r
-    def _GetPcdInfoFlag(self):\r
-        if self._PcdInfoFlag == None or self._PcdInfoFlag.upper() == 'FALSE':\r
-            return False\r
-        elif self._PcdInfoFlag.upper() == 'TRUE':\r
-            return True\r
-        else:\r
-            return False\r
-    def _GetVarCheckFlag(self):  \r
-        if self._VarCheckFlag == None or self._VarCheckFlag.upper() == 'FALSE':\r
-            return False\r
-        elif self._VarCheckFlag.upper() == 'TRUE':\r
-            return True\r
-        else:\r
-            return False\r
-    def _GetAviableSkuIds(self):\r
-        if self._AvilableSkuIds:\r
-            return self._AvilableSkuIds\r
-        return self.SkuIdentifier\r
-    def _GetSkuIdentifier(self):\r
-        if self._SkuName:\r
-            return self._SkuName\r
-        if self._SkuIdentifier == None:\r
-            if self._Header == None:\r
-                self._GetHeaderInfo()\r
-        return self._SkuIdentifier\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
-        self._SkuName = Value\r
-        self._Pcds = None\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
-    def _GetPrebuild(self):\r
-        if self._Prebuild == None:\r
-            if self._Header == None:\r
-                self._GetHeaderInfo()\r
-            if self._Prebuild == None:\r
-                self._Prebuild = ''\r
-        return self._Prebuild\r
-\r
-    def _GetPostbuild(self):\r
-        if self._Postbuild == None:\r
-            if self._Header == None:\r
-                self._GetHeaderInfo()\r
-            if self._Postbuild == None:\r
-                self._Postbuild = ''\r
-        return self._Postbuild\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 the top address for the load fix address\r
-    def _GetLoadFixAddress(self):\r
-        if self._LoadFixAddress == None:\r
-            if self._Header == None:\r
-                self._GetHeaderInfo()\r
-\r
-            if self._LoadFixAddress == None:\r
-                self._LoadFixAddress = self._Macros.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS, '0')\r
-\r
-            try:\r
-                self._LoadFixAddress = int (self._LoadFixAddress, 0)\r
-            except:\r
-                EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self._LoadFixAddress))\r
-         \r
-        #\r
-        # If command line defined, should override the value in DSC file.\r
-        #\r
-        if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData.gCommandLineDefines.keys():\r
-            try:\r
-                self._LoadFixAddress = int(GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)\r
-            except:\r
-                EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS']))\r
-                \r
-        if self._LoadFixAddress < 0:\r
-            EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self._LoadFixAddress))\r
-        if self._LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self._LoadFixAddress % 0x1000 != 0:\r
-            EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self._LoadFixAddress))\r
-            \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
-    ## 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
-            self._SkuIds = sdict()\r
-            RecordList = self._RawData[MODEL_EFI_SKU_ID, self._Arch]\r
-            for Record in RecordList:\r
-                if Record[0] in [None, '']:\r
-                    EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID number',\r
-                                    File=self.MetaFile, Line=Record[-1])\r
-                if Record[1] in [None, '']:\r
-                    EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID name',\r
-                                    File=self.MetaFile, Line=Record[-1])\r
-                self._SkuIds[Record[1]] = Record[0]\r
-            if 'DEFAULT' not in self._SkuIds:\r
-                self._SkuIds['DEFAULT'] = '0'\r
-            if 'COMMON' not in self._SkuIds:\r
-                self._SkuIds['COMMON'] = '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
-        Macros = self._Macros\r
-        Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
-        for Record in RecordList:\r
-            DuplicatedFile = False\r
-\r
-            ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
-            ModuleId = Record[5]\r
-            LineNo = Record[6]\r
-\r
-            # check the file validation\r
-            ErrorCode, ErrorInfo = ModuleFile.Validate('.inf')\r
-            if ErrorCode != 0:\r
-                EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
-                                ExtraData=ErrorInfo)\r
-            # Check duplication\r
-            # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected\r
-            if self._Arch != 'COMMON' and ModuleFile in self._Modules:\r
-                DuplicatedFile = True\r
-\r
-            Module = ModuleBuildClassObject()\r
-            Module.MetaFile = 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 = PathClass(NormPath(Record[1], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
-                LineNo = Record[-1]\r
-\r
-                # check the file validation\r
-                ErrorCode, ErrorInfo = LibraryPath.Validate('.inf')\r
-                if ErrorCode != 0:\r
-                    EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
-                                    ExtraData=ErrorInfo)\r
-\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
-                    TypeString = self._PCD_TYPE_STRING_[Type]\r
-                    Pcd = PcdClassObject(\r
-                            PcdCName,\r
-                            TokenSpaceGuid,\r
-                            TypeString,\r
-                            '',\r
-                            DefaultValue,\r
-                            '',\r
-                            MaxDatumSize,\r
-                            {},\r
-                            False,\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
-            RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, None, ModuleId]\r
-            if DuplicatedFile and not RecordList:\r
-                EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)\r
-            if RecordList:\r
-                if len(RecordList) != 1:\r
-                    EdkLogger.error('build', OPTION_UNKNOWN, 'Only FILE_GUID can be listed in <Defines> section.',\r
-                                    File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)\r
-                ModuleFile = ProcessDuplicatedInf(ModuleFile, RecordList[0][2], GlobalData.gWorkspace)\r
-                ModuleFile.Arch = self._Arch\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, None, -1]\r
-            Macros = self._Macros\r
-            for Record in RecordList:\r
-                LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy, LineNo = Record\r
-                if LibraryClass == '' or LibraryClass == 'NULL':\r
-                    self._NullLibraryNumber += 1\r
-                    LibraryClass = 'NULL%d' % self._NullLibraryNumber\r
-                    EdkLogger.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch, LibraryInstance, LibraryClass))\r
-                LibraryClassSet.add(LibraryClass)\r
-                LibraryInstance = PathClass(NormPath(LibraryInstance, Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
-                # check the file validation\r
-                ErrorCode, ErrorInfo = LibraryInstance.Validate('.inf')\r
-                if ErrorCode != 0:\r
-                    EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
-                                    ExtraData=ErrorInfo)\r
-\r
-                if ModuleType != 'COMMON' and ModuleType not in SUP_MODULE_LIST:\r
-                    EdkLogger.error('build', OPTION_UNKNOWN, "Unknown module type [%s]" % ModuleType,\r
-                                    File=self.MetaFile, 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 Edk style library instances, which are listed in different section\r
-            Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
-            RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch]\r
-            for Record in RecordList:\r
-                File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
-                LineNo = Record[-1]\r
-                # check the file validation\r
-                ErrorCode, ErrorInfo = File.Validate('.inf')\r
-                if ErrorCode != 0:\r
-                    EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
-                                    ExtraData=ErrorInfo)\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, self._Target, self._Toolchain]\r
-                self._LibraryClasses[Library.BaseName, ':dummy:'] = Library\r
-        return self._LibraryClasses\r
-\r
-    def _ValidatePcd(self, PcdCName, TokenSpaceGuid, Setting, PcdType, LineNo):\r
-        if self._DecPcds == None:\r
-            self._DecPcds = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain)\r
-            FdfInfList = []\r
-            if GlobalData.gFdfParser:\r
-                FdfInfList = GlobalData.gFdfParser.Profile.InfList\r
-\r
-            PkgSet = set()\r
-            for Inf in FdfInfList:\r
-                ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)\r
-                if ModuleFile in self._Modules:\r
-                    continue\r
-                ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]\r
-                PkgSet.update(ModuleData.Packages)\r
-            DecPcds = {}\r
-            for Pkg in PkgSet:\r
-                for Pcd in Pkg.Pcds:\r
-                    DecPcds[Pcd[0], Pcd[1]] = Pkg.Pcds[Pcd]\r
-            self._DecPcds.update(DecPcds)\r
-\r
-        if (PcdCName, TokenSpaceGuid) not in self._DecPcds:\r
-            EdkLogger.error('build', PARSER_ERROR,\r
-                            "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid, PcdCName, self._Arch),\r
-                            File=self.MetaFile, Line=LineNo)\r
-        ValueList, IsValid, Index = AnalyzeDscPcd(Setting, PcdType, self._DecPcds[PcdCName, TokenSpaceGuid].DatumType)\r
-        if not IsValid and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:\r
-            EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,\r
-                            ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))\r
-        if ValueList[Index] and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:\r
-            try:\r
-                ValueList[Index] = ValueExpression(ValueList[Index], GlobalData.gPlatformPcds)(True)\r
-            except WrnExpression, Value:\r
-                ValueList[Index] = Value.result\r
-            except EvaluationException, Excpt:\r
-                if hasattr(Excpt, 'Pcd'):\r
-                    if Excpt.Pcd in GlobalData.gPlatformOtherPcds:\r
-                        EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"\r
-                                        " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"\r
-                                        " of the DSC file" % Excpt.Pcd,\r
-                                        File=self.MetaFile, Line=LineNo)\r
-                    else:\r
-                        EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,\r
-                                        File=self.MetaFile, Line=LineNo)\r
-                else:\r
-                    EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),\r
-                                    File=self.MetaFile, Line=LineNo)\r
-            if ValueList[Index] == 'True':\r
-                ValueList[Index] = '1'\r
-            elif ValueList[Index] == 'False':\r
-                ValueList[Index] = '0'\r
-        if ValueList[Index]:\r
-            Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index])\r
-            if not Valid:\r
-                EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo,\r
-                                ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName))\r
-        return ValueList\r
-\r
-    ## Retrieve all PCD settings in platform\r
-    def _GetPcds(self):\r
-        if self._Pcds == None:\r
-            self._Pcds = sdict()\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 = sdict()\r
-            #\r
-            # Retrieve build option for EDKII and EDK style module\r
-            #\r
-            for CodeBase in (EDKII_NAME, EDK_NAME):\r
-                RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]\r
-                for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
-                    CurKey = (ToolChainFamily, ToolChain, CodeBase)\r
-                    #\r
-                    # Only flags can be appended\r
-                    #\r
-                    if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
-                        self._BuildOptions[CurKey] = Option\r
-                    else:\r
-                        self._BuildOptions[CurKey] += ' ' + Option\r
-        return self._BuildOptions\r
-\r
-    def GetBuildOptionsByModuleType(self, Edk, ModuleType):\r
-        if self._ModuleTypeOptions == None:\r
-            self._ModuleTypeOptions = sdict()\r
-        if (Edk, ModuleType) not in self._ModuleTypeOptions:\r
-            options = sdict()\r
-            self._ModuleTypeOptions[Edk, ModuleType] = options\r
-            DriverType = '%s.%s' % (Edk, ModuleType)\r
-            CommonDriverType = '%s.%s' % ('COMMON', ModuleType)\r
-            RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, DriverType]\r
-            for ToolChainFamily, ToolChain, Option, Arch, Type, Dummy3, Dummy4 in RecordList:\r
-                if Type == DriverType or Type == CommonDriverType:\r
-                    Key = (ToolChainFamily, ToolChain, Edk)\r
-                    if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
-                        options[Key] = Option\r
-                    else:\r
-                        options[Key] += ' ' + Option\r
-        return self._ModuleTypeOptions[Edk, ModuleType]\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 = sdict()\r
-        #\r
-        # tdict is a special dict kind of type, used for selecting correct\r
-        # PCD settings for certain ARCH\r
-        #\r
-        \r
-        SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)\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
-        PcdValueDict = sdict()\r
-        for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
-            if SkuName in (SkuObj.SystemSkuId,'DEFAULT','COMMON'):\r
-                PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,Dummy4))\r
-                PcdDict[Arch, PcdCName, TokenSpaceGuid,SkuName] = Setting\r
-        \r
-        #handle pcd value override        \r
-        for PcdCName, TokenSpaceGuid, SkuName,Dummy4 in PcdSet:\r
-            Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid,SkuName]\r
-            if Setting == None:\r
-                continue\r
-            PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
-            if (PcdCName, TokenSpaceGuid) in PcdValueDict:\r
-                PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue,DatumType,MaxDatumSize) \r
-            else:\r
-                PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue,DatumType,MaxDatumSize)}       \r
-        \r
-        PcdsKeys = PcdValueDict.keys()\r
-        for PcdCName,TokenSpaceGuid in PcdsKeys:\r
-            \r
-            PcdSetting = PcdValueDict[PcdCName, TokenSpaceGuid]\r
-            PcdValue = None\r
-            DatumType = None\r
-            MaxDatumSize = None\r
-            if 'COMMON' in PcdSetting:\r
-                PcdValue,DatumType,MaxDatumSize = PcdSetting['COMMON']\r
-            if 'DEFAULT' in PcdSetting:\r
-                PcdValue,DatumType,MaxDatumSize = PcdSetting['DEFAULT']\r
-            if SkuObj.SystemSkuId in PcdSetting:\r
-                PcdValue,DatumType,MaxDatumSize = PcdSetting[SkuObj.SystemSkuId]\r
-                \r
-            Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
-                                                PcdCName,\r
-                                                TokenSpaceGuid,\r
-                                                self._PCD_TYPE_STRING_[Type],\r
-                                                DatumType,\r
-                                                PcdValue,\r
-                                                '',\r
-                                                MaxDatumSize,\r
-                                                {},\r
-                                                False,\r
-                                                None,\r
-                                                IsDsc=True)\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
-        \r
-        SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)\r
-        \r
-        Pcds = sdict()\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
-        PcdList = []\r
-        # Find out all possible PCD candidates for self._Arch\r
-        RecordList = self._RawData[Type, self._Arch]\r
-        AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()\r
-        \r
-        AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})\r
-        for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
-            if SkuName not in AvailableSkuIdSet:\r
-                continue\r
-            \r
-            PcdList.append((PcdCName, TokenSpaceGuid, SkuName,Dummy4))\r
-            PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
-        # Remove redundant PCD candidates, per the ARCH and SKU\r
-        for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:\r
-            \r
-            Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
-            if Setting == None:\r
-                continue\r
-                      \r
-            PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
-            SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', '', PcdValue)\r
-            if (PcdCName,TokenSpaceGuid) in Pcds.keys(): \r
-                pcdObject = Pcds[PcdCName,TokenSpaceGuid]\r
-                pcdObject.SkuInfoList[SkuName] = SkuInfo\r
-                if MaxDatumSize.strip():\r
-                    CurrentMaxSize = int(MaxDatumSize.strip(),0)\r
-                else:\r
-                    CurrentMaxSize = 0\r
-                if pcdObject.MaxDatumSize:\r
-                    PcdMaxSize = int(pcdObject.MaxDatumSize,0)\r
-                else:\r
-                    PcdMaxSize = 0\r
-                if CurrentMaxSize > PcdMaxSize:\r
-                    pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
-            else:               \r
-                Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
-                                                    PcdCName,\r
-                                                    TokenSpaceGuid,\r
-                                                    self._PCD_TYPE_STRING_[Type],\r
-                                                    DatumType,\r
-                                                    PcdValue,\r
-                                                    '',\r
-                                                    MaxDatumSize,\r
-                                                    {SkuName : SkuInfo},\r
-                                                    False,\r
-                                                    None,\r
-                                                    IsDsc=True)\r
-\r
-        for pcd in Pcds.values():\r
-            pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]\r
-            if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():                \r
-                valuefromDec = pcdDecObject.DefaultValue\r
-                SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec)\r
-                pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
-            elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
-                pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
-                del(pcd.SkuInfoList['COMMON'])\r
-            elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
-                del(pcd.SkuInfoList['COMMON'])\r
-            if SkuObj.SkuUsageType == SkuObj.SINGLE:\r
-                if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():\r
-                    pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
-                del(pcd.SkuInfoList['DEFAULT'])\r
-               \r
-        return Pcds\r
-\r
-    def CompareVarAttr(self, Attr1, Attr2):\r
-        if not Attr1 or not Attr2:  # for empty string\r
-            return True\r
-        Attr1s = [attr.strip() for attr in Attr1.split(",")]\r
-        Attr1Set = set(Attr1s)\r
-        Attr2s = [attr.strip() for attr in Attr2.split(",")]\r
-        Attr2Set = set(Attr2s)\r
-        if Attr2Set == Attr1Set:\r
-            return True\r
-        else:\r
-            return False\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
-        \r
-        SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)\r
-        VariableAttrs = {}\r
-        \r
-        Pcds = sdict()\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
-        AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()\r
-        \r
-        AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})\r
-        for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
-            if SkuName not in AvailableSkuIdSet:\r
-                continue\r
-            PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,Dummy4))\r
-            PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
-        # Remove redundant PCD candidates, per the ARCH and SKU\r
-        for PcdCName, TokenSpaceGuid,SkuName, Dummy4 in PcdSet:\r
-            \r
-            Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
-            if Setting == None:\r
-                continue\r
-            VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
-            \r
-            rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)\r
-            if not rt:\r
-                EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),\r
-                        ExtraData = "[%s]" % VarAttribute)\r
-            ExceedMax = False\r
-            FormatCorrect = True\r
-            if VariableOffset.isdigit():\r
-                if int(VariableOffset,10) > 0xFFFF:\r
-                    ExceedMax = True\r
-            elif re.match(r'[\t\s]*0[xX][a-fA-F0-9]+$',VariableOffset):\r
-                if int(VariableOffset,16) > 0xFFFF:\r
-                    ExceedMax = True\r
-            # For Offset written in "A.B"\r
-            elif VariableOffset.find('.') > -1:\r
-                VariableOffsetList = VariableOffset.split(".")\r
-                if not (len(VariableOffsetList) == 2\r
-                        and IsValidWord(VariableOffsetList[0])\r
-                        and IsValidWord(VariableOffsetList[1])):\r
-                    FormatCorrect = False\r
-            else:\r
-                FormatCorrect = False\r
-            if not FormatCorrect:\r
-                EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid,PcdCName)))\r
-            \r
-            if ExceedMax:\r
-                EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid,PcdCName)))\r
-            if (VariableName, VariableGuid) not in VariableAttrs:\r
-                VariableAttrs[(VariableName, VariableGuid)] = VarAttribute\r
-            else:\r
-                if not self.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):\r
-                    EdkLogger.error('Build', PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR, "The variable %s.%s for DynamicHii PCDs has conflicting attributes [%s] and [%s] " % (VariableGuid, VariableName, VarAttribute, VariableAttrs[(VariableName, VariableGuid)]))\r
-            \r
-            SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute = VarAttribute)\r
-            pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]\r
-            if (PcdCName,TokenSpaceGuid) in Pcds.keys():  \r
-                pcdObject = Pcds[PcdCName,TokenSpaceGuid]\r
-                pcdObject.SkuInfoList[SkuName] = SkuInfo\r
-            else:\r
-                Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
-                                                PcdCName,\r
-                                                TokenSpaceGuid,\r
-                                                self._PCD_TYPE_STRING_[Type],\r
-                                                '',\r
-                                                DefaultValue,\r
-                                                '',\r
-                                                '',\r
-                                                {SkuName : SkuInfo},\r
-                                                False,\r
-                                                None,\r
-                                                pcdDecObject.validateranges,\r
-                                                pcdDecObject.validlists,\r
-                                                pcdDecObject.expressions,\r
-                                                IsDsc=True)\r
-\r
-        for pcd in Pcds.values():\r
-            SkuInfoObj = pcd.SkuInfoList.values()[0]\r
-            pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]\r
-            # Only fix the value while no value provided in DSC file.\r
-            for sku in pcd.SkuInfoList.values():\r
-                if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue==None):\r
-                    sku.HiiDefaultValue = pcdDecObject.DefaultValue\r
-            if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():              \r
-                valuefromDec = pcdDecObject.DefaultValue\r
-                SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec)\r
-                pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
-            elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
-                pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
-                del(pcd.SkuInfoList['COMMON'])\r
-            elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
-                del(pcd.SkuInfoList['COMMON'])\r
-                \r
-            if SkuObj.SkuUsageType == SkuObj.SINGLE:\r
-                if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():\r
-                    pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
-                del(pcd.SkuInfoList['DEFAULT'])\r
-            \r
-            \r
-            if pcd.MaxDatumSize.strip(): \r
-                MaxSize = int(pcd.MaxDatumSize,0)\r
-            else:\r
-                MaxSize = 0\r
-            if pcdDecObject.DatumType == 'VOID*':\r
-                for (skuname,skuobj) in pcd.SkuInfoList.items():\r
-                    datalen = 0\r
-                    if skuobj.HiiDefaultValue.startswith("L"):\r
-                        datalen = (len(skuobj.HiiDefaultValue)- 3 + 1) * 2\r
-                    elif skuobj.HiiDefaultValue.startswith("{"):\r
-                        datalen = len(skuobj.HiiDefaultValue.split(","))\r
-                    else:\r
-                        datalen = len(skuobj.HiiDefaultValue) -2 + 1 \r
-                    if datalen>MaxSize:\r
-                        MaxSize = datalen\r
-                pcd.MaxDatumSize = str(MaxSize)\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
-        \r
-        SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)\r
-        \r
-        Pcds = sdict()\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
-        PcdList = []\r
-        # Find out all possible PCD candidates for self._Arch\r
-        RecordList = self._RawData[Type, self._Arch]\r
-        AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()\r
-        \r
-        AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})\r
-        for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
-            if SkuName not in AvailableSkuIdSet:\r
-                continue\r
-\r
-            PcdList.append((PcdCName, TokenSpaceGuid,SkuName, Dummy4))\r
-            PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
-        # Remove redundant PCD candidates, per the ARCH and SKU\r
-        for PcdCName, TokenSpaceGuid, SkuName,Dummy4 in PcdList:\r
-            Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
-            if Setting == None:\r
-                continue\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 = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
-            SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', VpdOffset, InitialValue)\r
-            if (PcdCName,TokenSpaceGuid) in Pcds.keys():  \r
-                pcdObject = Pcds[PcdCName,TokenSpaceGuid]\r
-                pcdObject.SkuInfoList[SkuName] = SkuInfo\r
-                if MaxDatumSize.strip():\r
-                    CurrentMaxSize = int(MaxDatumSize.strip(),0)\r
-                else:\r
-                    CurrentMaxSize = 0\r
-                if pcdObject.MaxDatumSize:\r
-                    PcdMaxSize = int(pcdObject.MaxDatumSize,0)\r
-                else:\r
-                    PcdMaxSize = 0\r
-                if CurrentMaxSize > PcdMaxSize:\r
-                    pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
-            else:\r
-                Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
-                                                PcdCName,\r
-                                                TokenSpaceGuid,\r
-                                                self._PCD_TYPE_STRING_[Type],\r
-                                                '',\r
-                                                InitialValue,\r
-                                                '',\r
-                                                MaxDatumSize,\r
-                                                {SkuName : SkuInfo},\r
-                                                False,\r
-                                                None,\r
-                                                IsDsc=True)\r
-        for pcd in Pcds.values():\r
-            SkuInfoObj = pcd.SkuInfoList.values()[0]\r
-            pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]\r
-            if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
-                valuefromDec = pcdDecObject.DefaultValue\r
-                SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj.VpdOffset, valuefromDec)\r
-                pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
-            elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
-                pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
-                del(pcd.SkuInfoList['COMMON'])\r
-            elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
-                del(pcd.SkuInfoList['COMMON'])\r
-            if SkuObj.SkuUsageType == SkuObj.SINGLE:\r
-                if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():\r
-                    pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
-                del(pcd.SkuInfoList['DEFAULT'])\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.MetaFile = 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(Name, Guid, '', '', '', '', '', {}, False, None)\r
-        self.Pcds[Name, Guid].DefaultValue = Value\r
-\r
-    _Macros             = property(_GetMacros)\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
-    SkuIdentifier       = property(_GetSkuIdentifier)\r
-    AvilableSkuIds = property(_GetAviableSkuIds)\r
-    PcdInfoFlag         = property(_GetPcdInfoFlag)\r
-    VarCheckFlag = property(_GetVarCheckFlag)\r
-    FlashDefinition     = property(_GetFdfFile)\r
-    Prebuild            = property(_GetPrebuild)\r
-    Postbuild           = property(_GetPostbuild)\r
-    BuildNumber         = property(_GetBuildNumber)\r
-    MakefileName        = property(_GetMakefileName)\r
-    BsBaseAddress       = property(_GetBsBaseAddress)\r
-    RtBaseAddress       = property(_GetRtBaseAddress)\r
-    LoadFixAddress      = property(_GetLoadFixAddress)\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
-    LibraryClasses      = property(_GetLibraryClasses)\r
-    Pcds                = property(_GetPcds)\r
-    BuildOptions        = property(_GetBuildOptions)\r
-\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
-#\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
-        TAB_DEC_DEFINES_PKG_UNI_FILE                : "_PkgUniFile",\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, File, RawData, BuildDataBase, Arch='COMMON', Target=None, Toolchain=None):\r
-        self.MetaFile = File\r
-        self._PackageDir = File.Dir\r
-        self._RawData = RawData\r
-        self._Bdb = BuildDataBase\r
-        self._Arch = Arch\r
-        self._Target = Target\r
-        self._Toolchain = Toolchain\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._PkgUniFile        = 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
-        self.__Macros           = None\r
-        self._PrivateProtocols  = None\r
-        self._PrivatePpis       = None\r
-        self._PrivateGuids      = None\r
-        self._PrivateIncludes   = None\r
-\r
-    ## Get current effective macros\r
-    def _GetMacros(self):\r
-        if self.__Macros == None:\r
-            self.__Macros = {}\r
-            self.__Macros.update(GlobalData.gGlobalDefines)\r
-        return self.__Macros\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[1]\r
-            if Name in self:\r
-                self[Name] = Record[2]\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.MetaFile)\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.MetaFile)\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
-\r
-    ## Retrieve protocol definitions (name/value pairs)\r
-    def _GetProtocol(self):\r
-        if self._Protocols == None:\r
-            #\r
-            # tdict is a special kind of dict, used for selecting correct\r
-            # protocol defition for given ARCH\r
-            #\r
-            ProtocolDict = tdict(True)\r
-            PrivateProtocolDict = tdict(True)\r
-            NameList = []\r
-            PrivateNameList = []\r
-            PublicNameList = []\r
-            # find out all protocol definitions for specific and 'common' arch\r
-            RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch]\r
-            for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:\r
-                if PrivateFlag == 'PRIVATE':\r
-                    if Name not in PrivateNameList:\r
-                        PrivateNameList.append(Name)\r
-                        PrivateProtocolDict[Arch, Name] = Guid\r
-                    if Name in PublicNameList:\r
-                        EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)\r
-                else:\r
-                    if Name not in PublicNameList:\r
-                        PublicNameList.append(Name)\r
-                    if Name in PrivateNameList:\r
-                        EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)\r
-                if Name not in NameList:\r
-                    NameList.append(Name)\r
-                ProtocolDict[Arch, Name] = Guid\r
-            # use sdict to keep the order\r
-            self._Protocols = sdict()\r
-            self._PrivateProtocols = sdict()\r
-            for Name in NameList:\r
-                #\r
-                # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
-                # will automatically turn to 'common' ARCH for trying\r
-                #\r
-                self._Protocols[Name] = ProtocolDict[self._Arch, Name]\r
-            for Name in PrivateNameList:\r
-                self._PrivateProtocols[Name] = PrivateProtocolDict[self._Arch, Name]\r
-        return self._Protocols\r
-\r
-    ## Retrieve PPI definitions (name/value pairs)\r
-    def _GetPpi(self):\r
-        if self._Ppis == None:\r
-            #\r
-            # tdict is a special kind of dict, used for selecting correct\r
-            # PPI defition for given ARCH\r
-            #\r
-            PpiDict = tdict(True)\r
-            PrivatePpiDict = tdict(True)\r
-            NameList = []\r
-            PrivateNameList = []\r
-            PublicNameList = []\r
-            # find out all PPI definitions for specific arch and 'common' arch\r
-            RecordList = self._RawData[MODEL_EFI_PPI, self._Arch]\r
-            for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:\r
-                if PrivateFlag == 'PRIVATE':\r
-                    if Name not in PrivateNameList:\r
-                        PrivateNameList.append(Name)\r
-                        PrivatePpiDict[Arch, Name] = Guid\r
-                    if Name in PublicNameList:\r
-                        EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)\r
-                else:\r
-                    if Name not in PublicNameList:\r
-                        PublicNameList.append(Name)\r
-                    if Name in PrivateNameList:\r
-                        EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)\r
-                if Name not in NameList:\r
-                    NameList.append(Name)\r
-                PpiDict[Arch, Name] = Guid\r
-            # use sdict to keep the order\r
-            self._Ppis = sdict()\r
-            self._PrivatePpis = sdict()\r
-            for Name in NameList:\r
-                #\r
-                # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
-                # will automatically turn to 'common' ARCH for trying\r
-                #\r
-                self._Ppis[Name] = PpiDict[self._Arch, Name]\r
-            for Name in PrivateNameList:\r
-                self._PrivatePpis[Name] = PrivatePpiDict[self._Arch, Name]\r
-        return self._Ppis\r
-\r
-    ## Retrieve GUID definitions (name/value pairs)\r
-    def _GetGuid(self):\r
-        if self._Guids == None:\r
-            #\r
-            # tdict is a special kind of dict, used for selecting correct\r
-            # GUID defition for given ARCH\r
-            #\r
-            GuidDict = tdict(True)\r
-            PrivateGuidDict = tdict(True)\r
-            NameList = []\r
-            PrivateNameList = []\r
-            PublicNameList = []\r
-            # find out all protocol definitions for specific and 'common' arch\r
-            RecordList = self._RawData[MODEL_EFI_GUID, self._Arch]\r
-            for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:\r
-                if PrivateFlag == 'PRIVATE':\r
-                    if Name not in PrivateNameList:\r
-                        PrivateNameList.append(Name)\r
-                        PrivateGuidDict[Arch, Name] = Guid\r
-                    if Name in PublicNameList:\r
-                        EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)\r
-                else:\r
-                    if Name not in PublicNameList:\r
-                        PublicNameList.append(Name)\r
-                    if Name in PrivateNameList:\r
-                        EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)\r
-                if Name not in NameList:\r
-                    NameList.append(Name)\r
-                GuidDict[Arch, Name] = Guid\r
-            # use sdict to keep the order\r
-            self._Guids = sdict()\r
-            self._PrivateGuids = sdict()\r
-            for Name in NameList:\r
-                #\r
-                # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
-                # will automatically turn to 'common' ARCH for trying\r
-                #\r
-                self._Guids[Name] = GuidDict[self._Arch, Name]\r
-            for Name in PrivateNameList:\r
-                self._PrivateGuids[Name] = PrivateGuidDict[self._Arch, Name]\r
-        return self._Guids\r
-\r
-    ## Retrieve public include paths declared in this package\r
-    def _GetInclude(self):\r
-        if self._Includes == None:\r
-            self._Includes = []\r
-            self._PrivateIncludes = []\r
-            PublicInclues = []\r
-            RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch]\r
-            Macros = self._Macros\r
-            Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
-            for Record in RecordList:\r
-                File = PathClass(NormPath(Record[0], Macros), self._PackageDir, Arch=self._Arch)\r
-                LineNo = Record[-1]\r
-                # validate the path\r
-                ErrorCode, ErrorInfo = File.Validate()\r
-                if ErrorCode != 0:\r
-                    EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
-\r
-                # avoid duplicate include path\r
-                if File not in self._Includes:\r
-                    self._Includes.append(File)\r
-                if Record[4] == 'PRIVATE':\r
-                    if File not in self._PrivateIncludes:\r
-                        self._PrivateIncludes.append(File)\r
-                    if File in PublicInclues:\r
-                        EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % File, File=self.MetaFile, Line=LineNo)\r
-                else:\r
-                    if File not in PublicInclues:\r
-                        PublicInclues.append(File)\r
-                    if File in self._PrivateIncludes:\r
-                        EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % File, File=self.MetaFile, Line=LineNo)\r
-\r
-        return self._Includes\r
-\r
-    ## Retrieve library class declarations (not used in build at present)\r
-    def _GetLibraryClass(self):\r
-        if self._LibraryClasses == None:\r
-            #\r
-            # tdict is a special kind of dict, used for selecting correct\r
-            # library class declaration for given ARCH\r
-            #\r
-            LibraryClassDict = tdict(True)\r
-            LibraryClassSet = set()\r
-            RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]\r
-            Macros = self._Macros\r
-            for LibraryClass, File, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:\r
-                File = PathClass(NormPath(File, Macros), self._PackageDir, Arch=self._Arch)\r
-                # check the file validation\r
-                ErrorCode, ErrorInfo = File.Validate()\r
-                if ErrorCode != 0:\r
-                    EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
-                LibraryClassSet.add(LibraryClass)\r
-                LibraryClassDict[Arch, LibraryClass] = File\r
-            self._LibraryClasses = sdict()\r
-            for LibraryClass in LibraryClassSet:\r
-                self._LibraryClasses[LibraryClass] = LibraryClassDict[self._Arch, LibraryClass]\r
-        return self._LibraryClasses\r
-\r
-    ## Retrieve PCD declarations\r
-    def _GetPcds(self):\r
-        if self._Pcds == None:\r
-            self._Pcds = sdict()\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._GetPcd(MODEL_PCD_DYNAMIC))\r
-            self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))\r
-        return self._Pcds\r
-\r
-    ## Retrieve PCD declarations for given type\r
-    def _GetPcd(self, Type):\r
-        Pcds = sdict()\r
-        #\r
-        # tdict is a special kind of dict, used for selecting correct\r
-        # PCD declaration for given ARCH\r
-        #\r
-        PcdDict = tdict(True, 3)\r
-        # for summarizing PCD\r
-        PcdSet = set()\r
-        # find out all PCDs of the 'type'\r
-        RecordList = self._RawData[Type, self._Arch]\r
-        for TokenSpaceGuid, PcdCName, Setting, Arch, PrivateFlag, Dummy1, Dummy2 in RecordList:\r
-            PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting\r
-            PcdSet.add((PcdCName, TokenSpaceGuid))\r
-\r
-        for PcdCName, TokenSpaceGuid in PcdSet:\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
-            #\r
-            Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]\r
-            if Setting == None:\r
-                continue\r
-\r
-            DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting)\r
-                                       \r
-            validateranges, validlists, expressions = self._RawData.GetValidExpression(TokenSpaceGuid, PcdCName)                          \r
-            Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdClassObject(\r
-                                                                            PcdCName,\r
-                                                                            TokenSpaceGuid,\r
-                                                                            self._PCD_TYPE_STRING_[Type],\r
-                                                                            DatumType,\r
-                                                                            DefaultValue,\r
-                                                                            TokenNumber,\r
-                                                                            '',\r
-                                                                            {},\r
-                                                                            False,\r
-                                                                            None,\r
-                                                                            list(validateranges),\r
-                                                                            list(validlists),\r
-                                                                            list(expressions)\r
-                                                                            )\r
-        return Pcds\r
-\r
-\r
-    _Macros         = property(_GetMacros)\r
-    Arch            = property(_GetArch, _SetArch)\r
-    PackageName     = property(_GetPackageName)\r
-    Guid            = property(_GetFileGuid)\r
-    Version         = property(_GetVersion)\r
-\r
-    Protocols       = property(_GetProtocol)\r
-    Ppis            = property(_GetPpi)\r
-    Guids           = property(_GetGuid)\r
-    Includes        = property(_GetInclude)\r
-    LibraryClasses  = property(_GetLibraryClass)\r
-    Pcds            = property(_GetPcds)\r
-\r
-## Module build information from INF file\r
-#\r
-#  This class is used to retrieve information stored in database and convert them\r
-# into ModuleBuildClassObject form for easier use for AutoGen.\r
-#\r
-class InfBuildData(ModuleBuildClassObject):\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 InfBuildData directly\r
-    _PROPERTY_ = {\r
-        #\r
-        # Required Fields\r
-        #\r
-        TAB_INF_DEFINES_BASE_NAME                   : "_BaseName",\r
-        TAB_INF_DEFINES_FILE_GUID                   : "_Guid",\r
-        TAB_INF_DEFINES_MODULE_TYPE                 : "_ModuleType",\r
-        #\r
-        # Optional Fields\r
-        #\r
-        #TAB_INF_DEFINES_INF_VERSION                 : "_AutoGenVersion",\r
-        TAB_INF_DEFINES_COMPONENT_TYPE              : "_ComponentType",\r
-        TAB_INF_DEFINES_MAKEFILE_NAME               : "_MakefileName",\r
-        #TAB_INF_DEFINES_CUSTOM_MAKEFILE             : "_CustomMakefile",\r
-        TAB_INF_DEFINES_DPX_SOURCE                  :"_DxsFile",\r
-        TAB_INF_DEFINES_VERSION_NUMBER              : "_Version",\r
-        TAB_INF_DEFINES_VERSION_STRING              : "_Version",\r
-        TAB_INF_DEFINES_VERSION                     : "_Version",\r
-        TAB_INF_DEFINES_PCD_IS_DRIVER               : "_PcdIsDriver",\r
-        TAB_INF_DEFINES_SHADOW                      : "_Shadow",\r
-\r
-        TAB_COMPONENTS_SOURCE_OVERRIDE_PATH         : "_SourceOverridePath",\r
-    }\r
-\r
-    # dict used to convert Component type to Module type\r
-    _MODULE_TYPE_ = {\r
-        "LIBRARY"               :   "BASE",\r
-        "SECURITY_CORE"         :   "SEC",\r
-        "PEI_CORE"              :   "PEI_CORE",\r
-        "COMBINED_PEIM_DRIVER"  :   "PEIM",\r
-        "PIC_PEIM"              :   "PEIM",\r
-        "RELOCATABLE_PEIM"      :   "PEIM",\r
-        "PE32_PEIM"             :   "PEIM",\r
-        "BS_DRIVER"             :   "DXE_DRIVER",\r
-        "RT_DRIVER"             :   "DXE_RUNTIME_DRIVER",\r
-        "SAL_RT_DRIVER"         :   "DXE_SAL_DRIVER",\r
-        "DXE_SMM_DRIVER"        :   "DXE_SMM_DRIVER",\r
-    #    "SMM_DRIVER"            :   "DXE_SMM_DRIVER",\r
-    #    "BS_DRIVER"             :   "DXE_SMM_DRIVER",\r
-    #    "BS_DRIVER"             :   "UEFI_DRIVER",\r
-        "APPLICATION"           :   "UEFI_APPLICATION",\r
-        "LOGO"                  :   "BASE",\r
-    }\r
-\r
-    # regular expression for converting XXX_FLAGS in [nmake] section to new type\r
-    _NMAKE_FLAG_PATTERN_ = re.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re.UNICODE)\r
-    # dict used to convert old tool name used in [nmake] section to new ones\r
-    _TOOL_CODE_ = {\r
-        "C"         :   "CC",\r
-        "LIB"       :   "SLINK",\r
-        "LINK"      :   "DLINK",\r
-    }\r
-\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        The name of platform employing this module\r
-    #   @param      Macros          Macros used for replacement in DSC file\r
-    #\r
-    def __init__(self, FilePath, RawData, BuildDatabase, Arch='COMMON', Target=None, Toolchain=None):\r
-        self.MetaFile = FilePath\r
-        self._ModuleDir = FilePath.Dir\r
-        self._RawData = RawData\r
-        self._Bdb = BuildDatabase\r
-        self._Arch = Arch\r
-        self._Target = Target\r
-        self._Toolchain = Toolchain\r
-        self._Platform = 'COMMON'\r
-        self._SourceOverridePath = None\r
-        if FilePath.Key in GlobalData.gOverrideDir:\r
-            self._SourceOverridePath = GlobalData.gOverrideDir[FilePath.Key]\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 InfBuildData to None\r
-    def _Clear(self):\r
-        self._HeaderComments = None\r
-        self._TailComments = None\r
-        self._Header_               = None\r
-        self._AutoGenVersion        = None\r
-        self._BaseName              = None\r
-        self._DxsFile               = None\r
-        self._ModuleType            = None\r
-        self._ComponentType         = None\r
-        self._BuildType             = None\r
-        self._Guid                  = None\r
-        self._Version               = None\r
-        self._PcdIsDriver           = None\r
-        self._BinaryModule          = None\r
-        self._Shadow                = None\r
-        self._MakefileName          = None\r
-        self._CustomMakefile        = None\r
-        self._Specification         = None\r
-        self._LibraryClass          = None\r
-        self._ModuleEntryPointList  = None\r
-        self._ModuleUnloadImageList = None\r
-        self._ConstructorList       = None\r
-        self._DestructorList        = None\r
-        self._Defs                  = None\r
-        self._Binaries              = None\r
-        self._Sources               = None\r
-        self._LibraryClasses        = None\r
-        self._Libraries             = None\r
-        self._Protocols             = None\r
-        self._ProtocolComments = None\r
-        self._Ppis                  = None\r
-        self._PpiComments = None\r
-        self._Guids                 = None\r
-        self._GuidsUsedByPcd = sdict()\r
-        self._GuidComments = None\r
-        self._Includes              = None\r
-        self._Packages              = None\r
-        self._Pcds                  = None\r
-        self._PcdComments = None\r
-        self._BuildOptions          = None\r
-        self._Depex                 = None\r
-        self._DepexExpression       = None\r
-        self.__Macros               = None\r
-\r
-    ## Get current effective macros\r
-    def _GetMacros(self):\r
-        if self.__Macros == None:\r
-            self.__Macros = {}\r
-            # EDK_GLOBAL defined macros can be applied to EDK module\r
-            if self.AutoGenVersion < 0x00010005:\r
-                self.__Macros.update(GlobalData.gEdkGlobal)\r
-                self.__Macros.update(GlobalData.gGlobalDefines)\r
-        return self.__Macros\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
 \r
-    ## Return the name of platform employing this module\r
-    def _GetPlatform(self):\r
-        return self._Platform\r
-\r
-    ## Change the name of platform employing this module\r
-    #\r
-    #   Changing the default name of platform to another may affect some information\r
-    # because they may be PLATFORM-related. That's why we need to clear all internal\r
-    # used members, in order to cause all information to be re-retrieved.\r
-    #\r
-    def _SetPlatform(self, Value):\r
-        if self._Platform == Value:\r
-            return\r
-        self._Platform = Value\r
-        self._Clear()\r
-    def _GetHeaderComments(self):\r
-        if not self._HeaderComments:\r
-            self._HeaderComments = []\r
-            RecordList = self._RawData[MODEL_META_DATA_HEADER_COMMENT]\r
-            for Record in RecordList:\r
-                self._HeaderComments.append(Record[0])\r
-        return self._HeaderComments\r
-    def _GetTailComments(self):\r
-        if not self._TailComments:\r
-            self._TailComments = []\r
-            RecordList = self._RawData[MODEL_META_DATA_TAIL_COMMENT]\r
-            for Record in RecordList:\r
-                self._TailComments.append(Record[0])\r
-        return self._TailComments\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, self._Platform]\r
-        for Record in RecordList:\r
-            Name, Value = Record[1], ReplaceMacro(Record[2], self._Macros, False)\r
-            # items defined _PROPERTY_ don't need additional processing\r
-            if Name in self:\r
-                self[Name] = Value\r
-                if self._Defs == None:\r
-                    self._Defs = sdict()\r
-                self._Defs[Name] = Value\r
-                self._Macros[Name] = Value\r
-            # some special items in [Defines] section need special treatment\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[Name] = GetHexVerValue(Value)\r
-                if self._Specification[Name] == None:\r
-                    EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
-                                    "'%s' format is not supported for %s" % (Value, Name),\r
-                                    File=self.MetaFile, Line=Record[-1])\r
-            elif Name == 'LIBRARY_CLASS':\r
-                if self._LibraryClass == None:\r
-                    self._LibraryClass = []\r
-                ValueList = GetSplitValueList(Value)\r
-                LibraryClass = ValueList[0]\r
-                if len(ValueList) > 1:\r
-                    SupModuleList = GetSplitValueList(ValueList[1], ' ')\r
-                else:\r
-                    SupModuleList = SUP_MODULE_LIST\r
-                self._LibraryClass.append(LibraryClassObject(LibraryClass, SupModuleList))\r
-            elif Name == 'ENTRY_POINT':\r
-                if self._ModuleEntryPointList == None:\r
-                    self._ModuleEntryPointList = []\r
-                self._ModuleEntryPointList.append(Value)\r
-            elif Name == 'UNLOAD_IMAGE':\r
-                if self._ModuleUnloadImageList == None:\r
-                    self._ModuleUnloadImageList = []\r
-                if not Value:\r
-                    continue\r
-                self._ModuleUnloadImageList.append(Value)\r
-            elif Name == 'CONSTRUCTOR':\r
-                if self._ConstructorList == None:\r
-                    self._ConstructorList = []\r
-                if not Value:\r
-                    continue\r
-                self._ConstructorList.append(Value)\r
-            elif Name == 'DESTRUCTOR':\r
-                if self._DestructorList == None:\r
-                    self._DestructorList = []\r
-                if not Value:\r
-                    continue\r
-                self._DestructorList.append(Value)\r
-            elif Name == TAB_INF_DEFINES_CUSTOM_MAKEFILE:\r
-                TokenList = GetSplitValueList(Value)\r
-                if self._CustomMakefile == None:\r
-                    self._CustomMakefile = {}\r
-                if len(TokenList) < 2:\r
-                    self._CustomMakefile['MSFT'] = TokenList[0]\r
-                    self._CustomMakefile['GCC'] = TokenList[0]\r
-                else:\r
-                    if TokenList[0] not in ['MSFT', 'GCC']:\r
-                        EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
-                                        "No supported family [%s]" % TokenList[0],\r
-                                        File=self.MetaFile, Line=Record[-1])\r
-                    self._CustomMakefile[TokenList[0]] = TokenList[1]\r
-            else:\r
-                if self._Defs == None:\r
-                    self._Defs = sdict()\r
-                self._Defs[Name] = Value\r
-                self._Macros[Name] = Value\r
-\r
-        #\r
-        # Retrieve information in sections specific to Edk.x modules\r
-        #\r
-        if self.AutoGenVersion >= 0x00010005:\r
-            if not self._ModuleType:\r
-                EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
-                                "MODULE_TYPE is not given", File=self.MetaFile)\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[1]\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._Specification == None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x00010032):\r
-                if self._ModuleType == SUP_MODULE_MM_CORE_STANDALONE:\r
-                    EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "MM_CORE_STANDALONE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x00010032", File=self.MetaFile)\r
-                if self._ModuleType == SUP_MODULE_MM_STANDALONE:\r
-                    EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "MM_STANDALONE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x00010032", File=self.MetaFile)\r
-            if self._Defs and 'PCI_DEVICE_ID' in self._Defs and 'PCI_VENDOR_ID' in self._Defs \\r
-               and 'PCI_CLASS_CODE' in self._Defs and 'PCI_REVISION' in self._Defs:\r
-                self._BuildType = 'UEFI_OPTIONROM'\r
-                if 'PCI_COMPRESS' in self._Defs:\r
-                    if self._Defs['PCI_COMPRESS'] not in ('TRUE', 'FALSE'):\r
-                        EdkLogger.error("build", FORMAT_INVALID, "Expected TRUE/FALSE for PCI_COMPRESS: %s" %self.MetaFile)\r
-\r
-            elif self._Defs and 'UEFI_HII_RESOURCE_SECTION' in self._Defs \\r
-               and self._Defs['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':\r
-                self._BuildType = 'UEFI_HII'\r
-            else:\r
-                self._BuildType = self._ModuleType.upper()\r
-\r
-            if self._DxsFile:\r
-                File = PathClass(NormPath(self._DxsFile), self._ModuleDir, Arch=self._Arch)\r
-                # check the file validation\r
-                ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)\r
-                if ErrorCode != 0:\r
-                    EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,\r
-                                    File=self.MetaFile, Line=LineNo)\r
-                if self.Sources == None:\r
-                    self._Sources = []\r
-                self._Sources.append(File)\r
-        else:  \r
-            if not self._ComponentType:\r
-                EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
-                                "COMPONENT_TYPE is not given", File=self.MetaFile)\r
-            self._BuildType = self._ComponentType.upper()\r
-            if self._ComponentType in self._MODULE_TYPE_:\r
-                self._ModuleType = self._MODULE_TYPE_[self._ComponentType]\r
-            if self._ComponentType == 'LIBRARY':\r
-                self._LibraryClass = [LibraryClassObject(self._BaseName, SUP_MODULE_LIST)]\r
-            # make use some [nmake] section macros\r
-            Macros = self._Macros\r
-            Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
-            Macros['PROCESSOR'] = self._Arch\r
-            RecordList = self._RawData[MODEL_META_DATA_NMAKE, self._Arch, self._Platform]\r
-            for Name, Value, Dummy, Arch, Platform, ID, LineNo in RecordList:\r
-                Value = ReplaceMacro(Value, Macros, True)\r
-                if Name == "IMAGE_ENTRY_POINT":\r
-                    if self._ModuleEntryPointList == None:\r
-                        self._ModuleEntryPointList = []\r
-                    self._ModuleEntryPointList.append(Value)\r
-                elif Name == "DPX_SOURCE":\r
-                    File = PathClass(NormPath(Value), self._ModuleDir, Arch=self._Arch)\r
-                    # check the file validation\r
-                    ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)\r
-                    if ErrorCode != 0:\r
-                        EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,\r
-                                        File=self.MetaFile, Line=LineNo)\r
-                    if self.Sources == None:\r
-                        self._Sources = []\r
-                    self._Sources.append(File)\r
-                else:\r
-                    ToolList = self._NMAKE_FLAG_PATTERN_.findall(Name)\r
-                    if len(ToolList) == 0 or len(ToolList) != 1:\r
-                        pass\r
-#                        EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,\r
-#                                       File=self.MetaFile, Line=LineNo)\r
-                    else:\r
-                        if self._BuildOptions == None:\r
-                            self._BuildOptions = sdict()\r
-\r
-                        if ToolList[0] in self._TOOL_CODE_:\r
-                            Tool = self._TOOL_CODE_[ToolList[0]]\r
-                        else:\r
-                            Tool = ToolList[0]\r
-                        ToolChain = "*_*_*_%s_FLAGS" % Tool\r
-                        ToolChainFamily = 'MSFT'    # Edk.x only support MSFT tool chain\r
-                        #ignore not replaced macros in value\r
-                        ValueList = GetSplitList(' ' + Value, '/D')\r
-                        Dummy = ValueList[0]\r
-                        for Index in range(1, len(ValueList)):\r
-                            if ValueList[Index][-1] == '=' or ValueList[Index] == '':\r
-                                continue\r
-                            Dummy = Dummy + ' /D ' + ValueList[Index]\r
-                        Value = Dummy.strip()\r
-                        if (ToolChainFamily, ToolChain) not in self._BuildOptions:\r
-                            self._BuildOptions[ToolChainFamily, ToolChain] = Value\r
-                        else:\r
-                            OptionString = self._BuildOptions[ToolChainFamily, ToolChain]\r
-                            self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Value\r
-        # set _Header to non-None in order to avoid database re-querying\r
-        self._Header_ = 'DUMMY'\r
-\r
-    ## Retrieve file version\r
-    def _GetInfVersion(self):\r
-        if self._AutoGenVersion == None:\r
-            RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
-            for Record in RecordList:\r
-                if Record[1] == TAB_INF_DEFINES_INF_VERSION:\r
-                    if '.' in Record[2]:\r
-                        ValueList = Record[2].split('.')\r
-                        Major = '%04o' % int(ValueList[0], 0)\r
-                        Minor = '%04o' % int(ValueList[1], 0)\r
-                        self._AutoGenVersion = int('0x' + Major + Minor, 0)\r
-                    else:\r
-                        self._AutoGenVersion = int(Record[2], 0)\r
-                    break\r
-            if self._AutoGenVersion == None:\r
-                self._AutoGenVersion = 0x00010000\r
-        return self._AutoGenVersion\r
-\r
-    ## Retrieve BASE_NAME\r
-    def _GetBaseName(self):\r
-        if self._BaseName == None:\r
-            if self._Header_ == None:\r
-                self._GetHeaderInfo()\r
-            if self._BaseName == None:\r
-                EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BASE_NAME name", File=self.MetaFile)\r
-        return self._BaseName\r
-\r
-    ## Retrieve DxsFile\r
-    def _GetDxsFile(self):\r
-        if self._DxsFile == None:\r
-            if self._Header_ == None:\r
-                self._GetHeaderInfo()\r
-            if self._DxsFile == None:\r
-                self._DxsFile = ''\r
-        return self._DxsFile\r
-\r
-    ## Retrieve MODULE_TYPE\r
-    def _GetModuleType(self):\r
-        if self._ModuleType == None:\r
-            if self._Header_ == None:\r
-                self._GetHeaderInfo()\r
-            if self._ModuleType == None:\r
-                self._ModuleType = 'BASE'\r
-            if self._ModuleType not in SUP_MODULE_LIST:\r
-                self._ModuleType = "USER_DEFINED"\r
-        return self._ModuleType\r
-\r
-    ## Retrieve COMPONENT_TYPE\r
-    def _GetComponentType(self):\r
-        if self._ComponentType == None:\r
-            if self._Header_ == None:\r
-                self._GetHeaderInfo()\r
-            if self._ComponentType == None:\r
-                self._ComponentType = 'USER_DEFINED'\r
-        return self._ComponentType\r
-\r
-    ## Retrieve "BUILD_TYPE"\r
-    def _GetBuildType(self):\r
-        if self._BuildType == None:\r
-            if self._Header_ == None:\r
-                self._GetHeaderInfo()\r
-            if not self._BuildType:\r
-                self._BuildType = "BASE"\r
-        return self._BuildType\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
-                self._Guid = '00000000-0000-0000-0000-000000000000'\r
-        return self._Guid\r
-\r
-    ## Retrieve module 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 = '0.0'\r
-        return self._Version\r
-\r
-    ## Retrieve PCD_IS_DRIVER\r
-    def _GetPcdIsDriver(self):\r
-        if self._PcdIsDriver == None:\r
-            if self._Header_ == None:\r
-                self._GetHeaderInfo()\r
-            if self._PcdIsDriver == None:\r
-                self._PcdIsDriver = ''\r
-        return self._PcdIsDriver\r
-\r
-    ## Retrieve SHADOW\r
-    def _GetShadow(self):\r
-        if self._Shadow == None:\r
-            if self._Header_ == None:\r
-                self._GetHeaderInfo()\r
-            if self._Shadow != None and self._Shadow.upper() == 'TRUE':\r
-                self._Shadow = True\r
-            else:\r
-                self._Shadow = False\r
-        return self._Shadow\r
-\r
-    ## Retrieve CUSTOM_MAKEFILE\r
-    def _GetMakefile(self):\r
-        if self._CustomMakefile == None:\r
-            if self._Header_ == None:\r
-                self._GetHeaderInfo()\r
-            if self._CustomMakefile == None:\r
-                self._CustomMakefile = {}\r
-        return self._CustomMakefile\r
-\r
-    ## Retrieve EFI_SPECIFICATION_VERSION\r
-    def _GetSpec(self):\r
-        if self._Specification == None:\r
-            if self._Header_ == None:\r
-                self._GetHeaderInfo()\r
-            if self._Specification == None:\r
-                self._Specification = {}\r
-        return self._Specification\r
-\r
-    ## Retrieve LIBRARY_CLASS\r
-    def _GetLibraryClass(self):\r
-        if self._LibraryClass == None:\r
-            if self._Header_ == None:\r
-                self._GetHeaderInfo()\r
-            if self._LibraryClass == None:\r
-                self._LibraryClass = []\r
-        return self._LibraryClass\r
-\r
-    ## Retrieve ENTRY_POINT\r
-    def _GetEntryPoint(self):\r
-        if self._ModuleEntryPointList == None:\r
-            if self._Header_ == None:\r
-                self._GetHeaderInfo()\r
-            if self._ModuleEntryPointList == None:\r
-                self._ModuleEntryPointList = []\r
-        return self._ModuleEntryPointList\r
-\r
-    ## Retrieve UNLOAD_IMAGE\r
-    def _GetUnloadImage(self):\r
-        if self._ModuleUnloadImageList == None:\r
-            if self._Header_ == None:\r
-                self._GetHeaderInfo()\r
-            if self._ModuleUnloadImageList == None:\r
-                self._ModuleUnloadImageList = []\r
-        return self._ModuleUnloadImageList\r
-\r
-    ## Retrieve CONSTRUCTOR\r
-    def _GetConstructor(self):\r
-        if self._ConstructorList == None:\r
-            if self._Header_ == None:\r
-                self._GetHeaderInfo()\r
-            if self._ConstructorList == None:\r
-                self._ConstructorList = []\r
-        return self._ConstructorList\r
-\r
-    ## Retrieve DESTRUCTOR\r
-    def _GetDestructor(self):\r
-        if self._DestructorList == None:\r
-            if self._Header_ == None:\r
-                self._GetHeaderInfo()\r
-            if self._DestructorList == None:\r
-                self._DestructorList = []\r
-        return self._DestructorList\r
-\r
-    ## Retrieve definies other than above ones\r
-    def _GetDefines(self):\r
-        if self._Defs == None:\r
-            if self._Header_ == None:\r
-                self._GetHeaderInfo()\r
-            if self._Defs == None:\r
-                self._Defs = sdict()\r
-        return self._Defs\r
-\r
-    ## Retrieve binary files\r
-    def _GetBinaries(self):\r
-        if self._Binaries == None:\r
-            self._Binaries = []\r
-            RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform]\r
-            Macros = self._Macros\r
-            Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
-            Macros['PROCESSOR'] = self._Arch\r
-            for Record in RecordList:\r
-                FileType = Record[0]\r
-                LineNo = Record[-1]\r
-                Target = 'COMMON'\r
-                FeatureFlag = []\r
-                if Record[2]:\r
-                    TokenList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)\r
-                    if TokenList:\r
-                        Target = TokenList[0]\r
-                    if len(TokenList) > 1:\r
-                        FeatureFlag = Record[1:]\r
-\r
-                File = PathClass(NormPath(Record[1], Macros), self._ModuleDir, '', FileType, True, self._Arch, '', Target)\r
-                # check the file validation\r
-                ErrorCode, ErrorInfo = File.Validate()\r
-                if ErrorCode != 0:\r
-                    EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
-                self._Binaries.append(File)\r
-        return self._Binaries\r
-\r
-    ## Retrieve binary files with error check.\r
-    def _GetBinaryFiles(self):\r
-        Binaries = self._GetBinaries()\r
-        if GlobalData.gIgnoreSource and Binaries == []:\r
-            ErrorInfo = "The INF file does not contain any Binaries to use in creating the image\n"\r
-            EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, ExtraData=ErrorInfo, File=self.MetaFile)\r
-\r
-        return Binaries\r
-    ## Check whether it exists the binaries with current ARCH in AsBuild INF\r
-    def _IsSupportedArch(self):\r
-        if self._GetBinaries() and not self._GetSourceFiles():\r
-            return True\r
-        else:\r
-            return False\r
-    ## Retrieve source files\r
-    def _GetSourceFiles(self):\r
-        #Ignore all source files in a binary build mode\r
-        if GlobalData.gIgnoreSource:\r
-            self._Sources = []\r
-            return self._Sources\r
-\r
-        if self._Sources == None:\r
-            self._Sources = []\r
-            RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform]\r
-            Macros = self._Macros\r
-            for Record in RecordList:\r
-                LineNo = Record[-1]\r
-                ToolChainFamily = Record[1]\r
-                TagName = Record[2]\r
-                ToolCode = Record[3]\r
-                FeatureFlag = Record[4]\r
-                if self.AutoGenVersion < 0x00010005:\r
-                    Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
-                    Macros['PROCESSOR'] = self._Arch\r
-                    SourceFile = NormPath(Record[0], Macros)\r
-                    if SourceFile[0] == os.path.sep:\r
-                        SourceFile = mws.join(GlobalData.gWorkspace, SourceFile[1:])\r
-                    # old module source files (Edk)\r
-                    File = PathClass(SourceFile, self._ModuleDir, self._SourceOverridePath,\r
-                                     '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)\r
-                    # check the file validation\r
-                    ErrorCode, ErrorInfo = File.Validate(CaseSensitive=False)\r
-                    if ErrorCode != 0:\r
-                        if File.Ext.lower() == '.h':\r
-                            EdkLogger.warn('build', 'Include file not found', ExtraData=ErrorInfo,\r
-                                           File=self.MetaFile, Line=LineNo)\r
-                            continue\r
-                        else:\r
-                            EdkLogger.error('build', ErrorCode, ExtraData=File, File=self.MetaFile, Line=LineNo)\r
-                else:\r
-                    File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, '',\r
-                                     '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)\r
-                    # check the file validation\r
-                    ErrorCode, ErrorInfo = File.Validate()\r
-                    if ErrorCode != 0:\r
-                        EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
-\r
-                self._Sources.append(File)\r
-        return self._Sources\r
-\r
-    ## Retrieve library classes employed by this module\r
-    def _GetLibraryClassUses(self):\r
-        if self._LibraryClasses == None:\r
-            self._LibraryClasses = sdict()\r
-            RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, self._Platform]\r
-            for Record in RecordList:\r
-                Lib = Record[0]\r
-                Instance = Record[1]\r
-                if Instance:\r
-                    Instance = NormPath(Instance, self._Macros)\r
-                self._LibraryClasses[Lib] = Instance\r
-        return self._LibraryClasses\r
-\r
-    ## Retrieve library names (for Edk.x style of modules)\r
-    def _GetLibraryNames(self):\r
-        if self._Libraries == None:\r
-            self._Libraries = []\r
-            RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch, self._Platform]\r
-            for Record in RecordList:\r
-                LibraryName = ReplaceMacro(Record[0], self._Macros, False)\r
-                # in case of name with '.lib' extension, which is unusual in Edk.x inf\r
-                LibraryName = os.path.splitext(LibraryName)[0]\r
-                if LibraryName not in self._Libraries:\r
-                    self._Libraries.append(LibraryName)\r
-        return self._Libraries\r
-\r
-    def _GetProtocolComments(self):\r
-        self._GetProtocols()\r
-        return self._ProtocolComments\r
-    ## Retrieve protocols consumed/produced by this module\r
-    def _GetProtocols(self):\r
-        if self._Protocols == None:\r
-            self._Protocols = sdict()\r
-            self._ProtocolComments = sdict()\r
-            RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]\r
-            for Record in RecordList:\r
-                CName = Record[0]\r
-                Value = ProtocolValue(CName, self.Packages, self.MetaFile.Path)\r
-                if Value == None:\r
-                    PackageList = "\n\t".join([str(P) for P in self.Packages])\r
-                    EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
-                                    "Value of Protocol [%s] is not found under [Protocols] section in" % CName,\r
-                                    ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
-                self._Protocols[CName] = Value\r
-                CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
-                Comments = []\r
-                for CmtRec in CommentRecords:\r
-                    Comments.append(CmtRec[0])\r
-                self._ProtocolComments[CName] = Comments\r
-        return self._Protocols\r
-\r
-    def _GetPpiComments(self):\r
-        self._GetPpis()\r
-        return self._PpiComments\r
-    ## Retrieve PPIs consumed/produced by this module\r
-    def _GetPpis(self):\r
-        if self._Ppis == None:\r
-            self._Ppis = sdict()\r
-            self._PpiComments = sdict()\r
-            RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]\r
-            for Record in RecordList:\r
-                CName = Record[0]\r
-                Value = PpiValue(CName, self.Packages, self.MetaFile.Path)\r
-                if Value == None:\r
-                    PackageList = "\n\t".join([str(P) for P in self.Packages])\r
-                    EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
-                                    "Value of PPI [%s] is not found under [Ppis] section in " % CName,\r
-                                    ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
-                self._Ppis[CName] = Value\r
-                CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
-                Comments = []\r
-                for CmtRec in CommentRecords:\r
-                    Comments.append(CmtRec[0])\r
-                self._PpiComments[CName] = Comments\r
-        return self._Ppis\r
-\r
-    def _GetGuidComments(self):\r
-        self._GetGuids()\r
-        return self._GuidComments\r
-    ## Retrieve GUIDs consumed/produced by this module\r
-    def _GetGuids(self):\r
-        if self._Guids == None:\r
-            self._Guids = sdict()\r
-            self._GuidComments = sdict()\r
-            RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]\r
-            for Record in RecordList:\r
-                CName = Record[0]\r
-                Value = GuidValue(CName, self.Packages, self.MetaFile.Path)\r
-                if Value == None:\r
-                    PackageList = "\n\t".join([str(P) for P in self.Packages])\r
-                    EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
-                                    "Value of Guid [%s] is not found under [Guids] section in" % CName,\r
-                                    ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
-                self._Guids[CName] = Value\r
-                CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
-                Comments = []\r
-                for CmtRec in CommentRecords:\r
-                    Comments.append(CmtRec[0])\r
-                self._GuidComments[CName] = Comments\r
-        return self._Guids\r
-\r
-    ## Retrieve include paths necessary for this module (for Edk.x style of modules)\r
-    def _GetIncludes(self):\r
-        if self._Includes == None:\r
-            self._Includes = []\r
-            if self._SourceOverridePath:\r
-                self._Includes.append(self._SourceOverridePath)\r
-\r
-            Macros = self._Macros\r
-            if 'PROCESSOR' in GlobalData.gEdkGlobal.keys():\r
-                Macros['PROCESSOR'] = GlobalData.gEdkGlobal['PROCESSOR']\r
-            else:\r
-                Macros['PROCESSOR'] = self._Arch\r
-            RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch, self._Platform]\r
-            for Record in RecordList:\r
-                if Record[0].find('EDK_SOURCE') > -1:\r
-                    Macros['EDK_SOURCE'] = GlobalData.gEcpSource\r
-                    File = NormPath(Record[0], self._Macros)\r
-                    if File[0] == '.':\r
-                        File = os.path.join(self._ModuleDir, File)\r
-                    else:\r
-                        File = os.path.join(GlobalData.gWorkspace, File)\r
-                    File = RealPath(os.path.normpath(File))\r
-                    if File:\r
-                        self._Includes.append(File)\r
-\r
-                    #TRICK: let compiler to choose correct header file\r
-                    Macros['EDK_SOURCE'] = GlobalData.gEdkSource\r
-                    File = NormPath(Record[0], self._Macros)\r
-                    if File[0] == '.':\r
-                        File = os.path.join(self._ModuleDir, File)\r
-                    else:\r
-                        File = os.path.join(GlobalData.gWorkspace, File)\r
-                    File = RealPath(os.path.normpath(File))\r
-                    if File:\r
-                        self._Includes.append(File)\r
-                else:\r
-                    File = NormPath(Record[0], Macros)\r
-                    if File[0] == '.':\r
-                        File = os.path.join(self._ModuleDir, File)\r
-                    else:\r
-                        File = mws.join(GlobalData.gWorkspace, File)\r
-                    File = RealPath(os.path.normpath(File))\r
-                    if File:\r
-                        self._Includes.append(File)\r
-                    if not File and Record[0].find('EFI_SOURCE') > -1:\r
-                        # tricky to regard WorkSpace as EFI_SOURCE\r
-                        Macros['EFI_SOURCE'] = GlobalData.gWorkspace\r
-                        File = NormPath(Record[0], Macros)\r
-                        if File[0] == '.':\r
-                            File = os.path.join(self._ModuleDir, File)\r
-                        else:\r
-                            File = os.path.join(GlobalData.gWorkspace, File)\r
-                        File = RealPath(os.path.normpath(File))\r
-                        if File:\r
-                            self._Includes.append(File)\r
-        return self._Includes\r
-\r
-    ## Retrieve packages this module depends on\r
-    def _GetPackages(self):\r
-        if self._Packages == None:\r
-            self._Packages = []\r
-            RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform]\r
-            Macros = self._Macros\r
-            Macros['EDK_SOURCE'] = GlobalData.gEcpSource\r
-            for Record in RecordList:\r
-                File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
-                LineNo = Record[-1]\r
-                # check the file validation\r
-                ErrorCode, ErrorInfo = File.Validate('.dec')\r
-                if ErrorCode != 0:\r
-                    EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
-                # parse this package now. we need it to get protocol/ppi/guid value\r
-                Package = self._Bdb[File, self._Arch, self._Target, self._Toolchain]\r
-                self._Packages.append(Package)\r
-        return self._Packages\r
-\r
-    ## Retrieve PCD comments\r
-    def _GetPcdComments(self):\r
-        self._GetPcds()\r
-        return self._PcdComments\r
-    ## Retrieve PCDs used in this module\r
-    def _GetPcds(self):\r
-        if self._Pcds == None:\r
-            self._Pcds = sdict()\r
-            self._PcdComments = sdict()\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._GetPcd(MODEL_PCD_DYNAMIC))\r
-            self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))\r
-        return self._Pcds\r
-\r
-    ## Retrieve build options specific to this module\r
-    def _GetBuildOptions(self):\r
-        if self._BuildOptions == None:\r
-            self._BuildOptions = sdict()\r
-            RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, self._Platform]\r
-            for Record in RecordList:\r
-                ToolChainFamily = Record[0]\r
-                ToolChain = Record[1]\r
-                Option = Record[2]\r
-                if (ToolChainFamily, ToolChain) not in self._BuildOptions or Option.startswith('='):\r
-                    self._BuildOptions[ToolChainFamily, ToolChain] = Option\r
-                else:\r
-                    # concatenate the option string if they're for the same tool\r
-                    OptionString = self._BuildOptions[ToolChainFamily, ToolChain]\r
-                    self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r
-        return self._BuildOptions\r
-\r
-    ## Retrieve dependency expression\r
-    def _GetDepex(self):\r
-        if self._Depex == None:\r
-            self._Depex = tdict(False, 2)\r
-            RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\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
-                    self.ModuleType == 'DXE_SAL_DRIVER' or self.ModuleType == 'DXE_RUNTIME_DRIVER':\r
-                    EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \\r
-                                    % self.ModuleType, File=self.MetaFile)\r
-\r
-            if len(RecordList) != 0 and self.ModuleType == 'USER_DEFINED':\r
-                for Record in RecordList:\r
-                    if Record[4] not in ['PEIM', 'DXE_DRIVER', 'DXE_SMM_DRIVER']:\r
-                        EdkLogger.error('build', FORMAT_INVALID,\r
-                                        "'%s' module must specify the type of [Depex] section" % self.ModuleType,\r
-                                        File=self.MetaFile)\r
-\r
-            Depex = sdict()\r
-            for Record in RecordList:\r
-                DepexStr = ReplaceMacro(Record[0], self._Macros, False)\r
-                Arch = Record[3]\r
-                ModuleType = Record[4]\r
-                TokenList = DepexStr.split()\r
-                if (Arch, ModuleType) not in Depex:\r
-                    Depex[Arch, ModuleType] = []\r
-                DepexList = Depex[Arch, ModuleType]\r
-                for Token in TokenList:\r
-                    if Token in DEPEX_SUPPORTED_OPCODE:\r
-                        DepexList.append(Token)\r
-                    elif Token.endswith(".inf"):    # module file name\r
-                        ModuleFile = os.path.normpath(Token)\r
-                        Module = self.BuildDatabase[ModuleFile]\r
-                        if Module == None:\r
-                            EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "Module is not found in active platform",\r
-                                            ExtraData=Token, File=self.MetaFile, Line=Record[-1])\r
-                        DepexList.append(Module.Guid)\r
-                    else:\r
-                        # get the GUID value now\r
-                        Value = ProtocolValue(Token, self.Packages, self.MetaFile.Path)\r
-                        if Value == None:\r
-                            Value = PpiValue(Token, self.Packages, self.MetaFile.Path)\r
-                            if Value == None:\r
-                                Value = GuidValue(Token, self.Packages, self.MetaFile.Path)\r
-                        if Value == None:\r
-                            PackageList = "\n\t".join([str(P) for P in self.Packages])\r
-                            EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
-                                            "Value of [%s] is not found in" % Token,\r
-                                            ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
-                        DepexList.append(Value)\r
-            for Arch, ModuleType in Depex:\r
-                self._Depex[Arch, ModuleType] = Depex[Arch, ModuleType]\r
-        return self._Depex\r
-\r
-    ## Retrieve depedency expression\r
-    def _GetDepexExpression(self):\r
-        if self._DepexExpression == None:\r
-            self._DepexExpression = tdict(False, 2)\r
-            RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\r
-            DepexExpression = sdict()\r
-            for Record in RecordList:\r
-                DepexStr = ReplaceMacro(Record[0], self._Macros, False)\r
-                Arch = Record[3]\r
-                ModuleType = Record[4]\r
-                TokenList = DepexStr.split()\r
-                if (Arch, ModuleType) not in DepexExpression:\r
-                    DepexExpression[Arch, ModuleType] = ''\r
-                for Token in TokenList:\r
-                    DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType] + Token.strip() + ' '\r
-            for Arch, ModuleType in DepexExpression:\r
-                self._DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType]\r
-        return self._DepexExpression\r
-\r
-    def GetGuidsUsedByPcd(self):\r
-        return self._GuidsUsedByPcd\r
-    ## Retrieve PCD for given type\r
-    def _GetPcd(self, Type):\r
-        Pcds = sdict()\r
-        PcdDict = tdict(True, 4)\r
-        PcdList = []\r
-        RecordList = self._RawData[Type, self._Arch, self._Platform]\r
-        for TokenSpaceGuid, PcdCName, Setting, Arch, Platform, Id, LineNo in RecordList:\r
-            PcdDict[Arch, Platform, PcdCName, TokenSpaceGuid] = (Setting, LineNo)\r
-            PcdList.append((PcdCName, TokenSpaceGuid))\r
-            # get the guid value\r
-            if TokenSpaceGuid not in self.Guids:\r
-                Value = GuidValue(TokenSpaceGuid, self.Packages, self.MetaFile.Path)\r
-                if Value == None:\r
-                    PackageList = "\n\t".join([str(P) for P in self.Packages])\r
-                    EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
-                                    "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid,\r
-                                    ExtraData=PackageList, File=self.MetaFile, Line=LineNo)\r
-                self.Guids[TokenSpaceGuid] = Value\r
-                self._GuidsUsedByPcd[TokenSpaceGuid] = Value\r
-            CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Id]\r
-            Comments = []\r
-            for CmtRec in CommentRecords:\r
-                Comments.append(CmtRec[0])\r
-            self._PcdComments[TokenSpaceGuid, PcdCName] = Comments\r
-\r
-        # resolve PCD type, value, datum info, etc. by getting its definition from package\r
-        for PcdCName, TokenSpaceGuid in PcdList:\r
-            PcdRealName = PcdCName\r
-            Setting, LineNo = PcdDict[self._Arch, self.Platform, PcdCName, TokenSpaceGuid]\r
-            if Setting == None:\r
-                continue\r
-            ValueList = AnalyzePcdData(Setting)\r
-            DefaultValue = ValueList[0]\r
-            Pcd = PcdClassObject(\r
-                    PcdCName,\r
-                    TokenSpaceGuid,\r
-                    '',\r
-                    '',\r
-                    DefaultValue,\r
-                    '',\r
-                    '',\r
-                    {},\r
-                    False,\r
-                    self.Guids[TokenSpaceGuid]\r
-                    )\r
-            if Type == MODEL_PCD_PATCHABLE_IN_MODULE and ValueList[1]:\r
-                # Patch PCD: TokenSpace.PcdCName|Value|Offset\r
-                Pcd.Offset = ValueList[1]\r
-\r
-            if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:\r
-                for Package in self.Packages:\r
-                    for key in Package.Pcds:\r
-                        if (Package.Pcds[key].TokenCName, Package.Pcds[key].TokenSpaceGuidCName) == (PcdRealName, TokenSpaceGuid):\r
-                            for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:\r
-                                Pcd_Type = item[0].split('_')[-1]\r
-                                if Pcd_Type == Package.Pcds[key].Type:\r
-                                    Value = Package.Pcds[key]\r
-                                    Value.TokenCName = Package.Pcds[key].TokenCName + '_' + Pcd_Type\r
-                                    if len(key) == 2:\r
-                                        newkey = (Value.TokenCName, key[1])\r
-                                    elif len(key) == 3:\r
-                                        newkey = (Value.TokenCName, key[1], key[2])\r
-                                    del Package.Pcds[key]\r
-                                    Package.Pcds[newkey] = Value\r
-                                    break\r
-                                else:\r
-                                    pass\r
-                        else:\r
-                            pass\r
-\r
-            # get necessary info from package declaring this PCD\r
-            for Package in self.Packages:\r
-                #\r
-                # 'dynamic' in INF means its type is determined by platform;\r
-                # if platform doesn't give its type, use 'lowest' one in the\r
-                # following order, if any\r
-                #\r
-                #   "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"\r
-                #\r
-                PcdType = self._PCD_TYPE_STRING_[Type]\r
-                if Type == MODEL_PCD_DYNAMIC:\r
-                    Pcd.Pending = True\r
-                    for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:\r
-                        if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:\r
-                            for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:\r
-                                if str(item[0]).endswith(T) and (item[0], item[1], T) in Package.Pcds:\r
-                                    PcdType = T\r
-                                    PcdCName = item[0]\r
-                                    break\r
-                                else:\r
-                                    pass\r
-                            break\r
-                        else:\r
-                            if (PcdRealName, TokenSpaceGuid, T) in Package.Pcds:\r
-                                PcdType = T\r
-                                break\r
-\r
-                else:\r
-                    Pcd.Pending = False\r
-                    if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:\r
-                        for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:\r
-                            Pcd_Type = item[0].split('_')[-1]\r
-                            if Pcd_Type == PcdType:\r
-                                PcdCName = item[0]\r
-                                break\r
-                            else:\r
-                                pass\r
-                    else:\r
-                        pass\r
-\r
-                if (PcdCName, TokenSpaceGuid, PcdType) in Package.Pcds:\r
-                    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, PcdRealName, str(Package)),\r
-                                File=self.MetaFile, Line=LineNo,\r
-                                ExtraData=None\r
-                                )                        \r
-                    #\r
-                    # Check hexadecimal token value length and format.\r
-                    #\r
-                    ReIsValidPcdTokenValue = re.compile(r"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re.DOTALL)\r
-                    if Pcd.TokenValue.startswith("0x") or Pcd.TokenValue.startswith("0X"):\r
-                        if ReIsValidPcdTokenValue.match(Pcd.TokenValue) == None:\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, PcdRealName, 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, PcdRealName, 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, PcdRealName, 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
-                    if Pcd.DefaultValue in [None, '']:\r
-                        Pcd.DefaultValue = PcdInPackage.DefaultValue\r
-                    break\r
-            else:\r
-                EdkLogger.error(\r
-                            'build',\r
-                            FORMAT_INVALID,\r
-                            "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdRealName, 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
-    ## check whether current module is binary module\r
-    def _IsBinaryModule(self):\r
-        if self.Binaries and not self.Sources:\r
-            return True\r
-        elif GlobalData.gIgnoreSource:\r
-            return True\r
-        else:\r
-            return False\r
-\r
-    _Macros = property(_GetMacros)\r
-    Arch = property(_GetArch, _SetArch)\r
-    Platform = property(_GetPlatform, _SetPlatform)\r
-\r
-    HeaderComments = property(_GetHeaderComments)\r
-    TailComments = property(_GetTailComments)\r
-    AutoGenVersion          = property(_GetInfVersion)\r
-    BaseName                = property(_GetBaseName)\r
-    ModuleType              = property(_GetModuleType)\r
-    ComponentType           = property(_GetComponentType)\r
-    BuildType               = property(_GetBuildType)\r
-    Guid                    = property(_GetFileGuid)\r
-    Version                 = property(_GetVersion)\r
-    PcdIsDriver             = property(_GetPcdIsDriver)\r
-    Shadow                  = property(_GetShadow)\r
-    CustomMakefile          = property(_GetMakefile)\r
-    Specification           = property(_GetSpec)\r
-    LibraryClass            = property(_GetLibraryClass)\r
-    ModuleEntryPointList    = property(_GetEntryPoint)\r
-    ModuleUnloadImageList   = property(_GetUnloadImage)\r
-    ConstructorList         = property(_GetConstructor)\r
-    DestructorList          = property(_GetDestructor)\r
-    Defines                 = property(_GetDefines)\r
-    DxsFile                 = property(_GetDxsFile)\r
-    \r
-    Binaries                = property(_GetBinaryFiles)\r
-    Sources                 = property(_GetSourceFiles)\r
-    LibraryClasses          = property(_GetLibraryClassUses)\r
-    Libraries               = property(_GetLibraryNames)\r
-    Protocols               = property(_GetProtocols)\r
-    ProtocolComments = property(_GetProtocolComments)\r
-    Ppis                    = property(_GetPpis)\r
-    PpiComments = property(_GetPpiComments)\r
-    Guids                   = property(_GetGuids)\r
-    GuidComments = property(_GetGuidComments)\r
-    Includes                = property(_GetIncludes)\r
-    Packages                = property(_GetPackages)\r
-    Pcds                    = property(_GetPcds)\r
-    PcdComments = property(_GetPcdComments)\r
-    BuildOptions            = property(_GetBuildOptions)\r
-    Depex                   = property(_GetDepex)\r
-    DepexExpression         = property(_GetDepexExpression)\r
-    IsBinaryModule = property(_IsBinaryModule)\r
-    IsSupportedArch = property(_IsSupportedArch)\r
+from Workspace.DecBuildData import DecBuildData\r
+from Workspace.DscBuildData import DscBuildData\r
+from Workspace.InfBuildData import InfBuildData\r
 \r
 ## Database\r
 #\r
 \r
 ## Database\r
 #\r
@@ -2868,7 +41,6 @@ class InfBuildData(ModuleBuildClassObject):
 #\r
 class WorkspaceDatabase(object):\r
 \r
 #\r
 class WorkspaceDatabase(object):\r
 \r
-\r
     #\r
     # internal class used for call corresponding file parser and caching the result\r
     # to avoid unnecessary re-parsing\r
     #\r
     # internal class used for call corresponding file parser and caching the result\r
     # to avoid unnecessary re-parsing\r