## @file
# This file contained the parser for [Pcds] sections in INF file
#
# 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.
#
'''
InfPcdSectionParser
'''
##
# Import Modules
#

import Logger.Log as Logger
from Logger import StringTable as ST
from Logger.ToolError import FORMAT_INVALID
from Parser.InfParserMisc import InfExpandMacro
from Library import DataType as DT
from Library.Parsing import MacroParser
from Library.Misc import GetSplitValueList
from Library import GlobalData
from Library.StringUtils import SplitPcdEntry
from Parser.InfParserMisc import InfParserSectionRoot

class InfPcdSectionParser(InfParserSectionRoot):
    ## Section PCD related parser
    #
    # For 5 types of PCD list below, all use this function.
    # 'FixedPcd', 'FeaturePcd', 'PatchPcd', 'Pcd', 'PcdEx'
    #
    # This is a INF independent parser, the validation in this parser only
    # cover
    # INF spec scope, will not cross DEC/DSC to check pcd value
    #
    def InfPcdParser(self, SectionString, InfSectionObject, FileName):
        KeysList = []
        PcdList   = []
        CommentsList = []
        ValueList = []
        #
        # Current section archs
        #
        LineIndex = -1
        for Item in self.LastSectionHeaderContent:
            if (Item[0], Item[1], Item[3]) not in KeysList:
                KeysList.append((Item[0], Item[1], Item[3]))
                LineIndex = Item[3]

            if (Item[0].upper() == DT.TAB_INF_FIXED_PCD.upper() or \
                Item[0].upper() == DT.TAB_INF_FEATURE_PCD.upper() or \
                Item[0].upper() == DT.TAB_INF_PCD.upper()) and GlobalData.gIS_BINARY_INF:
                Logger.Error('InfParser', FORMAT_INVALID, ST.ERR_ASBUILD_PCD_SECTION_TYPE%("\"" + Item[0] + "\""),
                             File=FileName, Line=LineIndex)

        #
        # For Common INF file
        #
        if not GlobalData.gIS_BINARY_INF:
            #
            # Macro defined in this section
            #
            SectionMacros = {}
            for Line in SectionString:
                PcdLineContent = Line[0]
                PcdLineNo      = Line[1]
                if PcdLineContent.strip() == '':
                    CommentsList = []
                    continue

                if PcdLineContent.strip().startswith(DT.TAB_COMMENT_SPLIT):
                    CommentsList.append(Line)
                    continue
                else:
                    #
                    # Encounter a PCD entry
                    #
                    if PcdLineContent.find(DT.TAB_COMMENT_SPLIT) > -1:
                        CommentsList.append((
                                PcdLineContent[PcdLineContent.find(DT.TAB_COMMENT_SPLIT):],
                                PcdLineNo))
                        PcdLineContent = PcdLineContent[:PcdLineContent.find(DT.TAB_COMMENT_SPLIT)]

                if PcdLineContent != '':
                    #
                    # Find Macro
                    #
                    Name, Value = MacroParser((PcdLineContent, PcdLineNo),
                                              FileName,
                                              DT.MODEL_EFI_PCD,
                                              self.FileLocalMacros)
                    if Name is not None:
                        SectionMacros[Name] = Value
                        ValueList = []
                        CommentsList = []
                        continue

                    PcdEntryReturn = SplitPcdEntry(PcdLineContent)

                    if not PcdEntryReturn[1]:
                        TokenList = ['']
                    else:
                        TokenList = PcdEntryReturn[0]

                    ValueList[0:len(TokenList)] = TokenList

                    #
                    # Replace with Local section Macro and [Defines] section Macro.
                    #
                    ValueList = [InfExpandMacro(Value, (FileName, PcdLineContent, PcdLineNo),
                                                self.FileLocalMacros, SectionMacros, True)
                                for Value in ValueList]

                if len(ValueList) >= 1:
                    PcdList.append((ValueList, CommentsList, (PcdLineContent, PcdLineNo, FileName)))
                    ValueList = []
                    CommentsList = []
                continue
        #
        # For Binary INF file
        #
        else:
            for Line in SectionString:
                LineContent = Line[0].strip()
                LineNo      = Line[1]

                if LineContent == '':
                    CommentsList = []
                    continue

                if LineContent.startswith(DT.TAB_COMMENT_SPLIT):
                    CommentsList.append(LineContent)
                    continue
                #
                # Have comments at tail.
                #
                CommentIndex = LineContent.find(DT.TAB_COMMENT_SPLIT)
                if  CommentIndex > -1:
                    CommentsList.append(LineContent[CommentIndex+1:])
                    LineContent = LineContent[:CommentIndex]

                TokenList = GetSplitValueList(LineContent, DT.TAB_VALUE_SPLIT)
                #
                # PatchablePcd
                # TokenSpace.CName | Value | Offset
                #
                if KeysList[0][0].upper() == DT.TAB_INF_PATCH_PCD.upper():
                    if len(TokenList) != 3:
                        Logger.Error('InfParser',
                                     FORMAT_INVALID,
                                     ST.ERR_ASBUILD_PATCHPCD_FORMAT_INVALID,
                                     File=FileName,
                                     Line=LineNo,
                                     ExtraData=LineContent)
                #
                elif KeysList[0][0].upper() == DT.TAB_INF_PCD_EX.upper():
                    if len(TokenList) != 1:
                        Logger.Error('InfParser',
                                     FORMAT_INVALID,
                                     ST.ERR_ASBUILD_PCDEX_FORMAT_INVALID,
                                     File=FileName,
                                     Line=LineNo,
                                     ExtraData=LineContent)
                ValueList[0:len(TokenList)] = TokenList
                if len(ValueList) >= 1:
                    PcdList.append((ValueList, CommentsList, (LineContent, LineNo, FileName)))
                    ValueList = []
                    CommentsList = []
                continue

        if not InfSectionObject.SetPcds(PcdList, KeysList = KeysList,
                                        PackageInfo = self.InfPackageSection.GetPackages()):
            Logger.Error('InfParser',
                         FORMAT_INVALID,
                         ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR%("[PCD]"),
                         File=FileName,
                         Line=LineIndex)

