https://bugzilla.tianocore.org/show_bug.cgi?id=1373 Replace BSD 2-Clause License with BSD+Patent License. This change is based on the following emails: https://lists.01.org/pipermail/edk2-devel/2019-February/036260.html https://lists.01.org/pipermail/edk2-devel/2018-October/030385.html RFCs with detailed process for the license change: V3: https://lists.01.org/pipermail/edk2-devel/2019-March/038116.html V2: https://lists.01.org/pipermail/edk2-devel/2019-March/037669.html V1: https://lists.01.org/pipermail/edk2-devel/2019-March/037500.html Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Bob Feng <bob.c.feng@intel.com>
		
			
				
	
	
		
			1092 lines
		
	
	
		
			43 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			1092 lines
		
	
	
		
			43 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
## @file
 | 
						|
# This file is used to parse DEC file. It will consumed by DecParser
 | 
						|
#
 | 
						|
# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
 | 
						|
#
 | 
						|
# SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
'''
 | 
						|
DecParser
 | 
						|
'''
 | 
						|
## Import modules
 | 
						|
#
 | 
						|
import Logger.Log as Logger
 | 
						|
from Logger.ToolError import FILE_PARSE_FAILURE
 | 
						|
from Logger.ToolError import FILE_OPEN_FAILURE
 | 
						|
from Logger import StringTable as ST
 | 
						|
from Logger.ToolError import FORMAT_INVALID
 | 
						|
 | 
						|
import Library.DataType as DT
 | 
						|
from Library.ParserValidate import IsValidToken
 | 
						|
from Library.ParserValidate import IsValidPath
 | 
						|
from Library.ParserValidate import IsValidCFormatGuid
 | 
						|
from Library.ParserValidate import IsValidIdString
 | 
						|
from Library.ParserValidate import IsValidUserId
 | 
						|
from Library.ParserValidate import IsValidArch
 | 
						|
from Library.ParserValidate import IsValidWord
 | 
						|
from Library.ParserValidate import IsValidDecVersionVal
 | 
						|
from Parser.DecParserMisc import TOOL_NAME
 | 
						|
from Parser.DecParserMisc import CleanString
 | 
						|
from Parser.DecParserMisc import IsValidPcdDatum
 | 
						|
from Parser.DecParserMisc import ParserHelper
 | 
						|
from Parser.DecParserMisc import StripRoot
 | 
						|
from Parser.DecParserMisc import VERSION_PATTERN
 | 
						|
from Parser.DecParserMisc import CVAR_PATTERN
 | 
						|
from Parser.DecParserMisc import PCD_TOKEN_PATTERN
 | 
						|
from Parser.DecParserMisc import MACRO_PATTERN
 | 
						|
from Parser.DecParserMisc import FileContent
 | 
						|
from Object.Parser.DecObject import _DecComments
 | 
						|
from Object.Parser.DecObject import DecDefineObject
 | 
						|
from Object.Parser.DecObject import DecDefineItemObject
 | 
						|
from Object.Parser.DecObject import DecIncludeObject
 | 
						|
from Object.Parser.DecObject import DecIncludeItemObject
 | 
						|
from Object.Parser.DecObject import DecLibraryclassObject
 | 
						|
from Object.Parser.DecObject import DecLibraryclassItemObject
 | 
						|
from Object.Parser.DecObject import DecGuidObject
 | 
						|
from Object.Parser.DecObject import DecPpiObject
 | 
						|
from Object.Parser.DecObject import DecProtocolObject
 | 
						|
from Object.Parser.DecObject import DecGuidItemObject
 | 
						|
from Object.Parser.DecObject import DecUserExtensionObject
 | 
						|
from Object.Parser.DecObject import DecUserExtensionItemObject
 | 
						|
from Object.Parser.DecObject import DecPcdObject
 | 
						|
from Object.Parser.DecObject import DecPcdItemObject
 | 
						|
from Library.Misc import GuidStructureStringToGuidString
 | 
						|
from Library.Misc import CheckGuidRegFormat
 | 
						|
from Library.StringUtils import ReplaceMacro
 | 
						|
from Library.StringUtils import GetSplitValueList
 | 
						|
from Library.StringUtils import gMACRO_PATTERN
 | 
						|
from Library.StringUtils import ConvertSpecialChar
 | 
						|
from Library.CommentParsing import ParsePcdErrorCode
 | 
						|
 | 
						|
##
 | 
						|
# _DecBase class for parsing
 | 
						|
#
 | 
						|
class _DecBase:
 | 
						|
    def __init__(self, RawData):
 | 
						|
        self._RawData = RawData
 | 
						|
        self._ItemDict = {}
 | 
						|
        self._LocalMacro = {}
 | 
						|
        #
 | 
						|
        # Data parsed by 'self' are saved to this object
 | 
						|
        #
 | 
						|
        self.ItemObject = None
 | 
						|
 | 
						|
    def GetDataObject(self):
 | 
						|
        return self.ItemObject
 | 
						|
 | 
						|
    def GetLocalMacro(self):
 | 
						|
        return self._LocalMacro
 | 
						|
 | 
						|
    ## BlockStart
 | 
						|
    #
 | 
						|
    # Called if a new section starts
 | 
						|
    #
 | 
						|
    def BlockStart(self):
 | 
						|
        self._LocalMacro = {}
 | 
						|
 | 
						|
    ## _CheckReDefine
 | 
						|
    #
 | 
						|
    # @param Key: to be checked if multi-defined
 | 
						|
    # @param Scope: Format: [[SectionName, Arch], ...].
 | 
						|
    #               If scope is none, use global scope
 | 
						|
    #
 | 
						|
    def _CheckReDefine(self, Key, Scope = None):
 | 
						|
        if not Scope:
 | 
						|
            Scope = self._RawData.CurrentScope
 | 
						|
            return
 | 
						|
 | 
						|
        SecArch = []
 | 
						|
        #
 | 
						|
        # Copy scope to SecArch, avoid Scope be changed outside
 | 
						|
        #
 | 
						|
        SecArch[0:1] = Scope[:]
 | 
						|
        if Key not in self._ItemDict:
 | 
						|
            self._ItemDict[Key] = [[SecArch, self._RawData.LineIndex]]
 | 
						|
            return
 | 
						|
 | 
						|
        for Value in self._ItemDict[Key]:
 | 
						|
            for SubValue in Scope:
 | 
						|
                #
 | 
						|
                # If current is common section
 | 
						|
                #
 | 
						|
                if SubValue[-1] == 'COMMON':
 | 
						|
                    for Other in Value[0]:
 | 
						|
                        # Key in common cannot be redefined in other arches
 | 
						|
                        # [:-1] means stripping arch info
 | 
						|
                        if Other[:-1] == SubValue[:-1]:
 | 
						|
                            self._LoggerError(ST.ERR_DECPARSE_REDEFINE % (Key, Value[1]))
 | 
						|
                            return
 | 
						|
                    continue
 | 
						|
                CommonScope = []
 | 
						|
                CommonScope[0:1] = SubValue
 | 
						|
                CommonScope[-1] = 'COMMON'
 | 
						|
                #
 | 
						|
                # Cannot be redefined if this key already defined in COMMON Or defined in same arch
 | 
						|
                #
 | 
						|
                if SubValue in Value[0] or CommonScope in Value[0]:
 | 
						|
                    self._LoggerError(ST.ERR_DECPARSE_REDEFINE % (Key, Value[1]))
 | 
						|
                    return
 | 
						|
        self._ItemDict[Key].append([SecArch, self._RawData.LineIndex])
 | 
						|
 | 
						|
    ## CheckRequiredFields
 | 
						|
    # Some sections need to check if some fields exist, define section for example
 | 
						|
    # Derived class can re-implement, top parser will call this function after all parsing done
 | 
						|
    #
 | 
						|
    def CheckRequiredFields(self):
 | 
						|
        if self._RawData:
 | 
						|
            pass
 | 
						|
        return True
 | 
						|
 | 
						|
    ## IsItemRequired
 | 
						|
    # In DEC spec, sections must have at least one statement except user
 | 
						|
    # extension.
 | 
						|
    # For example: "[guids" [<attribs>] "]" <EOL> <statements>+
 | 
						|
    # sub class can override this method to indicate if statement is a must.
 | 
						|
    #
 | 
						|
    def _IsStatementRequired(self):
 | 
						|
        if self._RawData:
 | 
						|
            pass
 | 
						|
        return False
 | 
						|
 | 
						|
    def _LoggerError(self, ErrorString):
 | 
						|
        Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
 | 
						|
                     Line = self._RawData.LineIndex,
 | 
						|
                     ExtraData=ErrorString + ST.ERR_DECPARSE_LINE % self._RawData.CurrentLine)
 | 
						|
 | 
						|
    def _ReplaceMacro(self, String):
 | 
						|
        if gMACRO_PATTERN.findall(String):
 | 
						|
            String = ReplaceMacro(String, self._LocalMacro, False,
 | 
						|
                                  FileName = self._RawData.Filename,
 | 
						|
                                  Line = ['', self._RawData.LineIndex])
 | 
						|
            String = ReplaceMacro(String, self._RawData.Macros, False,
 | 
						|
                                  FileName = self._RawData.Filename,
 | 
						|
                                  Line = ['', self._RawData.LineIndex])
 | 
						|
            MacroUsed = gMACRO_PATTERN.findall(String)
 | 
						|
            if MacroUsed:
 | 
						|
                Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE,
 | 
						|
                             File=self._RawData.Filename,
 | 
						|
                             Line = self._RawData.LineIndex,
 | 
						|
                             ExtraData = ST.ERR_DECPARSE_MACRO_RESOLVE % (str(MacroUsed), String))
 | 
						|
        return String
 | 
						|
 | 
						|
    def _MacroParser(self, String):
 | 
						|
        TokenList = GetSplitValueList(String, ' ', 1)
 | 
						|
        if len(TokenList) < 2 or TokenList[1] == '':
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_MACRO_PAIR)
 | 
						|
 | 
						|
        TokenList = GetSplitValueList(TokenList[1], DT.TAB_EQUAL_SPLIT, 1)
 | 
						|
        if TokenList[0] == '':
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_MACRO_NAME)
 | 
						|
        elif not IsValidToken(MACRO_PATTERN, TokenList[0]):
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_MACRO_NAME_UPPER % TokenList[0])
 | 
						|
 | 
						|
        if len(TokenList) == 1:
 | 
						|
            self._LocalMacro[TokenList[0]] = ''
 | 
						|
        else:
 | 
						|
            self._LocalMacro[TokenList[0]] = self._ReplaceMacro(TokenList[1])
 | 
						|
 | 
						|
    ## _ParseItem
 | 
						|
    #
 | 
						|
    # Parse specified item, this function must be derived by subclass
 | 
						|
    #
 | 
						|
    def _ParseItem(self):
 | 
						|
        if self._RawData:
 | 
						|
            pass
 | 
						|
        #
 | 
						|
        # Should never be called
 | 
						|
        #
 | 
						|
        return None
 | 
						|
 | 
						|
 | 
						|
    ## _TailCommentStrategy
 | 
						|
    #
 | 
						|
    # This function can be derived to parse tail comment
 | 
						|
    # default is it will not consume any lines
 | 
						|
    #
 | 
						|
    # @param Comment: Comment of current line
 | 
						|
    #
 | 
						|
    def _TailCommentStrategy(self, Comment):
 | 
						|
        if Comment:
 | 
						|
            pass
 | 
						|
        if self._RawData:
 | 
						|
            pass
 | 
						|
        return False
 | 
						|
 | 
						|
    ## _StopCurrentParsing
 | 
						|
    #
 | 
						|
    # Called in Parse if current parsing should be stopped when encounter some
 | 
						|
    # keyword
 | 
						|
    # Default is section start and end
 | 
						|
    #
 | 
						|
    # @param Line: Current line
 | 
						|
    #
 | 
						|
    def _StopCurrentParsing(self, Line):
 | 
						|
        if self._RawData:
 | 
						|
            pass
 | 
						|
        return Line[0] == DT.TAB_SECTION_START and Line[-1] == DT.TAB_SECTION_END
 | 
						|
 | 
						|
    ## _TryBackSlash
 | 
						|
    #
 | 
						|
    # Split comment and DEC content, concatenate lines if end of char is '\'
 | 
						|
    #
 | 
						|
    # @param ProcessedLine: ProcessedLine line
 | 
						|
    # @param ProcessedComments: ProcessedComments line
 | 
						|
    #
 | 
						|
    def _TryBackSlash(self, ProcessedLine, ProcessedComments):
 | 
						|
        CatLine = ''
 | 
						|
        Comment = ''
 | 
						|
        Line = ProcessedLine
 | 
						|
        CommentList = ProcessedComments
 | 
						|
        while not self._RawData.IsEndOfFile():
 | 
						|
            if Line == '':
 | 
						|
                self._LoggerError(ST.ERR_DECPARSE_BACKSLASH_EMPTY)
 | 
						|
                break
 | 
						|
 | 
						|
            if Comment:
 | 
						|
                CommentList.append((Comment, self._RawData.LineIndex))
 | 
						|
            if Line[-1] != DT.TAB_SLASH:
 | 
						|
                CatLine += Line
 | 
						|
                break
 | 
						|
            elif len(Line) < 2 or Line[-2] != ' ':
 | 
						|
                self._LoggerError(ST.ERR_DECPARSE_BACKSLASH)
 | 
						|
            else:
 | 
						|
                CatLine += Line[:-1]
 | 
						|
                Line, Comment = CleanString(self._RawData.GetNextLine())
 | 
						|
        #
 | 
						|
        # Reach end of content
 | 
						|
        #
 | 
						|
        if self._RawData.IsEndOfFile():
 | 
						|
            if not CatLine:
 | 
						|
                if ProcessedLine[-1] == DT.TAB_SLASH:
 | 
						|
                    self._LoggerError(ST.ERR_DECPARSE_BACKSLASH_EMPTY)
 | 
						|
                CatLine = ProcessedLine
 | 
						|
            else:
 | 
						|
                if not Line or Line[-1] == DT.TAB_SLASH:
 | 
						|
                    self._LoggerError(ST.ERR_DECPARSE_BACKSLASH_EMPTY)
 | 
						|
                CatLine += Line
 | 
						|
 | 
						|
        #
 | 
						|
        # All MACRO values defined by the DEFINE statements in any section
 | 
						|
        # (except [Userextensions] sections for Intel) of the INF or DEC file
 | 
						|
        # must be expanded before processing of the file.
 | 
						|
        #
 | 
						|
        __IsReplaceMacro = True
 | 
						|
        Header = self._RawData.CurrentScope[0] if self._RawData.CurrentScope else None
 | 
						|
        if Header and len(Header) > 2:
 | 
						|
            if Header[0].upper() == 'USEREXTENSIONS' and not (Header[1] == 'TianoCore' and Header[2] == '"ExtraFiles"'):
 | 
						|
                __IsReplaceMacro = False
 | 
						|
        if __IsReplaceMacro:
 | 
						|
            self._RawData.CurrentLine = self._ReplaceMacro(CatLine)
 | 
						|
        else:
 | 
						|
            self._RawData.CurrentLine = CatLine
 | 
						|
 | 
						|
        return CatLine, CommentList
 | 
						|
 | 
						|
    ## Parse
 | 
						|
    # This is a template method in which other member functions which might
 | 
						|
    # override by sub class are called. It is responsible for reading file
 | 
						|
    # line by line, and call other member functions to parse. This function
 | 
						|
    # should not be re-implement by sub class.
 | 
						|
    #
 | 
						|
    def Parse(self):
 | 
						|
        HeadComments = []
 | 
						|
        TailComments = []
 | 
						|
 | 
						|
        #======================================================================
 | 
						|
        # CurComments may pointer to HeadComments or TailComments
 | 
						|
        #======================================================================
 | 
						|
        CurComments = HeadComments
 | 
						|
        CurObj = None
 | 
						|
        ItemNum = 0
 | 
						|
        FromBuf = False
 | 
						|
 | 
						|
        #======================================================================
 | 
						|
        # Used to report error information if empty section found
 | 
						|
        #======================================================================
 | 
						|
        Index = self._RawData.LineIndex
 | 
						|
        LineStr = self._RawData.CurrentLine
 | 
						|
        while not self._RawData.IsEndOfFile() or self._RawData.NextLine:
 | 
						|
            if self._RawData.NextLine:
 | 
						|
                #==============================================================
 | 
						|
                # Have processed line in buffer
 | 
						|
                #==============================================================
 | 
						|
                Line = self._RawData.NextLine
 | 
						|
                HeadComments.extend(self._RawData.HeadComment)
 | 
						|
                TailComments.extend(self._RawData.TailComment)
 | 
						|
                self._RawData.ResetNext()
 | 
						|
                Comment = ''
 | 
						|
                FromBuf = True
 | 
						|
            else:
 | 
						|
                #==============================================================
 | 
						|
                # No line in buffer, read next line
 | 
						|
                #==============================================================
 | 
						|
                Line, Comment = CleanString(self._RawData.GetNextLine())
 | 
						|
                FromBuf = False
 | 
						|
            if Line:
 | 
						|
                if not FromBuf and CurObj and TailComments:
 | 
						|
                    #==========================================================
 | 
						|
                    # Set tail comments to previous statement if not empty.
 | 
						|
                    #==========================================================
 | 
						|
                    CurObj.SetTailComment(CurObj.GetTailComment()+TailComments)
 | 
						|
 | 
						|
                if not FromBuf:
 | 
						|
                    del TailComments[:]
 | 
						|
                CurComments = TailComments
 | 
						|
                Comments = []
 | 
						|
                if Comment:
 | 
						|
                    Comments = [(Comment, self._RawData.LineIndex)]
 | 
						|
 | 
						|
                #==============================================================
 | 
						|
                # Try if last char of line has backslash
 | 
						|
                #==============================================================
 | 
						|
                Line, Comments = self._TryBackSlash(Line, Comments)
 | 
						|
                CurComments.extend(Comments)
 | 
						|
 | 
						|
                #==============================================================
 | 
						|
                # Macro found
 | 
						|
                #==============================================================
 | 
						|
                if Line.startswith('DEFINE '):
 | 
						|
                    self._MacroParser(Line)
 | 
						|
                    del HeadComments[:]
 | 
						|
                    del TailComments[:]
 | 
						|
                    CurComments = HeadComments
 | 
						|
                    continue
 | 
						|
 | 
						|
                if self._StopCurrentParsing(Line):
 | 
						|
                    #==========================================================
 | 
						|
                    # This line does not belong to this parse,
 | 
						|
                    # Save it, can be used by next parse
 | 
						|
                    #==========================================================
 | 
						|
                    self._RawData.SetNext(Line, HeadComments, TailComments)
 | 
						|
                    break
 | 
						|
 | 
						|
                Obj = self._ParseItem()
 | 
						|
                ItemNum += 1
 | 
						|
                if Obj:
 | 
						|
                    Obj.SetHeadComment(Obj.GetHeadComment()+HeadComments)
 | 
						|
                    Obj.SetTailComment(Obj.GetTailComment()+TailComments)
 | 
						|
                    del HeadComments[:]
 | 
						|
                    del TailComments[:]
 | 
						|
                    CurObj = Obj
 | 
						|
                else:
 | 
						|
                    CurObj = None
 | 
						|
            else:
 | 
						|
                if id(CurComments) == id(TailComments):
 | 
						|
                    #==========================================================
 | 
						|
                    # Check if this comment belongs to tail comment
 | 
						|
                    #==========================================================
 | 
						|
                    if not self._TailCommentStrategy(Comment):
 | 
						|
                        CurComments = HeadComments
 | 
						|
 | 
						|
                if Comment:
 | 
						|
                    CurComments.append(((Comment, self._RawData.LineIndex)))
 | 
						|
                else:
 | 
						|
                    del CurComments[:]
 | 
						|
 | 
						|
        if self._IsStatementRequired() and ItemNum == 0:
 | 
						|
            Logger.Error(
 | 
						|
                    TOOL_NAME, FILE_PARSE_FAILURE,
 | 
						|
                    File=self._RawData.Filename,
 | 
						|
                    Line=Index,
 | 
						|
                    ExtraData=ST.ERR_DECPARSE_STATEMENT_EMPTY % LineStr
 | 
						|
            )
 | 
						|
 | 
						|
## _DecDefine
 | 
						|
# Parse define section
 | 
						|
#
 | 
						|
class _DecDefine(_DecBase):
 | 
						|
    def __init__(self, RawData):
 | 
						|
        _DecBase.__init__(self, RawData)
 | 
						|
        self.ItemObject = DecDefineObject(RawData.Filename)
 | 
						|
        self._LocalMacro = self._RawData.Macros
 | 
						|
        self._DefSecNum = 0
 | 
						|
 | 
						|
        #
 | 
						|
        # Each field has a function to validate
 | 
						|
        #
 | 
						|
        self.DefineValidation = {
 | 
						|
            DT.TAB_DEC_DEFINES_DEC_SPECIFICATION   :   self._SetDecSpecification,
 | 
						|
            DT.TAB_DEC_DEFINES_PACKAGE_NAME        :   self._SetPackageName,
 | 
						|
            DT.TAB_DEC_DEFINES_PACKAGE_GUID        :   self._SetPackageGuid,
 | 
						|
            DT.TAB_DEC_DEFINES_PACKAGE_VERSION     :   self._SetPackageVersion,
 | 
						|
            DT.TAB_DEC_DEFINES_PKG_UNI_FILE        :   self._SetPackageUni,
 | 
						|
        }
 | 
						|
 | 
						|
    def BlockStart(self):
 | 
						|
        self._DefSecNum += 1
 | 
						|
        if self._DefSecNum > 1:
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_DEFINE_MULTISEC)
 | 
						|
 | 
						|
    ## CheckRequiredFields
 | 
						|
    #
 | 
						|
    # Check required fields: DEC_SPECIFICATION, PACKAGE_NAME
 | 
						|
    #                        PACKAGE_GUID, PACKAGE_VERSION
 | 
						|
    #
 | 
						|
    def CheckRequiredFields(self):
 | 
						|
        Ret = False
 | 
						|
        if self.ItemObject.GetPackageSpecification() == '':
 | 
						|
            Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
 | 
						|
                         ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_DEC_SPECIFICATION)
 | 
						|
        elif self.ItemObject.GetPackageName() == '':
 | 
						|
            Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
 | 
						|
                         ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_NAME)
 | 
						|
        elif self.ItemObject.GetPackageGuid() == '':
 | 
						|
            Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
 | 
						|
                         ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_GUID)
 | 
						|
        elif self.ItemObject.GetPackageVersion() == '':
 | 
						|
            Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
 | 
						|
                         ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_VERSION)
 | 
						|
        else:
 | 
						|
            Ret = True
 | 
						|
        return Ret
 | 
						|
 | 
						|
    def _ParseItem(self):
 | 
						|
        Line = self._RawData.CurrentLine
 | 
						|
        TokenList = GetSplitValueList(Line, DT.TAB_EQUAL_SPLIT, 1)
 | 
						|
        if TokenList[0] == DT.TAB_DEC_DEFINES_PKG_UNI_FILE:
 | 
						|
            self.DefineValidation[TokenList[0]](TokenList[1])
 | 
						|
        elif len(TokenList) < 2:
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_DEFINE_FORMAT)
 | 
						|
        elif TokenList[0] not in self.DefineValidation:
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_DEFINE_UNKNOWKEY % TokenList[0])
 | 
						|
        else:
 | 
						|
            self.DefineValidation[TokenList[0]](TokenList[1])
 | 
						|
 | 
						|
        DefineItem = DecDefineItemObject()
 | 
						|
        DefineItem.Key   = TokenList[0]
 | 
						|
        DefineItem.Value = TokenList[1]
 | 
						|
        self.ItemObject.AddItem(DefineItem, self._RawData.CurrentScope)
 | 
						|
        return DefineItem
 | 
						|
 | 
						|
    def _SetDecSpecification(self, Token):
 | 
						|
        if self.ItemObject.GetPackageSpecification():
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_DEC_SPECIFICATION)
 | 
						|
        if not IsValidToken('0[xX][0-9a-fA-F]{8}', Token):
 | 
						|
            if not IsValidDecVersionVal(Token):
 | 
						|
                self._LoggerError(ST.ERR_DECPARSE_DEFINE_SPEC)
 | 
						|
        self.ItemObject.SetPackageSpecification(Token)
 | 
						|
 | 
						|
    def _SetPackageName(self, Token):
 | 
						|
        if self.ItemObject.GetPackageName():
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_NAME)
 | 
						|
        if not IsValidWord(Token):
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGNAME)
 | 
						|
        self.ItemObject.SetPackageName(Token)
 | 
						|
 | 
						|
    def _SetPackageGuid(self, Token):
 | 
						|
        if self.ItemObject.GetPackageGuid():
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_GUID)
 | 
						|
        if not CheckGuidRegFormat(Token):
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGGUID)
 | 
						|
        self.ItemObject.SetPackageGuid(Token)
 | 
						|
 | 
						|
    def _SetPackageVersion(self, Token):
 | 
						|
        if self.ItemObject.GetPackageVersion():
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_VERSION)
 | 
						|
        if not IsValidToken(VERSION_PATTERN, Token):
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGVERSION)
 | 
						|
        else:
 | 
						|
            if not DT.TAB_SPLIT in Token:
 | 
						|
                Token = Token + '.0'
 | 
						|
            self.ItemObject.SetPackageVersion(Token)
 | 
						|
 | 
						|
    def _SetPackageUni(self, Token):
 | 
						|
        if self.ItemObject.GetPackageUniFile():
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PKG_UNI_FILE)
 | 
						|
        self.ItemObject.SetPackageUniFile(Token)
 | 
						|
 | 
						|
## _DecInclude
 | 
						|
#
 | 
						|
# Parse include section
 | 
						|
#
 | 
						|
class _DecInclude(_DecBase):
 | 
						|
    def __init__(self, RawData):
 | 
						|
        _DecBase.__init__(self, RawData)
 | 
						|
        self.ItemObject = DecIncludeObject(RawData.Filename)
 | 
						|
 | 
						|
    def _ParseItem(self):
 | 
						|
        Line = self._RawData.CurrentLine
 | 
						|
 | 
						|
        if not IsValidPath(Line, self._RawData.PackagePath):
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_INCLUDE % Line)
 | 
						|
 | 
						|
        Item = DecIncludeItemObject(StripRoot(self._RawData.PackagePath, Line), self._RawData.PackagePath)
 | 
						|
        self.ItemObject.AddItem(Item, self._RawData.CurrentScope)
 | 
						|
        return Item
 | 
						|
 | 
						|
## _DecLibraryclass
 | 
						|
#
 | 
						|
# Parse library class section
 | 
						|
#
 | 
						|
class _DecLibraryclass(_DecBase):
 | 
						|
    def __init__(self, RawData):
 | 
						|
        _DecBase.__init__(self, RawData)
 | 
						|
        self.ItemObject = DecLibraryclassObject(RawData.Filename)
 | 
						|
 | 
						|
    def _ParseItem(self):
 | 
						|
        Line = self._RawData.CurrentLine
 | 
						|
        TokenList = GetSplitValueList(Line, DT.TAB_VALUE_SPLIT)
 | 
						|
        if len(TokenList) != 2:
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_SPLIT)
 | 
						|
        if TokenList[0] == '' or TokenList[1] == '':
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_EMPTY)
 | 
						|
        if not IsValidToken('[A-Z][0-9A-Za-z]*', TokenList[0]):
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_LIB)
 | 
						|
 | 
						|
        self._CheckReDefine(TokenList[0])
 | 
						|
 | 
						|
        Value = TokenList[1]
 | 
						|
        #
 | 
						|
        # Must end with .h
 | 
						|
        #
 | 
						|
        if not Value.endswith('.h'):
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_PATH_EXT)
 | 
						|
 | 
						|
        #
 | 
						|
        # Path must be existed
 | 
						|
        #
 | 
						|
        if not IsValidPath(Value, self._RawData.PackagePath):
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_INCLUDE % Value)
 | 
						|
 | 
						|
        Item = DecLibraryclassItemObject(TokenList[0], StripRoot(self._RawData.PackagePath, Value),
 | 
						|
                                         self._RawData.PackagePath)
 | 
						|
        self.ItemObject.AddItem(Item, self._RawData.CurrentScope)
 | 
						|
        return Item
 | 
						|
 | 
						|
## _DecPcd
 | 
						|
#
 | 
						|
# Parse PCD section
 | 
						|
#
 | 
						|
class _DecPcd(_DecBase):
 | 
						|
    def __init__(self, RawData):
 | 
						|
        _DecBase.__init__(self, RawData)
 | 
						|
        self.ItemObject = DecPcdObject(RawData.Filename)
 | 
						|
        #
 | 
						|
        # Used to check duplicate token
 | 
						|
        # Key is token space and token number (integer), value is C name
 | 
						|
        #
 | 
						|
        self.TokenMap = {}
 | 
						|
 | 
						|
    def _ParseItem(self):
 | 
						|
        Line = self._RawData.CurrentLine
 | 
						|
        TokenList = Line.split(DT.TAB_VALUE_SPLIT)
 | 
						|
        if len(TokenList) < 4:
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_PCD_SPLIT)
 | 
						|
 | 
						|
        #
 | 
						|
        # Token space guid C name
 | 
						|
        #
 | 
						|
        PcdName = GetSplitValueList(TokenList[0], DT.TAB_SPLIT)
 | 
						|
        if len(PcdName) != 2 or PcdName[0] == '' or PcdName[1] == '':
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_PCD_NAME)
 | 
						|
 | 
						|
        Guid = PcdName[0]
 | 
						|
        if not IsValidToken(CVAR_PATTERN, Guid):
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_GUID)
 | 
						|
 | 
						|
        #
 | 
						|
        # PCD C name
 | 
						|
        #
 | 
						|
        CName = PcdName[1]
 | 
						|
        if not IsValidToken(CVAR_PATTERN, CName):
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_PCDCNAME)
 | 
						|
 | 
						|
        self._CheckReDefine(Guid + DT.TAB_SPLIT + CName)
 | 
						|
 | 
						|
        #
 | 
						|
        # Default value, may be C array, string or number
 | 
						|
        #
 | 
						|
        Data = DT.TAB_VALUE_SPLIT.join(TokenList[1:-2]).strip()
 | 
						|
 | 
						|
        #
 | 
						|
        # PCD data type
 | 
						|
        #
 | 
						|
        DataType = TokenList[-2].strip()
 | 
						|
        Valid, Cause = IsValidPcdDatum(DataType, Data)
 | 
						|
        if not Valid:
 | 
						|
            self._LoggerError(Cause)
 | 
						|
        PcdType = self._RawData.CurrentScope[0][0]
 | 
						|
        if PcdType == DT.TAB_PCDS_FEATURE_FLAG_NULL.upper() and DataType != 'BOOLEAN':
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_PCD_FEATUREFLAG)
 | 
						|
        #
 | 
						|
        # Token value is the last element in list.
 | 
						|
        #
 | 
						|
        Token = TokenList[-1].strip()
 | 
						|
        if not IsValidToken(PCD_TOKEN_PATTERN, Token):
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN % Token)
 | 
						|
        elif not Token.startswith('0x') and not Token.startswith('0X'):
 | 
						|
            if int(Token) > 4294967295:
 | 
						|
                self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN_INT % Token)
 | 
						|
            Token = '0x%x' % int(Token)
 | 
						|
 | 
						|
        IntToken = int(Token, 0)
 | 
						|
        if (Guid, IntToken) in self.TokenMap:
 | 
						|
            if self.TokenMap[Guid, IntToken] != CName:
 | 
						|
                self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN_UNIQUE%(Token))
 | 
						|
        else:
 | 
						|
            self.TokenMap[Guid, IntToken] = CName
 | 
						|
 | 
						|
        Item = DecPcdItemObject(Guid, CName, Data, DataType, Token)
 | 
						|
        self.ItemObject.AddItem(Item, self._RawData.CurrentScope)
 | 
						|
        return Item
 | 
						|
 | 
						|
## _DecGuid
 | 
						|
#
 | 
						|
# Parse GUID, PPI, Protocol section
 | 
						|
#
 | 
						|
class _DecGuid(_DecBase):
 | 
						|
    def __init__(self, RawData):
 | 
						|
        _DecBase.__init__(self, RawData)
 | 
						|
        self.GuidObj = DecGuidObject(RawData.Filename)
 | 
						|
        self.PpiObj = DecPpiObject(RawData.Filename)
 | 
						|
        self.ProtocolObj = DecProtocolObject(RawData.Filename)
 | 
						|
        self.ObjectDict = \
 | 
						|
        {
 | 
						|
            DT.TAB_GUIDS.upper()     :   self.GuidObj,
 | 
						|
            DT.TAB_PPIS.upper()      :   self.PpiObj,
 | 
						|
            DT.TAB_PROTOCOLS.upper() :   self.ProtocolObj
 | 
						|
        }
 | 
						|
 | 
						|
    def GetDataObject(self):
 | 
						|
        if self._RawData.CurrentScope:
 | 
						|
            return self.ObjectDict[self._RawData.CurrentScope[0][0]]
 | 
						|
        return None
 | 
						|
 | 
						|
    def GetGuidObject(self):
 | 
						|
        return self.GuidObj
 | 
						|
 | 
						|
    def GetPpiObject(self):
 | 
						|
        return self.PpiObj
 | 
						|
 | 
						|
    def GetProtocolObject(self):
 | 
						|
        return self.ProtocolObj
 | 
						|
 | 
						|
    def _ParseItem(self):
 | 
						|
        Line = self._RawData.CurrentLine
 | 
						|
        TokenList = GetSplitValueList(Line, DT.TAB_EQUAL_SPLIT, 1)
 | 
						|
        if len(TokenList) < 2:
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_CGUID)
 | 
						|
        if TokenList[0] == '':
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_CGUID_NAME)
 | 
						|
        if TokenList[1] == '':
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_CGUID_GUID)
 | 
						|
        if not IsValidToken(CVAR_PATTERN, TokenList[0]):
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_GUID)
 | 
						|
 | 
						|
        self._CheckReDefine(TokenList[0])
 | 
						|
 | 
						|
        if TokenList[1][0] != '{':
 | 
						|
            if not CheckGuidRegFormat(TokenList[1]):
 | 
						|
                self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGGUID)
 | 
						|
            GuidString = TokenList[1]
 | 
						|
        else:
 | 
						|
            #
 | 
						|
            # Convert C format GUID to GUID string and Simple error check
 | 
						|
            #
 | 
						|
            GuidString = GuidStructureStringToGuidString(TokenList[1])
 | 
						|
            if TokenList[1][0] != '{' or TokenList[1][-1] != '}' or GuidString == '':
 | 
						|
                self._LoggerError(ST.ERR_DECPARSE_CGUID_GUIDFORMAT)
 | 
						|
 | 
						|
            #
 | 
						|
            # Check C format GUID
 | 
						|
            #
 | 
						|
            if not IsValidCFormatGuid(TokenList[1]):
 | 
						|
                self._LoggerError(ST.ERR_DECPARSE_CGUID_GUIDFORMAT)
 | 
						|
 | 
						|
        Item = DecGuidItemObject(TokenList[0], TokenList[1], GuidString)
 | 
						|
        ItemObject = self.ObjectDict[self._RawData.CurrentScope[0][0]]
 | 
						|
        ItemObject.AddItem(Item, self._RawData.CurrentScope)
 | 
						|
        return Item
 | 
						|
 | 
						|
## _DecUserExtension
 | 
						|
#
 | 
						|
# Parse user extension section
 | 
						|
#
 | 
						|
class _DecUserExtension(_DecBase):
 | 
						|
    def __init__(self, RawData):
 | 
						|
        _DecBase.__init__(self, RawData)
 | 
						|
        self.ItemObject = DecUserExtensionObject(RawData.Filename)
 | 
						|
        self._Headers = []
 | 
						|
        self._CurItems = []
 | 
						|
 | 
						|
    def BlockStart(self):
 | 
						|
        self._CurItems = []
 | 
						|
        for Header in self._RawData.CurrentScope:
 | 
						|
            if Header in self._Headers:
 | 
						|
                self._LoggerError(ST.ERR_DECPARSE_UE_DUPLICATE)
 | 
						|
            else:
 | 
						|
                self._Headers.append(Header)
 | 
						|
 | 
						|
            for Item in self._CurItems:
 | 
						|
                if Item.UserId == Header[1] and Item.IdString == Header[2]:
 | 
						|
                    Item.ArchAndModuleType.append(Header[3])
 | 
						|
                    break
 | 
						|
            else:
 | 
						|
                Item = DecUserExtensionItemObject()
 | 
						|
                Item.UserId = Header[1]
 | 
						|
                Item.IdString = Header[2]
 | 
						|
                Item.ArchAndModuleType.append(Header[3])
 | 
						|
                self._CurItems.append(Item)
 | 
						|
                self.ItemObject.AddItem(Item, None)
 | 
						|
        self._LocalMacro = {}
 | 
						|
 | 
						|
    def _ParseItem(self):
 | 
						|
        Line = self._RawData.CurrentLine
 | 
						|
        Item = None
 | 
						|
        for Item in self._CurItems:
 | 
						|
            if Item.UserString:
 | 
						|
                Item.UserString = '\n'.join([Item.UserString, Line])
 | 
						|
            else:
 | 
						|
                Item.UserString = Line
 | 
						|
        return Item
 | 
						|
 | 
						|
## Dec
 | 
						|
#
 | 
						|
# Top dec parser
 | 
						|
#
 | 
						|
class Dec(_DecBase, _DecComments):
 | 
						|
    def __init__(self, DecFile, Parse = True):
 | 
						|
        try:
 | 
						|
            Content = ConvertSpecialChar(open(DecFile, 'r').readlines())
 | 
						|
        except BaseException:
 | 
						|
            Logger.Error(TOOL_NAME, FILE_OPEN_FAILURE, File=DecFile,
 | 
						|
                         ExtraData=ST.ERR_DECPARSE_FILEOPEN % DecFile)
 | 
						|
 | 
						|
        #
 | 
						|
        # Pre-parser for Private section
 | 
						|
        #
 | 
						|
        self._Private = ''
 | 
						|
        __IsFoundPrivate = False
 | 
						|
        NewContent = []
 | 
						|
        for Line in Content:
 | 
						|
            Line = Line.strip()
 | 
						|
            if Line.startswith(DT.TAB_SECTION_START) and Line.endswith(DT.TAB_PRIVATE + DT.TAB_SECTION_END):
 | 
						|
                __IsFoundPrivate = True
 | 
						|
            if Line.startswith(DT.TAB_SECTION_START) and Line.endswith(DT.TAB_SECTION_END)\
 | 
						|
               and not Line.endswith(DT.TAB_PRIVATE + DT.TAB_SECTION_END):
 | 
						|
                __IsFoundPrivate = False
 | 
						|
            if __IsFoundPrivate:
 | 
						|
                self._Private += Line + '\r'
 | 
						|
            if not __IsFoundPrivate:
 | 
						|
                NewContent.append(Line + '\r')
 | 
						|
 | 
						|
        RawData = FileContent(DecFile, NewContent)
 | 
						|
 | 
						|
        _DecComments.__init__(self)
 | 
						|
        _DecBase.__init__(self, RawData)
 | 
						|
 | 
						|
        self.BinaryHeadComment = []
 | 
						|
        self.PcdErrorCommentDict = {}
 | 
						|
 | 
						|
        self._Define    = _DecDefine(RawData)
 | 
						|
        self._Include   = _DecInclude(RawData)
 | 
						|
        self._Guid      = _DecGuid(RawData)
 | 
						|
        self._LibClass  = _DecLibraryclass(RawData)
 | 
						|
        self._Pcd       = _DecPcd(RawData)
 | 
						|
        self._UserEx    = _DecUserExtension(RawData)
 | 
						|
 | 
						|
        #
 | 
						|
        # DEC file supported data types (one type per section)
 | 
						|
        #
 | 
						|
        self._SectionParser = {
 | 
						|
            DT.TAB_DEC_DEFINES.upper()                     :   self._Define,
 | 
						|
            DT.TAB_INCLUDES.upper()                        :   self._Include,
 | 
						|
            DT.TAB_LIBRARY_CLASSES.upper()                 :   self._LibClass,
 | 
						|
            DT.TAB_GUIDS.upper()                           :   self._Guid,
 | 
						|
            DT.TAB_PPIS.upper()                            :   self._Guid,
 | 
						|
            DT.TAB_PROTOCOLS.upper()                       :   self._Guid,
 | 
						|
            DT.TAB_PCDS_FIXED_AT_BUILD_NULL.upper()        :   self._Pcd,
 | 
						|
            DT.TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper()   :   self._Pcd,
 | 
						|
            DT.TAB_PCDS_FEATURE_FLAG_NULL.upper()          :   self._Pcd,
 | 
						|
            DT.TAB_PCDS_DYNAMIC_NULL.upper()               :   self._Pcd,
 | 
						|
            DT.TAB_PCDS_DYNAMIC_EX_NULL.upper()            :   self._Pcd,
 | 
						|
            DT.TAB_USER_EXTENSIONS.upper()                 :   self._UserEx
 | 
						|
        }
 | 
						|
 | 
						|
        if Parse:
 | 
						|
            self.ParseDecComment()
 | 
						|
            self.Parse()
 | 
						|
            #
 | 
						|
            # Parsing done, check required fields
 | 
						|
            #
 | 
						|
            self.CheckRequiredFields()
 | 
						|
 | 
						|
    def CheckRequiredFields(self):
 | 
						|
        for SectionParser in self._SectionParser.values():
 | 
						|
            if not SectionParser.CheckRequiredFields():
 | 
						|
                return False
 | 
						|
        return True
 | 
						|
 | 
						|
    ##
 | 
						|
    # Parse DEC file
 | 
						|
    #
 | 
						|
    def ParseDecComment(self):
 | 
						|
        IsFileHeader = False
 | 
						|
        IsBinaryHeader = False
 | 
						|
        FileHeaderLineIndex = -1
 | 
						|
        BinaryHeaderLineIndex = -1
 | 
						|
        TokenSpaceGuidCName = ''
 | 
						|
 | 
						|
        #
 | 
						|
        # Parse PCD error comment section
 | 
						|
        #
 | 
						|
        while not self._RawData.IsEndOfFile():
 | 
						|
            self._RawData.CurrentLine = self._RawData.GetNextLine()
 | 
						|
            if self._RawData.CurrentLine.startswith(DT.TAB_COMMENT_SPLIT) and \
 | 
						|
                DT.TAB_SECTION_START in self._RawData.CurrentLine and \
 | 
						|
                DT.TAB_SECTION_END in self._RawData.CurrentLine:
 | 
						|
                self._RawData.CurrentLine = self._RawData.CurrentLine.replace(DT.TAB_COMMENT_SPLIT, '').strip()
 | 
						|
 | 
						|
                if self._RawData.CurrentLine[0] == DT.TAB_SECTION_START and \
 | 
						|
                    self._RawData.CurrentLine[-1] == DT.TAB_SECTION_END:
 | 
						|
                    RawSection = self._RawData.CurrentLine[1:-1].strip()
 | 
						|
                    if RawSection.upper().startswith(DT.TAB_PCD_ERROR.upper()+'.'):
 | 
						|
                        TokenSpaceGuidCName = RawSection.split(DT.TAB_PCD_ERROR+'.')[1].strip()
 | 
						|
                        continue
 | 
						|
 | 
						|
            if TokenSpaceGuidCName and self._RawData.CurrentLine.startswith(DT.TAB_COMMENT_SPLIT):
 | 
						|
                self._RawData.CurrentLine = self._RawData.CurrentLine.replace(DT.TAB_COMMENT_SPLIT, '').strip()
 | 
						|
                if self._RawData.CurrentLine != '':
 | 
						|
                    if DT.TAB_VALUE_SPLIT not in self._RawData.CurrentLine:
 | 
						|
                        self._LoggerError(ST.ERR_DECPARSE_PCDERRORMSG_MISS_VALUE_SPLIT)
 | 
						|
 | 
						|
                    PcdErrorNumber, PcdErrorMsg = GetSplitValueList(self._RawData.CurrentLine, DT.TAB_VALUE_SPLIT, 1)
 | 
						|
                    PcdErrorNumber = ParsePcdErrorCode(PcdErrorNumber, self._RawData.Filename, self._RawData.LineIndex)
 | 
						|
                    if not PcdErrorMsg.strip():
 | 
						|
                        self._LoggerError(ST.ERR_DECPARSE_PCD_MISS_ERRORMSG)
 | 
						|
 | 
						|
                    self.PcdErrorCommentDict[(TokenSpaceGuidCName, PcdErrorNumber)] = PcdErrorMsg.strip()
 | 
						|
            else:
 | 
						|
                TokenSpaceGuidCName = ''
 | 
						|
 | 
						|
        self._RawData.LineIndex = 0
 | 
						|
        self._RawData.CurrentLine = ''
 | 
						|
        self._RawData.NextLine = ''
 | 
						|
 | 
						|
        while not self._RawData.IsEndOfFile():
 | 
						|
            Line, Comment = CleanString(self._RawData.GetNextLine())
 | 
						|
 | 
						|
            #
 | 
						|
            # Header must be pure comment
 | 
						|
            #
 | 
						|
            if Line != '':
 | 
						|
                self._RawData.UndoNextLine()
 | 
						|
                break
 | 
						|
 | 
						|
            if Comment and Comment.startswith(DT.TAB_SPECIAL_COMMENT) and Comment.find(DT.TAB_HEADER_COMMENT) > 0 \
 | 
						|
                and not Comment[2:Comment.find(DT.TAB_HEADER_COMMENT)].strip():
 | 
						|
                IsFileHeader = True
 | 
						|
                IsBinaryHeader = False
 | 
						|
                FileHeaderLineIndex = self._RawData.LineIndex
 | 
						|
 | 
						|
            #
 | 
						|
            # Get license information before '@file'
 | 
						|
            #
 | 
						|
            if not IsFileHeader and not IsBinaryHeader and Comment and Comment.startswith(DT.TAB_COMMENT_SPLIT) and \
 | 
						|
            DT.TAB_BINARY_HEADER_COMMENT not in Comment:
 | 
						|
                self._HeadComment.append((Comment, self._RawData.LineIndex))
 | 
						|
 | 
						|
            if Comment and IsFileHeader and \
 | 
						|
            not(Comment.startswith(DT.TAB_SPECIAL_COMMENT) \
 | 
						|
            and Comment.find(DT.TAB_BINARY_HEADER_COMMENT) > 0):
 | 
						|
                self._HeadComment.append((Comment, self._RawData.LineIndex))
 | 
						|
            #
 | 
						|
            # Double '#' indicates end of header comments
 | 
						|
            #
 | 
						|
            if (not Comment or Comment == DT.TAB_SPECIAL_COMMENT) and IsFileHeader:
 | 
						|
                IsFileHeader = False
 | 
						|
                continue
 | 
						|
 | 
						|
            if Comment and Comment.startswith(DT.TAB_SPECIAL_COMMENT) \
 | 
						|
            and Comment.find(DT.TAB_BINARY_HEADER_COMMENT) > 0:
 | 
						|
                IsBinaryHeader = True
 | 
						|
                IsFileHeader = False
 | 
						|
                BinaryHeaderLineIndex = self._RawData.LineIndex
 | 
						|
 | 
						|
            if Comment and IsBinaryHeader:
 | 
						|
                self.BinaryHeadComment.append((Comment, self._RawData.LineIndex))
 | 
						|
            #
 | 
						|
            # Double '#' indicates end of header comments
 | 
						|
            #
 | 
						|
            if (not Comment or Comment == DT.TAB_SPECIAL_COMMENT) and IsBinaryHeader:
 | 
						|
                IsBinaryHeader = False
 | 
						|
                break
 | 
						|
 | 
						|
            if FileHeaderLineIndex > -1 and not IsFileHeader and not IsBinaryHeader:
 | 
						|
                break
 | 
						|
 | 
						|
        if FileHeaderLineIndex > BinaryHeaderLineIndex and FileHeaderLineIndex > -1 and BinaryHeaderLineIndex > -1:
 | 
						|
            self._LoggerError(ST.ERR_BINARY_HEADER_ORDER)
 | 
						|
 | 
						|
        if FileHeaderLineIndex == -1:
 | 
						|
#            self._LoggerError(ST.ERR_NO_SOURCE_HEADER)
 | 
						|
            Logger.Error(TOOL_NAME, FORMAT_INVALID,
 | 
						|
                         ST.ERR_NO_SOURCE_HEADER,
 | 
						|
                         File=self._RawData.Filename)
 | 
						|
        return
 | 
						|
 | 
						|
    def _StopCurrentParsing(self, Line):
 | 
						|
        return False
 | 
						|
 | 
						|
    def _ParseItem(self):
 | 
						|
        self._SectionHeaderParser()
 | 
						|
        if len(self._RawData.CurrentScope) == 0:
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_SECTION_EMPTY)
 | 
						|
        SectionObj = self._SectionParser[self._RawData.CurrentScope[0][0]]
 | 
						|
        SectionObj.BlockStart()
 | 
						|
        SectionObj.Parse()
 | 
						|
        return SectionObj.GetDataObject()
 | 
						|
 | 
						|
    def _UserExtentionSectionParser(self):
 | 
						|
        self._RawData.CurrentScope = []
 | 
						|
        ArchList = set()
 | 
						|
        Section = self._RawData.CurrentLine[1:-1]
 | 
						|
        Par = ParserHelper(Section, self._RawData.Filename)
 | 
						|
        while not Par.End():
 | 
						|
            #
 | 
						|
            # User extention
 | 
						|
            #
 | 
						|
            Token = Par.GetToken()
 | 
						|
            if Token.upper() != DT.TAB_USER_EXTENSIONS.upper():
 | 
						|
                self._LoggerError(ST.ERR_DECPARSE_SECTION_UE)
 | 
						|
            UserExtension = Token.upper()
 | 
						|
            Par.AssertChar(DT.TAB_SPLIT, ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)
 | 
						|
 | 
						|
            #
 | 
						|
            # UserID
 | 
						|
            #
 | 
						|
            Token = Par.GetToken()
 | 
						|
            if not IsValidUserId(Token):
 | 
						|
                self._LoggerError(ST.ERR_DECPARSE_SECTION_UE_USERID)
 | 
						|
            UserId = Token
 | 
						|
            Par.AssertChar(DT.TAB_SPLIT, ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)
 | 
						|
            #
 | 
						|
            # IdString
 | 
						|
            #
 | 
						|
            Token = Par.GetToken()
 | 
						|
            if not IsValidIdString(Token):
 | 
						|
                self._LoggerError(ST.ERR_DECPARSE_SECTION_UE_IDSTRING)
 | 
						|
            IdString = Token
 | 
						|
            Arch = 'COMMON'
 | 
						|
            if Par.Expect(DT.TAB_SPLIT):
 | 
						|
                Token = Par.GetToken()
 | 
						|
                Arch = Token.upper()
 | 
						|
                if not IsValidArch(Arch):
 | 
						|
                    self._LoggerError(ST.ERR_DECPARSE_ARCH)
 | 
						|
            ArchList.add(Arch)
 | 
						|
            if [UserExtension, UserId, IdString, Arch] not in \
 | 
						|
                self._RawData.CurrentScope:
 | 
						|
                self._RawData.CurrentScope.append(
 | 
						|
                    [UserExtension, UserId, IdString, Arch]
 | 
						|
                )
 | 
						|
            if not Par.Expect(DT.TAB_COMMA_SPLIT):
 | 
						|
                break
 | 
						|
            elif Par.End():
 | 
						|
                self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMA)
 | 
						|
        Par.AssertEnd(ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)
 | 
						|
        if 'COMMON' in ArchList and len(ArchList) > 1:
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMON)
 | 
						|
 | 
						|
    ## Section header parser
 | 
						|
    #
 | 
						|
    # The section header is always in following format:
 | 
						|
    #
 | 
						|
    # [section_name.arch<.platform|module_type>]
 | 
						|
    #
 | 
						|
    def _SectionHeaderParser(self):
 | 
						|
        if self._RawData.CurrentLine[0] != DT.TAB_SECTION_START or self._RawData.CurrentLine[-1] != DT.TAB_SECTION_END:
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_SECTION_IDENTIFY)
 | 
						|
 | 
						|
        RawSection = self._RawData.CurrentLine[1:-1].strip().upper()
 | 
						|
        #
 | 
						|
        # Check defines section which is only allowed to occur once and
 | 
						|
        # no arch can be followed
 | 
						|
        #
 | 
						|
        if RawSection.startswith(DT.TAB_DEC_DEFINES.upper()):
 | 
						|
            if RawSection != DT.TAB_DEC_DEFINES.upper():
 | 
						|
                self._LoggerError(ST.ERR_DECPARSE_DEFINE_SECNAME)
 | 
						|
        #
 | 
						|
        # Check user extension section
 | 
						|
        #
 | 
						|
        if RawSection.startswith(DT.TAB_USER_EXTENSIONS.upper()):
 | 
						|
            return self._UserExtentionSectionParser()
 | 
						|
        self._RawData.CurrentScope = []
 | 
						|
        SectionNames = []
 | 
						|
        ArchList = set()
 | 
						|
        for Item in GetSplitValueList(RawSection, DT.TAB_COMMA_SPLIT):
 | 
						|
            if Item == '':
 | 
						|
                self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBEMPTY % self._RawData.CurrentLine)
 | 
						|
 | 
						|
            ItemList = GetSplitValueList(Item, DT.TAB_SPLIT)
 | 
						|
            #
 | 
						|
            # different types of PCD are permissible in one section
 | 
						|
            #
 | 
						|
            SectionName = ItemList[0]
 | 
						|
            if SectionName not in self._SectionParser:
 | 
						|
                self._LoggerError(ST.ERR_DECPARSE_SECTION_UNKNOW % SectionName)
 | 
						|
            if SectionName not in SectionNames:
 | 
						|
                SectionNames.append(SectionName)
 | 
						|
            #
 | 
						|
            # In DEC specification, all section headers have at most two part:
 | 
						|
            # SectionName.Arch except UserExtension
 | 
						|
            #
 | 
						|
            if len(ItemList) > 2:
 | 
						|
                self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBTOOMANY % Item)
 | 
						|
 | 
						|
            if DT.TAB_PCDS_FEATURE_FLAG_NULL.upper() in SectionNames and len(SectionNames) > 1:
 | 
						|
                self._LoggerError(ST.ERR_DECPARSE_SECTION_FEATUREFLAG % DT.TAB_PCDS_FEATURE_FLAG_NULL)
 | 
						|
            #
 | 
						|
            # S1 is always Arch
 | 
						|
            #
 | 
						|
            if len(ItemList) > 1:
 | 
						|
                Str1 = ItemList[1]
 | 
						|
                if not IsValidArch(Str1):
 | 
						|
                    self._LoggerError(ST.ERR_DECPARSE_ARCH)
 | 
						|
            else:
 | 
						|
                Str1 = 'COMMON'
 | 
						|
            ArchList.add(Str1)
 | 
						|
 | 
						|
            if [SectionName, Str1] not in self._RawData.CurrentScope:
 | 
						|
                self._RawData.CurrentScope.append([SectionName, Str1])
 | 
						|
        #
 | 
						|
        # 'COMMON' must not be used with specific ARCHs at the same section
 | 
						|
        #
 | 
						|
        if 'COMMON' in ArchList and len(ArchList) > 1:
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMON)
 | 
						|
        if len(SectionNames) == 0:
 | 
						|
            self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBEMPTY % self._RawData.CurrentLine)
 | 
						|
        if len(SectionNames) != 1:
 | 
						|
            for Sec in SectionNames:
 | 
						|
                if not Sec.startswith(DT.TAB_PCDS.upper()):
 | 
						|
                    self._LoggerError(ST.ERR_DECPARSE_SECTION_NAME % str(SectionNames))
 | 
						|
 | 
						|
    def GetDefineSectionMacro(self):
 | 
						|
        return self._Define.GetLocalMacro()
 | 
						|
    def GetDefineSectionObject(self):
 | 
						|
        return self._Define.GetDataObject()
 | 
						|
    def GetIncludeSectionObject(self):
 | 
						|
        return self._Include.GetDataObject()
 | 
						|
    def GetGuidSectionObject(self):
 | 
						|
        return self._Guid.GetGuidObject()
 | 
						|
    def GetProtocolSectionObject(self):
 | 
						|
        return self._Guid.GetProtocolObject()
 | 
						|
    def GetPpiSectionObject(self):
 | 
						|
        return self._Guid.GetPpiObject()
 | 
						|
    def GetLibraryClassSectionObject(self):
 | 
						|
        return self._LibClass.GetDataObject()
 | 
						|
    def GetPcdSectionObject(self):
 | 
						|
        return self._Pcd.GetDataObject()
 | 
						|
    def GetUserExtensionSectionObject(self):
 | 
						|
        return self._UserEx.GetDataObject()
 | 
						|
    def GetPackageSpecification(self):
 | 
						|
        return self._Define.GetDataObject().GetPackageSpecification()
 | 
						|
    def GetPackageName(self):
 | 
						|
        return self._Define.GetDataObject().GetPackageName()
 | 
						|
    def GetPackageGuid(self):
 | 
						|
        return self._Define.GetDataObject().GetPackageGuid()
 | 
						|
    def GetPackageVersion(self):
 | 
						|
        return self._Define.GetDataObject().GetPackageVersion()
 | 
						|
    def GetPackageUniFile(self):
 | 
						|
        return self._Define.GetDataObject().GetPackageUniFile()
 | 
						|
    def GetPrivateSections(self):
 | 
						|
        return self._Private
 |