]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/UPT/Object/Parser/InfPpiObject.py
BaseTools: Clean up source files
[mirror_edk2.git] / BaseTools / Source / Python / UPT / Object / Parser / InfPpiObject.py
CommitLineData
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
16InfPpiObject\r
17'''\r
18\r
19from Library.ParserValidate import IsValidCVariableName\r
20from Library.CommentParsing import ParseComment\r
f7496d71
LG
21from Library.ExpressionValidate import IsValidFeatureFlagExp\r
22\r
4234283c 23from Library.Misc import Sdict\r
f7496d71 24from Library import DataType as DT\r
4234283c
LG
25import Logger.Log as Logger\r
26from Logger import ToolError\r
27from Logger import StringTable as ST\r
28\r
29def 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
143class 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
172class 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
202class 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