## @file
# This file is used to define class objects of [Defines] section for INF file. 
# It will consumed by InfParser
#
# Copyright (c) 2011 - 2014, 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.String 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 != 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 != 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 != 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 != 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 != 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 != 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 == 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 != 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 != 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 != 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 != 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 != 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 != 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 != 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 != 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 != 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 != 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 == 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 != 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 == 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 == 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 self.Defines.has_key(ArchListString):
                    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 != 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 != 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                      
        
