## @file
# This file contained the parser for [Sources] 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.
#
'''
InfSourceSectionParser
'''
##
# 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 Object.Parser.InfCommonObject import InfLineCommentObject
from Parser.InfParserMisc import InfParserSectionRoot

class InfSourceSectionParser(InfParserSectionRoot):
    ## InfSourceParser
    #
    #          
    def InfSourceParser(self, SectionString, InfSectionObject, FileName):
        SectionMacros = {}
        ValueList     = []
        SourceList    = []
        StillCommentFalg  = False
        HeaderComments    = []
        LineComment       = None
        SectionContent  = ''
        for Line in SectionString:
            SrcLineContent = Line[0]
            SrcLineNo      = Line[1]
            
            if SrcLineContent.strip() == '':
                continue
            
            #
            # Found Header Comments 
            #
            if SrcLineContent.strip().startswith(DT.TAB_COMMENT_SPLIT):
                #
                # Last line is comments, and this line go on.
                #
                if StillCommentFalg:
                    HeaderComments.append(Line)
                    SectionContent += SrcLineContent + DT.END_OF_LINE
                    continue
                #
                # First time encounter comment 
                #
                else:
                    #
                    # Clear original data
                    #
                    HeaderComments = []
                    HeaderComments.append(Line)
                    StillCommentFalg = True
                    SectionContent += SrcLineContent + DT.END_OF_LINE 
                    continue
            else:
                StillCommentFalg = False
                          
            if len(HeaderComments) >= 1:
                LineComment = InfLineCommentObject()
                LineCommentContent = ''
                for Item in HeaderComments:
                    LineCommentContent += Item[0] + DT.END_OF_LINE
                LineComment.SetHeaderComments(LineCommentContent)
            
            #
            # Find Tail comment.
            #
            if SrcLineContent.find(DT.TAB_COMMENT_SPLIT) > -1:
                TailComments = SrcLineContent[SrcLineContent.find(DT.TAB_COMMENT_SPLIT):]
                SrcLineContent = SrcLineContent[:SrcLineContent.find(DT.TAB_COMMENT_SPLIT)]
                if LineComment == None:
                    LineComment = InfLineCommentObject()
                LineComment.SetTailComments(TailComments)
                               
            #
            # Find Macro
            #
            Name, Value = MacroParser((SrcLineContent, SrcLineNo), 
                                      FileName,
                                      DT.MODEL_EFI_SOURCE_FILE,
                                      self.FileLocalMacros)
            if Name != None:
                SectionMacros[Name] = Value
                LineComment = None
                HeaderComments = []
                continue
            
            #
            # Replace with Local section Macro and [Defines] section Macro.
            #            
            SrcLineContent = InfExpandMacro(SrcLineContent, 
                                         (FileName, SrcLineContent, SrcLineNo), 
                                         self.FileLocalMacros, 
                                         SectionMacros)

            TokenList = GetSplitValueList(SrcLineContent, DT.TAB_VALUE_SPLIT, 4)
            ValueList[0:len(TokenList)] = TokenList
          
            #
            # Store section content string after MACRO replaced.
            #
            SectionContent += SrcLineContent + DT.END_OF_LINE 
            
            SourceList.append((ValueList, LineComment, 
                               (SrcLineContent, SrcLineNo, FileName)))
            ValueList = []
            LineComment = None
            TailComments = ''
            HeaderComments = []
            continue
        
        #
        # Current section archs
        #
        ArchList = []
        for Item in self.LastSectionHeaderContent:
            if Item[1] not in ArchList:
                ArchList.append(Item[1])  
                InfSectionObject.SetSupArchList(Item[1])
                
        InfSectionObject.SetAllContent(SectionContent)             
        if not InfSectionObject.SetSources(SourceList, Arch = ArchList):
            Logger.Error('InfParser', 
                         FORMAT_INVALID,
                         ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % ("[Sources]"),
                         File=FileName, 
                         Line=Item[3])            