## @file
# This file is used to define class objects of [Defines] section for INF file. 
# It will consumed by InfParser
#
# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials are licensed and made available 
# under the terms and conditions of the BSD License which accompanies this 
# distribution. The full text of the license may be found at 
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

'''
InfDefineObject
'''

import os
import re

from Logger import StringTable as ST
from Logger import ToolError
from Library import GlobalData 
from Library import DataType as DT
from Library.StringUtils import GetSplitValueList
from Library.Misc import CheckGuidRegFormat
from Library.Misc import Sdict
from Library.Misc import ConvPathFromAbsToRel
from Library.Misc import ValidateUNIFilePath
from Library.ExpressionValidate import IsValidFeatureFlagExp 
from Library.ParserValidate import IsValidWord
from Library.ParserValidate import IsValidInfMoudleType  
from Library.ParserValidate import IsValidHex  
from Library.ParserValidate import IsValidHexVersion  
from Library.ParserValidate import IsValidDecVersion  
from Library.ParserValidate import IsValidCVariableName 
from Library.ParserValidate import IsValidBoolType 
from Library.ParserValidate import IsValidPath
from Library.ParserValidate import IsValidFamily
from Library.ParserValidate import IsValidIdentifier
from Library.ParserValidate import IsValidDecVersionVal
from Object.Parser.InfCommonObject import InfLineCommentObject
from Object.Parser.InfCommonObject import CurrentLine
from Object.Parser.InfCommonObject import InfSectionCommonDef
from Object.Parser.InfMisc import ErrorInInf
from Object.Parser.InfDefineCommonObject import InfDefineLibraryItem
from Object.Parser.InfDefineCommonObject import InfDefineEntryPointItem
from Object.Parser.InfDefineCommonObject import InfDefineUnloadImageItem
from Object.Parser.InfDefineCommonObject import InfDefineConstructorItem 
from Object.Parser.InfDefineCommonObject import InfDefineDestructorItem

class InfDefSectionOptionRomInfo():
    def __init__(self):
        self.PciVendorId                = None
        self.PciDeviceId                = None
        self.PciClassCode               = None
        self.PciRevision                = None
        self.PciCompress                = None
        self.CurrentLine                = ['', -1, '']
    def SetPciVendorId(self, PciVendorId, Comments):
        #
        # Value has been set before.
        #
        if self.PciVendorId is not None:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_PCI_VENDOR_ID),
                       LineInfo=self.CurrentLine)
            return False           
        #
        # The PciVendorId should be hex string.  
        #
        if (IsValidHex(PciVendorId)):
            self.PciVendorId = InfDefMember()
            self.PciVendorId.SetValue(PciVendorId)
            self.PciVendorId.Comments = Comments
            return True
        else:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(PciVendorId),
                       LineInfo=self.CurrentLine)
            return False
        
    def GetPciVendorId(self):
        return self.PciVendorId
    
    def SetPciDeviceId(self, PciDeviceId, Comments):
        #
        # Value has been set before.
        #
        if self.PciDeviceId is not None:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_PCI_DEVICE_ID),
                       LineInfo=self.CurrentLine)
            return False         
        #
        # The PciDeviceId should be hex string.  
        #
        if (IsValidHex(PciDeviceId)):
            self.PciDeviceId = InfDefMember()
            self.PciDeviceId.SetValue(PciDeviceId)
            self.PciDeviceId.Comments = Comments            
            return True
        else:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(PciDeviceId),
                       LineInfo=self.CurrentLine)
            return False
        
    def GetPciDeviceId(self):
        return self.PciDeviceId
   
    def SetPciClassCode(self, PciClassCode, Comments):
        #
        # Value has been set before.
        #
        if self.PciClassCode is not None:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_PCI_CLASS_CODE),
                       LineInfo=self.CurrentLine)
            return False        
        #
        # The PciClassCode should be 4 bytes hex string.  
        #
        if (IsValidHex(PciClassCode)):
            self.PciClassCode = InfDefMember()
            self.PciClassCode.SetValue(PciClassCode)
            self.PciClassCode.Comments = Comments
            return True
        else:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%\
                       (PciClassCode),
                       LineInfo=self.CurrentLine)
            return False
        
    def GetPciClassCode(self):
        return self.PciClassCode
    
    def SetPciRevision(self, PciRevision, Comments):
        #
        # Value has been set before.
        #
        if self.PciRevision is not None:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_PCI_REVISION),
                       LineInfo=self.CurrentLine)
            return False          
        #
        # The PciRevision should be 4 bytes hex string.  
        #
        if (IsValidHex(PciRevision)):
            self.PciRevision = InfDefMember()
            self.PciRevision.SetValue(PciRevision)
            self.PciRevision.Comments = Comments
            return True
        else:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(PciRevision),
                       LineInfo=self.CurrentLine)
            return False
        
    def GetPciRevision(self):
        return self.PciRevision
    
    def SetPciCompress(self, PciCompress, Comments):
        #
        # Value has been set before.
        #
        if self.PciCompress is not None:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_PCI_COMPRESS),
                       LineInfo=self.CurrentLine)
            return False
        
        #
        # The PciCompress should be 'TRUE' or 'FALSE'.  
        #
        if (PciCompress == 'TRUE' or PciCompress == 'FALSE'):
            self.PciCompress = InfDefMember()
            self.PciCompress.SetValue(PciCompress)
            self.PciCompress.Comments = Comments
            return True
        else:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(PciCompress),
                       LineInfo=self.CurrentLine)
            return False        
    def GetPciCompress(self):
        return self.PciCompress        
##
# INF [Define] section Object
#
class InfDefSection(InfDefSectionOptionRomInfo):
    def __init__(self):
        self.BaseName                   = None
        self.FileGuid                   = None
        self.ModuleType                 = None
        self.ModuleUniFileName          = None
        self.InfVersion                 = None
        self.EdkReleaseVersion          = None
        self.UefiSpecificationVersion   = None
        self.PiSpecificationVersion     = None
        self.LibraryClass               = []
        self.Package                    = None
        self.VersionString              = None
        self.PcdIsDriver                = None
        self.EntryPoint                 = []
        self.UnloadImages               = []
        self.Constructor                = []
        self.Destructor                 = []
        self.Shadow                     = None
        self.CustomMakefile             = []
        self.Specification              = []
        self.UefiHiiResourceSection     = None
        self.DpxSource                  = []
        self.CurrentLine                = ['', -1, '']
        InfDefSectionOptionRomInfo.__init__(self)

    ## SetHeadComment
    #
    # @param BaseName: BaseName
    #    
    def SetBaseName(self, BaseName, Comments):
        #
        # Value has been set before.
        #
        if self.BaseName is not None:    
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_BASE_NAME),
                       LineInfo=self.CurrentLine)
            return False     
        if not (BaseName == '' or BaseName is None):
            if IsValidWord(BaseName) and not BaseName.startswith("_"):
                self.BaseName = InfDefMember()
                self.BaseName.SetValue(BaseName)
                self.BaseName.Comments = Comments
                return True
            else:
                ErrorInInf(ST.ERR_INF_PARSER_DEFINE_NAME_INVALID%(BaseName),
                           LineInfo=self.CurrentLine)
                return False

    ## GetBaseName
    #          
    def GetBaseName(self):
        return self.BaseName

    ## SetFileGuid
    #
    # @param FileGuid: FileGuid
    #        
    def SetFileGuid(self, FileGuid, Comments):
        #
        # Value has been set before.
        #
        if self.FileGuid is not None:    
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
                       %(DT.TAB_INF_DEFINES_FILE_GUID),
                       LineInfo=self.CurrentLine)
            return False                        
        #
        # Do verification of GUID content/format
        #          
        if (CheckGuidRegFormat(FileGuid)):
            self.FileGuid = InfDefMember()
            self.FileGuid.SetValue(FileGuid)
            self.FileGuid.Comments = Comments
            return True
        else:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_GUID_INVALID%(FileGuid),
                       LineInfo=self.CurrentLine)
            return False

    ## GetFileGuid
    #            
    def GetFileGuid(self):
        return self.FileGuid

    ## SetModuleType
    #
    # @param ModuleType: ModuleType
    #     
    def SetModuleType(self, ModuleType, Comments):
        #
        # Value has been set before.
        #
        if self.ModuleType is not None:    
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
                       %(DT.TAB_INF_DEFINES_MODULE_TYPE),
                       LineInfo=self.CurrentLine)
            return False           
        #
        # Valid Module Type or not
        #
        if (IsValidInfMoudleType(ModuleType)):
            self.ModuleType = InfDefMember()
            self.ModuleType.SetValue(ModuleType)
            self.ModuleType.CurrentLine = CurrentLine()
            self.ModuleType.CurrentLine.SetLineNo(self.CurrentLine[1])
            self.ModuleType.CurrentLine.SetLineString(self.CurrentLine[2])
            self.ModuleType.CurrentLine.SetFileName(self.CurrentLine[0])
            self.ModuleType.Comments = Comments            
            return True
        else:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_MODULETYPE_INVALID%\
                       (ModuleType),
                       LineInfo=self.CurrentLine)
            return False

    ## GetModuleType
    #                       
    def GetModuleType(self):
        return self.ModuleType
    
    ## SetModuleUniFileName
    #
    # @param ModuleUniFileName: ModuleUniFileName
    #     
    def SetModuleUniFileName(self, ModuleUniFileName, Comments):
        if Comments:
            pass
        if self.ModuleUniFileName is not None:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_MODULE_UNI_FILE),
                       LineInfo=self.CurrentLine)
        self.ModuleUniFileName = ModuleUniFileName

    ## GetModuleType
    #                       
    def GetModuleUniFileName(self):
        return self.ModuleUniFileName
    
    ## SetInfVersion
    #
    # @param InfVersion: InfVersion
    #            
    def SetInfVersion(self, InfVersion, Comments):
        #
        # Value has been set before.
        #
        if self.InfVersion is not None:    
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
                       %(DT.TAB_INF_DEFINES_INF_VERSION),
                       LineInfo=self.CurrentLine)
            return False        
        #
        # The InfVersion should be 4 bytes hex string. 
        #
        if (IsValidHex(InfVersion)):
            if (InfVersion < '0x00010005'):
                ErrorInInf(ST.ERR_INF_PARSER_NOT_SUPPORT_EDKI_INF,
                           ErrorCode=ToolError.EDK1_INF_ERROR,
                           LineInfo=self.CurrentLine)
        elif IsValidDecVersionVal(InfVersion):
            if (InfVersion < 65541):
                ErrorInInf(ST.ERR_INF_PARSER_NOT_SUPPORT_EDKI_INF,
                           ErrorCode=ToolError.EDK1_INF_ERROR,
                           LineInfo=self.CurrentLine)
        else:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(InfVersion),
                       LineInfo=self.CurrentLine)
            return False

        self.InfVersion = InfDefMember()
        self.InfVersion.SetValue(InfVersion)
        self.InfVersion.Comments = Comments
        return True

    ## GetInfVersion
    #                     
    def GetInfVersion(self):
        return self.InfVersion

    ## SetEdkReleaseVersion
    #
    # @param EdkReleaseVersion: EdkReleaseVersion
    #      
    def SetEdkReleaseVersion(self, EdkReleaseVersion, Comments):
        #
        # Value has been set before.
        #
        if self.EdkReleaseVersion is not None:    
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
                       %(DT.TAB_INF_DEFINES_EDK_RELEASE_VERSION),
                       LineInfo=self.CurrentLine)
            return False          
        #
        # The EdkReleaseVersion should be 4 bytes hex string.  
        #
        if IsValidHexVersion(EdkReleaseVersion) or \
           IsValidDecVersionVal(EdkReleaseVersion):
            self.EdkReleaseVersion = InfDefMember()
            self.EdkReleaseVersion.SetValue(EdkReleaseVersion)
            self.EdkReleaseVersion.Comments = Comments
            return True
        else:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID\
                       %(EdkReleaseVersion),
                       LineInfo=self.CurrentLine)
            return False

    ## GetEdkReleaseVersion
    #        
    def GetEdkReleaseVersion(self):
        return self.EdkReleaseVersion 

    ## SetUefiSpecificationVersion
    #
    # @param UefiSpecificationVersion: UefiSpecificationVersion
    #         
    def SetUefiSpecificationVersion(self, UefiSpecificationVersion, Comments):
        #
        # Value has been set before.
        #
        if self.UefiSpecificationVersion is not None:    
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
                       %(DT.TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION),
                       LineInfo=self.CurrentLine)
            return False            
        #
        # The EdkReleaseVersion should be 4 bytes hex string.  
        #
        if IsValidHexVersion(UefiSpecificationVersion) or \
           IsValidDecVersionVal(UefiSpecificationVersion):
            self.UefiSpecificationVersion = InfDefMember()
            self.UefiSpecificationVersion.SetValue(UefiSpecificationVersion)
            self.UefiSpecificationVersion.Comments = Comments
            return True
        else:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID\
                       %(UefiSpecificationVersion),
                       LineInfo=self.CurrentLine)
            return False

    ## GetUefiSpecificationVersion
    #           
    def GetUefiSpecificationVersion(self):
        return self.UefiSpecificationVersion            

    ## SetPiSpecificationVersion
    #
    # @param PiSpecificationVersion: PiSpecificationVersion
    #         
    def SetPiSpecificationVersion(self, PiSpecificationVersion, Comments):
        #
        # Value has been set before.
        #
        if self.PiSpecificationVersion is not None:    
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
                       %(DT.TAB_INF_DEFINES_PI_SPECIFICATION_VERSION),
                       LineInfo=self.CurrentLine)
            return False         
        #
        # The EdkReleaseVersion should be 4 bytes hex string.  
        #
        if IsValidHexVersion(PiSpecificationVersion) or \
           IsValidDecVersionVal(PiSpecificationVersion):
            self.PiSpecificationVersion = InfDefMember()
            self.PiSpecificationVersion.SetValue(PiSpecificationVersion)
            self.PiSpecificationVersion.Comments = Comments
            return True
        else:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID\
                       %(PiSpecificationVersion),
                       LineInfo=self.CurrentLine)            
            return False

    ## GetPiSpecificationVersion
    #      
    def GetPiSpecificationVersion(self):
        return self.PiSpecificationVersion

    ## SetLibraryClass
    #
    # @param LibraryClass: LibraryClass
    #            
    def SetLibraryClass(self, LibraryClass, Comments):
        ValueList = GetSplitValueList(LibraryClass)
        Name = ValueList[0]         
        if IsValidWord(Name):
            InfDefineLibraryItemObj = InfDefineLibraryItem()
            InfDefineLibraryItemObj.SetLibraryName(Name)            
            InfDefineLibraryItemObj.Comments = Comments
            if len(ValueList) == 2:
                Type = ValueList[1]
                TypeList = GetSplitValueList(Type, ' ')
                TypeList = [Type for Type in TypeList if Type != '']
                for Item in TypeList:
                    if Item not in DT.MODULE_LIST:
                        ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Item),
                                   LineInfo=self.CurrentLine)
                        return False
                InfDefineLibraryItemObj.SetTypes(TypeList)                    
            self.LibraryClass.append(InfDefineLibraryItemObj)               
        else:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Name),
                       LineInfo=self.CurrentLine)
            return False
        
        return True
    
    def GetLibraryClass(self):
        return self.LibraryClass
  
    def SetVersionString(self, VersionString, Comments):
        #
        # Value has been set before.
        #
        if self.VersionString is not None:    
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
                       %(DT.TAB_INF_DEFINES_VERSION_STRING),
                       LineInfo=self.CurrentLine)
            return False
        if not IsValidDecVersion(VersionString):
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID\
                       %(VersionString),
                       LineInfo=self.CurrentLine) 
        self.VersionString = InfDefMember()
        self.VersionString.SetValue(VersionString)
        self.VersionString.Comments = Comments
        return True

        
    def GetVersionString(self):
        return self.VersionString
    
    def SetPcdIsDriver(self, PcdIsDriver, Comments):
        #
        # Value has been set before.
        #
        if self.PcdIsDriver is not None:    
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
                       %(DT.TAB_INF_DEFINES_PCD_IS_DRIVER),
                       LineInfo=self.CurrentLine)
            return False         
        if PcdIsDriver == 'PEI_PCD_DRIVER' or PcdIsDriver == 'DXE_PCD_DRIVER':
            self.PcdIsDriver = InfDefMember()
            self.PcdIsDriver.SetValue(PcdIsDriver)
            self.PcdIsDriver.Comments = Comments
            return True
        else:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(PcdIsDriver),
                       LineInfo=self.CurrentLine)
            return False
    
    def GetPcdIsDriver(self):
        return self.PcdIsDriver
    
    #
    # SetEntryPoint
    #    
    def SetEntryPoint(self, EntryPoint, Comments):
        #
        # It can be a list
        #
        ValueList = []
        TokenList = GetSplitValueList(EntryPoint, DT.TAB_VALUE_SPLIT)
        ValueList[0:len(TokenList)] = TokenList        
        InfDefineEntryPointItemObj = InfDefineEntryPointItem()
        if not IsValidCVariableName(ValueList[0]):
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%\
                       (ValueList[0]),
                       LineInfo=self.CurrentLine)
        InfDefineEntryPointItemObj.SetCName(ValueList[0])
        if len(ValueList) == 2:
            if ValueList[1].strip() == '':
                ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%\
                           (ValueList[1]),
                           LineInfo=self.CurrentLine)
            #
            # Validate FFE    
            #
            FeatureFlagRtv = IsValidFeatureFlagExp(ValueList[1].strip())
            if not FeatureFlagRtv[0]:
                ErrorInInf(ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%\
                           (FeatureFlagRtv[1]),
                           LineInfo=self.CurrentLine)       
            InfDefineEntryPointItemObj.SetFeatureFlagExp(ValueList[1])     
        if len(ValueList) > 2:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(EntryPoint),
                       LineInfo=self.CurrentLine)
        InfDefineEntryPointItemObj.Comments = Comments             
        self.EntryPoint.append(InfDefineEntryPointItemObj)       
        
    def GetEntryPoint(self):
        return self.EntryPoint

    #
    # SetUnloadImages
    #      
    def SetUnloadImages(self, UnloadImages, Comments):
        #
        # It can be a list
        #
        ValueList = []
        TokenList = GetSplitValueList(UnloadImages, DT.TAB_VALUE_SPLIT)
        ValueList[0:len(TokenList)] = TokenList        
        InfDefineUnloadImageItemObj = InfDefineUnloadImageItem()
        if not IsValidCVariableName(ValueList[0]):
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[0]),
                       LineInfo=self.CurrentLine)
        InfDefineUnloadImageItemObj.SetCName(ValueList[0])
        if len(ValueList) == 2:
            if ValueList[1].strip() == '':
                ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[1]),
                           LineInfo=self.CurrentLine)
            #
            # Validate FFE    
            #
            FeatureFlagRtv = IsValidFeatureFlagExp(ValueList[1].strip())
            if not FeatureFlagRtv[0]:
                ErrorInInf(ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[1]),
                           LineInfo=self.CurrentLine)
            InfDefineUnloadImageItemObj.SetFeatureFlagExp(ValueList[1])
                
        if len(ValueList) > 2:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(UnloadImages),
                       LineInfo=self.CurrentLine)
        InfDefineUnloadImageItemObj.Comments = Comments
        self.UnloadImages.append(InfDefineUnloadImageItemObj)
        
    def GetUnloadImages(self):
        return self.UnloadImages

    #
    # SetConstructor
    #          
    def SetConstructor(self, Constructor, Comments):
        #
        # It can be a list
        #
        ValueList = []
        TokenList = GetSplitValueList(Constructor, DT.TAB_VALUE_SPLIT)
        ValueList[0:len(TokenList)] = TokenList        
        InfDefineConstructorItemObj = InfDefineConstructorItem()
        if not IsValidCVariableName(ValueList[0]):
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[0]),
                       LineInfo=self.CurrentLine)
        InfDefineConstructorItemObj.SetCName(ValueList[0])
        if len(ValueList) >= 2:
            ModList = GetSplitValueList(ValueList[1], ' ')
            if ValueList[1].strip() == '':
                ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[1]),
                           LineInfo=self.CurrentLine)
            for ModItem in ModList:
                if ModItem not in DT.MODULE_LIST:
                    ErrorInInf(ST.ERR_INF_PARSER_DEFINE_MODULETYPE_INVALID%(ModItem),
                               LineInfo=self.CurrentLine)
            InfDefineConstructorItemObj.SetSupModList(ModList)             
        if len(ValueList) == 3:
            if ValueList[2].strip() == '':
                ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[2]),
                           LineInfo=self.CurrentLine)
            #
            # Validate FFE    
            #
            FeatureFlagRtv = IsValidFeatureFlagExp(ValueList[2].strip())
            if not FeatureFlagRtv[0]:
                ErrorInInf(ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[2]),
                           LineInfo=self.CurrentLine)
            InfDefineConstructorItemObj.SetFeatureFlagExp(ValueList[2])
                    
        if len(ValueList) > 3:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Constructor),
                       LineInfo=self.CurrentLine)
        InfDefineConstructorItemObj.Comments = Comments    
        self.Constructor.append(InfDefineConstructorItemObj)     
           
    def GetConstructor(self):
        return self.Constructor

    #
    # SetDestructor
    #      
    def SetDestructor(self, Destructor, Comments):
        #
        # It can be a list and only 1 set to TRUE
        #        
        ValueList = []
        TokenList = GetSplitValueList(Destructor, DT.TAB_VALUE_SPLIT)
        ValueList[0:len(TokenList)] = TokenList        
        InfDefineDestructorItemObj = InfDefineDestructorItem()
        if not IsValidCVariableName(ValueList[0]):
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[0]),
                       LineInfo=self.CurrentLine)
        InfDefineDestructorItemObj.SetCName(ValueList[0])
        if len(ValueList) >= 2:
            ModList = GetSplitValueList(ValueList[1].strip(), ' ')
            if ValueList[1].strip() == '':
                ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[1]),
                           LineInfo=self.CurrentLine)
            for ModItem in ModList:
                if ModItem not in DT.MODULE_LIST:
                    ErrorInInf(ST.ERR_INF_PARSER_DEFINE_MODULETYPE_INVALID%(ModItem),
                               LineInfo=self.CurrentLine)
            InfDefineDestructorItemObj.SetSupModList(ModList)          
        if len(ValueList) == 3:
            if ValueList[2].strip() == '':
                ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[2]),
                           LineInfo=self.CurrentLine)
            #
            # Validate FFE    
            #
            FeatureFlagRtv = IsValidFeatureFlagExp(ValueList[2].strip())
            if not FeatureFlagRtv[0]:
                ErrorInInf(ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[1]),
                           LineInfo=self.CurrentLine)
            InfDefineDestructorItemObj.SetFeatureFlagExp(ValueList[2])
        
        if len(ValueList) > 3:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Destructor),
                       LineInfo=self.CurrentLine)
            
        InfDefineDestructorItemObj.Comments = Comments 
        self.Destructor.append(InfDefineDestructorItemObj) 
        
    def GetDestructor(self):
        return self.Destructor
    
    def SetShadow(self, Shadow, Comments):
        #
        # Value has been set before.
        #
        if self.Shadow is not None:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_SHADOW),
                       LineInfo=self.CurrentLine)
            return False          
        if (IsValidBoolType(Shadow)):
            self.Shadow = InfDefMember()
            self.Shadow.SetValue(Shadow)
            self.Shadow.Comments = Comments
            return True
        else:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Shadow),
                       LineInfo=self.CurrentLine)
            return False
    def GetShadow(self):
        return self.Shadow

    #
    # <Family>               ::=  {"MSFT"} {"GCC"}
    # <CustomMake>           ::=  [<Family> "|"] <Filename>
    #
    def SetCustomMakefile(self, CustomMakefile, Comments):
        if not (CustomMakefile == '' or CustomMakefile is None):
            ValueList = GetSplitValueList(CustomMakefile)
            if len(ValueList) == 1:
                FileName = ValueList[0]
                Family = ''
            else:
                Family = ValueList[0]
                FileName = ValueList[1]
            Family = Family.strip()
            if Family != '':
                if not IsValidFamily(Family):
                    ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Family),
                               LineInfo=self.CurrentLine)
                    return False
            #
            # The MakefileName specified file should exist
            #
            IsValidFileFlag = False
            ModulePath = os.path.split(self.CurrentLine[0])[0]
            if IsValidPath(FileName, ModulePath):
                IsValidFileFlag = True           
            else:
                ErrorInInf(ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID%(FileName),
                           LineInfo=self.CurrentLine)
                return False
            if IsValidFileFlag:
                FileName = ConvPathFromAbsToRel(FileName, GlobalData.gINF_MODULE_DIR)                     
                self.CustomMakefile.append((Family, FileName, Comments))
                IsValidFileFlag = False
            return True
        else:
            return False
        
    def GetCustomMakefile(self):
        return self.CustomMakefile
    
    #
    # ["SPEC" <Spec> <EOL>]*{0,}
    # <Spec>                 ::=  <Word> "=" <VersionVal>
    # <VersionVal>           ::=  {<HexVersion>] {<DecVersion>}
    # <HexNumber>            ::=  "0x" [<HexDigit>]{1,}
    # <DecVersion>           ::=  (0-9){1,} ["." (0-9){1,2}]
    #
    def SetSpecification(self, Specification, Comments):
        #
        # Valid the value of Specification
        #
        __ValueList = []
        TokenList = GetSplitValueList(Specification, DT.TAB_EQUAL_SPLIT, 1)
        __ValueList[0:len(TokenList)] = TokenList
        if len(__ValueList) != 2:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_NO_NAME + ' Or ' + ST.ERR_INF_PARSER_DEFINE_ITEM_NO_VALUE,
                       LineInfo=self.CurrentLine)
        Name = __ValueList[0].strip()
        Version = __ValueList[1].strip()   
        if IsValidIdentifier(Name):
            if IsValidDecVersion(Version):
                self.Specification.append((Name, Version, Comments))
                return True
            else:
                ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Version),
                           LineInfo=self.CurrentLine)
                return False
        else:                  
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Name),
                       LineInfo=self.CurrentLine)
            return False    
        return True

    def GetSpecification(self):
        return self.Specification
    
    #
    # [<UefiHiiResource> <EOL>]{0,1}
    # <UefiHiiResource>      ::=  "UEFI_HII_RESOURCE_SECTION" "=" <BoolType>
    #
    def SetUefiHiiResourceSection(self, UefiHiiResourceSection, Comments):
        #
        # Value has been set before.
        #
        if self.UefiHiiResourceSection is not None:
            ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND
                       %(DT.TAB_INF_DEFINES_UEFI_HII_RESOURCE_SECTION),
                       LineInfo=self.CurrentLine)
            return False           
        if not (UefiHiiResourceSection == '' or UefiHiiResourceSection is None):
            if (IsValidBoolType(UefiHiiResourceSection)):
                self.UefiHiiResourceSection = InfDefMember()
                self.UefiHiiResourceSection.SetValue(UefiHiiResourceSection)
                self.UefiHiiResourceSection.Comments = Comments                
                return True
            else:
                ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(UefiHiiResourceSection),
                           LineInfo=self.CurrentLine)
                return False
        else:
            return False
            
    def GetUefiHiiResourceSection(self):
        return self.UefiHiiResourceSection
    
    def SetDpxSource(self, DpxSource, Comments):    
        #
        # The MakefileName specified file should exist
        #
        IsValidFileFlag = False
        ModulePath = os.path.split(self.CurrentLine[0])[0]
        if IsValidPath(DpxSource, ModulePath):
            IsValidFileFlag = True           
        else:
            ErrorInInf(ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID%(DpxSource),
                       LineInfo=self.CurrentLine)
            return False
        if IsValidFileFlag:
            DpxSource = ConvPathFromAbsToRel(DpxSource, 
                            GlobalData.gINF_MODULE_DIR)     
            self.DpxSource.append((DpxSource, Comments))
            IsValidFileFlag = False
        return True               

    def GetDpxSource(self):
        return self.DpxSource

gFUNCTION_MAPPING_FOR_DEFINE_SECTION = {
    #
    # Required Fields
    #
    DT.TAB_INF_DEFINES_BASE_NAME                   : InfDefSection.SetBaseName,
    DT.TAB_INF_DEFINES_FILE_GUID                   : InfDefSection.SetFileGuid,
    DT.TAB_INF_DEFINES_MODULE_TYPE                 : InfDefSection.SetModuleType,
    #
    # Required by EDKII style INF file
    #
    DT.TAB_INF_DEFINES_INF_VERSION                 : InfDefSection.SetInfVersion,
    #
    # Optional Fields
    #        
    DT.TAB_INF_DEFINES_MODULE_UNI_FILE             : InfDefSection.SetModuleUniFileName,
    DT.TAB_INF_DEFINES_EDK_RELEASE_VERSION         : InfDefSection.SetEdkReleaseVersion,
    DT.TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION  : InfDefSection.SetUefiSpecificationVersion,
    DT.TAB_INF_DEFINES_PI_SPECIFICATION_VERSION    : InfDefSection.SetPiSpecificationVersion,
    DT.TAB_INF_DEFINES_LIBRARY_CLASS               : InfDefSection.SetLibraryClass,
    DT.TAB_INF_DEFINES_VERSION_STRING              : InfDefSection.SetVersionString,
    DT.TAB_INF_DEFINES_PCD_IS_DRIVER               : InfDefSection.SetPcdIsDriver,
    DT.TAB_INF_DEFINES_ENTRY_POINT                 : InfDefSection.SetEntryPoint,
    DT.TAB_INF_DEFINES_UNLOAD_IMAGE                : InfDefSection.SetUnloadImages,
    DT.TAB_INF_DEFINES_CONSTRUCTOR                 : InfDefSection.SetConstructor,
    DT.TAB_INF_DEFINES_DESTRUCTOR                  : InfDefSection.SetDestructor,
    DT.TAB_INF_DEFINES_SHADOW                      : InfDefSection.SetShadow,
    DT.TAB_INF_DEFINES_PCI_VENDOR_ID               : InfDefSection.SetPciVendorId,
    DT.TAB_INF_DEFINES_PCI_DEVICE_ID               : InfDefSection.SetPciDeviceId,
    DT.TAB_INF_DEFINES_PCI_CLASS_CODE              : InfDefSection.SetPciClassCode,   
    DT.TAB_INF_DEFINES_PCI_REVISION                : InfDefSection.SetPciRevision,
    DT.TAB_INF_DEFINES_PCI_COMPRESS                : InfDefSection.SetPciCompress,
    DT.TAB_INF_DEFINES_CUSTOM_MAKEFILE             : InfDefSection.SetCustomMakefile,  
    DT.TAB_INF_DEFINES_SPEC                        : InfDefSection.SetSpecification,
    DT.TAB_INF_DEFINES_UEFI_HII_RESOURCE_SECTION   : InfDefSection.SetUefiHiiResourceSection,
    DT.TAB_INF_DEFINES_DPX_SOURCE                  : InfDefSection.SetDpxSource
}

## InfDefMember
#
#
class InfDefMember():
    def __init__(self, Name='', Value=''):
        self.Comments = InfLineCommentObject()
        self.Name  = Name
        self.Value = Value
        self.CurrentLine = CurrentLine()
    def GetName(self):
        return self.Name
    def SetName(self, Name):
        self.Name = Name
    def GetValue(self):
        return self.Value
    def SetValue(self, Value):
        self.Value = Value
    
## InfDefObject
#
#
class InfDefObject(InfSectionCommonDef):
    def __init__(self):
        self.Defines = Sdict()
        InfSectionCommonDef.__init__(self)
    def SetDefines(self, DefineContent, Arch = None):
        #
        # Validate Arch
        #
        HasFoundInfVersionFalg = False
        LineInfo = ['', -1, '']
        ArchListString = ' '.join(Arch)  
        #
        # Parse Define items.
        #
        for InfDefMemberObj in DefineContent:
            ProcessFunc = None
            Name = InfDefMemberObj.GetName()
            Value = InfDefMemberObj.GetValue()
            if Name == DT.TAB_INF_DEFINES_MODULE_UNI_FILE:
                ValidateUNIFilePath(Value)
                Value = os.path.join(os.path.dirname(InfDefMemberObj.CurrentLine.FileName), Value)
                if not os.path.isfile(Value) or not os.path.exists(Value):
                    LineInfo[0] = InfDefMemberObj.CurrentLine.GetFileName()
                    LineInfo[1] = InfDefMemberObj.CurrentLine.GetLineNo()
                    LineInfo[2] = InfDefMemberObj.CurrentLine.GetLineString()
                    ErrorInInf(ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID%(Name),
                                   LineInfo=LineInfo)
            InfLineCommentObj = InfLineCommentObject()
            InfLineCommentObj.SetHeaderComments(InfDefMemberObj.Comments.GetHeaderComments())
            InfLineCommentObj.SetTailComments(InfDefMemberObj.Comments.GetTailComments())
            if Name == 'COMPONENT_TYPE':
                ErrorInInf(ST.ERR_INF_PARSER_NOT_SUPPORT_EDKI_INF,
                           ErrorCode=ToolError.EDK1_INF_ERROR,
                           RaiseError=True)
            if Name == DT.TAB_INF_DEFINES_INF_VERSION:
                HasFoundInfVersionFalg = True  
            if not (Name == '' or Name is None):
                #
                # Process "SPEC" Keyword definition.
                #
                ReName = re.compile(r"SPEC ", re.DOTALL)
                if ReName.match(Name):
                    SpecValue = Name[Name.find("SPEC") + len("SPEC"):].strip()
                    Name = "SPEC"
                    Value = SpecValue + " = " + Value
                if ArchListString in self.Defines:
                    DefineList = self.Defines[ArchListString]                 
                    LineInfo[0] = InfDefMemberObj.CurrentLine.GetFileName()
                    LineInfo[1] = InfDefMemberObj.CurrentLine.GetLineNo()
                    LineInfo[2] = InfDefMemberObj.CurrentLine.GetLineString()
                    DefineList.CurrentLine = LineInfo
                    #
                    # Found the process function from mapping table.
                    #
                    if Name not in gFUNCTION_MAPPING_FOR_DEFINE_SECTION.keys():
                        ErrorInInf(ST.ERR_INF_PARSER_DEFINE_SECTION_KEYWORD_INVALID%(Name),
                                   LineInfo=LineInfo)                           
                    else:
                        ProcessFunc = gFUNCTION_MAPPING_FOR_DEFINE_SECTION[Name]
                    if (ProcessFunc is not None):
                        ProcessFunc(DefineList, Value, InfLineCommentObj)
                    self.Defines[ArchListString] = DefineList
                else:
                    DefineList = InfDefSection()
                    LineInfo[0] = InfDefMemberObj.CurrentLine.GetFileName()
                    LineInfo[1] = InfDefMemberObj.CurrentLine.GetLineNo()
                    LineInfo[2] = InfDefMemberObj.CurrentLine.GetLineString()
                    DefineList.CurrentLine = LineInfo
                    #
                    # Found the process function from mapping table.
                    #
                    if Name not in gFUNCTION_MAPPING_FOR_DEFINE_SECTION.keys():
                        ErrorInInf(ST.ERR_INF_PARSER_DEFINE_SECTION_KEYWORD_INVALID%(Name),
                                   LineInfo=LineInfo)
                    #
                    # Found the process function from mapping table.
                    #                    
                    else:
                        ProcessFunc = gFUNCTION_MAPPING_FOR_DEFINE_SECTION[Name]
                    if (ProcessFunc is not None):
                        ProcessFunc(DefineList, Value, InfLineCommentObj)
                    self.Defines[ArchListString] = DefineList
        #
        # After set, check whether INF_VERSION defined.
        #
        if not HasFoundInfVersionFalg:
            ErrorInInf(ST.ERR_INF_PARSER_NOT_SUPPORT_EDKI_INF,
                       ErrorCode=ToolError.EDK1_INF_ERROR,
                       RaiseError=True) 
        return True
    
    def GetDefines(self):
        return self.Defines                      
        
