]>
Commit | Line | Data |
---|---|---|
4234283c LG |
1 | ## @file\r |
2 | # This file is used to define class objects of INF file [Ppis] section. \r | |
3 | # It will consumed by InfParser. \r | |
4 | #\r | |
5 | # Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r | |
6 | #\r | |
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 | |
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 | |
21 | from Library.ExpressionValidate import IsValidFeatureFlagExp \r | |
22 | \r | |
23 | from Library.Misc import Sdict\r | |
24 | from Library import DataType as DT \r | |
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 | |
31 | PreUsage = None \r | |
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 | |
42 | ParseComment(CommentItem, \r | |
43 | DT.ALL_USAGE_TOKENS, \r | |
44 | DT.PPI_NOTIFY_TOKENS, \r | |
45 | ['PPI'], \r | |
46 | False)\r | |
47 | \r | |
48 | #\r | |
49 | # To avoid PyLint error \r | |
50 | #\r | |
51 | if CommentItemString:\r | |
52 | pass\r | |
53 | \r | |
54 | if CommentItemHelpText == None:\r | |
55 | CommentItemHelpText = ''\r | |
56 | if Count == len(CommentsList) and CommentItemUsage == CommentItemNotify == DT.ITEM_UNDEFINED:\r | |
57 | CommentItemHelpText = DT.END_OF_LINE \r | |
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 | |
68 | BlockFlag = 4 \r | |
69 | \r | |
70 | #\r | |
71 | # Comment USAGE and NOTIFY information are "UNDEFINED"\r | |
72 | #\r | |
73 | if BlockFlag == -1 or BlockFlag == 1 or BlockFlag == 2: \r | |
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 | |
84 | # \r | |
85 | elif BlockFlag == -1:\r | |
86 | BlockFlag = 4\r | |
87 | \r | |
88 | #\r | |
89 | # Combine two comment line if they are generic comment\r | |
90 | # \r | |
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 | |
97 | \r | |
98 | if BlockFlag == 4: \r | |
99 | CommentItemIns = InfPpiItemCommentContent()\r | |
100 | CommentItemIns.SetUsage(CommentItemUsage)\r | |
101 | CommentItemIns.SetNotify(CommentItemNotify)\r | |
102 | CommentItemIns.SetHelpStringItem(CommentItemHelpText)\r | |
103 | CommentInsList.append(CommentItemIns)\r | |
104 | \r | |
105 | BlockFlag = -1\r | |
106 | PreUsage = None\r | |
107 | PreNotify = None\r | |
108 | PreHelpText = ''\r | |
109 | \r | |
110 | elif BlockFlag == 3:\r | |
111 | #\r | |
112 | # Add previous help string\r | |
113 | # \r | |
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 | |
118 | PreHelpText += DT.END_OF_LINE \r | |
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 | |
129 | \r | |
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 | |
138 | \r | |
139 | InfPpiItemObj.SetCommentList(CommentInsList)\r | |
140 | \r | |
141 | return InfPpiItemObj\r | |
142 | \r | |
143 | class InfPpiItemCommentContent():\r | |
144 | def __init__(self):\r | |
145 | #\r | |
146 | # ## SOMETIMES_CONSUMES ## HelpString \r | |
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 | |
155 | \r | |
156 | def SetUsage(self, UsageItem):\r | |
157 | self.UsageItem = UsageItem\r | |
158 | def GetUsage(self):\r | |
159 | return self.UsageItem\r | |
160 | \r | |
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 | |
166 | \r | |
167 | def SetHelpStringItem(self, HelpStringItem):\r | |
168 | self.HelpStringItem = HelpStringItem\r | |
169 | def GetHelpStringItem(self):\r | |
170 | return self.HelpStringItem\r | |
171 | \r | |
172 | class InfPpiItem():\r | |
173 | def __init__(self):\r | |
174 | self.Name = ''\r | |
175 | self.FeatureFlagExp = '' \r | |
176 | self.SupArchList = []\r | |
177 | self.CommentList = []\r | |
178 | \r | |
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 | |
187 | return self.SupArchList \r | |
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 | |
209 | \r | |
210 | def SetPpi(self, PpiList, Arch = None):\r | |
211 | __SupArchList = []\r | |
212 | for ArchItem in Arch:\r | |
213 | #\r | |
214 | # Validate Arch\r | |
215 | # \r | |
216 | if (ArchItem == '' or ArchItem == None):\r | |
217 | ArchItem = 'COMMON' \r | |
218 | __SupArchList.append(ArchItem)\r | |
219 | \r | |
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 | |
229 | InfPpiItemObj = InfPpiItem() \r | |
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 | |
235 | Logger.Error("InfParser", \r | |
236 | ToolError.FORMAT_INVALID, \r | |
237 | ST.ERR_INF_PARSER_INVALID_CNAME%(Item[0]),\r | |
238 | File=CurrentLineOfItem[2], \r | |
239 | Line=CurrentLineOfItem[1], \r | |
240 | ExtraData=CurrentLineOfItem[0])\r | |
241 | if (Item[0] != ''):\r | |
242 | InfPpiItemObj.SetName(Item[0])\r | |
243 | else:\r | |
244 | Logger.Error("InfParser", \r | |
245 | ToolError.FORMAT_INVALID, \r | |
246 | ST.ERR_INF_PARSER_CNAME_MISSING,\r | |
247 | File=CurrentLineOfItem[2], \r | |
248 | Line=CurrentLineOfItem[1], \r | |
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 | |
257 | # Item[1] should not be empty \r | |
258 | #\r | |
259 | if Item[1].strip() == '':\r | |
260 | Logger.Error("InfParser", \r | |
261 | ToolError.FORMAT_INVALID, \r | |
262 | ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING,\r | |
263 | File=CurrentLineOfItem[2], \r | |
264 | Line=CurrentLineOfItem[1], \r | |
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 | |
272 | Logger.Error("InfParser", \r | |
273 | ToolError.FORMAT_INVALID,\r | |
274 | ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[1]),\r | |
275 | File=CurrentLineOfItem[2], \r | |
276 | Line=CurrentLineOfItem[1], \r | |
277 | ExtraData=CurrentLineOfItem[0])\r | |
278 | InfPpiItemObj.SetFeatureFlagExp(Item[1])\r | |
279 | if len(Item) != 1 and len(Item) != 2:\r | |
280 | #\r | |
281 | # Invalid format of Ppi statement \r | |
282 | #\r | |
283 | Logger.Error("InfParser", \r | |
284 | ToolError.FORMAT_INVALID,\r | |
285 | ST.ERR_INF_PARSER_GUID_PPI_PROTOCOL_SECTION_CONTENT_ERROR,\r | |
286 | File=CurrentLineOfItem[2], \r | |
287 | Line=CurrentLineOfItem[1], \r | |
288 | ExtraData=CurrentLineOfItem[0])\r | |
289 | \r | |
290 | #\r | |
291 | # Get/Set Usage and HelpString for PPI entry\r | |
292 | #\r | |
293 | if CommentsList != None and len(CommentsList) != 0:\r | |
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 | |
300 | \r | |
301 | InfPpiItemObj.SetSupArchList(__SupArchList)\r | |
302 | \r | |
303 | #\r | |
304 | # Determine PPI name duplicate. Follow below rule:\r | |
305 | #\r | |
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 | |
310 | # [Ppis] section.\r | |
311 | # \r | |
312 | # NOTE: This check will not report error now.\r | |
313 | # \r | |
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 | |
327 | # \r | |
328 | pass\r | |
329 | \r | |
330 | if self.Ppis.has_key((InfPpiItemObj)): \r | |
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 | |
338 | \r | |
339 | return True \r | |
340 | \r | |
341 | \r | |
342 | def GetPpi(self):\r | |
343 | return self.Ppis |