]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/UPT/Parser/DecParser.py
BaseTools: Clean up source files
[mirror_edk2.git] / BaseTools / Source / Python / UPT / Parser / DecParser.py
index 060b9274f3c3e638b2bbfce453f8e06e80c2fcc8..a88b51d05529253f15c5254504afd3d484850596 100644 (file)
@@ -1,11 +1,11 @@
 ## @file\r
 # This file is used to parse DEC file. It will consumed by DecParser\r
 #\r
-# Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
 #\r
-# This program and the accompanying materials are licensed and made available \r
-# under the terms and conditions of the BSD License which accompanies this \r
-# distribution. The full text of the license may be found at \r
+# This program and the accompanying materials are licensed and made available\r
+# under the terms and conditions of the BSD License which accompanies this\r
+# 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
@@ -29,6 +29,7 @@ from Library.ParserValidate import IsValidIdString
 from Library.ParserValidate import IsValidUserId\r
 from Library.ParserValidate import IsValidArch\r
 from Library.ParserValidate import IsValidWord\r
+from Library.ParserValidate import IsValidDecVersionVal\r
 from Parser.DecParserMisc import TOOL_NAME\r
 from Parser.DecParserMisc import CleanString\r
 from Parser.DecParserMisc import IsValidPcdDatum\r
@@ -56,10 +57,11 @@ from Object.Parser.DecObject import DecPcdObject
 from Object.Parser.DecObject import DecPcdItemObject\r
 from Library.Misc import GuidStructureStringToGuidString\r
 from Library.Misc import CheckGuidRegFormat\r
-from Library.String import ReplaceMacro\r
-from Library.String import GetSplitValueList\r
-from Library.String import gMACRO_PATTERN\r
-from Library.String import ConvertSpecialChar\r
+from Library.StringUtils import ReplaceMacro\r
+from Library.StringUtils import GetSplitValueList\r
+from Library.StringUtils import gMACRO_PATTERN\r
+from Library.StringUtils import ConvertSpecialChar\r
+from Library.CommentParsing import ParsePcdErrorCode\r
 \r
 ##\r
 # _DecBase class for parsing\r
@@ -73,28 +75,31 @@ class _DecBase:
         # Data parsed by 'self' are saved to this object\r
         #\r
         self.ItemObject = None\r
-    \r
+\r
     def GetDataObject(self):\r
         return self.ItemObject\r
-    \r
+\r
+    def GetLocalMacro(self):\r
+        return self._LocalMacro\r
+\r
     ## BlockStart\r
     #\r
     # Called if a new section starts\r
     #\r
     def BlockStart(self):\r
         self._LocalMacro = {}\r
-    \r
+\r
     ## _CheckReDefine\r
     #\r
     # @param Key: to be checked if multi-defined\r
-    # @param Scope: Format: [[SectionName, Arch], ...]. \r
+    # @param Scope: Format: [[SectionName, Arch], ...].\r
     #               If scope is none, use global scope\r
     #\r
     def _CheckReDefine(self, Key, Scope = None):\r
         if not Scope:\r
             Scope = self._RawData.CurrentScope\r
             return\r
-        \r
+\r
         SecArch = []\r
         #\r
         # Copy scope to SecArch, avoid Scope be changed outside\r
@@ -103,7 +108,7 @@ class _DecBase:
         if Key not in self._ItemDict:\r
             self._ItemDict[Key] = [[SecArch, self._RawData.LineIndex]]\r
             return\r
-        \r
+\r
         for Value in self._ItemDict[Key]:\r
             for SubValue in Scope:\r
                 #\r
@@ -127,18 +132,18 @@ class _DecBase:
                     self._LoggerError(ST.ERR_DECPARSE_REDEFINE % (Key, Value[1]))\r
                     return\r
         self._ItemDict[Key].append([SecArch, self._RawData.LineIndex])\r
-    \r
+\r
     ## CheckRequiredFields\r
     # Some sections need to check if some fields exist, define section for example\r
     # Derived class can re-implement, top parser will call this function after all parsing done\r
-    #  \r
+    #\r
     def CheckRequiredFields(self):\r
         if self._RawData:\r
             pass\r
         return True\r
-    \r
+\r
     ## IsItemRequired\r
-    # In DEC spec, sections must have at least one statement except user \r
+    # In DEC spec, sections must have at least one statement except user\r
     # extension.\r
     # For example: "[guids" [<attribs>] "]" <EOL> <statements>+\r
     # sub class can override this method to indicate if statement is a must.\r
@@ -147,12 +152,12 @@ class _DecBase:
         if self._RawData:\r
             pass\r
         return False\r
-    \r
+\r
     def _LoggerError(self, ErrorString):\r
-        Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename, \r
+        Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,\r
                      Line = self._RawData.LineIndex,\r
                      ExtraData=ErrorString + ST.ERR_DECPARSE_LINE % self._RawData.CurrentLine)\r
-    \r
+\r
     def _ReplaceMacro(self, String):\r
         if gMACRO_PATTERN.findall(String):\r
             String = ReplaceMacro(String, self._LocalMacro, False,\r
@@ -164,11 +169,11 @@ class _DecBase:
             MacroUsed = gMACRO_PATTERN.findall(String)\r
             if MacroUsed:\r
                 Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE,\r
-                             File=self._RawData.Filename, \r
+                             File=self._RawData.Filename,\r
                              Line = self._RawData.LineIndex,\r
                              ExtraData = ST.ERR_DECPARSE_MACRO_RESOLVE % (str(MacroUsed), String))\r
         return String\r
-    \r
+\r
     def _MacroParser(self, String):\r
         TokenList = GetSplitValueList(String, ' ', 1)\r
         if len(TokenList) < 2 or TokenList[1] == '':\r
@@ -179,12 +184,12 @@ class _DecBase:
             self._LoggerError(ST.ERR_DECPARSE_MACRO_NAME)\r
         elif not IsValidToken(MACRO_PATTERN, TokenList[0]):\r
             self._LoggerError(ST.ERR_DECPARSE_MACRO_NAME_UPPER % TokenList[0])\r
-        \r
+\r
         if len(TokenList) == 1:\r
             self._LocalMacro[TokenList[0]] = ''\r
         else:\r
             self._LocalMacro[TokenList[0]] = self._ReplaceMacro(TokenList[1])\r
-    \r
+\r
     ## _ParseItem\r
     #\r
     # Parse specified item, this function must be derived by subclass\r
@@ -197,7 +202,7 @@ class _DecBase:
         #\r
         return None\r
 \r
-    \r
+\r
     ## _TailCommentStrategy\r
     #\r
     # This function can be derived to parse tail comment\r
@@ -211,7 +216,7 @@ class _DecBase:
         if self._RawData:\r
             pass\r
         return False\r
-    \r
+\r
     ## _StopCurrentParsing\r
     #\r
     # Called in Parse if current parsing should be stopped when encounter some\r
@@ -224,7 +229,7 @@ class _DecBase:
         if self._RawData:\r
             pass\r
         return Line[0] == DT.TAB_SECTION_START and Line[-1] == DT.TAB_SECTION_END\r
-    \r
+\r
     ## _TryBackSlash\r
     #\r
     # Split comment and DEC content, concatenate lines if end of char is '\'\r
@@ -241,7 +246,7 @@ class _DecBase:
             if Line == '':\r
                 self._LoggerError(ST.ERR_DECPARSE_BACKSLASH_EMPTY)\r
                 break\r
-            \r
+\r
             if Comment:\r
                 CommentList.append((Comment, self._RawData.LineIndex))\r
             if Line[-1] != DT.TAB_SLASH:\r
@@ -264,20 +269,34 @@ class _DecBase:
                 if not Line or Line[-1] == DT.TAB_SLASH:\r
                     self._LoggerError(ST.ERR_DECPARSE_BACKSLASH_EMPTY)\r
                 CatLine += Line\r
-         \r
-        self._RawData.CurrentLine = self._ReplaceMacro(CatLine)\r
+\r
+        #\r
+        # All MACRO values defined by the DEFINE statements in any section\r
+        # (except [Userextensions] sections for Intel) of the INF or DEC file\r
+        # must be expanded before processing of the file.\r
+        #\r
+        __IsReplaceMacro = True\r
+        Header = self._RawData.CurrentScope[0] if self._RawData.CurrentScope else None\r
+        if Header and len(Header) > 2:\r
+            if Header[0].upper() == 'USEREXTENSIONS' and not (Header[1] == 'TianoCore' and Header[2] == '"ExtraFiles"'):\r
+                __IsReplaceMacro = False\r
+        if __IsReplaceMacro:\r
+            self._RawData.CurrentLine = self._ReplaceMacro(CatLine)\r
+        else:\r
+            self._RawData.CurrentLine = CatLine\r
+\r
         return CatLine, CommentList\r
-    \r
+\r
     ## Parse\r
-    # This is a template method in which other member functions which might \r
-    # override by sub class are called. It is responsible for reading file \r
+    # This is a template method in which other member functions which might\r
+    # override by sub class are called. It is responsible for reading file\r
     # line by line, and call other member functions to parse. This function\r
     # should not be re-implement by sub class.\r
     #\r
     def Parse(self):\r
         HeadComments = []\r
         TailComments = []\r
-        \r
+\r
         #======================================================================\r
         # CurComments may pointer to HeadComments or TailComments\r
         #======================================================================\r
@@ -285,7 +304,7 @@ class _DecBase:
         CurObj = None\r
         ItemNum = 0\r
         FromBuf = False\r
-        \r
+\r
         #======================================================================\r
         # Used to report error information if empty section found\r
         #======================================================================\r
@@ -314,20 +333,20 @@ class _DecBase:
                     # Set tail comments to previous statement if not empty.\r
                     #==========================================================\r
                     CurObj.SetTailComment(CurObj.GetTailComment()+TailComments)\r
-                \r
+\r
                 if not FromBuf:\r
                     del TailComments[:]\r
                 CurComments = TailComments\r
                 Comments = []\r
                 if Comment:\r
                     Comments = [(Comment, self._RawData.LineIndex)]\r
-                \r
+\r
                 #==============================================================\r
                 # Try if last char of line has backslash\r
                 #==============================================================\r
                 Line, Comments = self._TryBackSlash(Line, Comments)\r
                 CurComments.extend(Comments)\r
-                \r
+\r
                 #==============================================================\r
                 # Macro found\r
                 #==============================================================\r
@@ -337,7 +356,7 @@ class _DecBase:
                     del TailComments[:]\r
                     CurComments = HeadComments\r
                     continue\r
-                \r
+\r
                 if self._StopCurrentParsing(Line):\r
                     #==========================================================\r
                     # This line does not belong to this parse,\r
@@ -345,7 +364,7 @@ class _DecBase:
                     #==========================================================\r
                     self._RawData.SetNext(Line, HeadComments, TailComments)\r
                     break\r
-                \r
+\r
                 Obj = self._ParseItem()\r
                 ItemNum += 1\r
                 if Obj:\r
@@ -368,7 +387,7 @@ class _DecBase:
                     CurComments.append(((Comment, self._RawData.LineIndex)))\r
                 else:\r
                     del CurComments[:]\r
-        \r
+\r
         if self._IsStatementRequired() and ItemNum == 0:\r
             Logger.Error(\r
                     TOOL_NAME, FILE_PARSE_FAILURE,\r
@@ -386,7 +405,7 @@ class _DecDefine(_DecBase):
         self.ItemObject = DecDefineObject(RawData.Filename)\r
         self._LocalMacro = self._RawData.Macros\r
         self._DefSecNum = 0\r
-        \r
+\r
         #\r
         # Each field has a function to validate\r
         #\r
@@ -395,13 +414,14 @@ class _DecDefine(_DecBase):
             DT.TAB_DEC_DEFINES_PACKAGE_NAME        :   self._SetPackageName,\r
             DT.TAB_DEC_DEFINES_PACKAGE_GUID        :   self._SetPackageGuid,\r
             DT.TAB_DEC_DEFINES_PACKAGE_VERSION     :   self._SetPackageVersion,\r
+            DT.TAB_DEC_DEFINES_PKG_UNI_FILE        :   self._SetPackageUni,\r
         }\r
-    \r
+\r
     def BlockStart(self):\r
         self._DefSecNum += 1\r
         if self._DefSecNum > 1:\r
             self._LoggerError(ST.ERR_DECPARSE_DEFINE_MULTISEC)\r
-    \r
+\r
     ## CheckRequiredFields\r
     #\r
     # Check required fields: DEC_SPECIFICATION, PACKAGE_NAME\r
@@ -410,61 +430,61 @@ class _DecDefine(_DecBase):
     def CheckRequiredFields(self):\r
         Ret = False\r
         if self.ItemObject.GetPackageSpecification() == '':\r
-            Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename, \r
+            Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,\r
                          ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_DEC_SPECIFICATION)\r
         elif self.ItemObject.GetPackageName() == '':\r
-            Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename, \r
+            Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,\r
                          ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_NAME)\r
         elif self.ItemObject.GetPackageGuid() == '':\r
-            Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename, \r
+            Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,\r
                          ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_GUID)\r
         elif self.ItemObject.GetPackageVersion() == '':\r
-            Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename, \r
+            Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,\r
                          ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_VERSION)\r
         else:\r
             Ret = True\r
         return Ret\r
-    \r
+\r
     def _ParseItem(self):\r
         Line = self._RawData.CurrentLine\r
         TokenList = GetSplitValueList(Line, DT.TAB_EQUAL_SPLIT, 1)\r
         if TokenList[0] == DT.TAB_DEC_DEFINES_PKG_UNI_FILE:\r
-            pass\r
+            self.DefineValidation[TokenList[0]](TokenList[1])\r
         elif len(TokenList) < 2:\r
             self._LoggerError(ST.ERR_DECPARSE_DEFINE_FORMAT)\r
         elif TokenList[0] not in self.DefineValidation:\r
             self._LoggerError(ST.ERR_DECPARSE_DEFINE_UNKNOWKEY % TokenList[0])\r
         else:\r
             self.DefineValidation[TokenList[0]](TokenList[1])\r
-        \r
+\r
         DefineItem = DecDefineItemObject()\r
-        if TokenList[0] != DT.TAB_DEC_DEFINES_PKG_UNI_FILE:\r
-            DefineItem.Key   = TokenList[0]\r
-            DefineItem.Value = TokenList[1]\r
-            self.ItemObject.AddItem(DefineItem, self._RawData.CurrentScope)\r
+        DefineItem.Key   = TokenList[0]\r
+        DefineItem.Value = TokenList[1]\r
+        self.ItemObject.AddItem(DefineItem, self._RawData.CurrentScope)\r
         return DefineItem\r
-    \r
+\r
     def _SetDecSpecification(self, Token):\r
         if self.ItemObject.GetPackageSpecification():\r
             self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_DEC_SPECIFICATION)\r
         if not IsValidToken('0[xX][0-9a-fA-F]{8}', Token):\r
-            self._LoggerError(ST.ERR_DECPARSE_DEFINE_SPEC)\r
+            if not IsValidDecVersionVal(Token):\r
+                self._LoggerError(ST.ERR_DECPARSE_DEFINE_SPEC)\r
         self.ItemObject.SetPackageSpecification(Token)\r
-    \r
+\r
     def _SetPackageName(self, Token):\r
         if self.ItemObject.GetPackageName():\r
             self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_NAME)\r
         if not IsValidWord(Token):\r
             self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGNAME)\r
         self.ItemObject.SetPackageName(Token)\r
-    \r
+\r
     def _SetPackageGuid(self, Token):\r
         if self.ItemObject.GetPackageGuid():\r
             self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_GUID)\r
         if not CheckGuidRegFormat(Token):\r
             self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGGUID)\r
         self.ItemObject.SetPackageGuid(Token)\r
-    \r
+\r
     def _SetPackageVersion(self, Token):\r
         if self.ItemObject.GetPackageVersion():\r
             self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_VERSION)\r
@@ -473,7 +493,12 @@ class _DecDefine(_DecBase):
         else:\r
             if not DT.TAB_SPLIT in Token:\r
                 Token = Token + '.0'\r
-            self.ItemObject._PkgVersion = Token\r
+            self.ItemObject.SetPackageVersion(Token)\r
+\r
+    def _SetPackageUni(self, Token):\r
+        if self.ItemObject.GetPackageUniFile():\r
+            self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PKG_UNI_FILE)\r
+        self.ItemObject.SetPackageUniFile(Token)\r
 \r
 ## _DecInclude\r
 #\r
@@ -483,13 +508,13 @@ class _DecInclude(_DecBase):
     def __init__(self, RawData):\r
         _DecBase.__init__(self, RawData)\r
         self.ItemObject = DecIncludeObject(RawData.Filename)\r
-    \r
+\r
     def _ParseItem(self):\r
         Line = self._RawData.CurrentLine\r
-        \r
+\r
         if not IsValidPath(Line, self._RawData.PackagePath):\r
-            self._LoggerError(ST.ERR_DECPARSE_INCLUDE % Line) \r
-        \r
+            self._LoggerError(ST.ERR_DECPARSE_INCLUDE % Line)\r
+\r
         Item = DecIncludeItemObject(StripRoot(self._RawData.PackagePath, Line), self._RawData.PackagePath)\r
         self.ItemObject.AddItem(Item, self._RawData.CurrentScope)\r
         return Item\r
@@ -502,32 +527,32 @@ class _DecLibraryclass(_DecBase):
     def __init__(self, RawData):\r
         _DecBase.__init__(self, RawData)\r
         self.ItemObject = DecLibraryclassObject(RawData.Filename)\r
-    \r
+\r
     def _ParseItem(self):\r
         Line = self._RawData.CurrentLine\r
         TokenList = GetSplitValueList(Line, DT.TAB_VALUE_SPLIT)\r
         if len(TokenList) != 2:\r
-            self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_SPLIT) \r
+            self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_SPLIT)\r
         if TokenList[0] == '' or TokenList[1] == '':\r
             self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_EMPTY)\r
         if not IsValidToken('[A-Z][0-9A-Za-z]*', TokenList[0]):\r
             self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_LIB)\r
-        \r
+\r
         self._CheckReDefine(TokenList[0])\r
-        \r
+\r
         Value = TokenList[1]\r
         #\r
         # Must end with .h\r
         #\r
         if not Value.endswith('.h'):\r
             self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_PATH_EXT)\r
-        \r
+\r
         #\r
         # Path must be existed\r
         #\r
         if not IsValidPath(Value, self._RawData.PackagePath):\r
             self._LoggerError(ST.ERR_DECPARSE_INCLUDE % Value)\r
-        \r
+\r
         Item = DecLibraryclassItemObject(TokenList[0], StripRoot(self._RawData.PackagePath, Value),\r
                                          self._RawData.PackagePath)\r
         self.ItemObject.AddItem(Item, self._RawData.CurrentScope)\r
@@ -546,38 +571,38 @@ class _DecPcd(_DecBase):
         # Key is token space and token number (integer), value is C name\r
         #\r
         self.TokenMap = {}\r
-    \r
+\r
     def _ParseItem(self):\r
         Line = self._RawData.CurrentLine\r
         TokenList = Line.split(DT.TAB_VALUE_SPLIT)\r
         if len(TokenList) < 4:\r
             self._LoggerError(ST.ERR_DECPARSE_PCD_SPLIT)\r
-        \r
+\r
         #\r
         # Token space guid C name\r
         #\r
         PcdName = GetSplitValueList(TokenList[0], DT.TAB_SPLIT)\r
         if len(PcdName) != 2 or PcdName[0] == '' or PcdName[1] == '':\r
             self._LoggerError(ST.ERR_DECPARSE_PCD_NAME)\r
-        \r
+\r
         Guid = PcdName[0]\r
         if not IsValidToken(CVAR_PATTERN, Guid):\r
             self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_GUID)\r
-        \r
+\r
         #\r
         # PCD C name\r
         #\r
         CName = PcdName[1]\r
         if not IsValidToken(CVAR_PATTERN, CName):\r
             self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_PCDCNAME)\r
-        \r
+\r
         self._CheckReDefine(Guid + DT.TAB_SPLIT + CName)\r
-        \r
+\r
         #\r
         # Default value, may be C array, string or number\r
         #\r
         Data = DT.TAB_VALUE_SPLIT.join(TokenList[1:-2]).strip()\r
-        \r
+\r
         #\r
         # PCD data type\r
         #\r
@@ -598,18 +623,18 @@ class _DecPcd(_DecBase):
             if long(Token) > 4294967295:\r
                 self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN_INT % Token)\r
             Token = hex(long(Token))[:-1]\r
-        \r
+\r
         IntToken = long(Token, 0)\r
         if (Guid, IntToken) in self.TokenMap:\r
             if self.TokenMap[Guid, IntToken] != CName:\r
                 self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN_UNIQUE%(Token))\r
         else:\r
             self.TokenMap[Guid, IntToken] = CName\r
-        \r
+\r
         Item = DecPcdItemObject(Guid, CName, Data, DataType, Token)\r
         self.ItemObject.AddItem(Item, self._RawData.CurrentScope)\r
         return Item\r
-        \r
+\r
 ## _DecGuid\r
 #\r
 # Parse GUID, PPI, Protocol section\r
@@ -626,21 +651,21 @@ class _DecGuid(_DecBase):
             DT.TAB_PPIS.upper()      :   self.PpiObj,\r
             DT.TAB_PROTOCOLS.upper() :   self.ProtocolObj\r
         }\r
-    \r
+\r
     def GetDataObject(self):\r
         if self._RawData.CurrentScope:\r
             return self.ObjectDict[self._RawData.CurrentScope[0][0]]\r
         return None\r
-    \r
+\r
     def GetGuidObject(self):\r
         return self.GuidObj\r
-    \r
+\r
     def GetPpiObject(self):\r
         return self.PpiObj\r
-    \r
+\r
     def GetProtocolObject(self):\r
         return self.ProtocolObj\r
-    \r
+\r
     def _ParseItem(self):\r
         Line = self._RawData.CurrentLine\r
         TokenList = GetSplitValueList(Line, DT.TAB_EQUAL_SPLIT, 1)\r
@@ -652,9 +677,9 @@ class _DecGuid(_DecBase):
             self._LoggerError(ST.ERR_DECPARSE_CGUID_GUID)\r
         if not IsValidToken(CVAR_PATTERN, TokenList[0]):\r
             self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_GUID)\r
-        \r
+\r
         self._CheckReDefine(TokenList[0])\r
-        \r
+\r
         if TokenList[1][0] != '{':\r
             if not CheckGuidRegFormat(TokenList[1]):\r
                 self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGGUID)\r
@@ -666,7 +691,7 @@ class _DecGuid(_DecBase):
             GuidString = GuidStructureStringToGuidString(TokenList[1])\r
             if TokenList[1][0] != '{' or TokenList[1][-1] != '}' or GuidString == '':\r
                 self._LoggerError(ST.ERR_DECPARSE_CGUID_GUIDFORMAT)\r
-    \r
+\r
             #\r
             # Check C format GUID\r
             #\r
@@ -688,7 +713,7 @@ class _DecUserExtension(_DecBase):
         self.ItemObject = DecUserExtensionObject(RawData.Filename)\r
         self._Headers = []\r
         self._CurItems = []\r
-    \r
+\r
     def BlockStart(self):\r
         self._CurItems = []\r
         for Header in self._RawData.CurrentScope:\r
@@ -696,7 +721,7 @@ class _DecUserExtension(_DecBase):
                 self._LoggerError(ST.ERR_DECPARSE_UE_DUPLICATE)\r
             else:\r
                 self._Headers.append(Header)\r
-            \r
+\r
             for Item in self._CurItems:\r
                 if Item.UserId == Header[1] and Item.IdString == Header[2]:\r
                     Item.ArchAndModuleType.append(Header[3])\r
@@ -709,7 +734,7 @@ class _DecUserExtension(_DecBase):
                 self._CurItems.append(Item)\r
                 self.ItemObject.AddItem(Item, None)\r
         self._LocalMacro = {}\r
-    \r
+\r
     def _ParseItem(self):\r
         Line = self._RawData.CurrentLine\r
         Item = None\r
@@ -724,26 +749,47 @@ class _DecUserExtension(_DecBase):
 #\r
 # Top dec parser\r
 #\r
-class Dec(_DecBase, _DecComments):    \r
-    def __init__(self, DecFile, Parse = True):        \r
+class Dec(_DecBase, _DecComments):\r
+    def __init__(self, DecFile, Parse = True):\r
         try:\r
-            Content   = ConvertSpecialChar(open(DecFile, 'rb').readlines())\r
+            Content = ConvertSpecialChar(open(DecFile, 'rb').readlines())\r
         except BaseException:\r
             Logger.Error(TOOL_NAME, FILE_OPEN_FAILURE, File=DecFile,\r
                          ExtraData=ST.ERR_DECPARSE_FILEOPEN % DecFile)\r
-        RawData = FileContent(DecFile, Content)\r
-        \r
+\r
+        #\r
+        # Pre-parser for Private section\r
+        #\r
+        self._Private = ''\r
+        __IsFoundPrivate = False\r
+        NewContent = []\r
+        for Line in Content:\r
+            Line = Line.strip()\r
+            if Line.startswith(DT.TAB_SECTION_START) and Line.endswith(DT.TAB_PRIVATE + DT.TAB_SECTION_END):\r
+                __IsFoundPrivate = True\r
+            if Line.startswith(DT.TAB_SECTION_START) and Line.endswith(DT.TAB_SECTION_END)\\r
+               and not Line.endswith(DT.TAB_PRIVATE + DT.TAB_SECTION_END):\r
+                __IsFoundPrivate = False\r
+            if __IsFoundPrivate:\r
+                self._Private += Line + '\r'\r
+            if not __IsFoundPrivate:\r
+                NewContent.append(Line + '\r')\r
+\r
+        RawData = FileContent(DecFile, NewContent)\r
+\r
         _DecComments.__init__(self)\r
         _DecBase.__init__(self, RawData)\r
-        \r
-        self.BinaryHeadComment = []        \r
+\r
+        self.BinaryHeadComment = []\r
+        self.PcdErrorCommentDict = {}\r
+\r
         self._Define    = _DecDefine(RawData)\r
         self._Include   = _DecInclude(RawData)\r
         self._Guid      = _DecGuid(RawData)\r
         self._LibClass  = _DecLibraryclass(RawData)\r
         self._Pcd       = _DecPcd(RawData)\r
         self._UserEx    = _DecUserExtension(RawData)\r
-        \r
+\r
         #\r
         # DEC file supported data types (one type per section)\r
         #\r
@@ -769,13 +815,13 @@ class Dec(_DecBase, _DecComments):
             # Parsing done, check required fields\r
             #\r
             self.CheckRequiredFields()\r
-    \r
+\r
     def CheckRequiredFields(self):\r
         for SectionParser in self._SectionParser.values():\r
             if not SectionParser.CheckRequiredFields():\r
                 return False\r
         return True\r
-    \r
+\r
     ##\r
     # Parse DEC file\r
     #\r
@@ -784,6 +830,44 @@ class Dec(_DecBase, _DecComments):
         IsBinaryHeader = False\r
         FileHeaderLineIndex = -1\r
         BinaryHeaderLineIndex = -1\r
+        TokenSpaceGuidCName = ''\r
+\r
+        #\r
+        # Parse PCD error comment section\r
+        #\r
+        while not self._RawData.IsEndOfFile():\r
+            self._RawData.CurrentLine = self._RawData.GetNextLine()\r
+            if self._RawData.CurrentLine.startswith(DT.TAB_COMMENT_SPLIT) and \\r
+                DT.TAB_SECTION_START in self._RawData.CurrentLine and \\r
+                DT.TAB_SECTION_END in self._RawData.CurrentLine:\r
+                self._RawData.CurrentLine = self._RawData.CurrentLine.replace(DT.TAB_COMMENT_SPLIT, '').strip()\r
+\r
+                if self._RawData.CurrentLine[0] == DT.TAB_SECTION_START and \\r
+                    self._RawData.CurrentLine[-1] == DT.TAB_SECTION_END:\r
+                    RawSection = self._RawData.CurrentLine[1:-1].strip()\r
+                    if RawSection.upper().startswith(DT.TAB_PCD_ERROR.upper()+'.'):\r
+                        TokenSpaceGuidCName = RawSection.split(DT.TAB_PCD_ERROR+'.')[1].strip()\r
+                        continue\r
+\r
+            if TokenSpaceGuidCName and self._RawData.CurrentLine.startswith(DT.TAB_COMMENT_SPLIT):\r
+                self._RawData.CurrentLine = self._RawData.CurrentLine.replace(DT.TAB_COMMENT_SPLIT, '').strip()\r
+                if self._RawData.CurrentLine != '':\r
+                    if DT.TAB_VALUE_SPLIT not in self._RawData.CurrentLine:\r
+                        self._LoggerError(ST.ERR_DECPARSE_PCDERRORMSG_MISS_VALUE_SPLIT)\r
+\r
+                    PcdErrorNumber, PcdErrorMsg = GetSplitValueList(self._RawData.CurrentLine, DT.TAB_VALUE_SPLIT, 1)\r
+                    PcdErrorNumber = ParsePcdErrorCode(PcdErrorNumber, self._RawData.Filename, self._RawData.LineIndex)\r
+                    if not PcdErrorMsg.strip():\r
+                        self._LoggerError(ST.ERR_DECPARSE_PCD_MISS_ERRORMSG)\r
+\r
+                    self.PcdErrorCommentDict[(TokenSpaceGuidCName, PcdErrorNumber)] = PcdErrorMsg.strip()\r
+            else:\r
+                TokenSpaceGuidCName = ''\r
+\r
+        self._RawData.LineIndex = 0\r
+        self._RawData.CurrentLine = ''\r
+        self._RawData.NextLine = ''\r
+\r
         while not self._RawData.IsEndOfFile():\r
             Line, Comment = CleanString(self._RawData.GetNextLine())\r
 \r
@@ -793,20 +877,20 @@ class Dec(_DecBase, _DecComments):
             if Line != '':\r
                 self._RawData.UndoNextLine()\r
                 break\r
-            \r
+\r
             if Comment and Comment.startswith(DT.TAB_SPECIAL_COMMENT) and Comment.find(DT.TAB_HEADER_COMMENT) > 0 \\r
                 and not Comment[2:Comment.find(DT.TAB_HEADER_COMMENT)].strip():\r
                 IsFileHeader = True\r
                 IsBinaryHeader = False\r
                 FileHeaderLineIndex = self._RawData.LineIndex\r
-                \r
+\r
+            #\r
+            # Get license information before '@file'\r
             #\r
-            # Get license information before '@file' \r
-            #   \r
             if not IsFileHeader and not IsBinaryHeader and Comment and Comment.startswith(DT.TAB_COMMENT_SPLIT) and \\r
             DT.TAB_BINARY_HEADER_COMMENT not in Comment:\r
                 self._HeadComment.append((Comment, self._RawData.LineIndex))\r
-            \r
+\r
             if Comment and IsFileHeader and \\r
             not(Comment.startswith(DT.TAB_SPECIAL_COMMENT) \\r
             and Comment.find(DT.TAB_BINARY_HEADER_COMMENT) > 0):\r
@@ -815,15 +899,15 @@ class Dec(_DecBase, _DecComments):
             # Double '#' indicates end of header comments\r
             #\r
             if (not Comment or Comment == DT.TAB_SPECIAL_COMMENT) and IsFileHeader:\r
-                IsFileHeader = False  \r
+                IsFileHeader = False\r
                 continue\r
-            \r
+\r
             if Comment and Comment.startswith(DT.TAB_SPECIAL_COMMENT) \\r
             and Comment.find(DT.TAB_BINARY_HEADER_COMMENT) > 0:\r
                 IsBinaryHeader = True\r
                 IsFileHeader = False\r
                 BinaryHeaderLineIndex = self._RawData.LineIndex\r
-                \r
+\r
             if Comment and IsBinaryHeader:\r
                 self.BinaryHeadComment.append((Comment, self._RawData.LineIndex))\r
             #\r
@@ -832,39 +916,36 @@ class Dec(_DecBase, _DecComments):
             if (not Comment or Comment == DT.TAB_SPECIAL_COMMENT) and IsBinaryHeader:\r
                 IsBinaryHeader = False\r
                 break\r
-            \r
+\r
             if FileHeaderLineIndex > -1 and not IsFileHeader and not IsBinaryHeader:\r
                 break\r
 \r
         if FileHeaderLineIndex > BinaryHeaderLineIndex and FileHeaderLineIndex > -1 and BinaryHeaderLineIndex > -1:\r
             self._LoggerError(ST.ERR_BINARY_HEADER_ORDER)\r
-            \r
+\r
         if FileHeaderLineIndex == -1:\r
-            Logger.Error(TOOL_NAME, FORMAT_INVALID, \r
+#            self._LoggerError(ST.ERR_NO_SOURCE_HEADER)\r
+            Logger.Error(TOOL_NAME, FORMAT_INVALID,\r
                          ST.ERR_NO_SOURCE_HEADER,\r
-                         File=self._RawData.Filename)        \r
+                         File=self._RawData.Filename)\r
         return\r
-    \r
+\r
     def _StopCurrentParsing(self, Line):\r
         return False\r
-    \r
+\r
     def _ParseItem(self):\r
         self._SectionHeaderParser()\r
         if len(self._RawData.CurrentScope) == 0:\r
             self._LoggerError(ST.ERR_DECPARSE_SECTION_EMPTY)\r
-\r
         SectionObj = self._SectionParser[self._RawData.CurrentScope[0][0]]\r
-\r
         SectionObj.BlockStart()\r
         SectionObj.Parse()\r
-        \r
         return SectionObj.GetDataObject()\r
 \r
     def _UserExtentionSectionParser(self):\r
         self._RawData.CurrentScope = []\r
         ArchList = set()\r
         Section = self._RawData.CurrentLine[1:-1]\r
-        \r
         Par = ParserHelper(Section, self._RawData.Filename)\r
         while not Par.End():\r
             #\r
@@ -874,8 +955,8 @@ class Dec(_DecBase, _DecComments):
             if Token.upper() != DT.TAB_USER_EXTENSIONS.upper():\r
                 self._LoggerError(ST.ERR_DECPARSE_SECTION_UE)\r
             UserExtension = Token.upper()\r
-\r
             Par.AssertChar(DT.TAB_SPLIT, ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)\r
+\r
             #\r
             # UserID\r
             #\r
@@ -883,7 +964,6 @@ class Dec(_DecBase, _DecComments):
             if not IsValidUserId(Token):\r
                 self._LoggerError(ST.ERR_DECPARSE_SECTION_UE_USERID)\r
             UserId = Token\r
-            \r
             Par.AssertChar(DT.TAB_SPLIT, ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)\r
             #\r
             # IdString\r
@@ -892,7 +972,6 @@ class Dec(_DecBase, _DecComments):
             if not IsValidIdString(Token):\r
                 self._LoggerError(ST.ERR_DECPARSE_SECTION_UE_IDSTRING)\r
             IdString = Token\r
-            \r
             Arch = 'COMMON'\r
             if Par.Expect(DT.TAB_SPLIT):\r
                 Token = Par.GetToken()\r
@@ -900,23 +979,19 @@ class Dec(_DecBase, _DecComments):
                 if not IsValidArch(Arch):\r
                     self._LoggerError(ST.ERR_DECPARSE_ARCH)\r
             ArchList.add(Arch)\r
-            \r
             if [UserExtension, UserId, IdString, Arch] not in \\r
                 self._RawData.CurrentScope:\r
                 self._RawData.CurrentScope.append(\r
                     [UserExtension, UserId, IdString, Arch]\r
                 )\r
-            \r
             if not Par.Expect(DT.TAB_COMMA_SPLIT):\r
                 break\r
             elif Par.End():\r
                 self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMA)\r
-        \r
         Par.AssertEnd(ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)\r
-        \r
         if 'COMMON' in ArchList and len(ArchList) > 1:\r
             self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMON)\r
\r
+\r
     ## Section header parser\r
     #\r
     # The section header is always in following format:\r
@@ -926,9 +1001,8 @@ class Dec(_DecBase, _DecComments):
     def _SectionHeaderParser(self):\r
         if self._RawData.CurrentLine[0] != DT.TAB_SECTION_START or self._RawData.CurrentLine[-1] != DT.TAB_SECTION_END:\r
             self._LoggerError(ST.ERR_DECPARSE_SECTION_IDENTIFY)\r
-        \r
+\r
         RawSection = self._RawData.CurrentLine[1:-1].strip().upper()\r
-        \r
         #\r
         # Check defines section which is only allowed to occur once and\r
         # no arch can be followed\r
@@ -936,13 +1010,11 @@ class Dec(_DecBase, _DecComments):
         if RawSection.startswith(DT.TAB_DEC_DEFINES.upper()):\r
             if RawSection != DT.TAB_DEC_DEFINES.upper():\r
                 self._LoggerError(ST.ERR_DECPARSE_DEFINE_SECNAME)\r
-        \r
         #\r
         # Check user extension section\r
         #\r
         if RawSection.startswith(DT.TAB_USER_EXTENSIONS.upper()):\r
             return self._UserExtentionSectionParser()\r
-        \r
         self._RawData.CurrentScope = []\r
         SectionNames = []\r
         ArchList = set()\r
@@ -951,17 +1023,14 @@ class Dec(_DecBase, _DecComments):
                 self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBEMPTY % self._RawData.CurrentLine)\r
 \r
             ItemList = GetSplitValueList(Item, DT.TAB_SPLIT)\r
-\r
             #\r
             # different types of PCD are permissible in one section\r
             #\r
             SectionName = ItemList[0]\r
             if SectionName not in self._SectionParser:\r
                 self._LoggerError(ST.ERR_DECPARSE_SECTION_UNKNOW % SectionName)\r
-            \r
             if SectionName not in SectionNames:\r
                 SectionNames.append(SectionName)\r
-            \r
             #\r
             # In DEC specification, all section headers have at most two part:\r
             # SectionName.Arch except UserExtention\r
@@ -970,7 +1039,7 @@ class Dec(_DecBase, _DecComments):
                 self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBTOOMANY % Item)\r
 \r
             if DT.TAB_PCDS_FEATURE_FLAG_NULL.upper() in SectionNames and len(SectionNames) > 1:\r
-                self._LoggerError(ST.ERR_DECPARSE_SECTION_FEATUREFLAG % DT.TAB_PCDS_FEATURE_FLAG_NULL) \r
+                self._LoggerError(ST.ERR_DECPARSE_SECTION_FEATUREFLAG % DT.TAB_PCDS_FEATURE_FLAG_NULL)\r
             #\r
             # S1 is always Arch\r
             #\r
@@ -989,49 +1058,40 @@ class Dec(_DecBase, _DecComments):
         #\r
         if 'COMMON' in ArchList and len(ArchList) > 1:\r
             self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMON)\r
-        \r
         if len(SectionNames) == 0:\r
             self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBEMPTY % self._RawData.CurrentLine)\r
         if len(SectionNames) != 1:\r
             for Sec in SectionNames:\r
                 if not Sec.startswith(DT.TAB_PCDS.upper()):\r
                     self._LoggerError(ST.ERR_DECPARSE_SECTION_NAME % str(SectionNames))\r
-    \r
+\r
+    def GetDefineSectionMacro(self):\r
+        return self._Define.GetLocalMacro()\r
     def GetDefineSectionObject(self):\r
         return self._Define.GetDataObject()\r
-    \r
     def GetIncludeSectionObject(self):\r
         return self._Include.GetDataObject()\r
-    \r
     def GetGuidSectionObject(self):\r
         return self._Guid.GetGuidObject()\r
-    \r
     def GetProtocolSectionObject(self):\r
         return self._Guid.GetProtocolObject()\r
-    \r
     def GetPpiSectionObject(self):\r
         return self._Guid.GetPpiObject()\r
-    \r
     def GetLibraryClassSectionObject(self):\r
         return self._LibClass.GetDataObject()\r
-    \r
     def GetPcdSectionObject(self):\r
         return self._Pcd.GetDataObject()\r
-    \r
     def GetUserExtensionSectionObject(self):\r
         return self._UserEx.GetDataObject()\r
-    \r
     def GetPackageSpecification(self):\r
         return self._Define.GetDataObject().GetPackageSpecification()\r
-    \r
     def GetPackageName(self):\r
         return self._Define.GetDataObject().GetPackageName()\r
-    \r
     def GetPackageGuid(self):\r
         return self._Define.GetDataObject().GetPackageGuid()\r
-    \r
     def GetPackageVersion(self):\r
         return self._Define.GetDataObject().GetPackageVersion()\r
-    \r
     def GetPackageUniFile(self):\r
         return self._Define.GetDataObject().GetPackageUniFile()\r
+    def GetPrivateSections(self):\r
+        return self._Private\r