1## @file
2# This file is used to parse INF file of EDK project
3#
4# Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
5# This program and the accompanying materials
6# are licensed and made available under the terms and conditions of the BSD License
7# which accompanies this distribution.  The full text of the license may be found at
8# http://opensource.org/licenses/bsd-license.php
9#
10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12#
13
14##
15# Import Modules
16#
17import Common.LongFilePathOs as os
18import Common.EdkLogger as EdkLogger
19from Common.DataType import *
20from CommonDataClass.DataClass import *
21from Common.Identification import *
22from Common.String import *
23from Parser import *
24import Database
25
26## EdkInfParser() class
27#
28# This class defined basic INF object which is used by inheriting
29#
30# @param object:       Inherited from object class
31#
32class EdkInfParser(object):
33    ## The constructor
34    #
35    #  @param  self: The object pointer
36    #  @param  Filename: INF file name
37    #  @param  Database: Eot database
38    #  @param  SourceFileList: A list for all source file belonging this INF file
39    #  @param  SourceOverridePath: Override path for source file
40    #  @param  Edk_Source: Envirnoment variable EDK_SOURCE
41    #  @param  Efi_Source: Envirnoment variable EFI_SOURCE
42    #
43    def __init__(self, Filename = None, Database = None, SourceFileList = None, SourceOverridePath = None, Edk_Source = None, Efi_Source = None):
44        self.Identification = Identification()
45        self.Sources = []
46        self.Macros = {}
47
48        self.Cur = Database.Cur
49        self.TblFile = Database.TblFile
50        self.TblInf = Database.TblInf
51        self.FileID = -1
52        self.SourceOverridePath = SourceOverridePath
53
54        # Load Inf file if filename is not None
55        if Filename != None:
56            self.LoadInfFile(Filename)
57
58        if SourceFileList:
59            for Item in SourceFileList:
60                self.TblInf.Insert(MODEL_EFI_SOURCE_FILE, Item, '', '', '', '', 'COMMON', -1, self.FileID, -1, -1, -1, -1, 0)
61
62
63    ## LoadInffile() method
64    #
65    #  Load INF file and insert a record in database
66    #
67    #  @param  self: The object pointer
68    #  @param Filename:  Input value for filename of Inf file
69    #
70    def LoadInfFile(self, Filename = None):
71        # Insert a record for file
72        Filename = NormPath(Filename)
73        self.Identification.FileFullPath = Filename
74        (self.Identification.FileRelativePath, self.Identification.FileName) = os.path.split(Filename)
75
76        self.FileID = self.TblFile.InsertFile(Filename, MODEL_FILE_INF)
77
78        self.ParseInf(PreProcess(Filename, False), self.Identification.FileRelativePath, Filename)
79
80    ## ParserSource() method
81    #
82    #  Parse Source section and insert records in database
83    #
84    #  @param self: The object pointer
85    #  @param CurrentSection: current section name
86    #  @param SectionItemList: the item belonging current section
87    #  @param ArchList: A list for arch for this section
88    #  @param ThirdList: A list for third item for this section
89    #
90    def ParserSource(self, CurrentSection, SectionItemList, ArchList, ThirdList):
91        for Index in range(0, len(ArchList)):
92            Arch = ArchList[Index]
93            Third = ThirdList[Index]
94            if Arch == '':
95                Arch = TAB_ARCH_COMMON
96
97            for Item in SectionItemList:
98                if CurrentSection.upper() == 'defines'.upper():
99                    (Name, Value) = AddToSelfMacro(self.Macros, Item[0])
100                    self.TblInf.Insert(MODEL_META_DATA_HEADER, Name, Value, Third, '', '', Arch, -1, self.FileID, Item[1], -1, Item[1], -1, 0)
101
102    ## ParseInf() method
103    #
104    #  Parse INF file and get sections information
105    #
106    #  @param self: The object pointer
107    #  @param Lines: contents of INF file
108    #  @param FileRelativePath: relative path of the file
109    #  @param Filename: file name of INF file
110    #
111    def ParseInf(self, Lines = [], FileRelativePath = '', Filename = ''):
112        IfDefList, SectionItemList, CurrentSection, ArchList, ThirdList, IncludeFiles = \
113        [], [], TAB_UNKNOWN, [], [], []
114        LineNo = 0
115
116        for Line in Lines:
117            LineNo = LineNo + 1
118            if Line == '':
119                continue
120            if Line.startswith(TAB_SECTION_START) and Line.endswith(TAB_SECTION_END):
121                self.ParserSource(CurrentSection, SectionItemList, ArchList, ThirdList)
122
123                # Parse the new section
124                SectionItemList = []
125                ArchList = []
126                ThirdList = []
127                # Parse section name
128                CurrentSection = ''
129                LineList = GetSplitValueList(Line[len(TAB_SECTION_START):len(Line) - len(TAB_SECTION_END)], TAB_COMMA_SPLIT)
130                for Item in LineList:
131                    ItemList = GetSplitValueList(Item, TAB_SPLIT)
132                    if CurrentSection == '':
133                        CurrentSection = ItemList[0]
134                    else:
135                        if CurrentSection != ItemList[0]:
136                            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)
137                    ItemList.append('')
138                    ItemList.append('')
139                    if len(ItemList) > 5:
140                        RaiseParserError(Line, CurrentSection, Filename, '', LineNo)
141                    else:
142                        ArchList.append(ItemList[1].upper())
143                        ThirdList.append(ItemList[2])
144
145                continue
146
147            # Add a section item
148            SectionItemList.append([Line, LineNo])
149            # End of parse
150
151        self.ParserSource(CurrentSection, SectionItemList, ArchList, ThirdList)
152        #End of For
153
154##
155#
156# This acts like the main() function for the script, unless it is 'import'ed into another
157# script.
158#
159if __name__ == '__main__':
160    EdkLogger.Initialize()
161    EdkLogger.SetLevel(EdkLogger.QUIET)
162
163    Db = Database.Database('Inf.db')
164    Db.InitDatabase()
165    P = EdkInfParser(os.path.normpath("C:\Framework\Edk\Sample\Platform\Nt32\Dxe\PlatformBds\PlatformBds.inf"), Db, '', '')
166    for Inf in P.Sources:
167        print Inf
168    for Item in P.Macros:
169        print Item, P.Macros[Item]
170
171    Db.Close()