## @file DecPomAlignment.py
# This file contained the adapter for convert INF parser object to POM Object
#
# 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.
#

'''
DecPomAlignment
'''

##
# Import Modules
#
import os.path
from os import sep
import platform

import re
import Logger.Log as Logger
from Logger import StringTable as ST
from Logger.ToolError import UPT_MUL_DEC_ERROR
from Logger.ToolError import FORMAT_INVALID

from Library.Parsing import NormPath
from Library.DataType import ARCH_LIST
from Library.DataType import TAB_GUIDS
from Library.DataType import TAB_PROTOCOLS
from Library.DataType import TAB_PPIS
from Library.DataType import TAB_DEC_DEFINES_PACKAGE_NAME
from Library.DataType import TAB_DEC_DEFINES_PACKAGE_GUID
from Library.DataType import TAB_DEC_DEFINES_PACKAGE_VERSION
from Library.DataType import TAB_DEC_DEFINES_DEC_SPECIFICATION
from Library.DataType import TAB_DEC_DEFINES_PKG_UNI_FILE
from Library.DataType import TAB_ARCH_COMMON
from Library.DataType import TAB_INCLUDES
from Library.DataType import TAB_LIBRARY_CLASSES
from Library.DataType import TAB_PCDS
from Library.DataType import TAB_PCDS_FIXED_AT_BUILD_NULL
from Library.DataType import TAB_PCDS_PATCHABLE_IN_MODULE_NULL
from Library.DataType import TAB_PCDS_FEATURE_FLAG_NULL
from Library.DataType import TAB_PCDS_DYNAMIC_EX_NULL
from Library.DataType import TAB_PCDS_DYNAMIC_NULL
from Library.DataType import TAB_PTR_TYPE_PCD
from Library.DataType import ITEM_UNDEFINED
from Library.DataType import TAB_DEC_BINARY_ABSTRACT
from Library.DataType import TAB_DEC_BINARY_DESCRIPTION
from Library.DataType import TAB_LANGUAGE_EN_US
from Library.DataType import TAB_BINARY_HEADER_IDENTIFIER
from Library.DataType import TAB_BINARY_HEADER_USERID
from Library.DataType import TAB_LANGUAGE_EN_X
from Library.DataType import TAB_LANGUAGE_EN
from Library.DataType import TAB_STR_TOKENCNAME
from Library.DataType import TAB_STR_TOKENPROMPT
from Library.DataType import TAB_STR_TOKENHELP
from Library.DataType import TAB_STR_TOKENERR
from Library.DataType import TAB_HEX_START
from Library.DataType import TAB_SPLIT
from Library.CommentParsing import ParseHeaderCommentSection
from Library.CommentParsing import ParseGenericComment
from Library.CommentParsing import ParseDecPcdGenericComment
from Library.CommentParsing import ParseDecPcdTailComment
from Library.Misc import GetFiles
from Library.Misc import Sdict
from Library.Misc import GetRelativePath
from Library.Misc import PathClass
from Library.Misc import ValidateUNIFilePath
from Library.UniClassObject import UniFileClassObject
from Library.UniClassObject import ConvertSpecialUnicodes
from Library.UniClassObject import GetLanguageCode1766
from Library.ParserValidate import IsValidPath
from Parser.DecParser import Dec
from Object.POM.PackageObject import PackageObject
from Object.POM.CommonObject import UserExtensionObject
from Object.POM.CommonObject import IncludeObject
from Object.POM.CommonObject import GuidObject
from Object.POM.CommonObject import ProtocolObject
from Object.POM.CommonObject import PpiObject
from Object.POM.CommonObject import LibraryClassObject
from Object.POM.CommonObject import PcdObject
from Object.POM.CommonObject import TextObject
from Object.POM.CommonObject import MiscFileObject
from Object.POM.CommonObject import FileObject


## DecPomAlignment
#
# Inherited from PackageObject
#
class DecPomAlignment(PackageObject):
    def __init__(self, Filename, WorkspaceDir = None, CheckMulDec = False):
        PackageObject.__init__(self)
        self.UserExtensions = ''
        self.WorkspaceDir = WorkspaceDir
        self.SupArchList = ARCH_LIST
        self.CheckMulDec = CheckMulDec
        self.DecParser = None
        self.UniFileClassObject = None
        self.PcdDefaultValueDict = {}
        
        #
        # Load Dec file
        #
        self.LoadDecFile(Filename)
        
        #
        # Transfer to Package Object if IsToPackage is True
        #
        self.DecToPackage()
    
    ## Load Dec file
    #
    # Load the file if it exists
    #
    # @param Filename:  Input value for filename of Dec file
    #
    def LoadDecFile(self, Filename):
        #
        # Insert a record for file
        #
        Filename = NormPath(Filename)
        (Path, Name) = os.path.split(Filename)
        self.SetFullPath(Filename)
        self.SetRelaPath(Path)
        self.SetFileName(Name)
        self.SetPackagePath(GetRelativePath(Path, self.WorkspaceDir))   
        self.SetCombinePath(GetRelativePath(Filename, self.WorkspaceDir))
        
        self.DecParser = Dec(Filename)
    
    ## Transfer to Package Object
    # 
    # Transfer all contents of a Dec file to a standard Package Object
    #
    def DecToPackage(self):
        #
        # Init global information for the file
        #
        ContainerFile = self.GetFullPath()
        
        #
        # Generate Package Header
        #
        self.GenPackageHeader(ContainerFile)
        
        #
        # Generate Includes
        #
        self.GenIncludes(ContainerFile)

        #
        # Generate Guids
        #
        self.GenGuidProtocolPpis(TAB_GUIDS, ContainerFile)

        #
        # Generate Protocols
        #
        self.GenGuidProtocolPpis(TAB_PROTOCOLS, ContainerFile)

        #
        # Generate Ppis
        #
        self.GenGuidProtocolPpis(TAB_PPIS, ContainerFile)
        
        #
        # Generate LibraryClasses
        #
        self.GenLibraryClasses(ContainerFile)
        
        #
        # Generate Pcds
        #
        self.GenPcds(ContainerFile)
        
        #
        # Generate Module File list, will be used later on to generate 
        # distribution
        #
        self.GenModuleFileList(ContainerFile)
        
        #
        # Generate user extensions
        #
        self.GenUserExtensions()
        
    ## Generate user extension
    #
    #
    def GenUserExtensions(self):
        UEObj = self.DecParser.GetUserExtensionSectionObject()
        UEList = UEObj.GetAllUserExtensions()
        for Item in UEList:
            if not Item.UserString:
                continue
            UserExtension = UserExtensionObject()
            UserId = Item.UserId
            if UserId.startswith('"') and UserId.endswith('"'):
                UserId = UserId[1:-1]
            UserExtension.SetUserID(UserId)
            Identifier = Item.IdString
            if Identifier.startswith('"') and Identifier.endswith('"'):
                Identifier = Identifier[1:-1]
            #
            # Generate miscellaneous files of DEC file
            #
            if UserId == 'TianoCore' and Identifier == 'ExtraFiles':
                self.GenMiscFiles(Item.UserString)
            UserExtension.SetIdentifier(Identifier)
            UserExtension.SetStatement(Item.UserString)
            UserExtension.SetSupArchList(
                Item.ArchAndModuleType
            )
            self.SetUserExtensionList(
                self.GetUserExtensionList() + [UserExtension]
            )
            
    ## Generate miscellaneous files on DEC file
    #
    #
    def GenMiscFiles(self, Content):
        MiscFileObj = MiscFileObject()
        for Line in Content.splitlines():
            FileName = ''
            if '#' in Line:
                FileName = Line[:Line.find('#')]
            else:
                FileName = Line
            if FileName:
                if IsValidPath(FileName, self.GetRelaPath()):
                    FileObj = FileObject()
                    FileObj.SetURI(FileName)
                    MiscFileObj.SetFileList(MiscFileObj.GetFileList()+[FileObj])
                else:
                    Logger.Error("InfParser", 
                                 FORMAT_INVALID,
                                 ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID%(Line),
                                 File=self.GetFileName(),
                                 ExtraData=Line)   
        self.SetMiscFileList(self.GetMiscFileList()+[MiscFileObj]) 
        
    ## Generate Package Header
    #
    # Gen Package Header of Dec as <Key> = <Value>
    #
    # @param ContainerFile: The Dec file full path 
    #
    def GenPackageHeader(self, ContainerFile):
        Logger.Debug(2, "Generate PackageHeader ...")
        DefinesDict = {}
        
        #
        # Update all defines item in database
        #
        DefObj = self.DecParser.GetDefineSectionObject()
        for Item in DefObj.GetDefines():
            #
            # put items into Dict except for PackageName, Guid, Version, DEC_SPECIFICATION
            #
            SkipItemList = [TAB_DEC_DEFINES_PACKAGE_NAME, \
                TAB_DEC_DEFINES_PACKAGE_GUID, TAB_DEC_DEFINES_PACKAGE_VERSION, \
                TAB_DEC_DEFINES_DEC_SPECIFICATION, TAB_DEC_DEFINES_PKG_UNI_FILE]
            if Item.Key in SkipItemList:
                continue
            DefinesDict['%s = %s' % (Item.Key, Item.Value)] = TAB_ARCH_COMMON

        self.SetBaseName(DefObj.GetPackageName())
        self.SetVersion(DefObj.GetPackageVersion())
#        self.SetName(DefObj.GetPackageName() + ' Version ' + \
#                     DefObj.GetPackageVersion())
        self.SetName(os.path.splitext(self.GetFileName())[0])
        self.SetGuid(DefObj.GetPackageGuid())
        if DefObj.GetPackageUniFile():
            ValidateUNIFilePath(DefObj.GetPackageUniFile())
            self.UniFileClassObject = \
            UniFileClassObject([PathClass(os.path.join(DefObj.GetPackagePath(), DefObj.GetPackageUniFile()))])
        else:
            self.UniFileClassObject = None
     
        if DefinesDict:
            UserExtension = UserExtensionObject()
            UserExtension.SetDefinesDict(DefinesDict)
            UserExtension.SetIdentifier('DefineModifiers')
            UserExtension.SetUserID('EDK2')  
            self.SetUserExtensionList(
                self.GetUserExtensionList() + [UserExtension]
            )

        #
        # Get File header information
        #
        if self.UniFileClassObject:
            Lang = TAB_LANGUAGE_EN_X
        else:
            Lang = TAB_LANGUAGE_EN_US
        Abstract, Description, Copyright, License = \
            ParseHeaderCommentSection(self.DecParser.GetHeadComment(),
                                      ContainerFile)
        if Abstract:
            self.SetAbstract((Lang, Abstract))
        if Description:
            self.SetDescription((Lang, Description))
        if Copyright:
            self.SetCopyright(('', Copyright))
        if License:
            self.SetLicense(('', License))
    
        #
        # Get Binary header information
        #
        if self.DecParser.BinaryHeadComment:
            Abstract, Description, Copyright, License = \
                ParseHeaderCommentSection(self.DecParser.BinaryHeadComment,
                                      ContainerFile, True)
                
            if not Abstract  or not Description or not Copyright or not License:
                Logger.Error('MkPkg',
                             FORMAT_INVALID,
                             ST.ERR_INVALID_BINARYHEADER_FORMAT,
                             ContainerFile)
            else:
                self.SetBinaryHeaderAbstract((Lang, Abstract))
                self.SetBinaryHeaderDescription((Lang, Description))
                self.SetBinaryHeaderCopyright(('', Copyright))
                self.SetBinaryHeaderLicense(('', License))

        BinaryAbstractList = []
        BinaryDescriptionList = []
        
        #Get Binary header from UNI file
        # Initialize the UniStrDict dictionary, top keys are language codes
        UniStrDict = {}
        if self.UniFileClassObject:
            UniStrDict = self.UniFileClassObject.OrderedStringList
            for Lang in UniStrDict:
                for StringDefClassObject in UniStrDict[Lang]:
                    Lang = GetLanguageCode1766(Lang)
                    if StringDefClassObject.StringName == TAB_DEC_BINARY_ABSTRACT:
                        if (Lang, ConvertSpecialUnicodes(StringDefClassObject.StringValue)) \
                        not in self.GetBinaryHeaderAbstract():
                            BinaryAbstractList.append((Lang, ConvertSpecialUnicodes(StringDefClassObject.StringValue)))
                    if StringDefClassObject.StringName == TAB_DEC_BINARY_DESCRIPTION:
                        if (Lang, ConvertSpecialUnicodes(StringDefClassObject.StringValue)) \
                        not in self.GetBinaryHeaderDescription():
                            BinaryDescriptionList.append((Lang, 
                                                          ConvertSpecialUnicodes(StringDefClassObject.StringValue)))
        #Combine Binary header from DEC file and UNI file
        BinaryAbstractList = self.GetBinaryHeaderAbstract() + BinaryAbstractList
        BinaryDescriptionList = self.GetBinaryHeaderDescription() + BinaryDescriptionList
        BinaryCopyrightList = self.GetBinaryHeaderCopyright()
        BinaryLicenseList = self.GetBinaryHeaderLicense()
        #Generate the UserExtensionObject for TianoCore."BinaryHeader"
        if BinaryAbstractList or BinaryDescriptionList or BinaryCopyrightList or BinaryLicenseList:
            BinaryUserExtension = UserExtensionObject()
            BinaryUserExtension.SetBinaryAbstract(BinaryAbstractList)
            BinaryUserExtension.SetBinaryDescription(BinaryDescriptionList)
            BinaryUserExtension.SetBinaryCopyright(BinaryCopyrightList)
            BinaryUserExtension.SetBinaryLicense(BinaryLicenseList)
            BinaryUserExtension.SetIdentifier(TAB_BINARY_HEADER_IDENTIFIER)
            BinaryUserExtension.SetUserID(TAB_BINARY_HEADER_USERID)
            self.SetUserExtensionList(self.GetUserExtensionList() + [BinaryUserExtension])
            
            
    ## GenIncludes
    #
    # Gen Includes of Dec
    # 
    # @param ContainerFile: The Dec file full path 
    #
    def GenIncludes(self, ContainerFile):
        if ContainerFile:
            pass
        Logger.Debug(2, "Generate %s ..." % TAB_INCLUDES)
        IncludesDict = Sdict()

        IncObj = self.DecParser.GetIncludeSectionObject()
        for Item in IncObj.GetAllIncludes():
            IncludePath = os.path.normpath(Item.File)
            if platform.system() != 'Windows' and platform.system() != 'Microsoft':
                IncludePath = IncludePath.replace('\\', '/')
            if IncludePath in IncludesDict:
                if Item.GetArchList() == [TAB_ARCH_COMMON] or IncludesDict[IncludePath] == [TAB_ARCH_COMMON]:
                    IncludesDict[IncludePath] = [TAB_ARCH_COMMON]
                else:
                    IncludesDict[IncludePath] = IncludesDict[IncludePath] + Item.GetArchList()
            else:
                IncludesDict[IncludePath] = Item.GetArchList()
                        
        # 
        # get the  standardIncludeFileList(industry), packageIncludeFileList
        # (others) for PackageObject  
        # 
        PackagePath = os.path.split(self.GetFullPath())[0]
        IncludePathList = \
            [os.path.normpath(Path) + sep for Path in IncludesDict.keys()]
        IncludePathList.sort()
        
        #
        # get a non-overlap set of include path, IncludePathList should be 
        # sorted, and path should be end with path seperator '\'
        #
        NonOverLapList = []
        for Path1 in IncludePathList:
            for Path2 in NonOverLapList:
                if Path1.startswith(Path2):
                    break
            else:
                NonOverLapList.append(Path1)
        #
        # revert the list so the longest path shown first in list, also need
        # to remove the extra path seperator '\'
        # as this list is used to search the supported Arch info
        #
        for IndexN in range (0, len(IncludePathList)):
            IncludePathList[IndexN] = os.path.normpath(IncludePathList[IndexN])
        IncludePathList.sort()            
        IncludePathList.reverse()
        #
        # save the include path list for later usage
        #
        self.SetIncludePathList(IncludePathList)
        StandardIncludeFileList = []
        PackageIncludeFileList = []
        
        IncludeFileList = []
        for Path in NonOverLapList:
            FileList = GetFiles(os.path.join(PackagePath, Path), ['CVS', '.svn'], False)
            IncludeFileList += [os.path.normpath(os.path.join(Path, File)) for File in FileList]
        for Includefile in IncludeFileList:
            ExtName = os.path.splitext(Includefile)[1]
            if ExtName.upper() == '.DEC' and self.CheckMulDec:
                Logger.Error('MkPkg', 
                             UPT_MUL_DEC_ERROR,
                             ST.ERR_MUL_DEC_ERROR%(os.path.dirname(ContainerFile), 
                                                   os.path.basename(ContainerFile),
                                                   Includefile))

            FileCombinePath = os.path.dirname(Includefile)
            Include = IncludeObject()
            for Path in IncludePathList:
                if FileCombinePath.startswith(Path):
                    SupArchList = IncludesDict[Path]
                    break
            Include.SetFilePath(Includefile)
            Include.SetSupArchList(SupArchList)
            if Includefile.find('IndustryStandard') != -1:
                StandardIncludeFileList.append(Include)
            else:
                PackageIncludeFileList.append(Include)            
    
        self.SetStandardIncludeFileList(StandardIncludeFileList)

        #
        # put include path into the PackageIncludeFileList
        #
        PackagePathList = []
        IncObj = self.DecParser.GetIncludeSectionObject()        
        for Item in IncObj.GetAllIncludes():
            IncludePath = Item.File
            Include = IncludeObject()
            Include.SetFilePath(IncludePath)
            Include.SetSupArchList(Item.GetArchList())
            PackagePathList.append(Include)
        self.SetPackageIncludeFileList(PackagePathList + PackageIncludeFileList)
    
    ## GenPpis
    #
    # Gen Ppis of Dec
    # <CName>=<GuidValue>
    #
    # @param ContainerFile: The Dec file full path 
    #
    def GenGuidProtocolPpis(self, Type, ContainerFile):
        if ContainerFile:
            pass
        Logger.Debug(2, "Generate %s ..." % Type)

        Obj = None
        Factory = None
        if Type == TAB_GUIDS:
            Obj = self.DecParser.GetGuidSectionObject()
            def CreateGuidObject():
                Object = GuidObject()
                Object.SetGuidTypeList([])
                Object.SetUsage(None)
                Object.SetName(None)
                return Object
            Factory = CreateGuidObject
        elif Type == TAB_PROTOCOLS:
            Obj = self.DecParser.GetProtocolSectionObject()
            
            def CreateProtocolObject():
                return ProtocolObject()
            Factory = CreateProtocolObject
        elif Type == TAB_PPIS:
            Obj = self.DecParser.GetPpiSectionObject()

            def CreatePpiObject():
                return PpiObject()
            Factory = CreatePpiObject
        else:
            #
            # Should not be here
            #
            return
        
        DeclarationsList = []
        
        #
        # Go through each arch
        #
        for Item in Obj.GetGuidStyleAllItems():
            Name = Item.GuidCName
            Value = Item.GuidString
            HelpTxt = ParseGenericComment(Item.GetHeadComment() + \
                                          Item.GetTailComment())
            
            ListObject = Factory()
            ListObject.SetCName(Name)
            ListObject.SetGuid(Value)
            ListObject.SetSupArchList(Item.GetArchList())
            if HelpTxt:
                if self.UniFileClassObject:
                    HelpTxt.SetLang(TAB_LANGUAGE_EN_X)
                ListObject.SetHelpTextList([HelpTxt])
            
            DeclarationsList.append(ListObject)

        #    
        #GuidTypeList is abstracted from help
        #
        if Type == TAB_GUIDS:
            self.SetGuidList(self.GetGuidList() + DeclarationsList)
        elif Type == TAB_PROTOCOLS:
            self.SetProtocolList(self.GetProtocolList() + DeclarationsList)
        elif Type == TAB_PPIS:
            self.SetPpiList(self.GetPpiList() + DeclarationsList)
    
    ## GenLibraryClasses
    #
    # Gen LibraryClasses of Dec
    # <CName>=<GuidValue>
    #
    # @param ContainerFile: The Dec file full path 
    #
    def GenLibraryClasses(self, ContainerFile):
        if ContainerFile:
            pass
        Logger.Debug(2, "Generate %s ..." % TAB_LIBRARY_CLASSES)
        LibraryClassDeclarations = []
        
        LibObj = self.DecParser.GetLibraryClassSectionObject()
        for Item in LibObj.GetAllLibraryclasses():
            LibraryClass = LibraryClassObject()
            LibraryClass.SetLibraryClass(Item.Libraryclass)
            LibraryClass.SetSupArchList(Item.GetArchList())
            LibraryClass.SetIncludeHeader(Item.File)
            HelpTxt = ParseGenericComment(Item.GetHeadComment() + \
                                          Item.GetTailComment(), None, '@libraryclass')
            if HelpTxt:
                if self.UniFileClassObject:
                    HelpTxt.SetLang(TAB_LANGUAGE_EN_X)
                LibraryClass.SetHelpTextList([HelpTxt])
            LibraryClassDeclarations.append(LibraryClass)
        
        self.SetLibraryClassList(self.GetLibraryClassList() + \
                                 LibraryClassDeclarations)
    
    ## GenPcds
    #
    # Gen Pcds of Dec
    # <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
    #
    # @param ContainerFile: The Dec file full path 
    #
    def GenPcds(self, ContainerFile):
        Logger.Debug(2, "Generate %s ..." % TAB_PCDS)
        PcdObj = self.DecParser.GetPcdSectionObject()
        #
        # Get all Pcds
        #        
        PcdDeclarations = []
        IterList = [
            (TAB_PCDS_FIXED_AT_BUILD_NULL,      'FixedPcd'),
            (TAB_PCDS_PATCHABLE_IN_MODULE_NULL, 'PatchPcd'), 
            (TAB_PCDS_FEATURE_FLAG_NULL,        'FeaturePcd'),
            (TAB_PCDS_DYNAMIC_EX_NULL,          'PcdEx'), 
            (TAB_PCDS_DYNAMIC_NULL,             'Pcd')]
        
        PromptStrList = []
        HelpStrList = []
        PcdErrStrList = []
        # Initialize UniStrDict dictionary, top keys are language codes
        UniStrDict = {}
        StrList = []
        
        Language = ''
        if self.UniFileClassObject:
            Language = TAB_LANGUAGE_EN_X
        else:
            Language = TAB_LANGUAGE_EN_US
            
        if self.UniFileClassObject:
            UniStrDict = self.UniFileClassObject.OrderedStringList
            for Lang in UniStrDict:
                for StringDefClassObject in UniStrDict[Lang]:
                    StrList = StringDefClassObject.StringName.split('_')
                    # StringName format is STR_<TOKENSPACECNAME>_<PCDCNAME>_PROMPT
                    if len(StrList) == 4 and StrList[0] == TAB_STR_TOKENCNAME and StrList[3] == TAB_STR_TOKENPROMPT:
                        PromptStrList.append((GetLanguageCode1766(Lang), StringDefClassObject.StringName, \
                                              StringDefClassObject.StringValue))
                    # StringName format is STR_<TOKENSPACECNAME>_<PCDCNAME>_HELP
                    if len(StrList) == 4 and StrList[0] == TAB_STR_TOKENCNAME and StrList[3] == TAB_STR_TOKENHELP:
                        HelpStrList.append((GetLanguageCode1766(Lang), StringDefClassObject.StringName, \
                                            StringDefClassObject.StringValue))
                    # StringName format is STR_<TOKENSPACECNAME>_ERR_##
                    if len(StrList) == 4 and StrList[0] == TAB_STR_TOKENCNAME and StrList[2] == TAB_STR_TOKENERR:
                        PcdErrStrList.append((GetLanguageCode1766(Lang), StringDefClassObject.StringName, \
                                              StringDefClassObject.StringValue))
        #
        # For each PCD type
        #
        for PcdType, Type in IterList:
            #
            # Go through all archs
            #
            # for Arch in self.SupArchList + [TAB_ARCH_COMMON]:
            #
            for Item in PcdObj.GetPcdsByType(PcdType.upper()):
                PcdDeclaration = GenPcdDeclaration(
                        ContainerFile,
                        (Item.TokenSpaceGuidCName, Item.TokenCName,
                        Item.DefaultValue, Item.DatumType, Item.TokenValue,
                        Type, Item.GetHeadComment(), Item.GetTailComment(),''),
                        Language,
                        self.DecParser.GetDefineSectionMacro()
                        )
                PcdDeclaration.SetSupArchList(Item.GetArchListOfType(PcdType))
                
                #
                # Get PCD error message from PCD error comment section in DEC file
                #
                for PcdErr in PcdDeclaration.GetPcdErrorsList():
                    if (PcdDeclaration.GetTokenSpaceGuidCName(), PcdErr.GetErrorNumber()) \
                        in self.DecParser.PcdErrorCommentDict:
                        Key = (PcdDeclaration.GetTokenSpaceGuidCName(), PcdErr.GetErrorNumber())
                        PcdErr.SetErrorMessageList(PcdErr.GetErrorMessageList() + \
                                                      [(Language, self.DecParser.PcdErrorCommentDict[Key])])
                
                for Index in range(0, len(PromptStrList)):
                    StrNameList = PromptStrList[Index][1].split('_')
                    if StrNameList[1].lower() == Item.TokenSpaceGuidCName.lower() and \
                    StrNameList[2].lower() == Item.TokenCName.lower():
                        TxtObj = TextObject()
                        TxtObj.SetLang(PromptStrList[Index][0])
                        TxtObj.SetString(PromptStrList[Index][2])
                        for Prompt in PcdDeclaration.GetPromptList():
                            if Prompt.GetLang() == TxtObj.GetLang() and \
                                Prompt.GetString() == TxtObj.GetString():
                                break
                        else:
                            PcdDeclaration.SetPromptList(PcdDeclaration.GetPromptList() + [TxtObj])
                        
                for Index in range(0, len(HelpStrList)):
                    StrNameList = HelpStrList[Index][1].split('_')
                    if StrNameList[1].lower() == Item.TokenSpaceGuidCName.lower() and \
                    StrNameList[2].lower() == Item.TokenCName.lower():
                        TxtObj = TextObject()
                        TxtObj.SetLang(HelpStrList[Index][0])
                        TxtObj.SetString(HelpStrList[Index][2])
                        for HelpStrObj in PcdDeclaration.GetHelpTextList():
                            if HelpStrObj.GetLang() == TxtObj.GetLang() and \
                                HelpStrObj.GetString() == TxtObj.GetString():
                                break
                        else:
                            PcdDeclaration.SetHelpTextList(PcdDeclaration.GetHelpTextList() + [TxtObj])

                #
                # Get PCD error message from UNI file
                #
                for Index in range(0, len(PcdErrStrList)):
                    StrNameList = PcdErrStrList[Index][1].split('_')
                    if StrNameList[1].lower() == Item.TokenSpaceGuidCName.lower() and \
                        StrNameList[2].lower() == TAB_STR_TOKENERR.lower():
                        for PcdErr in PcdDeclaration.GetPcdErrorsList():
                            if PcdErr.GetErrorNumber().lower() == (TAB_HEX_START + StrNameList[3]).lower() and \
                                (PcdErrStrList[Index][0], PcdErrStrList[Index][2]) not in PcdErr.GetErrorMessageList():
                                PcdErr.SetErrorMessageList(PcdErr.GetErrorMessageList() + \
                                                            [(PcdErrStrList[Index][0], PcdErrStrList[Index][2])])
                              
                #
                # Check to prevent missing error message if a Pcd has the error code.
                #
                for PcdErr in PcdDeclaration.GetPcdErrorsList():
                    if PcdErr.GetErrorNumber().strip():
                        if not PcdErr.GetErrorMessageList():
                            Logger.Error('UPT',
                                         FORMAT_INVALID,
                                         ST.ERR_DECPARSE_PCD_UNMATCHED_ERRORCODE % PcdErr.GetErrorNumber(),
                                         ContainerFile,
                                         PcdErr.GetLineNum(),
                                         PcdErr.GetFileLine())                        
                    
                PcdDeclarations.append(PcdDeclaration)
        self.SetPcdList(self.GetPcdList() + PcdDeclarations)
        self.CheckPcdValue()
        
    ##
    # Get error message via language
    # @param ErrorMessageList: Error message tuple list the language and its message
    # @param Lang: the language of setting
    # @return: the error message described in the related UNI file
    def GetEnErrorMessage(self, ErrorMessageList):
        if self.FullPath:
            pass
        Lang = TAB_LANGUAGE_EN_US
        for (Language, Message) in ErrorMessageList:
            if Language == Lang:
                return Message
        for (Language, Message) in ErrorMessageList:
            if Language.find(TAB_LANGUAGE_EN) >= 0:
                return Message
        else:
            try:
                return ErrorMessageList[0][1]
            except IndexError:
                return ''
        return ''    
        
    ##
    # Replace the strings for Python eval function.
    # @param ReplaceValue: The string that needs to be replaced. 
    # @return: The string was replaced, then eval function is always making out it.     
    def ReplaceForEval(self, ReplaceValue, IsRange=False, IsExpr=False):
        if self.FullPath:
            pass
        #
        # deal with "NOT EQ", "NOT LT", "NOT GT", "NOT LE", "NOT GE", "NOT NOT" 
        #
        NOTNOT_Pattern = '[\t\s]*NOT[\t\s]+NOT[\t\s]*'
        NOTGE_Pattern = '[\t\s]*NOT[\t\s]+GE[\t\s]*'
        NOTLE_Pattern = '[\t\s]*NOT[\t\s]+LE[\t\s]*'
        NOTGT_Pattern = '[\t\s]*NOT[\t\s]+GT[\t\s]*'
        NOTLT_Pattern = '[\t\s]*NOT[\t\s]+LT[\t\s]*'
        NOTEQ_Pattern = '[\t\s]*NOT[\t\s]+EQ[\t\s]*'
        ReplaceValue = re.compile(NOTNOT_Pattern).sub('', ReplaceValue)
        ReplaceValue = re.compile(NOTLT_Pattern).sub('x >= ', ReplaceValue)
        ReplaceValue = re.compile(NOTGT_Pattern).sub('x <= ', ReplaceValue)
        ReplaceValue = re.compile(NOTLE_Pattern).sub('x > ', ReplaceValue)
        ReplaceValue = re.compile(NOTGE_Pattern).sub('x < ', ReplaceValue)
        ReplaceValue = re.compile(NOTEQ_Pattern).sub('x != ', ReplaceValue)
        
        if IsRange:
            ReplaceValue = ReplaceValue.replace('EQ', 'x ==')
            ReplaceValue = ReplaceValue.replace('LT', 'x <')
            ReplaceValue = ReplaceValue.replace('LE', 'x <=')
            ReplaceValue = ReplaceValue.replace('GT', 'x >')
            ReplaceValue = ReplaceValue.replace('GE', 'x >=')
            ReplaceValue = ReplaceValue.replace('XOR', 'x ^')
        elif IsExpr:
            ReplaceValue = ReplaceValue.replace('EQ', '==')
            ReplaceValue = ReplaceValue.replace('NE', '!=')
            ReplaceValue = ReplaceValue.replace('LT', '<')
            ReplaceValue = ReplaceValue.replace('LE', '<=')
            ReplaceValue = ReplaceValue.replace('GT', '>')
            ReplaceValue = ReplaceValue.replace('GE', '>=')  
            ReplaceValue = ReplaceValue.replace('XOR', '^')  
            
        ReplaceValue = ReplaceValue.replace('AND', 'and')
        ReplaceValue = ReplaceValue.replace('&&', ' and ')
        ReplaceValue = ReplaceValue.replace('xor', '^')
        ReplaceValue = ReplaceValue.replace('OR', 'or')
        ReplaceValue = ReplaceValue.replace('||', ' or ')
        ReplaceValue = ReplaceValue.replace('NOT', 'not')
        if ReplaceValue.find('!') >= 0 and ReplaceValue[ReplaceValue.index('!') + 1] != '=':
            ReplaceValue = ReplaceValue.replace('!', ' not ')        
        if '.' in ReplaceValue:
            Pattern = '[a-zA-Z0-9]{1,}\.[a-zA-Z0-9]{1,}'
            MatchedList = re.findall(Pattern, ReplaceValue)
            for MatchedItem in MatchedList:
                if MatchedItem not in self.PcdDefaultValueDict:
                    Logger.Error("Dec File Parser", FORMAT_INVALID, Message=ST.ERR_DECPARSE_PCD_NODEFINED % MatchedItem,
                                     File=self.FullPath)
                    
                ReplaceValue = ReplaceValue.replace(MatchedItem, self.PcdDefaultValueDict[MatchedItem])

        return ReplaceValue

    ##
    # Check pcd's default value according to the pcd's description
    #
    def CheckPcdValue(self):
        for Pcd in self.GetPcdList():
            self.PcdDefaultValueDict[TAB_SPLIT.join((Pcd.GetTokenSpaceGuidCName(), Pcd.GetCName())).strip()] = \
            Pcd.GetDefaultValue()
        
        for Pcd in self.GetPcdList():
            ValidationExpressions = []
            PcdGuidName = TAB_SPLIT.join((Pcd.GetTokenSpaceGuidCName(), Pcd.GetCName()))
            Valids = Pcd.GetPcdErrorsList()
            for Valid in Valids:
                Expression = Valid.GetExpression()
                if Expression:
                    #
                    # Delete the 'L' prefix of a quoted string, this operation is for eval()
                    #
                    QUOTED_PATTERN = '[\t\s]*L?"[^"]*"'
                    QuotedMatchedObj = re.search(QUOTED_PATTERN, Expression)
                    if QuotedMatchedObj:
                        MatchedStr = QuotedMatchedObj.group().strip()
                        if MatchedStr.startswith('L'):
                            Expression = Expression.replace(MatchedStr, MatchedStr[1:].strip())  

                    Expression = self.ReplaceForEval(Expression, IsExpr=True)
                    Expression = Expression.replace(PcdGuidName, 'x')
                    Message = self.GetEnErrorMessage(Valid.GetErrorMessageList())
                    ValidationExpressions.append((Expression, Message))                   
                
                ValidList = Valid.GetValidValue()
                if ValidList:
                    ValidValue = 'x in %s' % [eval(v) for v in ValidList.split(' ') if v]
                    Message = self.GetEnErrorMessage(Valid.GetErrorMessageList())
                    ValidationExpressions.append((ValidValue, Message))
                    
                ValidValueRange = Valid.GetValidValueRange()                
                if ValidValueRange:
                    ValidValueRange = self.ReplaceForEval(ValidValueRange, IsRange=True)
                    if ValidValueRange.find('-') >= 0:
                        ValidValueRange = ValidValueRange.replace('-', '<= x <=')
                    elif not ValidValueRange.startswith('x ') and not ValidValueRange.startswith('not ') \
                        and not ValidValueRange.startswith('not(') and not ValidValueRange.startswith('('):
                        ValidValueRange = 'x %s' % ValidValueRange
                    Message = self.GetEnErrorMessage(Valid.GetErrorMessageList())
                    ValidationExpressions.append((ValidValueRange, Message))
                    
            DefaultValue = self.PcdDefaultValueDict[PcdGuidName.strip()]
            #
            # Delete the 'L' prefix of a quoted string, this operation is for eval()
            #
            QUOTED_PATTERN = '[\t\s]*L?"[^"]*"'
            QuotedMatchedObj = re.search(QUOTED_PATTERN, DefaultValue)
            if QuotedMatchedObj:
                MatchedStr = QuotedMatchedObj.group().strip()
                if MatchedStr.startswith('L'):
                    DefaultValue = DefaultValue.replace(MatchedStr, MatchedStr[1:].strip())
                    
            try:
                DefaultValue = eval(DefaultValue.replace('TRUE', 'True').replace('true', 'True')
                                        .replace('FALSE', 'False').replace('false', 'False'))
            except BaseException:
                pass

            for (Expression, Msg) in ValidationExpressions:
                try:
                    if not eval(Expression, {'x':DefaultValue}):
                        Logger.Error("Dec File Parser", FORMAT_INVALID, ExtraData='%s, value = %s' %\
                                     (PcdGuidName, DefaultValue), Message=Msg, File=self.FullPath)
                except TypeError:
                    Logger.Error("Dec File Parser", FORMAT_INVALID, ExtraData=PcdGuidName, \
                                    Message=Msg, File=self.FullPath)

    ## GenModuleFileList
    #
    def GenModuleFileList(self, ContainerFile):        
        ModuleFileList = []
        ContainerFileName = os.path.basename(ContainerFile)
        ContainerFilePath = os.path.dirname(ContainerFile)
        for Item in GetFiles(ContainerFilePath, 
                        ['CVS', '.svn'] + self.GetIncludePathList(), False):
            ExtName = os.path.splitext(Item)[1]
            if ExtName.lower() == '.inf':
                ModuleFileList.append(Item)
            elif ExtName.upper() == '.DEC' and self.CheckMulDec:
                if Item == ContainerFileName:
                    continue
                Logger.Error('MkPkg', 
                             UPT_MUL_DEC_ERROR,
                             ST.ERR_MUL_DEC_ERROR%(ContainerFilePath, 
                                                   ContainerFileName, 
                                                   Item))
                
        self.SetModuleFileList(ModuleFileList)
    
    ## Show detailed information of Package
    #
    # Print all members and their values of Package class
    #
    def ShowPackage(self):
        print '\nName =', self.GetName()
        print '\nBaseName =', self.GetBaseName()
        print '\nVersion =', self.GetVersion() 
        print '\nGuid =', self.GetGuid()
        
        print '\nStandardIncludes = %d ' \
            % len(self.GetStandardIncludeFileList()),
        for Item in self.GetStandardIncludeFileList():
            print Item.GetFilePath(), '  ', Item.GetSupArchList()
        print '\nPackageIncludes = %d \n' \
            % len(self.GetPackageIncludeFileList()),
        for Item in self.GetPackageIncludeFileList():
            print Item.GetFilePath(), '  ', Item.GetSupArchList()
             
        print '\nGuids =', self.GetGuidList()
        for Item in self.GetGuidList():
            print Item.GetCName(), Item.GetGuid(), Item.GetSupArchList()
        print '\nProtocols =', self.GetProtocolList()
        for Item in self.GetProtocolList():
            print Item.GetCName(), Item.GetGuid(), Item.GetSupArchList()
        print '\nPpis =', self.GetPpiList()
        for Item in self.GetPpiList():
            print Item.GetCName(), Item.GetGuid(), Item.GetSupArchList()
        print '\nLibraryClasses =', self.GetLibraryClassList()
        for Item in self.GetLibraryClassList():
            print Item.GetLibraryClass(), Item.GetRecommendedInstance(), \
            Item.GetSupArchList()
        print '\nPcds =', self.GetPcdList()
        for Item in self.GetPcdList():
            print 'CName=', Item.GetCName(), 'TokenSpaceGuidCName=', \
                Item.GetTokenSpaceGuidCName(), \
                'DefaultValue=', Item.GetDefaultValue(), \
                'ValidUsage=', Item.GetValidUsage(), \
                'SupArchList', Item.GetSupArchList(), \
                'Token=', Item.GetToken(), 'DatumType=', Item.GetDatumType()
 
        for Item in self.GetMiscFileList():
            print Item.GetName()
            for FileObjectItem in Item.GetFileList():
                print FileObjectItem.GetURI()
        print '****************\n'

## GenPcdDeclaration
#
# @param ContainerFile:   File name of the DEC file
# @param PcdInfo:         Pcd information, of format (TokenGuidCName, 
#                         TokenName, Value, DatumType, Token, Type, 
#                         GenericComment, TailComment, Arch)
# @param Language: The language of HelpText, Prompt 
# 
def GenPcdDeclaration(ContainerFile, PcdInfo, Language, MacroReplaceDict):
    HelpStr = ''
    PromptStr = ''
    TailHelpStr = ''
    TokenGuidCName, TokenName, Value, DatumType, Token, Type, \
        GenericComment, TailComment, Arch = PcdInfo
    Pcd = PcdObject()
    Pcd.SetCName(TokenName)
    Pcd.SetToken(Token)
    Pcd.SetTokenSpaceGuidCName(TokenGuidCName)
    Pcd.SetDatumType(DatumType)
    Pcd.SetDefaultValue(Value)
    Pcd.SetValidUsage(Type)
    #
    #  MaxDatumSize is required field for 'VOID*' PCD
    #
    if DatumType == TAB_PTR_TYPE_PCD:
        Pcd.SetMaxDatumSize(ITEM_UNDEFINED)

    SupArchList = [Arch]
    Pcd.SetSupArchList(SupArchList)
    
    if GenericComment:
        HelpStr, PcdErrList, PromptStr = ParseDecPcdGenericComment(GenericComment, 
                                                                   ContainerFile, 
                                                                   TokenGuidCName, 
                                                                   TokenName,
                                                                   MacroReplaceDict)
        if PcdErrList:
            Pcd.SetPcdErrorsList(PcdErrList)

    if TailComment:
        SupModuleList, TailHelpStr = ParseDecPcdTailComment(TailComment, 
                                                        ContainerFile)
        if SupModuleList:
            Pcd.SetSupModuleList(SupModuleList)
    
    if HelpStr and (not HelpStr.endswith('\n')) and TailHelpStr:
        HelpStr += '\n'
    HelpStr += TailHelpStr
    if HelpStr:
        HelpTxtObj = TextObject()
        HelpTxtObj.SetLang(Language)   
        HelpTxtObj.SetString(HelpStr)
        Pcd.SetHelpTextList([HelpTxtObj])
    if PromptStr:
        TxtObj = TextObject()
        TxtObj.SetLang(Language)
        TxtObj.SetString(PromptStr)
        Pcd.SetPromptList([TxtObj])

    return Pcd
