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