]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/UPT/Parser/DecParser.py
BaseTools: Clean up source files
[mirror_edk2.git] / BaseTools / Source / Python / UPT / Parser / DecParser.py
CommitLineData
4234283c
LG
1## @file\r
2# This file is used to parse DEC file. It will consumed by DecParser\r
3#\r
64285f15 4# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
4234283c 5#\r
f7496d71
LG
6# This program and the accompanying materials are licensed and made available\r
7# under the terms and conditions of the BSD License which accompanies this\r
8# distribution. The full text of the license may be found at\r
4234283c
LG
9# http://opensource.org/licenses/bsd-license.php\r
10#\r
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13'''\r
14DecParser\r
15'''\r
16## Import modules\r
17#\r
18import Logger.Log as Logger\r
19from Logger.ToolError import FILE_PARSE_FAILURE\r
20from Logger.ToolError import FILE_OPEN_FAILURE\r
21from Logger import StringTable as ST\r
2bc3256c 22from Logger.ToolError import FORMAT_INVALID\r
4234283c
LG
23\r
24import Library.DataType as DT\r
25from Library.ParserValidate import IsValidToken\r
26from Library.ParserValidate import IsValidPath\r
27from Library.ParserValidate import IsValidCFormatGuid\r
28from Library.ParserValidate import IsValidIdString\r
29from Library.ParserValidate import IsValidUserId\r
30from Library.ParserValidate import IsValidArch\r
31from Library.ParserValidate import IsValidWord\r
48b77f5e 32from Library.ParserValidate import IsValidDecVersionVal\r
4234283c
LG
33from Parser.DecParserMisc import TOOL_NAME\r
34from Parser.DecParserMisc import CleanString\r
35from Parser.DecParserMisc import IsValidPcdDatum\r
36from Parser.DecParserMisc import ParserHelper\r
37from Parser.DecParserMisc import StripRoot\r
38from Parser.DecParserMisc import VERSION_PATTERN\r
39from Parser.DecParserMisc import CVAR_PATTERN\r
40from Parser.DecParserMisc import PCD_TOKEN_PATTERN\r
41from Parser.DecParserMisc import MACRO_PATTERN\r
42from Parser.DecParserMisc import FileContent\r
43from Object.Parser.DecObject import _DecComments\r
44from Object.Parser.DecObject import DecDefineObject\r
45from Object.Parser.DecObject import DecDefineItemObject\r
46from Object.Parser.DecObject import DecIncludeObject\r
47from Object.Parser.DecObject import DecIncludeItemObject\r
48from Object.Parser.DecObject import DecLibraryclassObject\r
49from Object.Parser.DecObject import DecLibraryclassItemObject\r
50from Object.Parser.DecObject import DecGuidObject\r
51from Object.Parser.DecObject import DecPpiObject\r
52from Object.Parser.DecObject import DecProtocolObject\r
53from Object.Parser.DecObject import DecGuidItemObject\r
54from Object.Parser.DecObject import DecUserExtensionObject\r
55from Object.Parser.DecObject import DecUserExtensionItemObject\r
56from Object.Parser.DecObject import DecPcdObject\r
57from Object.Parser.DecObject import DecPcdItemObject\r
58from Library.Misc import GuidStructureStringToGuidString\r
59from Library.Misc import CheckGuidRegFormat\r
64285f15
YZ
60from Library.StringUtils import ReplaceMacro\r
61from Library.StringUtils import GetSplitValueList\r
62from Library.StringUtils import gMACRO_PATTERN\r
63from Library.StringUtils import ConvertSpecialChar\r
421ccda3 64from Library.CommentParsing import ParsePcdErrorCode\r
4234283c
LG
65\r
66##\r
67# _DecBase class for parsing\r
68#\r
69class _DecBase:\r
70 def __init__(self, RawData):\r
71 self._RawData = RawData\r
72 self._ItemDict = {}\r
73 self._LocalMacro = {}\r
74 #\r
75 # Data parsed by 'self' are saved to this object\r
76 #\r
77 self.ItemObject = None\r
f7496d71 78\r
4234283c
LG
79 def GetDataObject(self):\r
80 return self.ItemObject\r
f7496d71 81\r
421ccda3
HC
82 def GetLocalMacro(self):\r
83 return self._LocalMacro\r
f7496d71 84\r
4234283c
LG
85 ## BlockStart\r
86 #\r
87 # Called if a new section starts\r
88 #\r
89 def BlockStart(self):\r
90 self._LocalMacro = {}\r
f7496d71 91\r
4234283c
LG
92 ## _CheckReDefine\r
93 #\r
94 # @param Key: to be checked if multi-defined\r
f7496d71 95 # @param Scope: Format: [[SectionName, Arch], ...].\r
4234283c
LG
96 # If scope is none, use global scope\r
97 #\r
98 def _CheckReDefine(self, Key, Scope = None):\r
99 if not Scope:\r
100 Scope = self._RawData.CurrentScope\r
101 return\r
f7496d71 102\r
4234283c
LG
103 SecArch = []\r
104 #\r
105 # Copy scope to SecArch, avoid Scope be changed outside\r
106 #\r
107 SecArch[0:1] = Scope[:]\r
108 if Key not in self._ItemDict:\r
109 self._ItemDict[Key] = [[SecArch, self._RawData.LineIndex]]\r
110 return\r
f7496d71 111\r
4234283c
LG
112 for Value in self._ItemDict[Key]:\r
113 for SubValue in Scope:\r
114 #\r
115 # If current is common section\r
116 #\r
117 if SubValue[-1] == 'COMMON':\r
118 for Other in Value[0]:\r
119 # Key in common cannot be redefined in other arches\r
120 # [:-1] means stripping arch info\r
121 if Other[:-1] == SubValue[:-1]:\r
122 self._LoggerError(ST.ERR_DECPARSE_REDEFINE % (Key, Value[1]))\r
123 return\r
124 continue\r
125 CommonScope = []\r
126 CommonScope[0:1] = SubValue\r
127 CommonScope[-1] = 'COMMON'\r
128 #\r
129 # Cannot be redefined if this key already defined in COMMON Or defined in same arch\r
130 #\r
131 if SubValue in Value[0] or CommonScope in Value[0]:\r
132 self._LoggerError(ST.ERR_DECPARSE_REDEFINE % (Key, Value[1]))\r
133 return\r
134 self._ItemDict[Key].append([SecArch, self._RawData.LineIndex])\r
f7496d71 135\r
4234283c
LG
136 ## CheckRequiredFields\r
137 # Some sections need to check if some fields exist, define section for example\r
138 # Derived class can re-implement, top parser will call this function after all parsing done\r
f7496d71 139 #\r
4234283c
LG
140 def CheckRequiredFields(self):\r
141 if self._RawData:\r
142 pass\r
143 return True\r
f7496d71 144\r
4234283c 145 ## IsItemRequired\r
f7496d71 146 # In DEC spec, sections must have at least one statement except user\r
4234283c
LG
147 # extension.\r
148 # For example: "[guids" [<attribs>] "]" <EOL> <statements>+\r
149 # sub class can override this method to indicate if statement is a must.\r
150 #\r
151 def _IsStatementRequired(self):\r
152 if self._RawData:\r
153 pass\r
154 return False\r
f7496d71 155\r
4234283c 156 def _LoggerError(self, ErrorString):\r
f7496d71 157 Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,\r
4234283c
LG
158 Line = self._RawData.LineIndex,\r
159 ExtraData=ErrorString + ST.ERR_DECPARSE_LINE % self._RawData.CurrentLine)\r
f7496d71 160\r
4234283c
LG
161 def _ReplaceMacro(self, String):\r
162 if gMACRO_PATTERN.findall(String):\r
163 String = ReplaceMacro(String, self._LocalMacro, False,\r
164 FileName = self._RawData.Filename,\r
165 Line = ['', self._RawData.LineIndex])\r
166 String = ReplaceMacro(String, self._RawData.Macros, False,\r
167 FileName = self._RawData.Filename,\r
168 Line = ['', self._RawData.LineIndex])\r
169 MacroUsed = gMACRO_PATTERN.findall(String)\r
170 if MacroUsed:\r
171 Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE,\r
f7496d71 172 File=self._RawData.Filename,\r
4234283c
LG
173 Line = self._RawData.LineIndex,\r
174 ExtraData = ST.ERR_DECPARSE_MACRO_RESOLVE % (str(MacroUsed), String))\r
175 return String\r
f7496d71 176\r
4234283c
LG
177 def _MacroParser(self, String):\r
178 TokenList = GetSplitValueList(String, ' ', 1)\r
179 if len(TokenList) < 2 or TokenList[1] == '':\r
180 self._LoggerError(ST.ERR_DECPARSE_MACRO_PAIR)\r
181\r
182 TokenList = GetSplitValueList(TokenList[1], DT.TAB_EQUAL_SPLIT, 1)\r
183 if TokenList[0] == '':\r
184 self._LoggerError(ST.ERR_DECPARSE_MACRO_NAME)\r
185 elif not IsValidToken(MACRO_PATTERN, TokenList[0]):\r
186 self._LoggerError(ST.ERR_DECPARSE_MACRO_NAME_UPPER % TokenList[0])\r
f7496d71 187\r
4234283c
LG
188 if len(TokenList) == 1:\r
189 self._LocalMacro[TokenList[0]] = ''\r
190 else:\r
191 self._LocalMacro[TokenList[0]] = self._ReplaceMacro(TokenList[1])\r
421ccda3 192\r
4234283c
LG
193 ## _ParseItem\r
194 #\r
195 # Parse specified item, this function must be derived by subclass\r
196 #\r
197 def _ParseItem(self):\r
198 if self._RawData:\r
199 pass\r
200 #\r
201 # Should never be called\r
202 #\r
203 return None\r
204\r
f7496d71 205\r
4234283c
LG
206 ## _TailCommentStrategy\r
207 #\r
208 # This function can be derived to parse tail comment\r
209 # default is it will not consume any lines\r
210 #\r
211 # @param Comment: Comment of current line\r
212 #\r
213 def _TailCommentStrategy(self, Comment):\r
214 if Comment:\r
215 pass\r
216 if self._RawData:\r
217 pass\r
218 return False\r
f7496d71 219\r
4234283c
LG
220 ## _StopCurrentParsing\r
221 #\r
222 # Called in Parse if current parsing should be stopped when encounter some\r
223 # keyword\r
224 # Default is section start and end\r
225 #\r
226 # @param Line: Current line\r
227 #\r
228 def _StopCurrentParsing(self, Line):\r
229 if self._RawData:\r
230 pass\r
231 return Line[0] == DT.TAB_SECTION_START and Line[-1] == DT.TAB_SECTION_END\r
f7496d71 232\r
4234283c
LG
233 ## _TryBackSlash\r
234 #\r
235 # Split comment and DEC content, concatenate lines if end of char is '\'\r
236 #\r
237 # @param ProcessedLine: ProcessedLine line\r
238 # @param ProcessedComments: ProcessedComments line\r
239 #\r
240 def _TryBackSlash(self, ProcessedLine, ProcessedComments):\r
241 CatLine = ''\r
242 Comment = ''\r
243 Line = ProcessedLine\r
244 CommentList = ProcessedComments\r
245 while not self._RawData.IsEndOfFile():\r
246 if Line == '':\r
247 self._LoggerError(ST.ERR_DECPARSE_BACKSLASH_EMPTY)\r
248 break\r
f7496d71 249\r
4234283c
LG
250 if Comment:\r
251 CommentList.append((Comment, self._RawData.LineIndex))\r
252 if Line[-1] != DT.TAB_SLASH:\r
253 CatLine += Line\r
254 break\r
255 elif len(Line) < 2 or Line[-2] != ' ':\r
256 self._LoggerError(ST.ERR_DECPARSE_BACKSLASH)\r
257 else:\r
258 CatLine += Line[:-1]\r
259 Line, Comment = CleanString(self._RawData.GetNextLine())\r
260 #\r
261 # Reach end of content\r
262 #\r
263 if self._RawData.IsEndOfFile():\r
264 if not CatLine:\r
265 if ProcessedLine[-1] == DT.TAB_SLASH:\r
266 self._LoggerError(ST.ERR_DECPARSE_BACKSLASH_EMPTY)\r
267 CatLine = ProcessedLine\r
268 else:\r
269 if not Line or Line[-1] == DT.TAB_SLASH:\r
270 self._LoggerError(ST.ERR_DECPARSE_BACKSLASH_EMPTY)\r
271 CatLine += Line\r
f7496d71 272\r
0e025dea
HC
273 #\r
274 # All MACRO values defined by the DEFINE statements in any section\r
275 # (except [Userextensions] sections for Intel) of the INF or DEC file\r
276 # must be expanded before processing of the file.\r
277 #\r
278 __IsReplaceMacro = True\r
279 Header = self._RawData.CurrentScope[0] if self._RawData.CurrentScope else None\r
280 if Header and len(Header) > 2:\r
281 if Header[0].upper() == 'USEREXTENSIONS' and not (Header[1] == 'TianoCore' and Header[2] == '"ExtraFiles"'):\r
282 __IsReplaceMacro = False\r
283 if __IsReplaceMacro:\r
284 self._RawData.CurrentLine = self._ReplaceMacro(CatLine)\r
285 else:\r
286 self._RawData.CurrentLine = CatLine\r
287\r
4234283c 288 return CatLine, CommentList\r
f7496d71 289\r
4234283c 290 ## Parse\r
f7496d71
LG
291 # This is a template method in which other member functions which might\r
292 # override by sub class are called. It is responsible for reading file\r
4234283c
LG
293 # line by line, and call other member functions to parse. This function\r
294 # should not be re-implement by sub class.\r
295 #\r
296 def Parse(self):\r
297 HeadComments = []\r
298 TailComments = []\r
f7496d71 299\r
4234283c
LG
300 #======================================================================\r
301 # CurComments may pointer to HeadComments or TailComments\r
302 #======================================================================\r
303 CurComments = HeadComments\r
304 CurObj = None\r
305 ItemNum = 0\r
306 FromBuf = False\r
f7496d71 307\r
4234283c
LG
308 #======================================================================\r
309 # Used to report error information if empty section found\r
310 #======================================================================\r
311 Index = self._RawData.LineIndex\r
312 LineStr = self._RawData.CurrentLine\r
313 while not self._RawData.IsEndOfFile() or self._RawData.NextLine:\r
314 if self._RawData.NextLine:\r
315 #==============================================================\r
316 # Have processed line in buffer\r
317 #==============================================================\r
318 Line = self._RawData.NextLine\r
319 HeadComments.extend(self._RawData.HeadComment)\r
320 TailComments.extend(self._RawData.TailComment)\r
321 self._RawData.ResetNext()\r
322 Comment = ''\r
323 FromBuf = True\r
324 else:\r
325 #==============================================================\r
326 # No line in buffer, read next line\r
327 #==============================================================\r
328 Line, Comment = CleanString(self._RawData.GetNextLine())\r
329 FromBuf = False\r
330 if Line:\r
331 if not FromBuf and CurObj and TailComments:\r
332 #==========================================================\r
333 # Set tail comments to previous statement if not empty.\r
334 #==========================================================\r
335 CurObj.SetTailComment(CurObj.GetTailComment()+TailComments)\r
f7496d71 336\r
4234283c
LG
337 if not FromBuf:\r
338 del TailComments[:]\r
339 CurComments = TailComments\r
340 Comments = []\r
341 if Comment:\r
342 Comments = [(Comment, self._RawData.LineIndex)]\r
f7496d71 343\r
4234283c
LG
344 #==============================================================\r
345 # Try if last char of line has backslash\r
346 #==============================================================\r
347 Line, Comments = self._TryBackSlash(Line, Comments)\r
348 CurComments.extend(Comments)\r
f7496d71 349\r
4234283c
LG
350 #==============================================================\r
351 # Macro found\r
352 #==============================================================\r
353 if Line.startswith('DEFINE '):\r
354 self._MacroParser(Line)\r
355 del HeadComments[:]\r
356 del TailComments[:]\r
357 CurComments = HeadComments\r
358 continue\r
f7496d71 359\r
4234283c
LG
360 if self._StopCurrentParsing(Line):\r
361 #==========================================================\r
362 # This line does not belong to this parse,\r
363 # Save it, can be used by next parse\r
364 #==========================================================\r
365 self._RawData.SetNext(Line, HeadComments, TailComments)\r
366 break\r
f7496d71 367\r
4234283c
LG
368 Obj = self._ParseItem()\r
369 ItemNum += 1\r
370 if Obj:\r
371 Obj.SetHeadComment(Obj.GetHeadComment()+HeadComments)\r
372 Obj.SetTailComment(Obj.GetTailComment()+TailComments)\r
373 del HeadComments[:]\r
374 del TailComments[:]\r
375 CurObj = Obj\r
376 else:\r
377 CurObj = None\r
378 else:\r
379 if id(CurComments) == id(TailComments):\r
380 #==========================================================\r
381 # Check if this comment belongs to tail comment\r
382 #==========================================================\r
383 if not self._TailCommentStrategy(Comment):\r
384 CurComments = HeadComments\r
385\r
386 if Comment:\r
387 CurComments.append(((Comment, self._RawData.LineIndex)))\r
388 else:\r
389 del CurComments[:]\r
f7496d71 390\r
4234283c
LG
391 if self._IsStatementRequired() and ItemNum == 0:\r
392 Logger.Error(\r
393 TOOL_NAME, FILE_PARSE_FAILURE,\r
394 File=self._RawData.Filename,\r
395 Line=Index,\r
396 ExtraData=ST.ERR_DECPARSE_STATEMENT_EMPTY % LineStr\r
397 )\r
398\r
399## _DecDefine\r
400# Parse define section\r
401#\r
402class _DecDefine(_DecBase):\r
403 def __init__(self, RawData):\r
404 _DecBase.__init__(self, RawData)\r
405 self.ItemObject = DecDefineObject(RawData.Filename)\r
406 self._LocalMacro = self._RawData.Macros\r
407 self._DefSecNum = 0\r
f7496d71 408\r
4234283c
LG
409 #\r
410 # Each field has a function to validate\r
411 #\r
412 self.DefineValidation = {\r
413 DT.TAB_DEC_DEFINES_DEC_SPECIFICATION : self._SetDecSpecification,\r
414 DT.TAB_DEC_DEFINES_PACKAGE_NAME : self._SetPackageName,\r
415 DT.TAB_DEC_DEFINES_PACKAGE_GUID : self._SetPackageGuid,\r
416 DT.TAB_DEC_DEFINES_PACKAGE_VERSION : self._SetPackageVersion,\r
421ccda3 417 DT.TAB_DEC_DEFINES_PKG_UNI_FILE : self._SetPackageUni,\r
4234283c 418 }\r
f7496d71 419\r
4234283c
LG
420 def BlockStart(self):\r
421 self._DefSecNum += 1\r
422 if self._DefSecNum > 1:\r
423 self._LoggerError(ST.ERR_DECPARSE_DEFINE_MULTISEC)\r
f7496d71 424\r
4234283c
LG
425 ## CheckRequiredFields\r
426 #\r
427 # Check required fields: DEC_SPECIFICATION, PACKAGE_NAME\r
428 # PACKAGE_GUID, PACKAGE_VERSION\r
429 #\r
430 def CheckRequiredFields(self):\r
431 Ret = False\r
432 if self.ItemObject.GetPackageSpecification() == '':\r
f7496d71 433 Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,\r
4234283c
LG
434 ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_DEC_SPECIFICATION)\r
435 elif self.ItemObject.GetPackageName() == '':\r
f7496d71 436 Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,\r
4234283c
LG
437 ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_NAME)\r
438 elif self.ItemObject.GetPackageGuid() == '':\r
f7496d71 439 Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,\r
4234283c
LG
440 ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_GUID)\r
441 elif self.ItemObject.GetPackageVersion() == '':\r
f7496d71 442 Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,\r
4234283c
LG
443 ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_VERSION)\r
444 else:\r
445 Ret = True\r
446 return Ret\r
f7496d71 447\r
4234283c
LG
448 def _ParseItem(self):\r
449 Line = self._RawData.CurrentLine\r
450 TokenList = GetSplitValueList(Line, DT.TAB_EQUAL_SPLIT, 1)\r
451 if TokenList[0] == DT.TAB_DEC_DEFINES_PKG_UNI_FILE:\r
421ccda3 452 self.DefineValidation[TokenList[0]](TokenList[1])\r
4234283c
LG
453 elif len(TokenList) < 2:\r
454 self._LoggerError(ST.ERR_DECPARSE_DEFINE_FORMAT)\r
455 elif TokenList[0] not in self.DefineValidation:\r
456 self._LoggerError(ST.ERR_DECPARSE_DEFINE_UNKNOWKEY % TokenList[0])\r
457 else:\r
458 self.DefineValidation[TokenList[0]](TokenList[1])\r
f7496d71 459\r
4234283c 460 DefineItem = DecDefineItemObject()\r
421ccda3
HC
461 DefineItem.Key = TokenList[0]\r
462 DefineItem.Value = TokenList[1]\r
463 self.ItemObject.AddItem(DefineItem, self._RawData.CurrentScope)\r
4234283c 464 return DefineItem\r
f7496d71 465\r
4234283c
LG
466 def _SetDecSpecification(self, Token):\r
467 if self.ItemObject.GetPackageSpecification():\r
468 self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_DEC_SPECIFICATION)\r
469 if not IsValidToken('0[xX][0-9a-fA-F]{8}', Token):\r
48b77f5e
HC
470 if not IsValidDecVersionVal(Token):\r
471 self._LoggerError(ST.ERR_DECPARSE_DEFINE_SPEC)\r
4234283c 472 self.ItemObject.SetPackageSpecification(Token)\r
f7496d71 473\r
4234283c
LG
474 def _SetPackageName(self, Token):\r
475 if self.ItemObject.GetPackageName():\r
476 self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_NAME)\r
477 if not IsValidWord(Token):\r
478 self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGNAME)\r
479 self.ItemObject.SetPackageName(Token)\r
f7496d71 480\r
4234283c
LG
481 def _SetPackageGuid(self, Token):\r
482 if self.ItemObject.GetPackageGuid():\r
483 self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_GUID)\r
484 if not CheckGuidRegFormat(Token):\r
485 self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGGUID)\r
486 self.ItemObject.SetPackageGuid(Token)\r
f7496d71 487\r
4234283c
LG
488 def _SetPackageVersion(self, Token):\r
489 if self.ItemObject.GetPackageVersion():\r
490 self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_VERSION)\r
491 if not IsValidToken(VERSION_PATTERN, Token):\r
492 self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGVERSION)\r
493 else:\r
494 if not DT.TAB_SPLIT in Token:\r
495 Token = Token + '.0'\r
421ccda3 496 self.ItemObject.SetPackageVersion(Token)\r
f7496d71 497\r
421ccda3
HC
498 def _SetPackageUni(self, Token):\r
499 if self.ItemObject.GetPackageUniFile():\r
500 self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PKG_UNI_FILE)\r
501 self.ItemObject.SetPackageUniFile(Token)\r
4234283c
LG
502\r
503## _DecInclude\r
504#\r
505# Parse include section\r
506#\r
507class _DecInclude(_DecBase):\r
508 def __init__(self, RawData):\r
509 _DecBase.__init__(self, RawData)\r
510 self.ItemObject = DecIncludeObject(RawData.Filename)\r
f7496d71 511\r
4234283c
LG
512 def _ParseItem(self):\r
513 Line = self._RawData.CurrentLine\r
f7496d71 514\r
4234283c 515 if not IsValidPath(Line, self._RawData.PackagePath):\r
f7496d71
LG
516 self._LoggerError(ST.ERR_DECPARSE_INCLUDE % Line)\r
517\r
4234283c
LG
518 Item = DecIncludeItemObject(StripRoot(self._RawData.PackagePath, Line), self._RawData.PackagePath)\r
519 self.ItemObject.AddItem(Item, self._RawData.CurrentScope)\r
520 return Item\r
521\r
522## _DecLibraryclass\r
523#\r
524# Parse library class section\r
525#\r
526class _DecLibraryclass(_DecBase):\r
527 def __init__(self, RawData):\r
528 _DecBase.__init__(self, RawData)\r
529 self.ItemObject = DecLibraryclassObject(RawData.Filename)\r
f7496d71 530\r
4234283c
LG
531 def _ParseItem(self):\r
532 Line = self._RawData.CurrentLine\r
533 TokenList = GetSplitValueList(Line, DT.TAB_VALUE_SPLIT)\r
534 if len(TokenList) != 2:\r
f7496d71 535 self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_SPLIT)\r
4234283c
LG
536 if TokenList[0] == '' or TokenList[1] == '':\r
537 self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_EMPTY)\r
538 if not IsValidToken('[A-Z][0-9A-Za-z]*', TokenList[0]):\r
539 self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_LIB)\r
f7496d71 540\r
4234283c 541 self._CheckReDefine(TokenList[0])\r
f7496d71 542\r
4234283c
LG
543 Value = TokenList[1]\r
544 #\r
545 # Must end with .h\r
546 #\r
547 if not Value.endswith('.h'):\r
548 self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_PATH_EXT)\r
f7496d71 549\r
4234283c
LG
550 #\r
551 # Path must be existed\r
552 #\r
553 if not IsValidPath(Value, self._RawData.PackagePath):\r
554 self._LoggerError(ST.ERR_DECPARSE_INCLUDE % Value)\r
f7496d71 555\r
4234283c
LG
556 Item = DecLibraryclassItemObject(TokenList[0], StripRoot(self._RawData.PackagePath, Value),\r
557 self._RawData.PackagePath)\r
558 self.ItemObject.AddItem(Item, self._RawData.CurrentScope)\r
559 return Item\r
560\r
561## _DecPcd\r
562#\r
563# Parse PCD section\r
564#\r
565class _DecPcd(_DecBase):\r
566 def __init__(self, RawData):\r
567 _DecBase.__init__(self, RawData)\r
568 self.ItemObject = DecPcdObject(RawData.Filename)\r
569 #\r
570 # Used to check duplicate token\r
571 # Key is token space and token number (integer), value is C name\r
572 #\r
573 self.TokenMap = {}\r
f7496d71 574\r
4234283c
LG
575 def _ParseItem(self):\r
576 Line = self._RawData.CurrentLine\r
577 TokenList = Line.split(DT.TAB_VALUE_SPLIT)\r
578 if len(TokenList) < 4:\r
579 self._LoggerError(ST.ERR_DECPARSE_PCD_SPLIT)\r
f7496d71 580\r
4234283c
LG
581 #\r
582 # Token space guid C name\r
583 #\r
584 PcdName = GetSplitValueList(TokenList[0], DT.TAB_SPLIT)\r
585 if len(PcdName) != 2 or PcdName[0] == '' or PcdName[1] == '':\r
586 self._LoggerError(ST.ERR_DECPARSE_PCD_NAME)\r
f7496d71 587\r
4234283c
LG
588 Guid = PcdName[0]\r
589 if not IsValidToken(CVAR_PATTERN, Guid):\r
590 self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_GUID)\r
f7496d71 591\r
4234283c
LG
592 #\r
593 # PCD C name\r
594 #\r
595 CName = PcdName[1]\r
596 if not IsValidToken(CVAR_PATTERN, CName):\r
597 self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_PCDCNAME)\r
f7496d71 598\r
4234283c 599 self._CheckReDefine(Guid + DT.TAB_SPLIT + CName)\r
f7496d71 600\r
4234283c
LG
601 #\r
602 # Default value, may be C array, string or number\r
603 #\r
604 Data = DT.TAB_VALUE_SPLIT.join(TokenList[1:-2]).strip()\r
f7496d71 605\r
4234283c
LG
606 #\r
607 # PCD data type\r
608 #\r
609 DataType = TokenList[-2].strip()\r
610 Valid, Cause = IsValidPcdDatum(DataType, Data)\r
611 if not Valid:\r
612 self._LoggerError(Cause)\r
613 PcdType = self._RawData.CurrentScope[0][0]\r
614 if PcdType == DT.TAB_PCDS_FEATURE_FLAG_NULL.upper() and DataType != 'BOOLEAN':\r
615 self._LoggerError(ST.ERR_DECPARSE_PCD_FEATUREFLAG)\r
616 #\r
617 # Token value is the last element in list.\r
618 #\r
619 Token = TokenList[-1].strip()\r
620 if not IsValidToken(PCD_TOKEN_PATTERN, Token):\r
621 self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN % Token)\r
622 elif not Token.startswith('0x') and not Token.startswith('0X'):\r
623 if long(Token) > 4294967295:\r
624 self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN_INT % Token)\r
625 Token = hex(long(Token))[:-1]\r
f7496d71 626\r
4234283c
LG
627 IntToken = long(Token, 0)\r
628 if (Guid, IntToken) in self.TokenMap:\r
629 if self.TokenMap[Guid, IntToken] != CName:\r
630 self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN_UNIQUE%(Token))\r
631 else:\r
632 self.TokenMap[Guid, IntToken] = CName\r
f7496d71 633\r
4234283c
LG
634 Item = DecPcdItemObject(Guid, CName, Data, DataType, Token)\r
635 self.ItemObject.AddItem(Item, self._RawData.CurrentScope)\r
636 return Item\r
f7496d71 637\r
4234283c
LG
638## _DecGuid\r
639#\r
640# Parse GUID, PPI, Protocol section\r
641#\r
642class _DecGuid(_DecBase):\r
643 def __init__(self, RawData):\r
644 _DecBase.__init__(self, RawData)\r
645 self.GuidObj = DecGuidObject(RawData.Filename)\r
646 self.PpiObj = DecPpiObject(RawData.Filename)\r
647 self.ProtocolObj = DecProtocolObject(RawData.Filename)\r
648 self.ObjectDict = \\r
649 {\r
650 DT.TAB_GUIDS.upper() : self.GuidObj,\r
651 DT.TAB_PPIS.upper() : self.PpiObj,\r
652 DT.TAB_PROTOCOLS.upper() : self.ProtocolObj\r
653 }\r
f7496d71 654\r
4234283c
LG
655 def GetDataObject(self):\r
656 if self._RawData.CurrentScope:\r
657 return self.ObjectDict[self._RawData.CurrentScope[0][0]]\r
658 return None\r
f7496d71 659\r
4234283c
LG
660 def GetGuidObject(self):\r
661 return self.GuidObj\r
f7496d71 662\r
4234283c
LG
663 def GetPpiObject(self):\r
664 return self.PpiObj\r
f7496d71 665\r
4234283c
LG
666 def GetProtocolObject(self):\r
667 return self.ProtocolObj\r
f7496d71 668\r
4234283c
LG
669 def _ParseItem(self):\r
670 Line = self._RawData.CurrentLine\r
671 TokenList = GetSplitValueList(Line, DT.TAB_EQUAL_SPLIT, 1)\r
672 if len(TokenList) < 2:\r
673 self._LoggerError(ST.ERR_DECPARSE_CGUID)\r
674 if TokenList[0] == '':\r
675 self._LoggerError(ST.ERR_DECPARSE_CGUID_NAME)\r
676 if TokenList[1] == '':\r
677 self._LoggerError(ST.ERR_DECPARSE_CGUID_GUID)\r
678 if not IsValidToken(CVAR_PATTERN, TokenList[0]):\r
679 self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_GUID)\r
f7496d71 680\r
4234283c 681 self._CheckReDefine(TokenList[0])\r
f7496d71 682\r
4234283c
LG
683 if TokenList[1][0] != '{':\r
684 if not CheckGuidRegFormat(TokenList[1]):\r
685 self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGGUID)\r
686 GuidString = TokenList[1]\r
687 else:\r
688 #\r
689 # Convert C format GUID to GUID string and Simple error check\r
690 #\r
691 GuidString = GuidStructureStringToGuidString(TokenList[1])\r
692 if TokenList[1][0] != '{' or TokenList[1][-1] != '}' or GuidString == '':\r
693 self._LoggerError(ST.ERR_DECPARSE_CGUID_GUIDFORMAT)\r
f7496d71 694\r
4234283c
LG
695 #\r
696 # Check C format GUID\r
697 #\r
698 if not IsValidCFormatGuid(TokenList[1]):\r
699 self._LoggerError(ST.ERR_DECPARSE_CGUID_GUIDFORMAT)\r
700\r
701 Item = DecGuidItemObject(TokenList[0], TokenList[1], GuidString)\r
702 ItemObject = self.ObjectDict[self._RawData.CurrentScope[0][0]]\r
703 ItemObject.AddItem(Item, self._RawData.CurrentScope)\r
704 return Item\r
705\r
706## _DecUserExtension\r
707#\r
708# Parse user extention section\r
709#\r
710class _DecUserExtension(_DecBase):\r
711 def __init__(self, RawData):\r
712 _DecBase.__init__(self, RawData)\r
713 self.ItemObject = DecUserExtensionObject(RawData.Filename)\r
714 self._Headers = []\r
715 self._CurItems = []\r
f7496d71 716\r
4234283c
LG
717 def BlockStart(self):\r
718 self._CurItems = []\r
719 for Header in self._RawData.CurrentScope:\r
720 if Header in self._Headers:\r
721 self._LoggerError(ST.ERR_DECPARSE_UE_DUPLICATE)\r
722 else:\r
723 self._Headers.append(Header)\r
f7496d71 724\r
4234283c
LG
725 for Item in self._CurItems:\r
726 if Item.UserId == Header[1] and Item.IdString == Header[2]:\r
727 Item.ArchAndModuleType.append(Header[3])\r
728 break\r
729 else:\r
730 Item = DecUserExtensionItemObject()\r
731 Item.UserId = Header[1]\r
732 Item.IdString = Header[2]\r
733 Item.ArchAndModuleType.append(Header[3])\r
734 self._CurItems.append(Item)\r
735 self.ItemObject.AddItem(Item, None)\r
736 self._LocalMacro = {}\r
f7496d71 737\r
4234283c
LG
738 def _ParseItem(self):\r
739 Line = self._RawData.CurrentLine\r
740 Item = None\r
741 for Item in self._CurItems:\r
742 if Item.UserString:\r
743 Item.UserString = '\n'.join([Item.UserString, Line])\r
744 else:\r
745 Item.UserString = Line\r
746 return Item\r
747\r
748## Dec\r
749#\r
750# Top dec parser\r
751#\r
f7496d71
LG
752class Dec(_DecBase, _DecComments):\r
753 def __init__(self, DecFile, Parse = True):\r
4234283c 754 try:\r
421ccda3 755 Content = ConvertSpecialChar(open(DecFile, 'rb').readlines())\r
4234283c
LG
756 except BaseException:\r
757 Logger.Error(TOOL_NAME, FILE_OPEN_FAILURE, File=DecFile,\r
758 ExtraData=ST.ERR_DECPARSE_FILEOPEN % DecFile)\r
645a5128
HC
759\r
760 #\r
761 # Pre-parser for Private section\r
762 #\r
763 self._Private = ''\r
764 __IsFoundPrivate = False\r
765 NewContent = []\r
766 for Line in Content:\r
767 Line = Line.strip()\r
768 if Line.startswith(DT.TAB_SECTION_START) and Line.endswith(DT.TAB_PRIVATE + DT.TAB_SECTION_END):\r
769 __IsFoundPrivate = True\r
770 if Line.startswith(DT.TAB_SECTION_START) and Line.endswith(DT.TAB_SECTION_END)\\r
771 and not Line.endswith(DT.TAB_PRIVATE + DT.TAB_SECTION_END):\r
772 __IsFoundPrivate = False\r
773 if __IsFoundPrivate:\r
774 self._Private += Line + '\r'\r
775 if not __IsFoundPrivate:\r
776 NewContent.append(Line + '\r')\r
777\r
778 RawData = FileContent(DecFile, NewContent)\r
f7496d71 779\r
4234283c
LG
780 _DecComments.__init__(self)\r
781 _DecBase.__init__(self, RawData)\r
f7496d71 782\r
421ccda3
HC
783 self.BinaryHeadComment = []\r
784 self.PcdErrorCommentDict = {}\r
f7496d71 785\r
4234283c
LG
786 self._Define = _DecDefine(RawData)\r
787 self._Include = _DecInclude(RawData)\r
788 self._Guid = _DecGuid(RawData)\r
789 self._LibClass = _DecLibraryclass(RawData)\r
790 self._Pcd = _DecPcd(RawData)\r
791 self._UserEx = _DecUserExtension(RawData)\r
f7496d71 792\r
4234283c
LG
793 #\r
794 # DEC file supported data types (one type per section)\r
795 #\r
796 self._SectionParser = {\r
797 DT.TAB_DEC_DEFINES.upper() : self._Define,\r
798 DT.TAB_INCLUDES.upper() : self._Include,\r
799 DT.TAB_LIBRARY_CLASSES.upper() : self._LibClass,\r
800 DT.TAB_GUIDS.upper() : self._Guid,\r
801 DT.TAB_PPIS.upper() : self._Guid,\r
802 DT.TAB_PROTOCOLS.upper() : self._Guid,\r
803 DT.TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : self._Pcd,\r
804 DT.TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : self._Pcd,\r
805 DT.TAB_PCDS_FEATURE_FLAG_NULL.upper() : self._Pcd,\r
806 DT.TAB_PCDS_DYNAMIC_NULL.upper() : self._Pcd,\r
807 DT.TAB_PCDS_DYNAMIC_EX_NULL.upper() : self._Pcd,\r
808 DT.TAB_USER_EXTENSIONS.upper() : self._UserEx\r
809 }\r
810\r
811 if Parse:\r
812 self.ParseDecComment()\r
813 self.Parse()\r
814 #\r
815 # Parsing done, check required fields\r
816 #\r
817 self.CheckRequiredFields()\r
f7496d71 818\r
4234283c
LG
819 def CheckRequiredFields(self):\r
820 for SectionParser in self._SectionParser.values():\r
821 if not SectionParser.CheckRequiredFields():\r
822 return False\r
823 return True\r
421ccda3 824\r
4234283c
LG
825 ##\r
826 # Parse DEC file\r
827 #\r
828 def ParseDecComment(self):\r
2bc3256c
LG
829 IsFileHeader = False\r
830 IsBinaryHeader = False\r
831 FileHeaderLineIndex = -1\r
832 BinaryHeaderLineIndex = -1\r
421ccda3 833 TokenSpaceGuidCName = ''\r
f7496d71 834\r
421ccda3
HC
835 #\r
836 # Parse PCD error comment section\r
837 #\r
4234283c 838 while not self._RawData.IsEndOfFile():\r
421ccda3
HC
839 self._RawData.CurrentLine = self._RawData.GetNextLine()\r
840 if self._RawData.CurrentLine.startswith(DT.TAB_COMMENT_SPLIT) and \\r
841 DT.TAB_SECTION_START in self._RawData.CurrentLine and \\r
842 DT.TAB_SECTION_END in self._RawData.CurrentLine:\r
843 self._RawData.CurrentLine = self._RawData.CurrentLine.replace(DT.TAB_COMMENT_SPLIT, '').strip()\r
2bc3256c 844\r
421ccda3
HC
845 if self._RawData.CurrentLine[0] == DT.TAB_SECTION_START and \\r
846 self._RawData.CurrentLine[-1] == DT.TAB_SECTION_END:\r
847 RawSection = self._RawData.CurrentLine[1:-1].strip()\r
848 if RawSection.upper().startswith(DT.TAB_PCD_ERROR.upper()+'.'):\r
849 TokenSpaceGuidCName = RawSection.split(DT.TAB_PCD_ERROR+'.')[1].strip()\r
850 continue\r
851\r
852 if TokenSpaceGuidCName and self._RawData.CurrentLine.startswith(DT.TAB_COMMENT_SPLIT):\r
853 self._RawData.CurrentLine = self._RawData.CurrentLine.replace(DT.TAB_COMMENT_SPLIT, '').strip()\r
854 if self._RawData.CurrentLine != '':\r
855 if DT.TAB_VALUE_SPLIT not in self._RawData.CurrentLine:\r
f7496d71
LG
856 self._LoggerError(ST.ERR_DECPARSE_PCDERRORMSG_MISS_VALUE_SPLIT)\r
857\r
421ccda3
HC
858 PcdErrorNumber, PcdErrorMsg = GetSplitValueList(self._RawData.CurrentLine, DT.TAB_VALUE_SPLIT, 1)\r
859 PcdErrorNumber = ParsePcdErrorCode(PcdErrorNumber, self._RawData.Filename, self._RawData.LineIndex)\r
860 if not PcdErrorMsg.strip():\r
861 self._LoggerError(ST.ERR_DECPARSE_PCD_MISS_ERRORMSG)\r
f7496d71 862\r
421ccda3
HC
863 self.PcdErrorCommentDict[(TokenSpaceGuidCName, PcdErrorNumber)] = PcdErrorMsg.strip()\r
864 else:\r
865 TokenSpaceGuidCName = ''\r
866\r
867 self._RawData.LineIndex = 0\r
868 self._RawData.CurrentLine = ''\r
869 self._RawData.NextLine = ''\r
870\r
871 while not self._RawData.IsEndOfFile():\r
872 Line, Comment = CleanString(self._RawData.GetNextLine())\r
f7496d71 873\r
4234283c
LG
874 #\r
875 # Header must be pure comment\r
876 #\r
877 if Line != '':\r
878 self._RawData.UndoNextLine()\r
879 break\r
f7496d71 880\r
2bc3256c
LG
881 if Comment and Comment.startswith(DT.TAB_SPECIAL_COMMENT) and Comment.find(DT.TAB_HEADER_COMMENT) > 0 \\r
882 and not Comment[2:Comment.find(DT.TAB_HEADER_COMMENT)].strip():\r
883 IsFileHeader = True\r
884 IsBinaryHeader = False\r
885 FileHeaderLineIndex = self._RawData.LineIndex\r
f7496d71
LG
886\r
887 #\r
888 # Get license information before '@file'\r
2bc3256c 889 #\r
2bc3256c
LG
890 if not IsFileHeader and not IsBinaryHeader and Comment and Comment.startswith(DT.TAB_COMMENT_SPLIT) and \\r
891 DT.TAB_BINARY_HEADER_COMMENT not in Comment:\r
4234283c 892 self._HeadComment.append((Comment, self._RawData.LineIndex))\r
f7496d71 893\r
2bc3256c
LG
894 if Comment and IsFileHeader and \\r
895 not(Comment.startswith(DT.TAB_SPECIAL_COMMENT) \\r
896 and Comment.find(DT.TAB_BINARY_HEADER_COMMENT) > 0):\r
897 self._HeadComment.append((Comment, self._RawData.LineIndex))\r
898 #\r
899 # Double '#' indicates end of header comments\r
900 #\r
901 if (not Comment or Comment == DT.TAB_SPECIAL_COMMENT) and IsFileHeader:\r
f7496d71 902 IsFileHeader = False\r
2bc3256c 903 continue\r
f7496d71 904\r
2bc3256c
LG
905 if Comment and Comment.startswith(DT.TAB_SPECIAL_COMMENT) \\r
906 and Comment.find(DT.TAB_BINARY_HEADER_COMMENT) > 0:\r
907 IsBinaryHeader = True\r
908 IsFileHeader = False\r
909 BinaryHeaderLineIndex = self._RawData.LineIndex\r
f7496d71 910\r
2bc3256c
LG
911 if Comment and IsBinaryHeader:\r
912 self.BinaryHeadComment.append((Comment, self._RawData.LineIndex))\r
4234283c
LG
913 #\r
914 # Double '#' indicates end of header comments\r
915 #\r
2bc3256c
LG
916 if (not Comment or Comment == DT.TAB_SPECIAL_COMMENT) and IsBinaryHeader:\r
917 IsBinaryHeader = False\r
4234283c 918 break\r
f7496d71 919\r
2bc3256c
LG
920 if FileHeaderLineIndex > -1 and not IsFileHeader and not IsBinaryHeader:\r
921 break\r
922\r
923 if FileHeaderLineIndex > BinaryHeaderLineIndex and FileHeaderLineIndex > -1 and BinaryHeaderLineIndex > -1:\r
924 self._LoggerError(ST.ERR_BINARY_HEADER_ORDER)\r
f7496d71 925\r
2bc3256c 926 if FileHeaderLineIndex == -1:\r
421ccda3 927# self._LoggerError(ST.ERR_NO_SOURCE_HEADER)\r
f7496d71 928 Logger.Error(TOOL_NAME, FORMAT_INVALID,\r
2bc3256c 929 ST.ERR_NO_SOURCE_HEADER,\r
421ccda3 930 File=self._RawData.Filename)\r
4234283c 931 return\r
f7496d71 932\r
4234283c
LG
933 def _StopCurrentParsing(self, Line):\r
934 return False\r
f7496d71 935\r
4234283c
LG
936 def _ParseItem(self):\r
937 self._SectionHeaderParser()\r
938 if len(self._RawData.CurrentScope) == 0:\r
939 self._LoggerError(ST.ERR_DECPARSE_SECTION_EMPTY)\r
4234283c 940 SectionObj = self._SectionParser[self._RawData.CurrentScope[0][0]]\r
4234283c
LG
941 SectionObj.BlockStart()\r
942 SectionObj.Parse()\r
4234283c
LG
943 return SectionObj.GetDataObject()\r
944\r
945 def _UserExtentionSectionParser(self):\r
946 self._RawData.CurrentScope = []\r
947 ArchList = set()\r
948 Section = self._RawData.CurrentLine[1:-1]\r
4234283c
LG
949 Par = ParserHelper(Section, self._RawData.Filename)\r
950 while not Par.End():\r
951 #\r
952 # User extention\r
953 #\r
954 Token = Par.GetToken()\r
955 if Token.upper() != DT.TAB_USER_EXTENSIONS.upper():\r
956 self._LoggerError(ST.ERR_DECPARSE_SECTION_UE)\r
957 UserExtension = Token.upper()\r
f7496d71
LG
958 Par.AssertChar(DT.TAB_SPLIT, ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)\r
959\r
4234283c
LG
960 #\r
961 # UserID\r
962 #\r
963 Token = Par.GetToken()\r
964 if not IsValidUserId(Token):\r
965 self._LoggerError(ST.ERR_DECPARSE_SECTION_UE_USERID)\r
966 UserId = Token\r
4234283c
LG
967 Par.AssertChar(DT.TAB_SPLIT, ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)\r
968 #\r
969 # IdString\r
970 #\r
971 Token = Par.GetToken()\r
972 if not IsValidIdString(Token):\r
973 self._LoggerError(ST.ERR_DECPARSE_SECTION_UE_IDSTRING)\r
974 IdString = Token\r
4234283c
LG
975 Arch = 'COMMON'\r
976 if Par.Expect(DT.TAB_SPLIT):\r
977 Token = Par.GetToken()\r
978 Arch = Token.upper()\r
979 if not IsValidArch(Arch):\r
980 self._LoggerError(ST.ERR_DECPARSE_ARCH)\r
981 ArchList.add(Arch)\r
4234283c
LG
982 if [UserExtension, UserId, IdString, Arch] not in \\r
983 self._RawData.CurrentScope:\r
984 self._RawData.CurrentScope.append(\r
985 [UserExtension, UserId, IdString, Arch]\r
986 )\r
4234283c
LG
987 if not Par.Expect(DT.TAB_COMMA_SPLIT):\r
988 break\r
989 elif Par.End():\r
990 self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMA)\r
4234283c 991 Par.AssertEnd(ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)\r
4234283c
LG
992 if 'COMMON' in ArchList and len(ArchList) > 1:\r
993 self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMON)\r
f7496d71 994\r
4234283c
LG
995 ## Section header parser\r
996 #\r
997 # The section header is always in following format:\r
998 #\r
999 # [section_name.arch<.platform|module_type>]\r
1000 #\r
1001 def _SectionHeaderParser(self):\r
1002 if self._RawData.CurrentLine[0] != DT.TAB_SECTION_START or self._RawData.CurrentLine[-1] != DT.TAB_SECTION_END:\r
1003 self._LoggerError(ST.ERR_DECPARSE_SECTION_IDENTIFY)\r
f7496d71 1004\r
4234283c 1005 RawSection = self._RawData.CurrentLine[1:-1].strip().upper()\r
4234283c
LG
1006 #\r
1007 # Check defines section which is only allowed to occur once and\r
1008 # no arch can be followed\r
1009 #\r
1010 if RawSection.startswith(DT.TAB_DEC_DEFINES.upper()):\r
1011 if RawSection != DT.TAB_DEC_DEFINES.upper():\r
1012 self._LoggerError(ST.ERR_DECPARSE_DEFINE_SECNAME)\r
4234283c
LG
1013 #\r
1014 # Check user extension section\r
1015 #\r
1016 if RawSection.startswith(DT.TAB_USER_EXTENSIONS.upper()):\r
1017 return self._UserExtentionSectionParser()\r
4234283c
LG
1018 self._RawData.CurrentScope = []\r
1019 SectionNames = []\r
1020 ArchList = set()\r
1021 for Item in GetSplitValueList(RawSection, DT.TAB_COMMA_SPLIT):\r
1022 if Item == '':\r
1023 self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBEMPTY % self._RawData.CurrentLine)\r
1024\r
1025 ItemList = GetSplitValueList(Item, DT.TAB_SPLIT)\r
4234283c
LG
1026 #\r
1027 # different types of PCD are permissible in one section\r
1028 #\r
1029 SectionName = ItemList[0]\r
1030 if SectionName not in self._SectionParser:\r
1031 self._LoggerError(ST.ERR_DECPARSE_SECTION_UNKNOW % SectionName)\r
4234283c
LG
1032 if SectionName not in SectionNames:\r
1033 SectionNames.append(SectionName)\r
4234283c
LG
1034 #\r
1035 # In DEC specification, all section headers have at most two part:\r
1036 # SectionName.Arch except UserExtention\r
1037 #\r
1038 if len(ItemList) > 2:\r
1039 self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBTOOMANY % Item)\r
1040\r
1041 if DT.TAB_PCDS_FEATURE_FLAG_NULL.upper() in SectionNames and len(SectionNames) > 1:\r
f7496d71 1042 self._LoggerError(ST.ERR_DECPARSE_SECTION_FEATUREFLAG % DT.TAB_PCDS_FEATURE_FLAG_NULL)\r
4234283c
LG
1043 #\r
1044 # S1 is always Arch\r
1045 #\r
1046 if len(ItemList) > 1:\r
1047 Str1 = ItemList[1]\r
1048 if not IsValidArch(Str1):\r
1049 self._LoggerError(ST.ERR_DECPARSE_ARCH)\r
1050 else:\r
1051 Str1 = 'COMMON'\r
1052 ArchList.add(Str1)\r
1053\r
1054 if [SectionName, Str1] not in self._RawData.CurrentScope:\r
1055 self._RawData.CurrentScope.append([SectionName, Str1])\r
1056 #\r
1057 # 'COMMON' must not be used with specific ARCHs at the same section\r
1058 #\r
1059 if 'COMMON' in ArchList and len(ArchList) > 1:\r
1060 self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMON)\r
4234283c
LG
1061 if len(SectionNames) == 0:\r
1062 self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBEMPTY % self._RawData.CurrentLine)\r
1063 if len(SectionNames) != 1:\r
1064 for Sec in SectionNames:\r
1065 if not Sec.startswith(DT.TAB_PCDS.upper()):\r
1066 self._LoggerError(ST.ERR_DECPARSE_SECTION_NAME % str(SectionNames))\r
f7496d71 1067\r
421ccda3
HC
1068 def GetDefineSectionMacro(self):\r
1069 return self._Define.GetLocalMacro()\r
4234283c
LG
1070 def GetDefineSectionObject(self):\r
1071 return self._Define.GetDataObject()\r
4234283c
LG
1072 def GetIncludeSectionObject(self):\r
1073 return self._Include.GetDataObject()\r
4234283c
LG
1074 def GetGuidSectionObject(self):\r
1075 return self._Guid.GetGuidObject()\r
4234283c
LG
1076 def GetProtocolSectionObject(self):\r
1077 return self._Guid.GetProtocolObject()\r
4234283c
LG
1078 def GetPpiSectionObject(self):\r
1079 return self._Guid.GetPpiObject()\r
4234283c
LG
1080 def GetLibraryClassSectionObject(self):\r
1081 return self._LibClass.GetDataObject()\r
4234283c
LG
1082 def GetPcdSectionObject(self):\r
1083 return self._Pcd.GetDataObject()\r
4234283c
LG
1084 def GetUserExtensionSectionObject(self):\r
1085 return self._UserEx.GetDataObject()\r
4234283c 1086 def GetPackageSpecification(self):\r
f7496d71 1087 return self._Define.GetDataObject().GetPackageSpecification()\r
4234283c 1088 def GetPackageName(self):\r
f7496d71 1089 return self._Define.GetDataObject().GetPackageName()\r
4234283c 1090 def GetPackageGuid(self):\r
f7496d71 1091 return self._Define.GetDataObject().GetPackageGuid()\r
4234283c
LG
1092 def GetPackageVersion(self):\r
1093 return self._Define.GetDataObject().GetPackageVersion()\r
4234283c
LG
1094 def GetPackageUniFile(self):\r
1095 return self._Define.GetDataObject().GetPackageUniFile()\r
645a5128
HC
1096 def GetPrivateSections(self):\r
1097 return self._Private\r