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