4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync# This file is used to parse DEC file. It will consumed by DecParser
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync# This program and the accompanying materials are licensed and made available
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync# under the terms and conditions of the BSD License which accompanies this
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync# distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync## Import modules
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfrom Library.ParserValidate import IsValidCFormatGuid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfrom Object.Parser.DecObject import DecDefineItemObject
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfrom Object.Parser.DecObject import DecIncludeObject
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfrom Object.Parser.DecObject import DecIncludeItemObject
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfrom Object.Parser.DecObject import DecLibraryclassObject
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfrom Object.Parser.DecObject import DecLibraryclassItemObject
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfrom Object.Parser.DecObject import DecProtocolObject
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfrom Object.Parser.DecObject import DecGuidItemObject
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfrom Object.Parser.DecObject import DecUserExtensionObject
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfrom Object.Parser.DecObject import DecUserExtensionItemObject
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfrom Object.Parser.DecObject import DecPcdItemObject
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfrom Library.Misc import GuidStructureStringToGuidString
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync# _DecBase class for parsing
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Data parsed by 'self' are saved to this object
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ## BlockStart
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Called if a new section starts
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ## _CheckReDefine
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # @param Key: to be checked if multi-defined
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # @param Scope: Format: [[SectionName, Arch], ...].
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # If scope is none, use global scope
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Copy scope to SecArch, avoid Scope be changed outside
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._ItemDict[Key] = [[SecArch, self._RawData.LineIndex]]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # If current is common section
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Key in common cannot be redefined in other arches
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # [:-1] means stripping arch info
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_REDEFINE % (Key, Value[1]))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Cannot be redefined if this key already defined in COMMON Or defined in same arch
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if SubValue in Value[0] or CommonScope in Value[0]:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_REDEFINE % (Key, Value[1]))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._ItemDict[Key].append([SecArch, self._RawData.LineIndex])
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ## CheckRequiredFields
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Some sections need to check if some fields exist, define section for example
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Derived class can re-implement, top parser will call this function after all parsing done
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ## IsItemRequired
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # In DEC spec, sections must have at least one statement except user
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # extension.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # For example: "[guids" [<attribs>] "]" <EOL> <statements>+
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # sub class can override this method to indicate if statement is a must.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtraData=ErrorString + ST.ERR_DECPARSE_LINE % self._RawData.CurrentLine)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync String = ReplaceMacro(String, self._LocalMacro, False,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync String = ReplaceMacro(String, self._RawData.Macros, False,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtraData = ST.ERR_DECPARSE_MACRO_RESOLVE % (str(MacroUsed), String))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TokenList = GetSplitValueList(TokenList[1], DT.TAB_EQUAL_SPLIT, 1)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync elif not IsValidToken(MACRO_PATTERN, TokenList[0]):
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_MACRO_NAME_UPPER % TokenList[0])
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LocalMacro[TokenList[0]] = self._ReplaceMacro(TokenList[1])
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ## _ParseItem
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Parse specified item, this function must be derived by subclass
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Should never be called
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return None
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ## _TailCommentStrategy
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # This function can be derived to parse tail comment
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # default is it will not consume any lines
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # @param Comment: Comment of current line
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ## _StopCurrentParsing
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Called in Parse if current parsing should be stopped when encounter some
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Default is section start and end
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # @param Line: Current line
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Line[0] == DT.TAB_SECTION_START and Line[-1] == DT.TAB_SECTION_END
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ## _TryBackSlash
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Split comment and DEC content, concatenate lines if end of char is '\'
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # @param ProcessedLine: ProcessedLine line
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # @param ProcessedComments: ProcessedComments line
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync def _TryBackSlash(self, ProcessedLine, ProcessedComments):
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CommentList.append((Comment, self._RawData.LineIndex))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Line, Comment = CleanString(self._RawData.GetNextLine())
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Reach end of content
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._RawData.CurrentLine = self._ReplaceMacro(CatLine)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # This is a template method in which other member functions which might
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # override by sub class are called. It is responsible for reading file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # line by line, and call other member functions to parse. This function
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # should not be re-implement by sub class.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync #======================================================================
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # CurComments may pointer to HeadComments or TailComments
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync #======================================================================
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync #======================================================================
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Used to report error information if empty section found
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync #======================================================================
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while not self._RawData.IsEndOfFile() or self._RawData.NextLine:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync #==============================================================
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Have processed line in buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync #==============================================================
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync #==============================================================
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # No line in buffer, read next line
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync #==============================================================
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Line, Comment = CleanString(self._RawData.GetNextLine())
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync #==========================================================
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Set tail comments to previous statement if not empty.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync #==========================================================
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CurObj.SetTailComment(CurObj.GetTailComment()+TailComments)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync #==============================================================
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Try if last char of line has backslash
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync #==============================================================
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Line, Comments = self._TryBackSlash(Line, Comments)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync #==============================================================
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Macro found
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync #==============================================================
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync #==========================================================
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # This line does not belong to this parse,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Save it, can be used by next parse
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync #==========================================================
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._RawData.SetNext(Line, HeadComments, TailComments)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Obj.SetHeadComment(Obj.GetHeadComment()+HeadComments)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Obj.SetTailComment(Obj.GetTailComment()+TailComments)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync #==========================================================
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Check if this comment belongs to tail comment
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync #==========================================================
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CurComments.append(((Comment, self._RawData.LineIndex)))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtraData=ST.ERR_DECPARSE_STATEMENT_EMPTY % LineStr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync## _DecDefine
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync# Parse define section
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self.ItemObject = DecDefineObject(RawData.Filename)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Each field has a function to validate
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DT.TAB_DEC_DEFINES_DEC_SPECIFICATION : self._SetDecSpecification,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DT.TAB_DEC_DEFINES_PACKAGE_NAME : self._SetPackageName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DT.TAB_DEC_DEFINES_PACKAGE_GUID : self._SetPackageGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DT.TAB_DEC_DEFINES_PACKAGE_VERSION : self._SetPackageVersion,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ## CheckRequiredFields
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Check required fields: DEC_SPECIFICATION, PACKAGE_NAME
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # PACKAGE_GUID, PACKAGE_VERSION
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if self.ItemObject.GetPackageSpecification() == '':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_DEC_SPECIFICATION)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_NAME)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_GUID)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_VERSION)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TokenList = GetSplitValueList(Line, DT.TAB_EQUAL_SPLIT, 1)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if TokenList[0] == DT.TAB_DEC_DEFINES_PKG_UNI_FILE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_DEFINE_UNKNOWKEY % TokenList[0])
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if TokenList[0] != DT.TAB_DEC_DEFINES_PKG_UNI_FILE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self.ItemObject.AddItem(DefineItem, self._RawData.CurrentScope)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_DEC_SPECIFICATION)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_NAME)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_GUID)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_VERSION)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGVERSION)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync## _DecInclude
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync# Parse include section
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self.ItemObject = DecIncludeObject(RawData.Filename)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if not IsValidPath(Line, self._RawData.PackagePath):
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Item = DecIncludeItemObject(StripRoot(self._RawData.PackagePath, Line), self._RawData.PackagePath)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self.ItemObject.AddItem(Item, self._RawData.CurrentScope)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync## _DecLibraryclass
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync# Parse library class section
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self.ItemObject = DecLibraryclassObject(RawData.Filename)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TokenList = GetSplitValueList(Line, DT.TAB_VALUE_SPLIT)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if not IsValidToken('[A-Z][0-9A-Za-z]*', TokenList[0]):
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Must end with .h
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_PATH_EXT)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Path must be existed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if not IsValidPath(Value, self._RawData.PackagePath):
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Item = DecLibraryclassItemObject(TokenList[0], StripRoot(self._RawData.PackagePath, Value),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self.ItemObject.AddItem(Item, self._RawData.CurrentScope)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync# Parse PCD section
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Used to check duplicate token
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Key is token space and token number (integer), value is C name
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Token space guid C name
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PcdName = GetSplitValueList(TokenList[0], DT.TAB_SPLIT)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if len(PcdName) != 2 or PcdName[0] == '' or PcdName[1] == '':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # PCD C name
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_PCDCNAME)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Default value, may be C array, string or number
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Data = DT.TAB_VALUE_SPLIT.join(TokenList[1:-2]).strip()
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # PCD data type
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if PcdType == DT.TAB_PCDS_FEATURE_FLAG_NULL.upper() and DataType != 'BOOLEAN':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Token value is the last element in list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN % Token)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync elif not Token.startswith('0x') and not Token.startswith('0X'):
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN_INT % Token)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN_UNIQUE%(Token))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Item = DecPcdItemObject(Guid, CName, Data, DataType, Token)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self.ItemObject.AddItem(Item, self._RawData.CurrentScope)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync# Parse GUID, PPI, Protocol section
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self.ProtocolObj = DecProtocolObject(RawData.Filename)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return self.ObjectDict[self._RawData.CurrentScope[0][0]]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return None
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TokenList = GetSplitValueList(Line, DT.TAB_EQUAL_SPLIT, 1)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Convert C format GUID to GUID string and Simple error check
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync GuidString = GuidStructureStringToGuidString(TokenList[1])
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if TokenList[1][0] != '{' or TokenList[1][-1] != '}' or GuidString == '':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_CGUID_GUIDFORMAT)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Check C format GUID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_CGUID_GUIDFORMAT)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Item = DecGuidItemObject(TokenList[0], TokenList[1], GuidString)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ItemObject = self.ObjectDict[self._RawData.CurrentScope[0][0]]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ItemObject.AddItem(Item, self._RawData.CurrentScope)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync## _DecUserExtension
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync# Parse user extention section
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self.ItemObject = DecUserExtensionObject(RawData.Filename)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if Item.UserId == Header[1] and Item.IdString == Header[2]:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Item.UserString = '\n'.join([Item.UserString, Line])
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync# Top dec parser
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Content = ConvertSpecialChar(open(DecFile, 'rb').readlines())
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Logger.Error(TOOL_NAME, FILE_OPEN_FAILURE, File=DecFile,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # DEC file supported data types (one type per section)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DT.TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : self._Pcd,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DT.TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : self._Pcd,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Parsing done, check required fields
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Parse DEC file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Line, Comment = CleanString(self._RawData.GetNextLine())
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Header must be pure comment
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._HeadComment.append((Comment, self._RawData.LineIndex))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Double '#' indicates end of header comments
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if not Comment or Comment == DT.TAB_SPECIAL_COMMENT:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SectionObj = self._SectionParser[self._RawData.CurrentScope[0][0]]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Par = ParserHelper(Section, self._RawData.Filename)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # User extention
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if Token.upper() != DT.TAB_USER_EXTENSIONS.upper():
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Par.AssertChar(DT.TAB_SPLIT, ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_SECTION_UE_USERID)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Par.AssertChar(DT.TAB_SPLIT, ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_SECTION_UE_IDSTRING)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if [UserExtension, UserId, IdString, Arch] not in \
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Par.AssertEnd(ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ## Section header parser
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # The section header is always in following format:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # [section_name.arch<.platform|module_type>]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if self._RawData.CurrentLine[0] != DT.TAB_SECTION_START or self._RawData.CurrentLine[-1] != DT.TAB_SECTION_END:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_SECTION_IDENTIFY)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RawSection = self._RawData.CurrentLine[1:-1].strip().upper()
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Check defines section which is only allowed to occur once and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # no arch can be followed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if RawSection.startswith(DT.TAB_DEC_DEFINES.upper()):
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # Check user extension section
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if RawSection.startswith(DT.TAB_USER_EXTENSIONS.upper()):
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for Item in GetSplitValueList(RawSection, DT.TAB_COMMA_SPLIT):
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBEMPTY % self._RawData.CurrentLine)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # different types of PCD are permissible in one section
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_SECTION_UNKNOW % SectionName)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # In DEC specification, all section headers have at most two part:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # SectionName.Arch except UserExtention
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBTOOMANY % Item)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if DT.TAB_PCDS_FEATURE_FLAG_NULL.upper() in SectionNames and len(SectionNames) > 1:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_SECTION_FEATUREFLAG % DT.TAB_PCDS_FEATURE_FLAG_NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # S1 is always Arch
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if [SectionName, Str1] not in self._RawData.CurrentScope:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._RawData.CurrentScope.append([SectionName, Str1])
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync # 'COMMON' must not be used with specific ARCHs at the same section
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBEMPTY % self._RawData.CurrentLine)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync self._LoggerError(ST.ERR_DECPARSE_SECTION_NAME % str(SectionNames))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return self._Define.GetDataObject().GetPackageSpecification()
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return self._Define.GetDataObject().GetPackageName()
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return self._Define.GetDataObject().GetPackageGuid()
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return self._Define.GetDataObject().GetPackageVersion()