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