## @file
# This file is used to parse INF file of EDK project
#
# Copyright (c) 2008 - 2014, 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.
#

##
# Import Modules
#
from __future__ import print_function
import Common.LongFilePathOs as os
import Common.EdkLogger as EdkLogger
from Common.DataType import *
from CommonDataClass.DataClass import *
from Common.Identification import *
from Common.StringUtils import *
from Parser import *
import Database

## EdkInfParser() class
#
# This class defined basic INF object which is used by inheriting
#
# @param object:       Inherited from object class
#
class EdkInfParser(object):
    ## The constructor
    #
    #  @param  self: The object pointer
    #  @param  Filename: INF file name
    #  @param  Database: Eot database
    #  @param  SourceFileList: A list for all source file belonging this INF file
    #  @param  SourceOverridePath: Override path for source file
    #  @param  Edk_Source: Envirnoment variable EDK_SOURCE
    #  @param  Efi_Source: Envirnoment variable EFI_SOURCE
    #
    def __init__(self, Filename = None, Database = None, SourceFileList = None, SourceOverridePath = None, Edk_Source = None, Efi_Source = None):
        self.Identification = Identification()
        self.Sources = []
        self.Macros = {}

        self.Cur = Database.Cur
        self.TblFile = Database.TblFile
        self.TblInf = Database.TblInf
        self.FileID = -1
        self.SourceOverridePath = SourceOverridePath

        # Load Inf file if filename is not None
        if Filename is not None:
            self.LoadInfFile(Filename)

        if SourceFileList:
            for Item in SourceFileList:
                self.TblInf.Insert(MODEL_EFI_SOURCE_FILE, Item, '', '', '', '', 'COMMON', -1, self.FileID, -1, -1, -1, -1, 0)


    ## LoadInffile() method
    #
    #  Load INF file and insert a record in database
    #
    #  @param  self: The object pointer
    #  @param Filename:  Input value for filename of Inf file
    #
    def LoadInfFile(self, Filename = None):
        # Insert a record for file
        Filename = NormPath(Filename)
        self.Identification.FileFullPath = Filename
        (self.Identification.FileRelativePath, self.Identification.FileName) = os.path.split(Filename)

        self.FileID = self.TblFile.InsertFile(Filename, MODEL_FILE_INF)

        self.ParseInf(PreProcess(Filename, False), self.Identification.FileRelativePath, Filename)

    ## ParserSource() method
    #
    #  Parse Source section and insert records in database
    #
    #  @param self: The object pointer
    #  @param CurrentSection: current section name
    #  @param SectionItemList: the item belonging current section
    #  @param ArchList: A list for arch for this section
    #  @param ThirdList: A list for third item for this section
    #
    def ParserSource(self, CurrentSection, SectionItemList, ArchList, ThirdList):
        for Index in range(0, len(ArchList)):
            Arch = ArchList[Index]
            Third = ThirdList[Index]
            if Arch == '':
                Arch = TAB_ARCH_COMMON

            for Item in SectionItemList:
                if CurrentSection.upper() == 'defines'.upper():
                    (Name, Value) = AddToSelfMacro(self.Macros, Item[0])
                    self.TblInf.Insert(MODEL_META_DATA_HEADER, Name, Value, Third, '', '', Arch, -1, self.FileID, Item[1], -1, Item[1], -1, 0)

    ## ParseInf() method
    #
    #  Parse INF file and get sections information
    #
    #  @param self: The object pointer
    #  @param Lines: contents of INF file
    #  @param FileRelativePath: relative path of the file
    #  @param Filename: file name of INF file
    #
    def ParseInf(self, Lines = [], FileRelativePath = '', Filename = ''):
        IfDefList, SectionItemList, CurrentSection, ArchList, ThirdList, IncludeFiles = \
        [], [], TAB_UNKNOWN, [], [], []
        LineNo = 0

        for Line in Lines:
            LineNo = LineNo + 1
            if Line == '':
                continue
            if Line.startswith(TAB_SECTION_START) and Line.endswith(TAB_SECTION_END):
                self.ParserSource(CurrentSection, SectionItemList, ArchList, ThirdList)

                # Parse the new section
                SectionItemList = []
                ArchList = []
                ThirdList = []
                # Parse section name
                CurrentSection = ''
                LineList = GetSplitValueList(Line[len(TAB_SECTION_START):len(Line) - len(TAB_SECTION_END)], TAB_COMMA_SPLIT)
                for Item in LineList:
                    ItemList = GetSplitValueList(Item, TAB_SPLIT)
                    if CurrentSection == '':
                        CurrentSection = ItemList[0]
                    else:
                        if CurrentSection != ItemList[0]:
                            EdkLogger.error("Parser", PARSER_ERROR, "Different section names '%s' and '%s' are found in one section definition, this is not allowed." % (CurrentSection, ItemList[0]), File=Filename, Line=LineNo)
                    ItemList.append('')
                    ItemList.append('')
                    if len(ItemList) > 5:
                        RaiseParserError(Line, CurrentSection, Filename, '', LineNo)
                    else:
                        ArchList.append(ItemList[1].upper())
                        ThirdList.append(ItemList[2])

                continue

            # Add a section item
            SectionItemList.append([Line, LineNo])
            # End of parse

        self.ParserSource(CurrentSection, SectionItemList, ArchList, ThirdList)
        #End of For

##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
    EdkLogger.Initialize()
    EdkLogger.SetLevel(EdkLogger.QUIET)

    Db = Database.Database('Inf.db')
    Db.InitDatabase()
    P = EdkInfParser(os.path.normpath("C:\Framework\Edk\Sample\Platform\Nt32\Dxe\PlatformBds\PlatformBds.inf"), Db, '', '')
    for Inf in P.Sources:
        print(Inf)
    for Item in P.Macros:
        print(Item, P.Macros[Item])

    Db.Close()
