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