1## @file
2# This file is used to define class objects of INF file [LibraryClasses] section.
3# It will consumed by InfParser.
4#
5# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
6#
7# SPDX-License-Identifier: BSD-2-Clause-Patent
8
9'''
10InfLibraryClassesObject
11'''
12
13from Logger import StringTable as ST
14from Logger import ToolError
15import Logger.Log as Logger
16from Library import GlobalData
17
18from Library.Misc import Sdict
19from Object.Parser.InfCommonObject import CurrentLine
20from Library.ExpressionValidate import IsValidFeatureFlagExp
21from Library.ParserValidate import IsValidLibName
22
23## GetArchModuleType
24#
25# Get Arch List and ModuleType List
26#
27def GetArchModuleType(KeyList):
28    __SupArchList = []
29    __SupModuleList = []
30
31    for (ArchItem, ModuleItem) in KeyList:
32        #
33        # Validate Arch
34        #
35        if (ArchItem == '' or ArchItem is None):
36            ArchItem = 'COMMON'
37
38        if (ModuleItem == '' or ModuleItem is None):
39            ModuleItem = 'COMMON'
40
41        if ArchItem not in __SupArchList:
42            __SupArchList.append(ArchItem)
43
44        List = ModuleItem.split('|')
45        for Entry in List:
46            if Entry not in __SupModuleList:
47                __SupModuleList.append(Entry)
48
49    return (__SupArchList, __SupModuleList)
50
51
52class InfLibraryClassItem():
53    def __init__(self, LibName='', FeatureFlagExp='', HelpString=None):
54        self.LibName = LibName
55        self.FeatureFlagExp = FeatureFlagExp
56        self.HelpString = HelpString
57        self.CurrentLine = CurrentLine()
58        self.SupArchList = []
59        self.SupModuleList = []
60        self.FileGuid = ''
61        self.Version = ''
62
63    def SetLibName(self, LibName):
64        self.LibName = LibName
65    def GetLibName(self):
66        return self.LibName
67
68    def SetHelpString(self, HelpString):
69        self.HelpString = HelpString
70    def GetHelpString(self):
71        return self.HelpString
72
73    def SetFeatureFlagExp(self, FeatureFlagExp):
74        self.FeatureFlagExp = FeatureFlagExp
75    def GetFeatureFlagExp(self):
76        return self.FeatureFlagExp
77
78    def SetSupArchList(self, SupArchList):
79        self.SupArchList = SupArchList
80    def GetSupArchList(self):
81        return self.SupArchList
82
83    def SetSupModuleList(self, SupModuleList):
84        self.SupModuleList = SupModuleList
85    def GetSupModuleList(self):
86        return self.SupModuleList
87
88    #
89    # As Build related information
90    #
91    def SetFileGuid(self, FileGuid):
92        self.FileGuid = FileGuid
93    def GetFileGuid(self):
94        return self.FileGuid
95
96    def SetVersion(self, Version):
97        self.Version = Version
98    def GetVersion(self):
99        return self.Version
100
101## INF LibraryClass Section
102#
103#
104#
105class InfLibraryClassObject():
106    def __init__(self):
107        self.LibraryClasses = Sdict()
108        #
109        # Macro defined in this section should be only used in this section.
110        #
111        self.Macros = {}
112
113    ##SetLibraryClasses
114    #
115    #
116    # @param HelpString:     It can be a common comment or contain a recommend
117    #                        instance.
118    #
119    def SetLibraryClasses(self, LibContent, KeyList=None):
120        #
121        # Validate Arch
122        #
123        (__SupArchList, __SupModuleList) = GetArchModuleType(KeyList)
124
125        for LibItem in LibContent:
126            LibItemObj = InfLibraryClassItem()
127            if not GlobalData.gIS_BINARY_INF:
128                HelpStringObj = LibItem[1]
129                LibItemObj.CurrentLine.SetFileName(LibItem[2][2])
130                LibItemObj.CurrentLine.SetLineNo(LibItem[2][1])
131                LibItemObj.CurrentLine.SetLineString(LibItem[2][0])
132                LibItem = LibItem[0]
133                if HelpStringObj is not None:
134                    LibItemObj.SetHelpString(HelpStringObj)
135                if len(LibItem) >= 1:
136                    if LibItem[0].strip() != '':
137                        if IsValidLibName(LibItem[0].strip()):
138                            if LibItem[0].strip() != 'NULL':
139                                LibItemObj.SetLibName(LibItem[0])
140                            else:
141                                Logger.Error("InfParser",
142                                         ToolError.FORMAT_INVALID,
143                                         ST.ERR_INF_PARSER_DEFINE_LIB_NAME_INVALID,
144                                         File=GlobalData.gINF_MODULE_NAME,
145                                         Line=LibItemObj.CurrentLine.GetLineNo(),
146                                         ExtraData=LibItemObj.CurrentLine.GetLineString())
147                        else:
148                            Logger.Error("InfParser",
149                                         ToolError.FORMAT_INVALID,
150                                         ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID % (LibItem[0]),
151                                         File=GlobalData.gINF_MODULE_NAME,
152                                         Line=LibItemObj.CurrentLine.GetLineNo(),
153                                         ExtraData=LibItemObj.CurrentLine.GetLineString())
154                    else:
155                        Logger.Error("InfParser",
156                                     ToolError.FORMAT_INVALID,
157                                     ST.ERR_INF_PARSER_LIBRARY_SECTION_LIBNAME_MISSING,
158                                     File=GlobalData.gINF_MODULE_NAME,
159                                     Line=LibItemObj.CurrentLine.GetLineNo(),
160                                     ExtraData=LibItemObj.CurrentLine.GetLineString())
161                if len(LibItem) == 2:
162                    if LibItem[1].strip() == '':
163                        Logger.Error("InfParser",
164                                     ToolError.FORMAT_INVALID,
165                                     ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING,
166                                     File=GlobalData.gINF_MODULE_NAME,
167                                     Line=LibItemObj.CurrentLine.GetLineNo(),
168                                     ExtraData=LibItemObj.CurrentLine.GetLineString())
169                    #
170                    # Validate FFE
171                    #
172                    FeatureFlagRtv = IsValidFeatureFlagExp(LibItem[1].strip())
173                    if not FeatureFlagRtv[0]:
174                        Logger.Error("InfParser",
175                                     ToolError.FORMAT_INVALID,
176                                     ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID % (FeatureFlagRtv[1]),
177                                     File=GlobalData.gINF_MODULE_NAME,
178                                     Line=LibItemObj.CurrentLine.GetLineNo(),
179                                     ExtraData=LibItemObj.CurrentLine.GetLineString())
180                    LibItemObj.SetFeatureFlagExp(LibItem[1].strip())
181
182                #
183                # Invalid strings
184                #
185                if len(LibItem) < 1 or len(LibItem) > 2:
186                    Logger.Error("InfParser",
187                                 ToolError.FORMAT_INVALID,
188                                 ST.ERR_INF_PARSER_LIBRARY_SECTION_CONTENT_ERROR,
189                                 File=GlobalData.gINF_MODULE_NAME,
190                                 Line=LibItemObj.CurrentLine.GetLineNo(),
191                                 ExtraData=LibItemObj.CurrentLine.GetLineString())
192
193                LibItemObj.SetSupArchList(__SupArchList)
194                LibItemObj.SetSupModuleList(__SupModuleList)
195
196                #
197                # Determine Library class duplicate. Follow below rule:
198                #
199                # A library class keyword must not be duplicated within a
200                # [LibraryClasses] section. Library class keywords may appear in
201                # multiple architectural and module type [LibraryClasses] sections.
202                # A library class keyword listed in an architectural or module type
203                # [LibraryClasses] section must not be listed in the common
204                # architectural or module type [LibraryClasses] section.
205                #
206                # NOTE: This check will not report error now. But keep code for future enhancement.
207                #
208#                for Item in self.LibraryClasses:
209#                    if Item.GetLibName() == LibItemObj.GetLibName():
210#                        ItemSupArchList = Item.GetSupArchList()
211#                        ItemSupModuleList = Item.GetSupModuleList()
212#                        for ItemArch in ItemSupArchList:
213#                            for ItemModule in ItemSupModuleList:
214#                                for LibItemObjArch in __SupArchList:
215#                                    for LibItemObjModule in __SupModuleList:
216#                                        if ItemArch == LibItemObjArch and LibItemObjModule == ItemModule:
217#                                            #
218#                                            # ERR_INF_PARSER_ITEM_DUPLICATE
219#                                            #
220#                                            pass
221#                                        if (ItemArch.upper() == 'COMMON' or LibItemObjArch.upper() == 'COMMON') \
222#                                           and LibItemObjModule == ItemModule:
223#                                            #
224#                                            # ERR_INF_PARSER_ITEM_DUPLICATE_COMMON
225#                                            #
226#                                            pass
227            else:
228                #
229                # Assume the file GUID is well formatted.
230                #
231                LibItemObj.SetFileGuid(LibItem[0])
232                LibItemObj.SetVersion(LibItem[1])
233                LibItemObj.SetSupArchList(__SupArchList)
234
235            if (LibItemObj) in self.LibraryClasses:
236                LibraryList = self.LibraryClasses[LibItemObj]
237                LibraryList.append(LibItemObj)
238                self.LibraryClasses[LibItemObj] = LibraryList
239            else:
240                LibraryList = []
241                LibraryList.append(LibItemObj)
242                self.LibraryClasses[LibItemObj] = LibraryList
243
244        return True
245
246    def GetLibraryClasses(self):
247        return self.LibraryClasses
248