## @file
# This file contained the parser for sections in INF file 
#
# Copyright (c) 2011, 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.
#

'''
InfSectionParser
'''
##
# Import Modules
#
from copy import deepcopy
import re

from Library.String import GetSplitValueList
from Library.CommentParsing import ParseHeaderCommentSection
from Library.CommentParsing import ParseComment

from Library import DataType as DT

import Logger.Log as Logger
from Logger import StringTable as ST
from Logger.ToolError import FORMAT_INVALID

from Object.Parser.InfDefineObject import InfDefObject
from Object.Parser.InfBuildOptionObject import InfBuildOptionsObject
from Object.Parser.InfLibraryClassesObject import InfLibraryClassObject
from Object.Parser.InfPackagesObject import InfPackageObject
from Object.Parser.InfPcdObject import InfPcdObject
from Object.Parser.InfSoucesObject import InfSourcesObject
from Object.Parser.InfUserExtensionObject import InfUserExtensionObject
from Object.Parser.InfProtocolObject import InfProtocolObject
from Object.Parser.InfPpiObject import InfPpiObject
from Object.Parser.InfGuidObject import InfGuidObject
from Object.Parser.InfDepexObject import InfDepexObject
from Object.Parser.InfBinaryObject import InfBinariesObject
from Object.Parser.InfHeaderObject import InfHeaderObject
from Object.Parser.InfMisc import InfSpecialCommentObject
from Object.Parser.InfMisc import InfHobObject
from Object.Parser.InfMisc import InfBootModeObject
from Object.Parser.InfMisc import InfEventObject
from Parser.InfParserMisc import gINF_SECTION_DEF
from Parser.InfDefineSectionParser import InfDefinSectionParser
from Parser.InfBuildOptionSectionParser import InfBuildOptionSectionParser
from Parser.InfSourceSectionParser import InfSourceSectionParser
from Parser.InfLibrarySectionParser import InfLibrarySectionParser
from Parser.InfPackageSectionParser import InfPackageSectionParser
from Parser.InfGuidPpiProtocolSectionParser import InfGuidPpiProtocolSectionParser
from Parser.InfBinarySectionParser import InfBinarySectionParser
from Parser.InfPcdSectionParser import InfPcdSectionParser
from Parser.InfDepexSectionParser import InfDepexSectionParser

## GetSpecialStr2
#
# GetSpecialStr2
#
def GetSpecialStr2(ItemList, FileName, LineNo, SectionString):
    Str2 = ''
    #
    # S2 may be Platform or ModuleType
    #
    if len(ItemList) == 3:
        #
        # Except [LibraryClass], [Depex]
        # section can has more than 2 items in section header string,
        # others should report error.
        #
        if not (ItemList[0].upper() == DT.TAB_LIBRARY_CLASSES.upper() or \
                ItemList[0].upper() == DT.TAB_DEPEX.upper() or \
                ItemList[0].upper() == DT.TAB_USER_EXTENSIONS.upper()):
            if ItemList[2] != '':
                Logger.Error('Parser',
                             FORMAT_INVALID,
                             ST.ERR_INF_PARSER_SOURCE_SECTION_SECTIONNAME_INVALID % (SectionString),
                             File=FileName,
                             Line=LineNo,
                             ExtraData=SectionString)
        Str2 = ItemList[2]
    elif len(ItemList) == 4:
        #
        # Except [UserExtension]
        # section can has 4 items in section header string,
        # others should report error.
        #
        if not ItemList[0].upper() == DT.TAB_USER_EXTENSIONS.upper() or ItemList[0].upper() == DT.TAB_DEPEX.upper():
            if ItemList[3] != '':
                Logger.Error('Parser', FORMAT_INVALID, ST.ERR_INF_PARSER_SOURCE_SECTION_SECTIONNAME_INVALID \
                             % (SectionString), File=FileName, Line=LineNo, ExtraData=SectionString)
        
        if not ItemList[0].upper() == DT.TAB_USER_EXTENSIONS.upper():
            Str2 = ItemList[2] + ' | ' + ItemList[3]
        else:
            Str2 = ItemList[2]

    elif len(ItemList) > 4:
        Logger.Error('Parser', FORMAT_INVALID, ST.ERR_INF_PARSER_SOURCE_SECTION_SECTIONNAME_INVALID \
                     % (SectionString), File=FileName, Line=LineNo, ExtraData=SectionString)

    return Str2

## ProcessUseExtHeader
# 
#
def ProcessUseExtHeader(ItemList):
    NewItemList = []
    AppendContent = ''
    CompleteFlag = False
    for Item in ItemList:
        if Item.startswith('\"') and not Item.endswith('\"'):
            AppendContent = Item
            CompleteFlag = True
        elif Item.endswith('\"') and not Item.startswith('\"'):
            #
            # Should not have an userId or IdString not starts with " before but ends with ".
            #
            if not CompleteFlag:
                return False, []
            AppendContent = AppendContent + "." + Item
            NewItemList.append(AppendContent)
            CompleteFlag = False
            AppendContent = ''
        elif Item.endswith('\"') and Item.startswith('\"'):
            #
            # Common item, not need to combine the information
            #
            NewItemList.append(Item)
        else:
            if not CompleteFlag:
                NewItemList.append(Item)
            else:
                AppendContent = AppendContent + "." + Item
    
    if len(NewItemList) > 4:
        return False, []
    
    return True, NewItemList
  
## GetArch
#
# GetArch
#
def GetArch(ItemList, ArchList, FileName, LineNo, SectionString):
    #
    # S1 is always Arch
    #
    if len(ItemList) > 1:
        Arch = ItemList[1]
    else:
        Arch = 'COMMON'
    ArchList.add(Arch)

    #
    # 'COMMON' must not be used with specific ARCHs at the same section
    #
    if 'COMMON' in ArchList and len(ArchList) > 1:
        Logger.Error('Parser',
                     FORMAT_INVALID,
                     ST.ERR_INF_PARSER_SECTION_ARCH_CONFLICT,
                     File=FileName,
                     Line=LineNo,
                     ExtraData=SectionString)

    return Arch, ArchList

## InfSectionParser
#
# Inherit from object
#
class InfSectionParser(InfDefinSectionParser,
                       InfBuildOptionSectionParser,
                       InfSourceSectionParser,
                       InfLibrarySectionParser,
                       InfPackageSectionParser,
                       InfGuidPpiProtocolSectionParser,
                       InfBinarySectionParser,
                       InfPcdSectionParser,
                       InfDepexSectionParser):
    #
    # Parser objects used to implement singleton
    #
    MetaFiles = {}

    ## Factory method
    #
    # One file, one parser object. This factory method makes sure that there's
    # only one object constructed for one meta file.
    #
    #   @param  Class           class object of real AutoGen class
    #                           (InfParser, DecParser or DscParser)
    #   @param  FilePath        The path of meta file
    #
    def __new__(cls, FilePath, *args, **kwargs):
        if args:
            pass
        if kwargs:
            pass
        if FilePath in cls.MetaFiles:
            return cls.MetaFiles[FilePath]
        else:
            ParserObject = super(InfSectionParser, cls).__new__(cls)
            cls.MetaFiles[FilePath] = ParserObject
            return ParserObject

    def __init__(self):
        InfDefinSectionParser.__init__(self)
        InfBuildOptionSectionParser.__init__(self)
        InfSourceSectionParser.__init__(self)
        InfLibrarySectionParser.__init__(self)
        InfPackageSectionParser.__init__(self)
        InfGuidPpiProtocolSectionParser.__init__(self)
        InfBinarySectionParser.__init__(self)
        InfPcdSectionParser.__init__(self)
        InfDepexSectionParser.__init__(self)
        #
        # Initialize all objects that an INF file will generated.
        #
        self.InfDefSection = InfDefObject()
        self.InfBuildOptionSection = InfBuildOptionsObject()
        self.InfLibraryClassSection = InfLibraryClassObject()
        self.InfPackageSection = InfPackageObject()
        self.InfPcdSection = InfPcdObject(self.MetaFiles.keys()[0])
        self.InfSourcesSection = InfSourcesObject()
        self.InfUserExtensionSection = InfUserExtensionObject()
        self.InfProtocolSection = InfProtocolObject()
        self.InfPpiSection = InfPpiObject()
        self.InfGuidSection = InfGuidObject()
        self.InfDepexSection = InfDepexObject()
        self.InfPeiDepexSection = InfDepexObject()
        self.InfDxeDepexSection = InfDepexObject()
        self.InfSmmDepexSection = InfDepexObject()
        self.InfBinariesSection = InfBinariesObject()
        self.InfHeader = InfHeaderObject()
        self.InfSpecialCommentSection = InfSpecialCommentObject()

        #
        # A List for store define section content.
        #    
        self._PcdNameList = []
        self._SectionName = ''
        self._SectionType = 0
        self.RelaPath = ''
        self.FileName = ''

    #
    # File Header content parser
    #    
    def InfHeaderParser(self, Content, InfHeaderObject2, FileName):
        (Abstract, Description, Copyright, License) = ParseHeaderCommentSection(Content, FileName)
        #
        # Not process file name now, for later usage.
        #
        if self.FileName:
            pass

        #
        # Insert Abstract, Description, CopyRight, License into header object
        #                                
        InfHeaderObject2.SetAbstract(Abstract)
        InfHeaderObject2.SetDescription(Description)
        InfHeaderObject2.SetCopyright(Copyright)
        InfHeaderObject2.SetLicense(License)




    ## Section header parser
    #
    #   The section header is always in following format:
    #
    #       [section_name.arch<.platform|module_type>]
    #
    # @param String    A string contained the content need to be parsed. 
    #
    def SectionHeaderParser(self, SectionString, FileName, LineNo):
        _Scope = []
        _SectionName = ''
        ArchList = set()
        _ValueList = []
        _PcdNameList = [DT.TAB_INF_FIXED_PCD.upper(),
                             DT.TAB_INF_FEATURE_PCD.upper(),
                             DT.TAB_INF_PATCH_PCD.upper(),
                             DT.TAB_INF_PCD.upper(),
                             DT.TAB_INF_PCD_EX.upper()
                             ]
        SectionString = SectionString.strip()
        for Item in GetSplitValueList(SectionString[1:-1], DT.TAB_COMMA_SPLIT):
            if Item == '':
                Logger.Error('Parser',
                             FORMAT_INVALID,
                             ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % (""),
                             File=FileName,
                             Line=LineNo,
                             ExtraData=SectionString)
            ItemList = GetSplitValueList(Item, DT.TAB_SPLIT)
            #
            # different section should not mix in one section
            # Allow different PCD type sections mixed together
            # 
            if _SectionName.upper() not in _PcdNameList:
                if _SectionName != '' and _SectionName.upper() != ItemList[0].upper():
                    Logger.Error('Parser',
                                 FORMAT_INVALID,
                                 ST.ERR_INF_PARSER_SECTION_NAME_DUPLICATE,
                                 File=FileName,
                                 Line=LineNo,
                                 ExtraData=SectionString)
            elif _PcdNameList[1] in [_SectionName.upper(), ItemList[0].upper()] and \
                (_SectionName.upper()!= ItemList[0].upper()):
                Logger.Error('Parser',
                             FORMAT_INVALID,
                             ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % (""),
                             File=FileName,
                             Line=LineNo,
                             ExtraData=SectionString)

            _SectionName = ItemList[0]
            if _SectionName.upper() in gINF_SECTION_DEF:
                self._SectionType = gINF_SECTION_DEF[_SectionName.upper()]
            else:
                self._SectionType = DT.MODEL_UNKNOWN
                Logger.Error("Parser",
                             FORMAT_INVALID,
                             ST.ERR_INF_PARSER_UNKNOWN_SECTION,
                             File=FileName,
                             Line=LineNo,
                             ExtraData=SectionString)

            #
            # Get Arch
            #
            Str1, ArchList = GetArch(ItemList, ArchList, FileName, LineNo, SectionString)

            #
            # For [Defines] section, do special check.
            # 
            if ItemList[0].upper() == DT.TAB_COMMON_DEFINES.upper():
                if len(ItemList) != 1:
                    Logger.Error('Parser',
                                 FORMAT_INVALID,
                                 ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID % (SectionString),
                                 File=FileName, Line=LineNo, ExtraData=SectionString)

            #
            # For [UserExtension] section, do special check.
            # 
            if ItemList[0].upper() == DT.TAB_USER_EXTENSIONS.upper():
            
                RetValue = ProcessUseExtHeader(ItemList)
                
                if not RetValue[0]:
                    Logger.Error('Parser',
                                 FORMAT_INVALID,
                                 ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID % (SectionString),
                                 File=FileName, Line=LineNo, ExtraData=SectionString)
                else:
                    ItemList = RetValue[1]              
                
                if len(ItemList) == 3:
                    ItemList.append('COMMON')
                
                Str1 = ItemList[1]

            #
            # For Library classes, need to check module type.       
            #
            if ItemList[0].upper() == DT.TAB_LIBRARY_CLASSES.upper() and len(ItemList) == 3:
                if ItemList[2] != '':
                    ModuleTypeList = GetSplitValueList(ItemList[2], DT.TAB_VALUE_SPLIT)
                    for Item in ModuleTypeList:
                        if Item.strip() not in DT.MODULE_LIST:
                            Logger.Error('Parser',
                                         FORMAT_INVALID,
                                         ST.ERR_INF_PARSER_DEFINE_MODULETYPE_INVALID % (Item),
                                         File=FileName,
                                         Line=LineNo,
                                         ExtraData=SectionString)
            #
            # GetSpecialStr2
            #
            Str2 = GetSpecialStr2(ItemList, FileName, LineNo, SectionString)

            _Scope.append([Str1, Str2])

            _NewValueList = []
            _AppendFlag = True
            if _SectionName.upper() in _PcdNameList:
                for ValueItem in _ValueList:
                    if _SectionName.upper() == ValueItem[0].upper() and Str1.upper() not in ValueItem[1].split():
                        ValueItem[1] = ValueItem[1] + " " + Str1
                        _AppendFlag = False
                    elif _SectionName.upper() == ValueItem[0].upper() and Str1.upper() in ValueItem[1].split():
                        _AppendFlag = False

                    _NewValueList.append(ValueItem)

                _ValueList = _NewValueList

            if _AppendFlag:
                if not ItemList[0].upper() == DT.TAB_USER_EXTENSIONS.upper():
                    _ValueList.append([_SectionName, Str1, Str2, LineNo])
                else:
                    if len(ItemList) == 4:
                        _ValueList.append([_SectionName, Str1, Str2, ItemList[3], LineNo])

        self.SectionHeaderContent = deepcopy(_ValueList)

    ## GenSpecialSectionList
    #
    #  @param SpecialSectionList: a list of list, of which item's format 
    #                             (Comment, LineNum)
    #  @param ContainerFile:      Input value for filename of Inf file
    # 
    def InfSpecialCommentParser (self, SpecialSectionList, InfSectionObject, ContainerFile, SectionType):
        ReFindSpecialCommentRe = re.compile(r"""#(?:\s*)\[(.*?)\](?:.*)""", re.DOTALL)
        ReFindHobArchRe = re.compile(r"""[Hh][Oo][Bb]\.([^,]*)""", re.DOTALL)
        if self.FileName:
            pass
        SpecialObjectList = []
        ArchList = []
        if SectionType == DT.TYPE_EVENT_SECTION:
            TokenDict = DT.EVENT_TOKENS
        elif SectionType == DT.TYPE_HOB_SECTION:
            TokenDict = DT.HOB_TOKENS
        else:
            TokenDict = DT.BOOTMODE_TOKENS

        for List in SpecialSectionList:
            #
            # Hob has Arch attribute, need to be handled specially here
            #
            if SectionType == DT.TYPE_HOB_SECTION:

                MatchObject = ReFindSpecialCommentRe.search(List[0][0])
                HobSectionStr = MatchObject.group(1)
                ArchList = []
                for Match in ReFindHobArchRe.finditer(HobSectionStr):
                    Arch = Match.groups(1)[0].upper()
                    ArchList.append(Arch)
            CommentSoFar = ''
            for Index in xrange(1, len(List)):
                Result = ParseComment(List[Index], DT.ALL_USAGE_TOKENS, TokenDict, [], False)
                Usage = Result[0]
                Type = Result[1]
                HelpText = Result[3]

                if Usage == DT.ITEM_UNDEFINED and Type == DT.ITEM_UNDEFINED:
                    if HelpText is None:
                        HelpText = ''
                    if not HelpText.endswith('\n'):
                        HelpText += '\n'
                    CommentSoFar += HelpText
                else:
                    if HelpText:
                        CommentSoFar += HelpText
                    if SectionType == DT.TYPE_EVENT_SECTION:
                        SpecialObject = InfEventObject()
                        SpecialObject.SetEventType(Type)
                        SpecialObject.SetUsage(Usage)
                        SpecialObject.SetHelpString(CommentSoFar)
                    elif SectionType == DT.TYPE_HOB_SECTION:
                        SpecialObject = InfHobObject()
                        SpecialObject.SetHobType(Type)
                        SpecialObject.SetUsage(Usage)
                        SpecialObject.SetHelpString(CommentSoFar)
                        if len(ArchList) >= 1:
                            SpecialObject.SetSupArchList(ArchList)
                    else:
                        SpecialObject = InfBootModeObject()
                        SpecialObject.SetSupportedBootModes(Type)
                        SpecialObject.SetUsage(Usage)
                        SpecialObject.SetHelpString(CommentSoFar)

                    SpecialObjectList.append(SpecialObject)
                    CommentSoFar = ''
        if not InfSectionObject.SetSpecialComments(SpecialObjectList,
                                                   SectionType):
            Logger.Error('InfParser',
                         FORMAT_INVALID,
                         ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % (SectionType),
                         ContainerFile
                         )
