1## @file
2# This file is used to parse INF file of EDK project
3#
4# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
5# SPDX-License-Identifier: BSD-2-Clause-Patent
6#
7
8##
9# Import Modules
10#
11from __future__ import print_function
12from __future__ import absolute_import
13
14import Common.LongFilePathOs as os
15import Common.EdkLogger as EdkLogger
16from Common.DataType import *
17from CommonDataClass.DataClass import *
18from Eot.Identification import Identification
19from Common.StringUtils import *
20from Eot.Parser import *
21from Eot import Database
22from Eot import EotGlobalData
23
24## EdkInfParser() class
25#
26# This class defined basic INF object which is used by inheriting
27#
28# @param object:       Inherited from object class
29#
30class EdkInfParser(object):
31    ## The constructor
32    #
33    #  @param  self: The object pointer
34    #  @param  Filename: INF file name
35    #  @param  Database: Eot database
36    #  @param  SourceFileList: A list for all source file belonging this INF file
37    #
38    def __init__(self, Filename = None, Database = None, SourceFileList = None):
39        self.Identification = Identification()
40        self.Sources = []
41        self.Macros = {}
42
43        self.Cur = Database.Cur
44        self.TblFile = Database.TblFile
45        self.TblInf = Database.TblInf
46        self.FileID = -1
47
48        # Load Inf file if filename is not None
49        if Filename is not None:
50            self.LoadInfFile(Filename)
51
52        if SourceFileList:
53            for Item in SourceFileList:
54                self.TblInf.Insert(MODEL_EFI_SOURCE_FILE, Item, '', '', '', '', 'COMMON', -1, self.FileID, -1, -1, -1, -1, 0)
55
56
57    ## LoadInffile() method
58    #
59    #  Load INF file and insert a record in database
60    #
61    #  @param  self: The object pointer
62    #  @param Filename:  Input value for filename of Inf file
63    #
64    def LoadInfFile(self, Filename = None):
65        # Insert a record for file
66        Filename = NormPath(Filename)
67        self.Identification.FileFullPath = Filename
68        (self.Identification.FileRelativePath, self.Identification.FileName) = os.path.split(Filename)
69
70        self.FileID = self.TblFile.InsertFile(Filename, MODEL_FILE_INF)
71
72        self.ParseInf(PreProcess(Filename, False), self.Identification.FileRelativePath, Filename)
73
74    ## ParserSource() method
75    #
76    #  Parse Source section and insert records in database
77    #
78    #  @param self: The object pointer
79    #  @param CurrentSection: current section name
80    #  @param SectionItemList: the item belonging current section
81    #  @param ArchList: A list for arch for this section
82    #  @param ThirdList: A list for third item for this section
83    #
84    def ParserSource(self, CurrentSection, SectionItemList, ArchList, ThirdList):
85        for Index in range(0, len(ArchList)):
86            Arch = ArchList[Index]
87            Third = ThirdList[Index]
88            if Arch == '':
89                Arch = TAB_ARCH_COMMON
90
91            for Item in SectionItemList:
92                if CurrentSection.upper() == 'defines'.upper():
93                    (Name, Value) = AddToSelfMacro(self.Macros, Item[0])
94                    self.TblInf.Insert(MODEL_META_DATA_HEADER, Name, Value, Third, '', '', Arch, -1, self.FileID, Item[1], -1, Item[1], -1, 0)
95
96    ## ParseInf() method
97    #
98    #  Parse INF file and get sections information
99    #
100    #  @param self: The object pointer
101    #  @param Lines: contents of INF file
102    #  @param FileRelativePath: relative path of the file
103    #  @param Filename: file name of INF file
104    #
105    def ParseInf(self, Lines = [], FileRelativePath = '', Filename = ''):
106        IfDefList, SectionItemList, CurrentSection, ArchList, ThirdList, IncludeFiles = \
107        [], [], TAB_UNKNOWN, [], [], []
108        LineNo = 0
109
110        for Line in Lines:
111            LineNo = LineNo + 1
112            if Line == '':
113                continue
114            if Line.startswith(TAB_SECTION_START) and Line.endswith(TAB_SECTION_END):
115                self.ParserSource(CurrentSection, SectionItemList, ArchList, ThirdList)
116
117                # Parse the new section
118                SectionItemList = []
119                ArchList = []
120                ThirdList = []
121                # Parse section name
122                CurrentSection = ''
123                LineList = GetSplitValueList(Line[len(TAB_SECTION_START):len(Line) - len(TAB_SECTION_END)], TAB_COMMA_SPLIT)
124                for Item in LineList:
125                    ItemList = GetSplitValueList(Item, TAB_SPLIT)
126                    if CurrentSection == '':
127                        CurrentSection = ItemList[0]
128                    else:
129                        if CurrentSection != ItemList[0]:
130                            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)
131                    ItemList.append('')
132                    ItemList.append('')
133                    if len(ItemList) > 5:
134                        RaiseParserError(Line, CurrentSection, Filename, '', LineNo)
135                    else:
136                        ArchList.append(ItemList[1].upper())
137                        ThirdList.append(ItemList[2])
138
139                continue
140
141            # Add a section item
142            SectionItemList.append([Line, LineNo])
143            # End of parse
144
145        self.ParserSource(CurrentSection, SectionItemList, ArchList, ThirdList)
146        #End of For
147
148
149