## @file
# This file is used to define common parsing related functions used in parsing 
# INF/DEC/DSC process
#
# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials are licensed and made available 
# under the terms and conditions of the BSD License which accompanies this 
# distribution. The full text of the license may be found at 
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#

'''
Parsing
'''

##
# Import Modules
#
import os.path
import re

from Library.StringUtils import RaiseParserError
from Library.StringUtils import GetSplitValueList
from Library.StringUtils import CheckFileType
from Library.StringUtils import CheckFileExist
from Library.StringUtils import CleanString
from Library.StringUtils import NormPath

from Logger.ToolError import FILE_NOT_FOUND
from Logger.ToolError import FatalError
from Logger.ToolError import FORMAT_INVALID

from Library import DataType

from Library.Misc import GuidStructureStringToGuidString
from Library.Misc import CheckGuidRegFormat
from Logger import StringTable as ST
import Logger.Log as Logger

from Parser.DecParser import Dec
import GlobalData

gPKG_INFO_DICT = {}

## GetBuildOption
#
# Parse a string with format "[<Family>:]<ToolFlag>=Flag"
# Return (Family, ToolFlag, Flag)
#
# @param String:  String with BuildOption statement
# @param File:    The file which defines build option, used in error report
#
def GetBuildOption(String, File, LineNo= -1):
    (Family, ToolChain, Flag) = ('', '', '')
    if String.find(DataType.TAB_EQUAL_SPLIT) < 0:
        RaiseParserError(String, 'BuildOptions', File, \
                         '[<Family>:]<ToolFlag>=Flag', LineNo)
    else:
        List = GetSplitValueList(String, DataType.TAB_EQUAL_SPLIT, MaxSplit=1)
        if List[0].find(':') > -1:
            Family = List[0][ : List[0].find(':')].strip()
            ToolChain = List[0][List[0].find(':') + 1 : ].strip()
        else:
            ToolChain = List[0].strip()
        Flag = List[1].strip()
    return (Family, ToolChain, Flag)

## Get Library Class
#
# Get Library of Dsc as <LibraryClassKeyWord>|<LibraryInstance>
#
# @param Item:           String as <LibraryClassKeyWord>|<LibraryInstance>
# @param ContainerFile:  The file which describes the library class, used for 
#                        error report
#
def GetLibraryClass(Item, ContainerFile, WorkspaceDir, LineNo= -1):
    List = GetSplitValueList(Item[0])
    SupMod = DataType.SUP_MODULE_LIST_STRING
    if len(List) != 2:
        RaiseParserError(Item[0], 'LibraryClasses', ContainerFile, \
                         '<LibraryClassKeyWord>|<LibraryInstance>')
    else:
        CheckFileType(List[1], '.Inf', ContainerFile, \
                      'library class instance', Item[0], LineNo)
        CheckFileExist(WorkspaceDir, List[1], ContainerFile, \
                       'LibraryClasses', Item[0], LineNo)
        if Item[1] != '':
            SupMod = Item[1]

    return (List[0], List[1], SupMod)

## Get Library Class
#
# Get Library of Dsc as <LibraryClassKeyWord>[|<LibraryInstance>]
# [|<TokenSpaceGuidCName>.<PcdCName>]
#
# @param Item:           String as <LibraryClassKeyWord>|<LibraryInstance>
# @param ContainerFile:  The file which describes the library class, used for 
#                        error report
#
def GetLibraryClassOfInf(Item, ContainerFile, WorkspaceDir, LineNo= -1):
    ItemList = GetSplitValueList((Item[0] + DataType.TAB_VALUE_SPLIT * 2))
    SupMod = DataType.SUP_MODULE_LIST_STRING

    if len(ItemList) > 5:
        RaiseParserError\
        (Item[0], 'LibraryClasses', ContainerFile, \
         '<LibraryClassKeyWord>[|<LibraryInstance>]\
         [|<TokenSpaceGuidCName>.<PcdCName>]')
    else:
        CheckFileType(ItemList[1], '.Inf', ContainerFile, 'LibraryClasses', \
                      Item[0], LineNo)
        CheckFileExist(WorkspaceDir, ItemList[1], ContainerFile, \
                       'LibraryClasses', Item[0], LineNo)
        if ItemList[2] != '':
            CheckPcdTokenInfo(ItemList[2], 'LibraryClasses', \
                              ContainerFile, LineNo)
        if Item[1] != '':
            SupMod = Item[1]

    return (ItemList[0], ItemList[1], ItemList[2], SupMod)

## CheckPcdTokenInfo
#
# Check if PcdTokenInfo is following <TokenSpaceGuidCName>.<PcdCName>
#
# @param TokenInfoString:  String to be checked
# @param Section:          Used for error report
# @param File:             Used for error report
#
def CheckPcdTokenInfo(TokenInfoString, Section, File, LineNo= -1):
    Format = '<TokenSpaceGuidCName>.<PcdCName>'
    if TokenInfoString != '' and TokenInfoString is not None:
        TokenInfoList = GetSplitValueList(TokenInfoString, DataType.TAB_SPLIT)
        if len(TokenInfoList) == 2:
            return True

    RaiseParserError(TokenInfoString, Section, File, Format, LineNo)

## Get Pcd
#
# Get Pcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>
# [|<Type>|<MaximumDatumSize>]
#
# @param Item:           String as <PcdTokenSpaceGuidCName>.<TokenCName>|
#                        <Value>[|<Type>|<MaximumDatumSize>]
# @param ContainerFile:  The file which describes the pcd, used for error 
#                        report

#
def GetPcd(Item, Type, ContainerFile, LineNo= -1):
    TokenGuid, TokenName, Value, MaximumDatumSize, Token = '', '', '', '', ''
    List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT * 2)

    if len(List) < 4 or len(List) > 6:
        RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \
                         '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>\
                         [|<Type>|<MaximumDatumSize>]', LineNo)
    else:
        Value = List[1]
        MaximumDatumSize = List[2]
        Token = List[3]

    if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
        (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)

    return (TokenName, TokenGuid, Value, MaximumDatumSize, Token, Type)

## Get FeatureFlagPcd
#
# Get FeatureFlagPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
#
# @param Item:           String as <PcdTokenSpaceGuidCName>
#                        .<TokenCName>|TRUE/FALSE
# @param ContainerFile:  The file which describes the pcd, used for error 
#                        report
#
def GetFeatureFlagPcd(Item, Type, ContainerFile, LineNo= -1):
    TokenGuid, TokenName, Value = '', '', ''
    List = GetSplitValueList(Item)
    if len(List) != 2:
        RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \
                         '<PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE', \
                         LineNo)
    else:
        Value = List[1]
    if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
        (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)

    return (TokenName, TokenGuid, Value, Type)

## Get DynamicDefaultPcd
#
# Get DynamicDefaultPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>
# |<Value>[|<DatumTyp>[|<MaxDatumSize>]]
#
# @param Item:           String as <PcdTokenSpaceGuidCName>.<TokenCName>|
#                        TRUE/FALSE
# @param ContainerFile:  The file which describes the pcd, used for error 
#                        report
#
def GetDynamicDefaultPcd(Item, Type, ContainerFile, LineNo= -1):
    TokenGuid, TokenName, Value, DatumTyp, MaxDatumSize = '', '', '', '', ''
    List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT * 2)
    if len(List) < 4 or len(List) > 8:
        RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \
                         '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>\
                         [|<DatumTyp>[|<MaxDatumSize>]]', LineNo)
    else:
        Value = List[1]
        DatumTyp = List[2]
        MaxDatumSize = List[3]
    if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
        (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)

    return (TokenName, TokenGuid, Value, DatumTyp, MaxDatumSize, Type)

## Get DynamicHiiPcd
#
# Get DynamicHiiPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<String>|
# <VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]
#
# @param Item:           String as <PcdTokenSpaceGuidCName>.<TokenCName>|
#                        TRUE/FALSE
# @param ContainerFile:  The file which describes the pcd, used for error 
#                        report
#
def GetDynamicHiiPcd(Item, Type, ContainerFile, LineNo= -1):
    TokenGuid, TokenName, List1, List2, List3, List4, List5 = \
    '', '', '', '', '', '', ''
    List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT * 2)
    if len(List) < 6 or len(List) > 8:
        RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \
                         '<PcdTokenSpaceGuidCName>.<TokenCName>|<String>|\
                         <VariableGuidCName>|<VariableOffset>[|<DefaultValue>\
                         [|<MaximumDatumSize>]]', LineNo)
    else:
        List1, List2, List3, List4, List5 = \
        List[1], List[2], List[3], List[4], List[5]
    if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
        (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)

    return (TokenName, TokenGuid, List1, List2, List3, List4, List5, Type)

## Get DynamicVpdPcd
#
# Get DynamicVpdPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|
# <VpdOffset>[|<MaximumDatumSize>]
#
# @param Item:           String as <PcdTokenSpaceGuidCName>.<TokenCName>
#                        |TRUE/FALSE
# @param ContainerFile:  The file which describes the pcd, used for error 
#                        report
#
def GetDynamicVpdPcd(Item, Type, ContainerFile, LineNo= -1):
    TokenGuid, TokenName, List1, List2 = '', '', '', ''
    List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT)
    if len(List) < 3 or len(List) > 4:
        RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \
                         '<PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>\
                         [|<MaximumDatumSize>]', LineNo)
    else:
        List1, List2 = List[1], List[2]
    if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
        (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)

    return (TokenName, TokenGuid, List1, List2, Type)

## GetComponent
#
# Parse block of the components defined in dsc file
# Set KeyValues as [ ['component name', [lib1, lib2, lib3], 
# [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...]
#
# @param Lines:             The content to be parsed
# @param KeyValues:         To store data after parsing
#
def GetComponent(Lines, KeyValues):
    (FindBlock, FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
     FindPcdsPatchableInModule, FindPcdsFixedAtBuild, FindPcdsDynamic, \
     FindPcdsDynamicEx) = (False, False, False, False, False, False, False, \
                           False)
    ListItem = None
    LibraryClassItem = []
    BuildOption = []
    Pcd = []

    for Line in Lines:
        Line = Line[0]
        #
        # Ignore !include statement
        #
        if Line.upper().find(DataType.TAB_INCLUDE.upper() + ' ') > -1 or \
        Line.upper().find(DataType.TAB_DEFINE + ' ') > -1:
            continue

        if FindBlock == False:
            ListItem = Line
            #
            # find '{' at line tail
            #
            if Line.endswith('{'):
                FindBlock = True
                ListItem = CleanString(Line.rsplit('{', 1)[0], \
                                       DataType.TAB_COMMENT_SPLIT)

        #
        # Parse a block content
        #
        if FindBlock:
            if Line.find('<LibraryClasses>') != -1:
                (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
                 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
                 FindPcdsDynamic, FindPcdsDynamicEx) = \
                 (True, False, False, False, False, False, False)
                continue
            if Line.find('<BuildOptions>') != -1:
                (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
                 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
                 FindPcdsDynamic, FindPcdsDynamicEx) = \
                 (False, True, False, False, False, False, False)
                continue
            if Line.find('<PcdsFeatureFlag>') != -1:
                (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
                 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
                 FindPcdsDynamic, FindPcdsDynamicEx) = \
                 (False, False, True, False, False, False, False)
                continue
            if Line.find('<PcdsPatchableInModule>') != -1:
                (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
                 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
                 FindPcdsDynamic, FindPcdsDynamicEx) = \
                 (False, False, False, True, False, False, False)
                continue
            if Line.find('<PcdsFixedAtBuild>') != -1:
                (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
                 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
                 FindPcdsDynamic, FindPcdsDynamicEx) = \
                 (False, False, False, False, True, False, False)
                continue
            if Line.find('<PcdsDynamic>') != -1:
                (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
                 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
                 FindPcdsDynamic, FindPcdsDynamicEx) = \
                 (False, False, False, False, False, True, False)
                continue
            if Line.find('<PcdsDynamicEx>') != -1:
                (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
                 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
                 FindPcdsDynamic, FindPcdsDynamicEx) = \
                 (False, False, False, False, False, False, True)
                continue
            if Line.endswith('}'):
                #
                # find '}' at line tail
                #
                KeyValues.append([ListItem, LibraryClassItem, \
                                  BuildOption, Pcd])
                (FindBlock, FindLibraryClass, FindBuildOption, \
                 FindPcdsFeatureFlag, FindPcdsPatchableInModule, \
                 FindPcdsFixedAtBuild, FindPcdsDynamic, FindPcdsDynamicEx) = \
                 (False, False, False, False, False, False, False, False)
                LibraryClassItem, BuildOption, Pcd = [], [], []
                continue

        if FindBlock:
            if FindLibraryClass:
                LibraryClassItem.append(Line)
            elif FindBuildOption:
                BuildOption.append(Line)
            elif FindPcdsFeatureFlag:
                Pcd.append((DataType.TAB_PCDS_FEATURE_FLAG_NULL, Line))
            elif FindPcdsPatchableInModule:
                Pcd.append((DataType.TAB_PCDS_PATCHABLE_IN_MODULE_NULL, Line))
            elif FindPcdsFixedAtBuild:
                Pcd.append((DataType.TAB_PCDS_FIXED_AT_BUILD_NULL, Line))
            elif FindPcdsDynamic:
                Pcd.append((DataType.TAB_PCDS_DYNAMIC_DEFAULT_NULL, Line))
            elif FindPcdsDynamicEx:
                Pcd.append((DataType.TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL, Line))
        else:
            KeyValues.append([ListItem, [], [], []])

    return True

## GetExec
#
# Parse a string with format "InfFilename [EXEC = ExecFilename]"
# Return (InfFilename, ExecFilename)
#
# @param String:  String with EXEC statement
#
def GetExec(String):
    InfFilename = ''
    ExecFilename = ''
    if String.find('EXEC') > -1:
        InfFilename = String[ : String.find('EXEC')].strip()
        ExecFilename = String[String.find('EXEC') + len('EXEC') : ].strip()
    else:
        InfFilename = String.strip()

    return (InfFilename, ExecFilename)

## GetComponents
#
# Parse block of the components defined in dsc file
# Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3], 
# [pcd1, pcd2, pcd3]], ...]
#
# @param Lines:             The content to be parsed
# @param Key:               Reserved
# @param KeyValues:         To store data after parsing
# @param CommentCharacter:  Comment char, used to ignore comment content
#
# @retval True Get component successfully
#
def GetComponents(Lines, KeyValues, CommentCharacter):
    if Lines.find(DataType.TAB_SECTION_END) > -1:
        Lines = Lines.split(DataType.TAB_SECTION_END, 1)[1]
    (FindBlock, FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
     FindPcdsPatchableInModule, FindPcdsFixedAtBuild, FindPcdsDynamic, \
     FindPcdsDynamicEx) = \
     (False, False, False, False, False, False, False, False)
    ListItem = None
    LibraryClassItem = []
    BuildOption = []
    Pcd = []

    LineList = Lines.split('\n')
    for Line in LineList:
        Line = CleanString(Line, CommentCharacter)
        if Line is None or Line == '':
            continue

        if FindBlock == False:
            ListItem = Line
            #
            # find '{' at line tail
            #
            if Line.endswith('{'):
                FindBlock = True
                ListItem = CleanString(Line.rsplit('{', 1)[0], CommentCharacter)

        #
        # Parse a block content
        #
        if FindBlock:
            if Line.find('<LibraryClasses>') != -1:
                (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
                 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
                 FindPcdsDynamic, FindPcdsDynamicEx) = \
                 (True, False, False, False, False, False, False)
                continue
            if Line.find('<BuildOptions>') != -1:
                (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
                 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
                 FindPcdsDynamic, FindPcdsDynamicEx) = \
                 (False, True, False, False, False, False, False)
                continue
            if Line.find('<PcdsFeatureFlag>') != -1:
                (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
                 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
                 FindPcdsDynamic, FindPcdsDynamicEx) = \
                 (False, False, True, False, False, False, False)
                continue
            if Line.find('<PcdsPatchableInModule>') != -1:
                (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
                 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
                 FindPcdsDynamic, FindPcdsDynamicEx) = \
                 (False, False, False, True, False, False, False)
                continue
            if Line.find('<PcdsFixedAtBuild>') != -1:
                (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
                 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
                 FindPcdsDynamic, FindPcdsDynamicEx) = \
                 (False, False, False, False, True, False, False)
                continue
            if Line.find('<PcdsDynamic>') != -1:
                (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
                 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
                 FindPcdsDynamic, FindPcdsDynamicEx) = \
                 (False, False, False, False, False, True, False)
                continue
            if Line.find('<PcdsDynamicEx>') != -1:
                (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
                 FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
                 FindPcdsDynamic, FindPcdsDynamicEx) = \
                 (False, False, False, False, False, False, True)
                continue
            if Line.endswith('}'):
                #
                # find '}' at line tail
                #
                KeyValues.append([ListItem, LibraryClassItem, BuildOption, \
                                  Pcd])
                (FindBlock, FindLibraryClass, FindBuildOption, \
                 FindPcdsFeatureFlag, FindPcdsPatchableInModule, \
                 FindPcdsFixedAtBuild, FindPcdsDynamic, FindPcdsDynamicEx) = \
                 (False, False, False, False, False, False, False, False)
                LibraryClassItem, BuildOption, Pcd = [], [], []
                continue

        if FindBlock:
            if FindLibraryClass:
                LibraryClassItem.append(Line)
            elif FindBuildOption:
                BuildOption.append(Line)
            elif FindPcdsFeatureFlag:
                Pcd.append((DataType.TAB_PCDS_FEATURE_FLAG, Line))
            elif FindPcdsPatchableInModule:
                Pcd.append((DataType.TAB_PCDS_PATCHABLE_IN_MODULE, Line))
            elif FindPcdsFixedAtBuild:
                Pcd.append((DataType.TAB_PCDS_FIXED_AT_BUILD, Line))
            elif FindPcdsDynamic:
                Pcd.append((DataType.TAB_PCDS_DYNAMIC, Line))
            elif FindPcdsDynamicEx:
                Pcd.append((DataType.TAB_PCDS_DYNAMIC_EX, Line))
        else:
            KeyValues.append([ListItem, [], [], []])

    return True

## Get Source
#
# Get Source of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>
# [|<PcdFeatureFlag>]]]]
#
# @param Item:           String as <Filename>[|<Family>[|<TagName>[|<ToolCode>
#                        [|<PcdFeatureFlag>]]]]
# @param ContainerFile:  The file which describes the library class, used 
#                        for error report
#
def GetSource(Item, ContainerFile, FileRelativePath, LineNo= -1):
    ItemNew = Item + DataType.TAB_VALUE_SPLIT * 4
    List = GetSplitValueList(ItemNew)
    if len(List) < 5 or len(List) > 9:
        RaiseParserError(Item, 'Sources', ContainerFile, \
                         '<Filename>[|<Family>[|<TagName>[|<ToolCode>\
                         [|<PcdFeatureFlag>]]]]', LineNo)
    List[0] = NormPath(List[0])
    CheckFileExist(FileRelativePath, List[0], ContainerFile, 'Sources', \
                   Item, LineNo)
    if List[4] != '':
        CheckPcdTokenInfo(List[4], 'Sources', ContainerFile, LineNo)

    return (List[0], List[1], List[2], List[3], List[4])

## Get Binary
#
# Get Binary of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>
# [|<PcdFeatureFlag>]]]]
#
# @param Item:           String as <Filename>[|<Family>[|<TagName>
#                        [|<ToolCode>[|<PcdFeatureFlag>]]]]
# @param ContainerFile:  The file which describes the library class, 
#                        used for error report
#
def GetBinary(Item, ContainerFile, LineNo= -1):
    ItemNew = Item + DataType.TAB_VALUE_SPLIT
    List = GetSplitValueList(ItemNew)
    if len(List) < 3 or len(List) > 5:
        RaiseParserError(Item, 'Binaries', ContainerFile, \
                         "<FileType>|<Filename>[|<Target>\
                         [|<TokenSpaceGuidCName>.<PcdCName>]]", LineNo)

    if len(List) >= 4:
        if List[3] != '':
            CheckPcdTokenInfo(List[3], 'Binaries', ContainerFile, LineNo)
        return (List[0], List[1], List[2], List[3])
    elif len(List) == 3:
        return (List[0], List[1], List[2], '')

## Get Guids/Protocols/Ppis
#
# Get Guids/Protocols/Ppis of Inf as <GuidCName>[|<PcdFeatureFlag>]
#
# @param Item:           String as <GuidCName>[|<PcdFeatureFlag>]
# @param Type:           Type of parsing string
# @param ContainerFile:  The file which describes the library class, 
#                        used for error report
#
def GetGuidsProtocolsPpisOfInf(Item):
    ItemNew = Item + DataType.TAB_VALUE_SPLIT
    List = GetSplitValueList(ItemNew)
    return (List[0], List[1])

## Get Guids/Protocols/Ppis
#
# Get Guids/Protocols/Ppis of Dec as <GuidCName>=<GuidValue>
#
# @param Item:           String as <GuidCName>=<GuidValue>
# @param Type:           Type of parsing string
# @param ContainerFile:  The file which describes the library class, 
# used for error report
#
def GetGuidsProtocolsPpisOfDec(Item, Type, ContainerFile, LineNo= -1):
    List = GetSplitValueList(Item, DataType.TAB_EQUAL_SPLIT)
    if len(List) != 2:
        RaiseParserError(Item, Type, ContainerFile, '<CName>=<GuidValue>', \
                         LineNo)
    #
    #convert C-Format Guid to Register Format
    #
    if List[1][0] == '{' and List[1][-1] == '}':
        RegisterFormatGuid = GuidStructureStringToGuidString(List[1])
        if RegisterFormatGuid == '':
            RaiseParserError(Item, Type, ContainerFile, \
                             'CFormat or RegisterFormat', LineNo)
    else:
        if CheckGuidRegFormat(List[1]):
            RegisterFormatGuid = List[1]
        else:
            RaiseParserError(Item, Type, ContainerFile, \
                             'CFormat or RegisterFormat', LineNo)

    return (List[0], RegisterFormatGuid)

## GetPackage
#
# Get Package of Inf as <PackagePath>[|<PcdFeatureFlag>]
#
# @param Item:           String as <PackagePath>[|<PcdFeatureFlag>]
# @param Type:           Type of parsing string
# @param ContainerFile:  The file which describes the library class, 
#                        used for error report
#
def GetPackage(Item, ContainerFile, FileRelativePath, LineNo= -1):
    ItemNew = Item + DataType.TAB_VALUE_SPLIT
    List = GetSplitValueList(ItemNew)
    CheckFileType(List[0], '.Dec', ContainerFile, 'package', List[0], LineNo)
    CheckFileExist(FileRelativePath, List[0], ContainerFile, 'Packages', \
                   List[0], LineNo)
    if List[1] != '':
        CheckPcdTokenInfo(List[1], 'Packages', ContainerFile, LineNo)

    return (List[0], List[1])

## Get Pcd Values of Inf
#
# Get Pcd of Inf as <TokenSpaceGuidCName>.<PcdCName>[|<Value>]
#
# @param Item:  The string describes pcd
# @param Type:  The type of Pcd
# @param File:  The file which describes the pcd, used for error report
#
def GetPcdOfInf(Item, Type, File, LineNo):
    Format = '<TokenSpaceGuidCName>.<PcdCName>[|<Value>]'
    TokenGuid, TokenName, Value, InfType = '', '', '', ''

    if Type == DataType.TAB_PCDS_FIXED_AT_BUILD:
        InfType = DataType.TAB_INF_FIXED_PCD
    elif Type == DataType.TAB_PCDS_PATCHABLE_IN_MODULE:
        InfType = DataType.TAB_INF_PATCH_PCD
    elif Type == DataType.TAB_PCDS_FEATURE_FLAG:
        InfType = DataType.TAB_INF_FEATURE_PCD
    elif Type == DataType.TAB_PCDS_DYNAMIC_EX:
        InfType = DataType.TAB_INF_PCD_EX
    elif Type == DataType.TAB_PCDS_DYNAMIC:
        InfType = DataType.TAB_INF_PCD
    List = GetSplitValueList(Item, DataType.TAB_VALUE_SPLIT, 1)
    TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT)
    if len(TokenInfo) != 2:
        RaiseParserError(Item, InfType, File, Format, LineNo)
    else:
        TokenGuid = TokenInfo[0]
        TokenName = TokenInfo[1]

    if len(List) > 1:
        Value = List[1]
    else:
        Value = None
    return (TokenGuid, TokenName, Value, InfType)


## Get Pcd Values of Dec
#
# Get Pcd of Dec as <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
# @param Item:  Pcd item
# @param Type:  Pcd type
# @param File:  Dec file
# @param LineNo:  Line number
#
def GetPcdOfDec(Item, Type, File, LineNo= -1):
    Format = '<TokenSpaceGuidCName>.<PcdCName>|<Value>|<DatumType>|<Token>'
    TokenGuid, TokenName, Value, DatumType, Token = '', '', '', '', ''
    List = GetSplitValueList(Item)
    if len(List) != 4:
        RaiseParserError(Item, 'Pcds' + Type, File, Format, LineNo)
    else:
        Value = List[1]
        DatumType = List[2]
        Token = List[3]
    TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT)
    if len(TokenInfo) != 2:
        RaiseParserError(Item, 'Pcds' + Type, File, Format, LineNo)
    else:
        TokenGuid = TokenInfo[0]
        TokenName = TokenInfo[1]

    return (TokenGuid, TokenName, Value, DatumType, Token, Type)

## Parse DEFINE statement
#
# Get DEFINE macros
#
# @param LineValue:  A DEFINE line value
# @param StartLine:  A DEFINE start line
# @param Table:      A table
# @param FileID:     File ID
# @param Filename:   File name
# @param SectionName:  DEFINE section name
# @param SectionModel:  DEFINE section model
# @param Arch:   DEFINE arch
#
def ParseDefine(LineValue, StartLine, Table, FileID, SectionName, \
                SectionModel, Arch):
    Logger.Debug(Logger.DEBUG_2, ST.MSG_DEFINE_STATEMENT_FOUND % (LineValue, \
                                                                  SectionName))
    Define = \
    GetSplitValueList(CleanString\
                      (LineValue[LineValue.upper().\
                                 find(DataType.TAB_DEFINE.upper() + ' ') + \
                                 len(DataType.TAB_DEFINE + ' ') : ]), \
                                 DataType.TAB_EQUAL_SPLIT, 1)
    Table.Insert(DataType.MODEL_META_DATA_DEFINE, Define[0], Define[1], '', \
                 '', '', Arch, SectionModel, FileID, StartLine, -1, \
                 StartLine, -1, 0)

## InsertSectionItems
#
# Insert item data of a section to a dict
#
# @param Model:   A model
# @param CurrentSection:   Current section
# @param SectionItemList:   Section item list
# @param ArchList:   Arch list
# @param ThirdList:   Third list
# @param RecordSet:   Record set
#
def InsertSectionItems(Model, SectionItemList, ArchList, \
                       ThirdList, RecordSet):
    #
    # Insert each item data of a section
    #
    for Index in range(0, len(ArchList)):
        Arch = ArchList[Index]
        Third = ThirdList[Index]
        if Arch == '':
            Arch = DataType.TAB_ARCH_COMMON

        Records = RecordSet[Model]
        for SectionItem in SectionItemList:
            LineValue, StartLine, Comment = SectionItem[0], \
            SectionItem[1], SectionItem[2]

            Logger.Debug(4, ST.MSG_PARSING % LineValue)
            #
            # And then parse DEFINE statement
            #
            if LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') > -1:
                continue
            #
            # At last parse other sections
            #
            IdNum = -1
            Records.append([LineValue, Arch, StartLine, IdNum, Third, Comment])

        if RecordSet != {}:
            RecordSet[Model] = Records

## GenMetaDatSectionItem
#
# @param Key:    A key
# @param Value:  A value
# @param List:   A list
#
def GenMetaDatSectionItem(Key, Value, List):
    if Key not in List:
        List[Key] = [Value]
    else:
        List[Key].append(Value)

## GetPkgInfoFromDec
#
# get package name, guid, version info from dec files
#
# @param Path:   File path
#
def GetPkgInfoFromDec(Path):
    PkgName = None
    PkgGuid = None
    PkgVersion = None

    Path = Path.replace('\\', '/')

    if not os.path.exists(Path):
        Logger.Error("\nUPT", FILE_NOT_FOUND, File=Path)

    if Path in gPKG_INFO_DICT:
        return gPKG_INFO_DICT[Path]

    try:
        DecParser = None
        if Path not in GlobalData.gPackageDict:
            DecParser = Dec(Path)
            GlobalData.gPackageDict[Path] = DecParser
        else:
            DecParser = GlobalData.gPackageDict[Path]

        PkgName = DecParser.GetPackageName()
        PkgGuid = DecParser.GetPackageGuid()
        PkgVersion = DecParser.GetPackageVersion()
        gPKG_INFO_DICT[Path] = (PkgName, PkgGuid, PkgVersion)
        return PkgName, PkgGuid, PkgVersion
    except FatalError:
        return None, None, None


## GetWorkspacePackage
#
# Get a list of workspace package information.
#
def GetWorkspacePackage():
    DecFileList = []
    WorkspaceDir = GlobalData.gWORKSPACE
    PackageDir = GlobalData.gPACKAGE_PATH
    for PkgRoot in [WorkspaceDir] + PackageDir:
        for Root, Dirs, Files in os.walk(PkgRoot):
            if 'CVS' in Dirs:
                Dirs.remove('CVS')
            if '.svn' in Dirs:
                Dirs.remove('.svn')
            for Dir in Dirs:
                if Dir.startswith('.'):
                    Dirs.remove(Dir)
            for FileSp in Files:
                if FileSp.startswith('.'):
                    continue
                Ext = os.path.splitext(FileSp)[1]
                if Ext.lower() in ['.dec']:
                    DecFileList.append\
                    (os.path.normpath(os.path.join(Root, FileSp)))
    #
    # abstract package guid, version info from DecFile List
    #
    PkgList = []
    for DecFile in DecFileList:
        (PkgName, PkgGuid, PkgVersion) = GetPkgInfoFromDec(DecFile)
        if PkgName and PkgGuid and PkgVersion:
            PkgList.append((PkgName, PkgGuid, PkgVersion, DecFile))

    return PkgList

## GetWorkspaceModule
#
# Get a list of workspace modules.
#
def GetWorkspaceModule():
    InfFileList = []
    WorkspaceDir = GlobalData.gWORKSPACE
    for Root, Dirs, Files in os.walk(WorkspaceDir):
        if 'CVS' in Dirs:
            Dirs.remove('CVS')
        if '.svn' in Dirs:
            Dirs.remove('.svn')
        if 'Build' in Dirs:
            Dirs.remove('Build')
        for Dir in Dirs:
            if Dir.startswith('.'):
                Dirs.remove(Dir)
        for FileSp in Files:
            if FileSp.startswith('.'):
                continue
            Ext = os.path.splitext(FileSp)[1]
            if Ext.lower() in ['.inf']:
                InfFileList.append\
                (os.path.normpath(os.path.join(Root, FileSp)))

    return InfFileList

## MacroParser used to parse macro definition
#
# @param Line:            The content contain linestring and line number
# @param FileName:        The meta-file file name
# @param SectionType:     Section for the Line belong to
# @param FileLocalMacros: A list contain Macro defined in [Defines] section.
#
def MacroParser(Line, FileName, SectionType, FileLocalMacros):
    MacroDefPattern = re.compile("^(DEFINE)[ \t]+")
    LineContent = Line[0]
    LineNo = Line[1]
    Match = MacroDefPattern.match(LineContent)
    if not Match:
        #
        # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method
        #
        return None, None

    TokenList = GetSplitValueList(LineContent[Match.end(1):], \
                                  DataType.TAB_EQUAL_SPLIT, 1)
    #
    # Syntax check
    #
    if not TokenList[0]:
        Logger.Error('Parser', FORMAT_INVALID, ST.ERR_MACRONAME_NOGIVEN,
                        ExtraData=LineContent, File=FileName, Line=LineNo)
    if len(TokenList) < 2:
        Logger.Error('Parser', FORMAT_INVALID, ST.ERR_MACROVALUE_NOGIVEN,
                        ExtraData=LineContent, File=FileName, Line=LineNo)

    Name, Value = TokenList

    #
    # DEFINE defined macros
    #
    if SectionType == DataType.MODEL_META_DATA_HEADER:
        FileLocalMacros[Name] = Value

    ReIsValidMacroName = re.compile(r"^[A-Z][A-Z0-9_]*$", re.DOTALL)
    if ReIsValidMacroName.match(Name) is None:
        Logger.Error('Parser',
                     FORMAT_INVALID,
                     ST.ERR_MACRONAME_INVALID % (Name),
                     ExtraData=LineContent,
                     File=FileName,
                     Line=LineNo)

    # Validate MACRO Value
    #
    # <MacroDefinition> ::=  [<Comments>]{0,}
    #                       "DEFINE" <MACRO> "=" [{<PATH>} {<VALUE>}] <EOL>
    # <Value>           ::=  {<NumVal>} {<Boolean>} {<AsciiString>} {<GUID>}
    #                        {<CString>} {<UnicodeString>} {<CArray>}
    #
    # The definition of <NumVal>, <PATH>, <Boolean>, <GUID>, <CString>, 
    # <UnicodeString>, <CArray> are subset of <AsciiString>.
    #
    ReIsValidMacroValue = re.compile(r"^[\x20-\x7e]*$", re.DOTALL)
    if ReIsValidMacroValue.match(Value) is None:
        Logger.Error('Parser',
                     FORMAT_INVALID,
                     ST.ERR_MACROVALUE_INVALID % (Value),
                     ExtraData=LineContent,
                     File=FileName,
                     Line=LineNo)

    return Name, Value

## GenSection 
#
# generate section contents
#
# @param  SectionName:  indicate the name of the section, details refer to 
#                       INF, DEC specs
# @param  SectionDict:  section statement dict, key is SectionAttrs(arch, 
#                       moduletype or platform may exist as needed) list 
#                       seperated by space, 
#                       value is statement
#
def GenSection(SectionName, SectionDict, SplitArch=True, NeedBlankLine=False):
    Content = ''
    for SectionAttrs in SectionDict:
        StatementList = SectionDict[SectionAttrs]
        if SectionAttrs and SectionName != 'Defines' and SectionAttrs.strip().upper() != DataType.TAB_ARCH_COMMON:
            if SplitArch:
                ArchList = GetSplitValueList(SectionAttrs, DataType.TAB_SPACE_SPLIT)
            else:
                if SectionName != 'UserExtensions':
                    ArchList = GetSplitValueList(SectionAttrs, DataType.TAB_COMMENT_SPLIT)
                else:
                    ArchList = [SectionAttrs]
            for Index in xrange(0, len(ArchList)):
                ArchList[Index] = ConvertArchForInstall(ArchList[Index])
            Section = '[' + SectionName + '.' + (', ' + SectionName + '.').join(ArchList) + ']'
        else:
            Section = '[' + SectionName + ']'
        Content += '\n' + Section + '\n'
        if StatementList is not None:
            for Statement in StatementList:
                LineList = Statement.split('\n')
                NewStatement = ""
                for Line in LineList:
                    # ignore blank comment
                    if not Line.replace("#", '').strip() and SectionName not in ('Defines', 'Hob', 'Event', 'BootMode'):
                        continue
                    # add two space before non-comments line except the comments in Defines section
                    if Line.strip().startswith('#') and SectionName == 'Defines':
                        NewStatement += "%s\n" % Line
                        continue
                    NewStatement += "  %s\n" % Line
                if NeedBlankLine:
                    Content += NewStatement + '\n'
                else:
                    Content += NewStatement

        if NeedBlankLine:
            Content = Content[:-1]
    if not Content.replace('\\n', '').strip():
        return ''
    return Content

## ConvertArchForInstall
# if Arch.upper() is in "IA32", "X64", "IPF", and "EBC", it must be upper case.  "common" must be lower case.  
# Anything else, the case must be preserved
#
# @param Arch: the arch string that need to be converted, it should be stripped before pass in 
# @return: the arch string that get converted
#
def ConvertArchForInstall(Arch):
    if Arch.upper() in [DataType.TAB_ARCH_IA32, DataType.TAB_ARCH_X64,
                                   DataType.TAB_ARCH_IPF, DataType.TAB_ARCH_EBC]:
        Arch = Arch.upper()
    elif Arch.upper() == DataType.TAB_ARCH_COMMON:
        Arch = Arch.lower()

    return Arch
