## @file
# This file contained the miscellaneous functions for INF parser 
#
# 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.
#

'''
InfParserMisc
'''

##
# Import Modules
#
import re


from Library import DataType as DT


from Library.String import gMACRO_PATTERN
from Library.String import ReplaceMacro
from Object.Parser.InfMisc import ErrorInInf
from Logger.StringTable import ERR_MARCO_DEFINITION_MISS_ERROR

#
# Global variable
#

#
# Sections can exist in INF file
#
gINF_SECTION_DEF = {
       DT.TAB_UNKNOWN.upper()          : DT.MODEL_UNKNOWN,
       DT.TAB_HEADER.upper()           : DT.MODEL_META_DATA_FILE_HEADER,
       DT.TAB_INF_DEFINES.upper()      : DT.MODEL_META_DATA_DEFINE,
       DT.TAB_BUILD_OPTIONS.upper()    : DT.MODEL_META_DATA_BUILD_OPTION,
       DT.TAB_LIBRARY_CLASSES.upper()  : DT.MODEL_EFI_LIBRARY_CLASS,
       DT.TAB_PACKAGES.upper()         : DT.MODEL_META_DATA_PACKAGE,
       DT.TAB_INF_FIXED_PCD.upper()    : DT.MODEL_PCD_FIXED_AT_BUILD,
       DT.TAB_INF_PATCH_PCD.upper()    : DT.MODEL_PCD_PATCHABLE_IN_MODULE,
       DT.TAB_INF_FEATURE_PCD.upper()  : DT.MODEL_PCD_FEATURE_FLAG,
       DT.TAB_INF_PCD_EX.upper()       : DT.MODEL_PCD_DYNAMIC_EX,
       DT.TAB_INF_PCD.upper()          : DT.MODEL_PCD_DYNAMIC,
       DT.TAB_SOURCES.upper()          : DT.MODEL_EFI_SOURCE_FILE,
       DT.TAB_GUIDS.upper()            : DT.MODEL_EFI_GUID,
       DT.TAB_PROTOCOLS.upper()        : DT.MODEL_EFI_PROTOCOL,
       DT.TAB_PPIS.upper()             : DT.MODEL_EFI_PPI,
       DT.TAB_DEPEX.upper()            : DT.MODEL_EFI_DEPEX,
       DT.TAB_BINARIES.upper()         : DT.MODEL_EFI_BINARY_FILE,
       DT.TAB_USER_EXTENSIONS.upper()  : DT.MODEL_META_DATA_USER_EXTENSION
       #
       # EDK1 section
       # TAB_NMAKE.upper()            : MODEL_META_DATA_NMAKE
       # 
       }

## InfExpandMacro
#
# Expand MACRO definition with MACROs defined in [Defines] section and specific section. 
# The MACROs defined in specific section has high priority and will be expanded firstly.
#
# @param LineInfo      Contain information of FileName, LineContent, LineNo
# @param GlobalMacros  MACROs defined in INF [Defines] section
# @param SectionMacros MACROs defined in INF specific section
# @param Flag          If the flag set to True, need to skip macros in a quoted string 
#
def InfExpandMacro(Content, LineInfo, GlobalMacros=None, SectionMacros=None, Flag=False):
    if GlobalMacros == None:
        GlobalMacros = {}
    if SectionMacros == None:
        SectionMacros = {}
    
    FileName = LineInfo[0]
    LineContent = LineInfo[1]
    LineNo = LineInfo[2]
    
    NewLineInfo = (FileName, LineNo, LineContent)
    
    #
    # First, replace MARCOs with value defined in specific section
    #
    Content = ReplaceMacro (Content, 
                            SectionMacros,
                            False,
                            (LineContent, LineNo),
                            FileName,
                            Flag)
    #
    # Then replace MARCOs with value defined in [Defines] section
    #
    Content = ReplaceMacro (Content, 
                            GlobalMacros,
                            False,
                            (LineContent, LineNo),
                            FileName,
                            Flag)
    
    MacroUsed = gMACRO_PATTERN.findall(Content)
    #
    # no macro found in String, stop replacing
    #
    if len(MacroUsed) == 0:
        return Content
    else:
        for Macro in MacroUsed:
            gQuotedMacro = re.compile(".*\".*\$\(%s\).*\".*"%(Macro))
            if not gQuotedMacro.match(Content):
                #
                # Still have MACROs can't be expanded.
                #
                ErrorInInf (ERR_MARCO_DEFINITION_MISS_ERROR,
                            LineInfo=NewLineInfo)
        
    return Content
    

## IsBinaryInf
#
# Judge whether the INF file is Binary INF or Common INF
#
# @param FileLineList     A list contain all INF file content.
#
def IsBinaryInf(FileLineList):
    if not FileLineList:
        return False
    
    ReIsSourcesSection = re.compile("^\s*\[Sources.*\]\s.*$", re.IGNORECASE)
    ReIsBinarySection = re.compile("^\s*\[Binaries.*\]\s.*$", re.IGNORECASE)
    BinarySectionFoundFlag = False
    
    for Line in FileLineList:
        if ReIsSourcesSection.match(Line):
            return False
        if ReIsBinarySection.match(Line):
            BinarySectionFoundFlag = True
            
    if BinarySectionFoundFlag:
        return True
    
    return False
    
    
## IsLibInstanceInfo
# 
# Judge whether the string contain the information of ## @LIB_INSTANCES.
#
# @param  String
#
# @return Flag
#
def IsLibInstanceInfo(String):
    ReIsLibInstance = re.compile("^\s*##\s*@LIB_INSTANCES\s*$")
    if ReIsLibInstance.match(String):
        return True
    else:
        return False
       
            
## IsAsBuildOptionInfo
# 
# Judge whether the string contain the information of ## @ASBUILD.
#
# @param  String
#
# @return Flag
#
def IsAsBuildOptionInfo(String):
    ReIsAsBuildInstance = re.compile("^\s*##\s*@AsBuilt\s*$")
    if ReIsAsBuildInstance.match(String):
        return True
    else:
        return False            
        

class InfParserSectionRoot(object):
    def __init__(self):
        #
        # Macros defined in [Define] section are file scope global
        #
        self.FileLocalMacros = {}
        
        #
        # Current Section Header content. 
        #
        self.SectionHeaderContent = []

        #
        # Last time Section Header content. 
        #
        self.LastSectionHeaderContent = []        
         
        self.FullPath = ''
        
        self.InfDefSection              = None
        self.InfBuildOptionSection      = None
        self.InfLibraryClassSection     = None
        self.InfPackageSection          = None
        self.InfPcdSection              = None
        self.InfSourcesSection          = None
        self.InfUserExtensionSection    = None
        self.InfProtocolSection         = None
        self.InfPpiSection              = None
        self.InfGuidSection             = None
        self.InfDepexSection            = None
        self.InfPeiDepexSection         = None
        self.InfDxeDepexSection         = None
        self.InfSmmDepexSection         = None
        self.InfBinariesSection         = None
        self.InfHeader                  = None
        self.InfSpecialCommentSection   = None              
