• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1## @file
2# This file is used to define class objects of INF file [Guids] 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'''
16InfGuidObject
17'''
18
19from Library.ParserValidate import IsValidCVariableName
20from Library.CommentParsing import ParseComment
21from Library.ExpressionValidate import IsValidFeatureFlagExp
22
23from Library.Misc import Sdict
24from Library import DataType as DT
25import Logger.Log as Logger
26from Logger import ToolError
27from Logger import StringTable as ST
28
29class InfGuidItemCommentContent():
30    def __init__(self):
31        #
32        # ## SOMETIMES_CONSUMES ## Variable:L"MemoryTypeInformation"
33        # TailString.
34        #
35        #
36        # SOMETIMES_CONSUMES
37        #
38        self.UsageItem = ''
39        #
40        # Variable
41        #
42        self.GuidTypeItem = ''
43        #
44        # MemoryTypeInformation
45        #
46        self.VariableNameItem = ''
47        #
48        # TailString
49        #
50        self.HelpStringItem = ''
51
52    def SetUsageItem(self, UsageItem):
53        self.UsageItem = UsageItem
54    def GetUsageItem(self):
55        return self.UsageItem
56
57    def SetGuidTypeItem(self, GuidTypeItem):
58        self.GuidTypeItem = GuidTypeItem
59    def GetGuidTypeItem(self):
60        return self.GuidTypeItem
61
62    def SetVariableNameItem(self, VariableNameItem):
63        self.VariableNameItem = VariableNameItem
64    def GetVariableNameItem(self):
65        return self.VariableNameItem
66
67    def SetHelpStringItem(self, HelpStringItem):
68        self.HelpStringItem = HelpStringItem
69    def GetHelpStringItem(self):
70        return self.HelpStringItem
71
72class InfGuidItem():
73    def __init__(self):
74        self.Name = ''
75        self.FeatureFlagExp = ''
76        #
77        # A list contain instance of InfGuidItemCommentContent
78        #
79        self.CommentList = []
80        self.SupArchList = []
81
82    def SetName(self, Name):
83        self.Name = Name
84    def GetName(self):
85        return self.Name
86
87    def SetFeatureFlagExp(self, FeatureFlagExp):
88        self.FeatureFlagExp = FeatureFlagExp
89    def GetFeatureFlagExp(self):
90        return self.FeatureFlagExp
91
92    def SetCommentList(self, CommentList):
93        self.CommentList = CommentList
94    def GetCommentList(self):
95        return self.CommentList
96
97    def SetSupArchList(self, SupArchList):
98        self.SupArchList = SupArchList
99    def GetSupArchList(self):
100        return self.SupArchList
101
102## ParseComment
103#
104# ParseComment
105#
106def ParseGuidComment(CommentsList, InfGuidItemObj):
107    #
108    # Get/Set Usage and HelpString
109    #
110    if CommentsList != None and len(CommentsList) != 0 :
111        CommentInsList = []
112        PreUsage = None
113        PreGuidType = None
114        PreHelpText = ''
115        BlockFlag = -1
116        Count = 0
117        for CommentItem in CommentsList:
118            Count = Count + 1
119            CommentItemUsage, \
120            CommentItemGuidType, \
121            CommentItemVarString, \
122            CommentItemHelpText = \
123                    ParseComment(CommentItem,
124                                 DT.ALL_USAGE_TOKENS,
125                                 DT.GUID_TYPE_TOKENS,
126                                 [],
127                                 True)
128
129            if CommentItemHelpText == None:
130                CommentItemHelpText = ''
131                if Count == len(CommentsList) and CommentItemUsage == CommentItemGuidType == DT.ITEM_UNDEFINED:
132                    CommentItemHelpText = DT.END_OF_LINE
133
134            if Count == len(CommentsList):
135                if BlockFlag == 1 or BlockFlag == 2:
136                    if CommentItemUsage == CommentItemGuidType == DT.ITEM_UNDEFINED:
137                        BlockFlag = 4
138                    else:
139                        BlockFlag = 3
140                if BlockFlag == -1:
141                    BlockFlag = 4
142            if BlockFlag == -1 or BlockFlag == 1 or BlockFlag == 2:
143                if CommentItemUsage == CommentItemGuidType == DT.ITEM_UNDEFINED:
144                    if BlockFlag == -1:
145                        BlockFlag = 1
146                    elif BlockFlag == 1:
147                        BlockFlag = 2
148                else:
149                    if BlockFlag == 1 or BlockFlag == 2:
150                        BlockFlag = 3
151                    elif BlockFlag == -1:
152                        BlockFlag = 4
153
154            #
155            # Combine two comment line if they are generic comment
156            #
157            if CommentItemUsage == CommentItemGuidType == PreUsage == PreGuidType == DT.ITEM_UNDEFINED:
158                CommentItemHelpText = PreHelpText + DT.END_OF_LINE + CommentItemHelpText
159                PreHelpText = CommentItemHelpText
160
161            if BlockFlag == 4:
162                CommentItemIns = InfGuidItemCommentContent()
163                CommentItemIns.SetUsageItem(CommentItemUsage)
164                CommentItemIns.SetGuidTypeItem(CommentItemGuidType)
165                CommentItemIns.SetVariableNameItem(CommentItemVarString)
166                if CommentItemHelpText == '' or CommentItemHelpText.endswith(DT.END_OF_LINE):
167                    CommentItemHelpText = CommentItemHelpText.strip(DT.END_OF_LINE)
168                CommentItemIns.SetHelpStringItem(CommentItemHelpText)
169                CommentInsList.append(CommentItemIns)
170
171                BlockFlag = -1
172                PreUsage = None
173                PreGuidType = None
174                PreHelpText = ''
175
176            elif BlockFlag == 3:
177                #
178                # Add previous help string
179                #
180                CommentItemIns = InfGuidItemCommentContent()
181                CommentItemIns.SetUsageItem(DT.ITEM_UNDEFINED)
182                CommentItemIns.SetGuidTypeItem(DT.ITEM_UNDEFINED)
183                if PreHelpText == '' or PreHelpText.endswith(DT.END_OF_LINE):
184                    PreHelpText = PreHelpText.strip(DT.END_OF_LINE)
185                CommentItemIns.SetHelpStringItem(PreHelpText)
186                CommentInsList.append(CommentItemIns)
187                #
188                # Add Current help string
189                #
190                CommentItemIns = InfGuidItemCommentContent()
191                CommentItemIns.SetUsageItem(CommentItemUsage)
192                CommentItemIns.SetGuidTypeItem(CommentItemGuidType)
193                CommentItemIns.SetVariableNameItem(CommentItemVarString)
194                if CommentItemHelpText == '' or CommentItemHelpText.endswith(DT.END_OF_LINE):
195                    CommentItemHelpText = CommentItemHelpText.strip(DT.END_OF_LINE)
196                CommentItemIns.SetHelpStringItem(CommentItemHelpText)
197                CommentInsList.append(CommentItemIns)
198
199                BlockFlag = -1
200                PreUsage = None
201                PreGuidType = None
202                PreHelpText = ''
203
204            else:
205                PreUsage = CommentItemUsage
206                PreGuidType = CommentItemGuidType
207                PreHelpText = CommentItemHelpText
208
209        InfGuidItemObj.SetCommentList(CommentInsList)
210    else:
211        #
212        # Still need to set the USAGE/GUIDTYPE to undefined.
213        #
214        CommentItemIns = InfGuidItemCommentContent()
215        CommentItemIns.SetUsageItem(DT.ITEM_UNDEFINED)
216        CommentItemIns.SetGuidTypeItem(DT.ITEM_UNDEFINED)
217        InfGuidItemObj.SetCommentList([CommentItemIns])
218
219    return InfGuidItemObj
220
221## InfGuidObject
222#
223# InfGuidObject
224#
225class InfGuidObject():
226    def __init__(self):
227        self.Guids = Sdict()
228        #
229        # Macro defined in this section should be only used in this section.
230        #
231        self.Macros = {}
232
233    def SetGuid(self, GuidList, Arch = None):
234        __SupportArchList = []
235        for ArchItem in Arch:
236            #
237            # Validate Arch
238            #
239            if (ArchItem == '' or ArchItem == None):
240                ArchItem = 'COMMON'
241
242            __SupportArchList.append(ArchItem)
243
244        for Item in GuidList:
245            #
246            # Get Comment content of this protocol
247            #
248            CommentsList = None
249            if len(Item) == 3:
250                CommentsList = Item[1]
251            CurrentLineOfItem = Item[2]
252            Item = Item[0]
253            InfGuidItemObj = InfGuidItem()
254            if len(Item) >= 1 and len(Item) <= 2:
255                #
256                # Only GuildName contained
257                #
258                if not IsValidCVariableName(Item[0]):
259                    Logger.Error("InfParser",
260                                 ToolError.FORMAT_INVALID,
261                                 ST.ERR_INF_PARSER_INVALID_CNAME%(Item[0]),
262                                 File=CurrentLineOfItem[2],
263                                 Line=CurrentLineOfItem[1],
264                                 ExtraData=CurrentLineOfItem[0])
265                if (Item[0] != ''):
266                    InfGuidItemObj.SetName(Item[0])
267                else:
268                    Logger.Error("InfParser",
269                                 ToolError.FORMAT_INVALID,
270                                 ST.ERR_INF_PARSER_CNAME_MISSING,
271                                 File=CurrentLineOfItem[2],
272                                 Line=CurrentLineOfItem[1],
273                                 ExtraData=CurrentLineOfItem[0])
274            if len(Item) == 2:
275                #
276                # Contained CName and Feature Flag Express
277                # <statements>           ::=  <CName> ["|" <FeatureFlagExpress>]
278                # For GUID entry.
279                #
280                if Item[1].strip() == '':
281                    Logger.Error("InfParser",
282                                 ToolError.FORMAT_INVALID,
283                                 ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING,
284                                 File=CurrentLineOfItem[2],
285                                 Line=CurrentLineOfItem[1],
286                                 ExtraData=CurrentLineOfItem[0])
287                #
288                # Validate Feature Flag Express
289                #
290                FeatureFlagRtv = IsValidFeatureFlagExp(Item[1].strip())
291                if not FeatureFlagRtv[0]:
292                    Logger.Error("InfParser",
293                                 ToolError.FORMAT_INVALID,
294                                 ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[1]),
295                                 File=CurrentLineOfItem[2],
296                                 Line=CurrentLineOfItem[1],
297                                 ExtraData=CurrentLineOfItem[0])
298                InfGuidItemObj.SetFeatureFlagExp(Item[1])
299            if len(Item) != 1 and len(Item) != 2:
300                #
301                # Invalid format of GUID statement
302                #
303                Logger.Error("InfParser",
304                             ToolError.FORMAT_INVALID,
305                             ST.ERR_INF_PARSER_GUID_PPI_PROTOCOL_SECTION_CONTENT_ERROR,
306                             File=CurrentLineOfItem[2],
307                             Line=CurrentLineOfItem[1],
308                             ExtraData=CurrentLineOfItem[0])
309
310            InfGuidItemObj = ParseGuidComment(CommentsList, InfGuidItemObj)
311            InfGuidItemObj.SetSupArchList(__SupportArchList)
312
313            #
314            # Determine GUID name duplicate. Follow below rule:
315            #
316            # A GUID must not be duplicated within a [Guids] section.
317            # A GUID may appear in multiple architectural [Guids]
318            # sections. A GUID listed in an architectural [Guids]
319            # section must not be listed in the common architectural
320            # [Guids] section.
321            #
322            # NOTE: This check will not report error now.
323            #
324            for Item in self.Guids:
325                if Item.GetName() == InfGuidItemObj.GetName():
326                    ItemSupArchList = Item.GetSupArchList()
327                    for ItemArch in ItemSupArchList:
328                        for GuidItemObjArch in __SupportArchList:
329                            if ItemArch == GuidItemObjArch:
330                                #
331                                # ST.ERR_INF_PARSER_ITEM_DUPLICATE
332                                #
333                                pass
334
335                            if ItemArch.upper() == 'COMMON' or GuidItemObjArch.upper() == 'COMMON':
336                                #
337                                # ST.ERR_INF_PARSER_ITEM_DUPLICATE_COMMON
338                                #
339                                pass
340
341            if self.Guids.has_key((InfGuidItemObj)):
342                GuidList = self.Guids[InfGuidItemObj]
343                GuidList.append(InfGuidItemObj)
344                self.Guids[InfGuidItemObj] = GuidList
345            else:
346                GuidList = []
347                GuidList.append(InfGuidItemObj)
348                self.Guids[InfGuidItemObj] = GuidList
349
350        return True
351
352    def GetGuid(self):
353        return self.Guids