]>
Commit | Line | Data |
---|---|---|
4234283c | 1 | ## @file\r |
f7496d71 LG |
2 | # This file is used to define class objects of INF file [Pcds] section.\r |
3 | # It will consumed by InfParser.\r | |
4234283c | 4 | #\r |
64285f15 | 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 | |
10 | InfPcdObject\r | |
11 | '''\r | |
12 | import os\r | |
13 | import re\r | |
14 | \r | |
15 | from Logger import StringTable as ST\r | |
16 | from Logger import ToolError\r | |
17 | import Logger.Log as Logger\r | |
421ccda3 | 18 | from Library import GlobalData\r |
4234283c LG |
19 | from Library import DataType as DT\r |
20 | \r | |
21 | from Library.Misc import Sdict\r | |
22 | from Library.Misc import GetHelpStringByRemoveHashKey\r | |
421ccda3 | 23 | from Library.ParserValidate import IsValidPcdType\r |
4234283c LG |
24 | from Library.ParserValidate import IsValidCVariableName\r |
25 | from Library.ParserValidate import IsValidPcdValue\r | |
26 | from Library.ParserValidate import IsValidArch\r | |
27 | from Library.CommentParsing import ParseComment\r | |
64285f15 YZ |
28 | from Library.StringUtils import GetSplitValueList\r |
29 | from Library.StringUtils import IsHexDigitUINT32\r | |
4234283c LG |
30 | from Library.ExpressionValidate import IsValidFeatureFlagExp\r |
31 | from Parser.InfAsBuiltProcess import GetPackageListInfo\r | |
32 | from Parser.DecParser import Dec\r | |
33 | \r | |
34 | from Object.Parser.InfPackagesObject import InfPackageItem\r | |
35 | \r | |
36 | def ValidateArch(ArchItem, PcdTypeItem1, LineNo, SupArchDict, SupArchList):\r | |
37 | #\r | |
38 | # Validate Arch\r | |
f7496d71 | 39 | #\r |
4231a819 | 40 | if (ArchItem == '' or ArchItem is None):\r |
4234283c | 41 | ArchItem = 'COMMON'\r |
421ccda3 | 42 | \r |
4234283c LG |
43 | if PcdTypeItem1.upper != DT.TAB_INF_FEATURE_PCD.upper():\r |
44 | ArchList = GetSplitValueList(ArchItem, ' ')\r | |
45 | for ArchItemNew in ArchList:\r | |
46 | if not IsValidArch(ArchItemNew):\r | |
421ccda3 | 47 | Logger.Error("InfParser",\r |
4234283c | 48 | ToolError.FORMAT_INVALID,\r |
421ccda3 | 49 | ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID % (ArchItemNew),\r |
4234283c | 50 | File=GlobalData.gINF_MODULE_NAME,\r |
421ccda3 | 51 | Line=LineNo,\r |
4234283c | 52 | ExtraData=ArchItemNew)\r |
421ccda3 | 53 | SupArchDict[PcdTypeItem1] = ArchList\r |
4234283c LG |
54 | else:\r |
55 | SupArchList.append(ArchItem)\r | |
421ccda3 | 56 | \r |
4234283c LG |
57 | return SupArchList, SupArchDict\r |
58 | \r | |
59 | def ParsePcdComment(CommentList, PcdTypeItem, PcdItemObj):\r | |
60 | CommentInsList = []\r | |
61 | PreUsage = None\r | |
62 | PreHelpText = ''\r | |
63 | BlockFlag = -1\r | |
64 | FFEHelpText = ''\r | |
421ccda3 HC |
65 | CommentItemHelpText = ''\r |
66 | Count = 0\r | |
4234283c LG |
67 | for CommentItem in CommentList:\r |
68 | Count = Count + 1\r | |
421ccda3 HC |
69 | CommentItemUsage, CommentType, CommentString, CommentItemHelpText = ParseComment(CommentItem,\r |
70 | DT.ALL_USAGE_TOKENS,\r | |
71 | {},\r | |
4234283c LG |
72 | [],\r |
73 | False)\r | |
74 | if CommentType and CommentString:\r | |
421ccda3 HC |
75 | pass\r |
76 | \r | |
4234283c LG |
77 | if PcdTypeItem == 'FeaturePcd':\r |
78 | CommentItemUsage = DT.USAGE_ITEM_CONSUMES\r | |
4231a819 | 79 | if CommentItemHelpText is None:\r |
4234283c | 80 | CommentItemHelpText = ''\r |
421ccda3 | 81 | \r |
4234283c LG |
82 | if Count == 1:\r |
83 | FFEHelpText = CommentItemHelpText\r | |
84 | else:\r | |
85 | FFEHelpText = FFEHelpText + DT.END_OF_LINE + CommentItemHelpText\r | |
421ccda3 | 86 | \r |
4234283c LG |
87 | if Count == len(CommentList):\r |
88 | CommentItemHelpText = FFEHelpText\r | |
89 | BlockFlag = 4\r | |
90 | else:\r | |
91 | continue\r | |
421ccda3 | 92 | \r |
4231a819 | 93 | if CommentItemHelpText is None:\r |
4234283c LG |
94 | CommentItemHelpText = ''\r |
95 | if Count == len(CommentList) and CommentItemUsage == DT.ITEM_UNDEFINED:\r | |
96 | CommentItemHelpText = DT.END_OF_LINE\r | |
421ccda3 | 97 | \r |
4234283c LG |
98 | if Count == len(CommentList) and (BlockFlag == 1 or BlockFlag == 2):\r |
99 | if CommentItemUsage == DT.ITEM_UNDEFINED:\r | |
100 | BlockFlag = 4\r | |
101 | else:\r | |
102 | BlockFlag = 3\r | |
103 | elif BlockFlag == -1 and Count == len(CommentList):\r | |
421ccda3 HC |
104 | BlockFlag = 4\r |
105 | \r | |
4234283c LG |
106 | if BlockFlag == -1 or BlockFlag == 1 or BlockFlag == 2:\r |
107 | if CommentItemUsage == DT.ITEM_UNDEFINED:\r | |
108 | if BlockFlag == -1:\r | |
109 | BlockFlag = 1\r | |
110 | elif BlockFlag == 1:\r | |
111 | BlockFlag = 2\r | |
112 | else:\r | |
113 | if BlockFlag == 1 or BlockFlag == 2:\r | |
114 | BlockFlag = 3\r | |
115 | elif BlockFlag == -1:\r | |
116 | BlockFlag = 4\r | |
117 | #\r | |
118 | # Combine two comment line if they are generic comment\r | |
f7496d71 | 119 | #\r |
4234283c LG |
120 | if CommentItemUsage == PreUsage == DT.ITEM_UNDEFINED:\r |
121 | CommentItemHelpText = PreHelpText + DT.END_OF_LINE + CommentItemHelpText\r | |
421ccda3 | 122 | \r |
4234283c | 123 | PreHelpText = CommentItemHelpText\r |
421ccda3 HC |
124 | \r |
125 | if BlockFlag == 4:\r | |
4234283c LG |
126 | CommentItemIns = InfPcdItemCommentContent()\r |
127 | CommentItemIns.SetUsageItem(CommentItemUsage)\r | |
128 | CommentItemIns.SetHelpStringItem(CommentItemHelpText)\r | |
129 | CommentInsList.append(CommentItemIns)\r | |
421ccda3 | 130 | \r |
4234283c LG |
131 | BlockFlag = -1\r |
132 | PreUsage = None\r | |
133 | PreHelpText = ''\r | |
421ccda3 | 134 | \r |
4234283c LG |
135 | elif BlockFlag == 3:\r |
136 | #\r | |
137 | # Add previous help string\r | |
f7496d71 | 138 | #\r |
4234283c LG |
139 | CommentItemIns = InfPcdItemCommentContent()\r |
140 | CommentItemIns.SetUsageItem(DT.ITEM_UNDEFINED)\r | |
141 | if PreHelpText == '' or PreHelpText.endswith(DT.END_OF_LINE):\r | |
421ccda3 | 142 | PreHelpText += DT.END_OF_LINE\r |
4234283c LG |
143 | CommentItemIns.SetHelpStringItem(PreHelpText)\r |
144 | CommentInsList.append(CommentItemIns)\r | |
145 | #\r | |
146 | # Add Current help string\r | |
147 | #\r | |
148 | CommentItemIns = InfPcdItemCommentContent()\r | |
149 | CommentItemIns.SetUsageItem(CommentItemUsage)\r | |
150 | CommentItemIns.SetHelpStringItem(CommentItemHelpText)\r | |
151 | CommentInsList.append(CommentItemIns)\r | |
421ccda3 | 152 | \r |
4234283c LG |
153 | BlockFlag = -1\r |
154 | PreUsage = None\r | |
421ccda3 HC |
155 | PreHelpText = ''\r |
156 | \r | |
4234283c LG |
157 | else:\r |
158 | PreUsage = CommentItemUsage\r | |
159 | PreHelpText = CommentItemHelpText\r | |
421ccda3 | 160 | \r |
4234283c | 161 | PcdItemObj.SetHelpStringList(CommentInsList)\r |
421ccda3 HC |
162 | \r |
163 | return PcdItemObj\r | |
4234283c LG |
164 | \r |
165 | class InfPcdItemCommentContent():\r | |
166 | def __init__(self):\r | |
167 | #\r | |
f7496d71 | 168 | # ## SOMETIMES_CONSUMES ## HelpString\r |
4234283c LG |
169 | #\r |
170 | self.UsageItem = ''\r | |
171 | #\r | |
172 | # Help String\r | |
173 | #\r | |
174 | self.HelpStringItem = ''\r | |
421ccda3 | 175 | \r |
4234283c LG |
176 | def SetUsageItem(self, UsageItem):\r |
177 | self.UsageItem = UsageItem\r | |
178 | def GetUsageItem(self):\r | |
179 | return self.UsageItem\r | |
421ccda3 | 180 | \r |
4234283c LG |
181 | def SetHelpStringItem(self, HelpStringItem):\r |
182 | self.HelpStringItem = HelpStringItem\r | |
183 | def GetHelpStringItem(self):\r | |
184 | return self.HelpStringItem\r | |
421ccda3 | 185 | \r |
4234283c LG |
186 | ## InfPcdItem\r |
187 | #\r | |
188 | # This class defined Pcd item used in Module files\r | |
189 | #\r | |
190 | # @param CName: Input value for CName, default is ''\r | |
191 | # @param Token: Input value for Token, default is ''\r | |
f7496d71 | 192 | # @param TokenSpaceGuidCName: Input value for TokenSpaceGuidCName, default\r |
4234283c LG |
193 | # is ''\r |
194 | # @param DatumType: Input value for DatumType, default is ''\r | |
195 | # @param MaxDatumSize: Input value for MaxDatumSize, default is ''\r | |
196 | # @param DefaultValue: Input value for DefaultValue, default is ''\r | |
197 | # @param ItemType: Input value for ItemType, default is ''\r | |
198 | # @param ValidUsage: Input value for ValidUsage, default is []\r | |
199 | # @param SkuInfoList: Input value for SkuInfoList, default is {}\r | |
200 | # @param SupModuleList: Input value for SupModuleList, default is []\r | |
201 | #\r | |
202 | class InfPcdItem():\r | |
203 | def __init__(self):\r | |
204 | self.CName = ''\r | |
205 | self.Token = ''\r | |
206 | self.TokenSpaceGuidCName = ''\r | |
207 | self.TokenSpaceGuidValue = ''\r | |
421ccda3 HC |
208 | self.DatumType = ''\r |
209 | self.MaxDatumSize = ''\r | |
210 | self.DefaultValue = ''\r | |
211 | self.Offset = ''\r | |
212 | self.ValidUsage = ''\r | |
213 | self.ItemType = ''\r | |
214 | self.SupModuleList = []\r | |
4234283c LG |
215 | self.HelpStringList = []\r |
216 | self.FeatureFlagExp = ''\r | |
421ccda3 | 217 | self.SupArchList = []\r |
4234283c | 218 | self.PcdErrorsList = []\r |
421ccda3 | 219 | \r |
4234283c | 220 | def SetCName(self, CName):\r |
421ccda3 | 221 | self.CName = CName\r |
4234283c LG |
222 | def GetCName(self):\r |
223 | return self.CName\r | |
421ccda3 | 224 | \r |
4234283c | 225 | def SetToken(self, Token):\r |
421ccda3 | 226 | self.Token = Token\r |
4234283c LG |
227 | def GetToken(self):\r |
228 | return self.Token\r | |
421ccda3 | 229 | \r |
4234283c | 230 | def SetTokenSpaceGuidCName(self, TokenSpaceGuidCName):\r |
421ccda3 | 231 | self.TokenSpaceGuidCName = TokenSpaceGuidCName\r |
4234283c LG |
232 | def GetTokenSpaceGuidCName(self):\r |
233 | return self.TokenSpaceGuidCName\r | |
421ccda3 | 234 | \r |
4234283c | 235 | def SetTokenSpaceGuidValue(self, TokenSpaceGuidValue):\r |
421ccda3 | 236 | self.TokenSpaceGuidValue = TokenSpaceGuidValue\r |
4234283c LG |
237 | def GetTokenSpaceGuidValue(self):\r |
238 | return self.TokenSpaceGuidValue\r | |
421ccda3 | 239 | \r |
4234283c | 240 | def SetDatumType(self, DatumType):\r |
421ccda3 | 241 | self.DatumType = DatumType\r |
4234283c LG |
242 | def GetDatumType(self):\r |
243 | return self.DatumType\r | |
421ccda3 | 244 | \r |
4234283c | 245 | def SetMaxDatumSize(self, MaxDatumSize):\r |
421ccda3 | 246 | self.MaxDatumSize = MaxDatumSize\r |
4234283c LG |
247 | def GetMaxDatumSize(self):\r |
248 | return self.MaxDatumSize\r | |
249 | \r | |
250 | def SetDefaultValue(self, DefaultValue):\r | |
421ccda3 | 251 | self.DefaultValue = DefaultValue\r |
4234283c LG |
252 | def GetDefaultValue(self):\r |
253 | return self.DefaultValue\r | |
421ccda3 | 254 | \r |
4234283c | 255 | def SetPcdErrorsList(self, PcdErrorsList):\r |
421ccda3 | 256 | self.PcdErrorsList = PcdErrorsList\r |
4234283c LG |
257 | def GetPcdErrorsList(self):\r |
258 | return self.PcdErrorsList\r | |
259 | \r | |
260 | def SetItemType(self, ItemType):\r | |
421ccda3 | 261 | self.ItemType = ItemType\r |
4234283c LG |
262 | def GetItemType(self):\r |
263 | return self.ItemType\r | |
264 | \r | |
265 | def SetSupModuleList(self, SupModuleList):\r | |
421ccda3 | 266 | self.SupModuleList = SupModuleList\r |
4234283c LG |
267 | def GetSupModuleList(self):\r |
268 | return self.SupModuleList\r | |
421ccda3 | 269 | \r |
4234283c LG |
270 | def SetHelpStringList(self, HelpStringList):\r |
271 | self.HelpStringList = HelpStringList\r | |
272 | def GetHelpStringList(self):\r | |
273 | return self.HelpStringList\r | |
421ccda3 | 274 | \r |
4234283c LG |
275 | def SetFeatureFlagExp(self, FeatureFlagExp):\r |
276 | self.FeatureFlagExp = FeatureFlagExp\r | |
277 | def GetFeatureFlagExp(self):\r | |
278 | return self.FeatureFlagExp\r | |
421ccda3 | 279 | \r |
4234283c LG |
280 | def SetSupportArchList(self, ArchList):\r |
281 | self.SupArchList = ArchList\r | |
282 | def GetSupportArchList(self):\r | |
283 | return self.SupArchList\r | |
421ccda3 | 284 | \r |
4234283c LG |
285 | def SetOffset(self, Offset):\r |
286 | self.Offset = Offset\r | |
287 | def GetOffset(self):\r | |
288 | return self.Offset\r | |
289 | \r | |
421ccda3 HC |
290 | def SetValidUsage(self, ValidUsage):\r |
291 | self.ValidUsage = ValidUsage\r | |
292 | \r | |
293 | def GetValidUsage(self):\r | |
294 | return self.ValidUsage\r | |
295 | \r | |
4234283c LG |
296 | ##\r |
297 | #\r | |
298 | #\r | |
299 | #\r | |
300 | class InfPcdObject():\r | |
301 | def __init__(self, FileName):\r | |
302 | self.Pcds = Sdict()\r | |
303 | self.FileName = FileName\r | |
421ccda3 HC |
304 | \r |
305 | def SetPcds(self, PcdContent, KeysList=None, PackageInfo=None):\r | |
306 | \r | |
4234283c LG |
307 | if GlobalData.gIS_BINARY_INF:\r |
308 | self.SetAsBuildPcds(PcdContent, KeysList, PackageInfo)\r | |
309 | return True\r | |
421ccda3 | 310 | \r |
4234283c LG |
311 | #\r |
312 | # Validate Arch\r | |
313 | #\r | |
314 | SupArchList = []\r | |
315 | SupArchDict = {}\r | |
316 | PcdTypeItem = ''\r | |
317 | for (PcdTypeItem1, ArchItem, LineNo) in KeysList:\r | |
318 | SupArchList, SupArchDict = ValidateArch(ArchItem, PcdTypeItem1, LineNo, SupArchDict, SupArchList)\r | |
421ccda3 | 319 | \r |
4234283c LG |
320 | #\r |
321 | # Validate PcdType\r | |
322 | #\r | |
4231a819 | 323 | if (PcdTypeItem1 == '' or PcdTypeItem1 is None):\r |
4234283c LG |
324 | return False\r |
325 | else:\r | |
326 | if not IsValidPcdType(PcdTypeItem1):\r | |
421ccda3 HC |
327 | Logger.Error("InfParser",\r |
328 | ToolError.FORMAT_INVALID,\r | |
329 | ST.ERR_INF_PARSER_PCD_SECTION_TYPE_ERROR % (DT.PCD_USAGE_TYPE_LIST_OF_MODULE),\r | |
330 | File=GlobalData.gINF_MODULE_NAME,\r | |
331 | Line=LineNo,\r | |
4234283c LG |
332 | ExtraData=PcdTypeItem1)\r |
333 | return False\r | |
421ccda3 | 334 | \r |
4234283c | 335 | PcdTypeItem = PcdTypeItem1\r |
421ccda3 | 336 | \r |
4234283c LG |
337 | for PcdItem in PcdContent:\r |
338 | PcdItemObj = InfPcdItem()\r | |
339 | CommentList = PcdItem[1]\r | |
340 | CurrentLineOfPcdItem = PcdItem[2]\r | |
341 | PcdItem = PcdItem[0]\r | |
421ccda3 | 342 | \r |
4231a819 | 343 | if CommentList is not None and len(CommentList) != 0:\r |
4234283c LG |
344 | PcdItemObj = ParsePcdComment(CommentList, PcdTypeItem, PcdItemObj)\r |
345 | else:\r | |
346 | CommentItemIns = InfPcdItemCommentContent()\r | |
347 | CommentItemIns.SetUsageItem(DT.ITEM_UNDEFINED)\r | |
348 | PcdItemObj.SetHelpStringList([CommentItemIns])\r | |
421ccda3 | 349 | \r |
4234283c LG |
350 | if len(PcdItem) >= 1 and len(PcdItem) <= 3:\r |
351 | PcdItemObj = SetPcdName(PcdItem, CurrentLineOfPcdItem, PcdItemObj)\r | |
421ccda3 | 352 | \r |
4234283c LG |
353 | if len(PcdItem) >= 2 and len(PcdItem) <= 3:\r |
354 | #\r | |
355 | # Contain PcdName and Value, validate value.\r | |
356 | #\r | |
357 | if IsValidPcdValue(PcdItem[1]) or PcdItem[1].strip() == "":\r | |
358 | PcdItemObj.SetDefaultValue(PcdItem[1])\r | |
359 | else:\r | |
421ccda3 HC |
360 | Logger.Error("InfParser",\r |
361 | ToolError.FORMAT_INVALID,\r | |
4234283c | 362 | ST.ERR_INF_PARSER_PCD_VALUE_INVALID,\r |
421ccda3 HC |
363 | File=CurrentLineOfPcdItem[2],\r |
364 | Line=CurrentLineOfPcdItem[1],\r | |
4234283c | 365 | ExtraData=PcdItem[1])\r |
421ccda3 | 366 | \r |
4234283c LG |
367 | if len(PcdItem) == 3:\r |
368 | #\r | |
369 | # Contain PcdName, value, and FeatureFlag express\r | |
370 | #\r | |
371 | #\r | |
372 | # Validate Feature Flag Express\r | |
373 | #\r | |
374 | if PcdItem[2].strip() == '':\r | |
421ccda3 HC |
375 | Logger.Error("InfParser",\r |
376 | ToolError.FORMAT_INVALID,\r | |
4234283c | 377 | ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING,\r |
421ccda3 HC |
378 | File=CurrentLineOfPcdItem[2],\r |
379 | Line=CurrentLineOfPcdItem[1],\r | |
4234283c LG |
380 | ExtraData=CurrentLineOfPcdItem[0])\r |
381 | #\r | |
f7496d71 | 382 | # Validate FFE\r |
4234283c LG |
383 | #\r |
384 | FeatureFlagRtv = IsValidFeatureFlagExp(PcdItem[2].strip())\r | |
385 | if not FeatureFlagRtv[0]:\r | |
421ccda3 HC |
386 | Logger.Error("InfParser",\r |
387 | ToolError.FORMAT_INVALID,\r | |
388 | ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID % (FeatureFlagRtv[1]),\r | |
389 | File=CurrentLineOfPcdItem[2],\r | |
390 | Line=CurrentLineOfPcdItem[1],\r | |
4234283c LG |
391 | ExtraData=CurrentLineOfPcdItem[0])\r |
392 | PcdItemObj.SetFeatureFlagExp(PcdItem[2])\r | |
421ccda3 | 393 | \r |
4234283c | 394 | if len(PcdItem) < 1 or len(PcdItem) > 3:\r |
421ccda3 HC |
395 | Logger.Error("InfParser",\r |
396 | ToolError.FORMAT_INVALID,\r | |
4234283c | 397 | ST.ERR_INF_PARSER_PCD_SECTION_CONTENT_ERROR,\r |
421ccda3 HC |
398 | File=CurrentLineOfPcdItem[2],\r |
399 | Line=CurrentLineOfPcdItem[1],\r | |
4234283c | 400 | ExtraData=CurrentLineOfPcdItem[0])\r |
421ccda3 HC |
401 | return False\r |
402 | \r | |
4234283c LG |
403 | if PcdTypeItem.upper != DT.TAB_INF_FEATURE_PCD.upper():\r |
404 | PcdItemObj.SetSupportArchList(SupArchDict[PcdTypeItem])\r | |
405 | else:\r | |
406 | PcdItemObj.SetSupportArchList(SupArchList)\r | |
421ccda3 | 407 | \r |
27c4ceb4 | 408 | if (PcdTypeItem, PcdItemObj) in self.Pcds:\r |
4234283c LG |
409 | PcdsList = self.Pcds[PcdTypeItem, PcdItemObj]\r |
410 | PcdsList.append(PcdItemObj)\r | |
411 | self.Pcds[PcdTypeItem, PcdItemObj] = PcdsList\r | |
412 | else:\r | |
413 | PcdsList = []\r | |
414 | PcdsList.append(PcdItemObj)\r | |
415 | self.Pcds[PcdTypeItem, PcdItemObj] = PcdsList\r | |
421ccda3 | 416 | \r |
4234283c | 417 | return True\r |
421ccda3 HC |
418 | \r |
419 | def SetAsBuildPcds(self, PcdContent, KeysList=None, PackageInfo=None):\r | |
4234283c LG |
420 | for PcdItem in PcdContent:\r |
421 | PcdItemObj = InfPcdItem()\r | |
422 | CommentList = PcdItem[1]\r | |
423 | CurrentLineOfPcdItem = PcdItem[2]\r | |
424 | PcdItem = PcdItem[0]\r | |
425 | CommentString = ''\r | |
421ccda3 HC |
426 | \r |
427 | for CommentLine in CommentList:\r | |
428 | CommentString = GetHelpStringByRemoveHashKey(CommentLine)\r | |
429 | CommentItemIns = InfPcdItemCommentContent()\r | |
430 | CommentItemIns.SetHelpStringItem(CommentString)\r | |
431 | CommentItemIns.SetUsageItem(CommentString)\r | |
432 | PcdItemObj.SetHelpStringList(PcdItemObj.GetHelpStringList() + [CommentItemIns])\r | |
433 | if PcdItemObj.GetValidUsage():\r | |
434 | PcdItemObj.SetValidUsage(PcdItemObj.GetValidUsage() + DT.TAB_VALUE_SPLIT + CommentString)\r | |
435 | else:\r | |
436 | PcdItemObj.SetValidUsage(CommentString)\r | |
437 | \r | |
4234283c LG |
438 | PcdItemObj.SetItemType(KeysList[0][0])\r |
439 | #\r | |
440 | # Set PcdTokenSpaceCName and CName\r | |
441 | #\r | |
421ccda3 | 442 | PcdItemObj = SetPcdName(PcdItem, CurrentLineOfPcdItem, PcdItemObj)\r |
4234283c | 443 | #\r |
421ccda3 | 444 | # Set Value/DatumType/OffSet/Token\r |
4234283c | 445 | #\r |
421ccda3 HC |
446 | PcdItemObj = SetValueDatumTypeMaxSizeToken(PcdItem,\r |
447 | CurrentLineOfPcdItem,\r | |
4234283c LG |
448 | PcdItemObj,\r |
449 | KeysList[0][1],\r | |
450 | PackageInfo)\r | |
421ccda3 | 451 | \r |
4234283c | 452 | PcdTypeItem = KeysList[0][0]\r |
27c4ceb4 | 453 | if (PcdTypeItem, PcdItemObj) in self.Pcds:\r |
4234283c LG |
454 | PcdsList = self.Pcds[PcdTypeItem, PcdItemObj]\r |
455 | PcdsList.append(PcdItemObj)\r | |
456 | self.Pcds[PcdTypeItem, PcdItemObj] = PcdsList\r | |
457 | else:\r | |
458 | PcdsList = []\r | |
459 | PcdsList.append(PcdItemObj)\r | |
421ccda3 HC |
460 | self.Pcds[PcdTypeItem, PcdItemObj] = PcdsList\r |
461 | \r | |
4234283c LG |
462 | def GetPcds(self):\r |
463 | return self.Pcds\r | |
464 | \r | |
465 | def ParserPcdInfoInDec(String):\r | |
466 | ValueList = GetSplitValueList(String, DT.TAB_VALUE_SPLIT, 3)\r | |
421ccda3 | 467 | \r |
4234283c LG |
468 | #\r |
469 | # DatumType, Token\r | |
470 | #\r | |
471 | return ValueList[2], ValueList[3]\r | |
472 | \r | |
421ccda3 | 473 | def SetValueDatumTypeMaxSizeToken(PcdItem, CurrentLineOfPcdItem, PcdItemObj, Arch, PackageInfo=None):\r |
4234283c | 474 | #\r |
f7496d71 | 475 | # Package information not been generated currently, we need to parser INF file to get information.\r |
4234283c LG |
476 | #\r |
477 | if not PackageInfo:\r | |
478 | PackageInfo = []\r | |
479 | InfFileName = CurrentLineOfPcdItem[2]\r | |
480 | PackageInfoList = GetPackageListInfo(InfFileName, GlobalData.gWORKSPACE, -1)\r | |
481 | for PackageInfoListItem in PackageInfoList:\r | |
482 | PackageInfoIns = InfPackageItem()\r | |
483 | PackageInfoIns.SetPackageName(PackageInfoListItem)\r | |
484 | PackageInfo.append(PackageInfoIns)\r | |
485 | \r | |
486 | PcdInfoInDecHasFound = False\r | |
487 | for PackageItem in PackageInfo:\r | |
488 | if PcdInfoInDecHasFound:\r | |
489 | break\r | |
490 | PackageName = PackageItem.PackageName\r | |
491 | #\r | |
492 | # Open DEC file to get information\r | |
493 | #\r | |
494 | FullFileName = os.path.normpath(os.path.realpath(os.path.join(GlobalData.gWORKSPACE, PackageName)))\r | |
421ccda3 HC |
495 | \r |
496 | DecParser = None\r | |
497 | if FullFileName not in GlobalData.gPackageDict:\r | |
498 | DecParser = Dec(FullFileName)\r | |
499 | GlobalData.gPackageDict[FullFileName] = DecParser\r | |
500 | else:\r | |
501 | DecParser = GlobalData.gPackageDict[FullFileName]\r | |
502 | \r | |
4234283c | 503 | #\r |
f7496d71 | 504 | # Find PCD information.\r |
4234283c LG |
505 | #\r |
506 | DecPcdsDict = DecParser.GetPcdSectionObject().ValueDict\r | |
507 | for Key in DecPcdsDict.keys():\r | |
508 | if (Key[0] == 'PCDSDYNAMICEX' and PcdItemObj.GetItemType() == 'PcdEx') and \\r | |
509 | (Key[1] == 'COMMON' or Key[1] == Arch):\r | |
510 | for PcdInDec in DecPcdsDict[Key]:\r | |
511 | if PcdInDec.TokenCName == PcdItemObj.CName and \\r | |
512 | PcdInDec.TokenSpaceGuidCName == PcdItemObj.TokenSpaceGuidCName:\r | |
513 | PcdItemObj.SetToken(PcdInDec.TokenValue)\r | |
514 | PcdItemObj.SetDatumType(PcdInDec.DatumType)\r | |
515 | PcdItemObj.SetSupportArchList([Arch])\r | |
421ccda3 HC |
516 | PcdItemObj.SetDefaultValue(PcdInDec.DefaultValue)\r |
517 | \r | |
4234283c LG |
518 | if (Key[0] == 'PCDSPATCHABLEINMODULE' and PcdItemObj.GetItemType() == 'PatchPcd') and \\r |
519 | (Key[1] == 'COMMON' or Key[1] == Arch):\r | |
520 | for PcdInDec in DecPcdsDict[Key]:\r | |
521 | if PcdInDec.TokenCName == PcdItemObj.CName and \\r | |
522 | PcdInDec.TokenSpaceGuidCName == PcdItemObj.TokenSpaceGuidCName:\r | |
523 | PcdItemObj.SetToken(PcdInDec.TokenValue)\r | |
524 | PcdItemObj.SetDatumType(PcdInDec.DatumType)\r | |
421ccda3 HC |
525 | PcdItemObj.SetSupportArchList([Arch])\r |
526 | \r | |
4234283c | 527 | if PcdItemObj.GetDatumType() == 'VOID*':\r |
421ccda3 HC |
528 | if len(PcdItem) > 1:\r |
529 | PcdItemObj.SetMaxDatumSize('%s' % (len(GetSplitValueList(PcdItem[1], DT.TAB_COMMA_SPLIT))))\r | |
530 | \r | |
4234283c LG |
531 | DecGuidsDict = DecParser.GetGuidSectionObject().ValueDict\r |
532 | for Key in DecGuidsDict.keys():\r | |
533 | if Key == 'COMMON' or Key == Arch:\r | |
534 | for GuidInDec in DecGuidsDict[Key]:\r | |
535 | if GuidInDec.GuidCName == PcdItemObj.TokenSpaceGuidCName:\r | |
536 | PcdItemObj.SetTokenSpaceGuidValue(GuidInDec.GuidString)\r | |
537 | \r | |
4234283c | 538 | if PcdItemObj.GetItemType().upper() == DT.TAB_INF_PATCH_PCD.upper():\r |
421ccda3 HC |
539 | #\r |
540 | # Validate Value.\r | |
541 | #\r | |
542 | # convert the value from a decimal 0 to a formatted hex value.\r | |
543 | if PcdItem[1] == "0":\r | |
544 | DatumType = PcdItemObj.GetDatumType()\r | |
545 | if DatumType == "UINT8":\r | |
546 | PcdItem[1] = "0x00"\r | |
547 | if DatumType == "UINT16":\r | |
548 | PcdItem[1] = "0x0000"\r | |
549 | if DatumType == "UINT32":\r | |
550 | PcdItem[1] = "0x00000000"\r | |
551 | if DatumType == "UINT64":\r | |
552 | PcdItem[1] = "0x0000000000000000"\r | |
553 | \r | |
554 | if ValidatePcdValueOnDatumType(PcdItem[1], PcdItemObj.GetDatumType()):\r | |
555 | PcdItemObj.SetDefaultValue(PcdItem[1])\r | |
556 | else:\r | |
557 | Logger.Error("InfParser",\r | |
558 | ToolError.FORMAT_INVALID,\r | |
559 | ST.ERR_ASBUILD_PCD_VALUE_INVALID % ("\"" + PcdItem[1] + "\"", "\"" +\r | |
560 | PcdItemObj.GetDatumType() + "\""),\r | |
561 | File=CurrentLineOfPcdItem[2],\r | |
562 | Line=CurrentLineOfPcdItem[1],\r | |
563 | ExtraData=CurrentLineOfPcdItem[0])\r | |
564 | #\r | |
565 | # validate offset\r | |
566 | #\r | |
567 | if PcdItemObj.GetItemType().upper() == DT.TAB_INF_PATCH_PCD.upper():\r | |
568 | if not IsHexDigitUINT32(PcdItem[2]):\r | |
569 | Logger.Error("InfParser",\r | |
570 | ToolError.FORMAT_INVALID,\r | |
571 | ST.ERR_ASBUILD_PCD_OFFSET_FORMAT_INVALID % ("\"" + PcdItem[2] + "\""),\r | |
572 | File=CurrentLineOfPcdItem[2],\r | |
573 | Line=CurrentLineOfPcdItem[1],\r | |
574 | ExtraData=CurrentLineOfPcdItem[0])\r | |
575 | PcdItemObj.SetOffset(PcdItem[2])\r | |
576 | \r | |
4234283c | 577 | if PcdItemObj.GetToken() == '' or PcdItemObj.GetDatumType() == '':\r |
421ccda3 HC |
578 | Logger.Error("InfParser",\r |
579 | ToolError.FORMAT_INVALID,\r | |
580 | ST.ERR_ASBUILD_PCD_DECLARITION_MISS % ("\"" + PcdItem[0] + "\""),\r | |
581 | File=CurrentLineOfPcdItem[2],\r | |
582 | Line=CurrentLineOfPcdItem[1],\r | |
4234283c | 583 | ExtraData=CurrentLineOfPcdItem[0])\r |
421ccda3 | 584 | \r |
4234283c LG |
585 | return PcdItemObj\r |
586 | \r | |
587 | def ValidatePcdValueOnDatumType(Value, Type):\r | |
421ccda3 | 588 | \r |
4234283c LG |
589 | Value = Value.strip()\r |
590 | #\r | |
591 | # Boolean type only allow 0x00 or 0x01 as value per INF spec\r | |
592 | #\r | |
593 | if Type == 'BOOLEAN':\r | |
594 | if not (Value == '0x00' or Value == '0x01'):\r | |
421ccda3 | 595 | return False\r |
4234283c LG |
596 | elif Type == 'VOID*':\r |
597 | if not Value.startswith("{"):\r | |
598 | return False\r | |
599 | if not Value.endswith("}"):\r | |
600 | return False\r | |
601 | #\r | |
602 | # Strip "{" at head and "}" at tail.\r | |
603 | #\r | |
421ccda3 | 604 | Value = Value[1:-1]\r |
4234283c | 605 | ValueList = GetSplitValueList(Value, DT.TAB_COMMA_SPLIT)\r |
421ccda3 | 606 | \r |
4234283c LG |
607 | ReIsValidHexByte = re.compile("^0x[0-9a-f]{1,2}$", re.IGNORECASE)\r |
608 | for ValueItem in ValueList:\r | |
609 | if not ReIsValidHexByte.match(ValueItem):\r | |
610 | return False\r | |
421ccda3 | 611 | \r |
4234283c | 612 | elif Type == 'UINT8' or Type == 'UINT16' or Type == 'UINT32' or Type == 'UINT64':\r |
421ccda3 | 613 | \r |
4234283c LG |
614 | ReIsValidUint8z = re.compile('^0[x|X][a-fA-F0-9]{2}$')\r |
615 | ReIsValidUint16z = re.compile('^0[x|X][a-fA-F0-9]{4}$')\r | |
616 | ReIsValidUint32z = re.compile('^0[x|X][a-fA-F0-9]{8}$')\r | |
617 | ReIsValidUint64z = re.compile('^0[x|X][a-fA-F0-9]{16}$')\r | |
421ccda3 | 618 | \r |
4234283c | 619 | if not ReIsValidUint8z.match(Value) and Type == 'UINT8':\r |
421ccda3 | 620 | return False\r |
4234283c LG |
621 | elif not ReIsValidUint16z.match(Value) and Type == 'UINT16':\r |
622 | return False\r | |
623 | elif not ReIsValidUint32z.match(Value) and Type == 'UINT32':\r | |
624 | return False\r | |
625 | elif not ReIsValidUint64z.match(Value) and Type == 'UINT64':\r | |
626 | return False\r | |
627 | else:\r | |
628 | #\r | |
629 | # Since we assume the DEC file always correct, should never go to here.\r | |
630 | #\r | |
631 | pass\r | |
421ccda3 HC |
632 | \r |
633 | return True\r | |
634 | \r | |
4234283c LG |
635 | def SetPcdName(PcdItem, CurrentLineOfPcdItem, PcdItemObj):\r |
636 | #\r | |
f7496d71 | 637 | # Only PCD Name specified\r |
4234283c LG |
638 | # <PcdName> ::= <TokenSpaceGuidCName> "." <TokenCName>\r |
639 | #\r | |
640 | PcdId = GetSplitValueList(PcdItem[0], DT.TAB_SPLIT)\r | |
421ccda3 HC |
641 | if len(PcdId) != 2:\r |
642 | Logger.Error("InfParser",\r | |
643 | ToolError.FORMAT_INVALID,\r | |
4234283c | 644 | ST.ERR_INF_PARSER_PCD_NAME_FORMAT_ERROR,\r |
421ccda3 HC |
645 | File=CurrentLineOfPcdItem[2],\r |
646 | Line=CurrentLineOfPcdItem[1],\r | |
4234283c LG |
647 | ExtraData=CurrentLineOfPcdItem[0])\r |
648 | else:\r | |
649 | #\r | |
650 | # Validate PcdTokenSpaceGuidCName\r | |
651 | #\r | |
652 | if not IsValidCVariableName(PcdId[0]):\r | |
421ccda3 HC |
653 | Logger.Error("InfParser",\r |
654 | ToolError.FORMAT_INVALID,\r | |
4234283c | 655 | ST.ERR_INF_PARSER_PCD_CVAR_GUID,\r |
421ccda3 HC |
656 | File=CurrentLineOfPcdItem[2],\r |
657 | Line=CurrentLineOfPcdItem[1],\r | |
4234283c LG |
658 | ExtraData=PcdId[0])\r |
659 | if not IsValidCVariableName(PcdId[1]):\r | |
421ccda3 HC |
660 | Logger.Error("InfParser",\r |
661 | ToolError.FORMAT_INVALID,\r | |
4234283c | 662 | ST.ERR_INF_PARSER_PCD_CVAR_PCDCNAME,\r |
421ccda3 HC |
663 | File=CurrentLineOfPcdItem[2],\r |
664 | Line=CurrentLineOfPcdItem[1],\r | |
4234283c LG |
665 | ExtraData=PcdId[1])\r |
666 | PcdItemObj.SetTokenSpaceGuidCName(PcdId[0])\r | |
667 | PcdItemObj.SetCName(PcdId[1])\r | |
421ccda3 HC |
668 | \r |
669 | return PcdItemObj\r |