]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/UPT/Parser/DecParser.py
BaseTool/Upt: Add support for Private
[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
645a5128 4# Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>\r
4234283c
LG
5#\r
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
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
60from Library.String import ReplaceMacro\r
61from Library.String import GetSplitValueList\r
62from Library.String import gMACRO_PATTERN\r
63from Library.String 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
78 \r
79 def GetDataObject(self):\r
80 return self.ItemObject\r
81 \r
421ccda3
HC
82 def GetLocalMacro(self):\r
83 return self._LocalMacro\r
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
91 \r
92 ## _CheckReDefine\r
93 #\r
94 # @param Key: to be checked if multi-defined\r
95 # @param Scope: Format: [[SectionName, Arch], ...]. \r
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
102 \r
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
111 \r
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
135 \r
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
139 # \r
140 def CheckRequiredFields(self):\r
141 if self._RawData:\r
142 pass\r
143 return True\r
144 \r
145 ## IsItemRequired\r
146 # In DEC spec, sections must have at least one statement except user \r
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
155 \r
156 def _LoggerError(self, ErrorString):\r
157 Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename, \r
158 Line = self._RawData.LineIndex,\r
159 ExtraData=ErrorString + ST.ERR_DECPARSE_LINE % self._RawData.CurrentLine)\r
160 \r
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
172 File=self._RawData.Filename, \r
173 Line = self._RawData.LineIndex,\r
174 ExtraData = ST.ERR_DECPARSE_MACRO_RESOLVE % (str(MacroUsed), String))\r
175 return String\r
176 \r
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
187 \r
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
205 \r
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
219 \r
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
232 \r
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
249 \r
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
272 \r
273 self._RawData.CurrentLine = self._ReplaceMacro(CatLine)\r
274 return CatLine, CommentList\r
275 \r
276 ## Parse\r
277 # This is a template method in which other member functions which might \r
278 # override by sub class are called. It is responsible for reading file \r
279 # line by line, and call other member functions to parse. This function\r
280 # should not be re-implement by sub class.\r
281 #\r
282 def Parse(self):\r
283 HeadComments = []\r
284 TailComments = []\r
285 \r
286 #======================================================================\r
287 # CurComments may pointer to HeadComments or TailComments\r
288 #======================================================================\r
289 CurComments = HeadComments\r
290 CurObj = None\r
291 ItemNum = 0\r
292 FromBuf = False\r
293 \r
294 #======================================================================\r
295 # Used to report error information if empty section found\r
296 #======================================================================\r
297 Index = self._RawData.LineIndex\r
298 LineStr = self._RawData.CurrentLine\r
299 while not self._RawData.IsEndOfFile() or self._RawData.NextLine:\r
300 if self._RawData.NextLine:\r
301 #==============================================================\r
302 # Have processed line in buffer\r
303 #==============================================================\r
304 Line = self._RawData.NextLine\r
305 HeadComments.extend(self._RawData.HeadComment)\r
306 TailComments.extend(self._RawData.TailComment)\r
307 self._RawData.ResetNext()\r
308 Comment = ''\r
309 FromBuf = True\r
310 else:\r
311 #==============================================================\r
312 # No line in buffer, read next line\r
313 #==============================================================\r
314 Line, Comment = CleanString(self._RawData.GetNextLine())\r
315 FromBuf = False\r
316 if Line:\r
317 if not FromBuf and CurObj and TailComments:\r
318 #==========================================================\r
319 # Set tail comments to previous statement if not empty.\r
320 #==========================================================\r
321 CurObj.SetTailComment(CurObj.GetTailComment()+TailComments)\r
322 \r
323 if not FromBuf:\r
324 del TailComments[:]\r
325 CurComments = TailComments\r
326 Comments = []\r
327 if Comment:\r
328 Comments = [(Comment, self._RawData.LineIndex)]\r
329 \r
330 #==============================================================\r
331 # Try if last char of line has backslash\r
332 #==============================================================\r
333 Line, Comments = self._TryBackSlash(Line, Comments)\r
334 CurComments.extend(Comments)\r
335 \r
336 #==============================================================\r
337 # Macro found\r
338 #==============================================================\r
339 if Line.startswith('DEFINE '):\r
340 self._MacroParser(Line)\r
341 del HeadComments[:]\r
342 del TailComments[:]\r
343 CurComments = HeadComments\r
344 continue\r
345 \r
346 if self._StopCurrentParsing(Line):\r
347 #==========================================================\r
348 # This line does not belong to this parse,\r
349 # Save it, can be used by next parse\r
350 #==========================================================\r
351 self._RawData.SetNext(Line, HeadComments, TailComments)\r
352 break\r
353 \r
354 Obj = self._ParseItem()\r
355 ItemNum += 1\r
356 if Obj:\r
357 Obj.SetHeadComment(Obj.GetHeadComment()+HeadComments)\r
358 Obj.SetTailComment(Obj.GetTailComment()+TailComments)\r
359 del HeadComments[:]\r
360 del TailComments[:]\r
361 CurObj = Obj\r
362 else:\r
363 CurObj = None\r
364 else:\r
365 if id(CurComments) == id(TailComments):\r
366 #==========================================================\r
367 # Check if this comment belongs to tail comment\r
368 #==========================================================\r
369 if not self._TailCommentStrategy(Comment):\r
370 CurComments = HeadComments\r
371\r
372 if Comment:\r
373 CurComments.append(((Comment, self._RawData.LineIndex)))\r
374 else:\r
375 del CurComments[:]\r
376 \r
377 if self._IsStatementRequired() and ItemNum == 0:\r
378 Logger.Error(\r
379 TOOL_NAME, FILE_PARSE_FAILURE,\r
380 File=self._RawData.Filename,\r
381 Line=Index,\r
382 ExtraData=ST.ERR_DECPARSE_STATEMENT_EMPTY % LineStr\r
383 )\r
384\r
385## _DecDefine\r
386# Parse define section\r
387#\r
388class _DecDefine(_DecBase):\r
389 def __init__(self, RawData):\r
390 _DecBase.__init__(self, RawData)\r
391 self.ItemObject = DecDefineObject(RawData.Filename)\r
392 self._LocalMacro = self._RawData.Macros\r
393 self._DefSecNum = 0\r
394 \r
395 #\r
396 # Each field has a function to validate\r
397 #\r
398 self.DefineValidation = {\r
399 DT.TAB_DEC_DEFINES_DEC_SPECIFICATION : self._SetDecSpecification,\r
400 DT.TAB_DEC_DEFINES_PACKAGE_NAME : self._SetPackageName,\r
401 DT.TAB_DEC_DEFINES_PACKAGE_GUID : self._SetPackageGuid,\r
402 DT.TAB_DEC_DEFINES_PACKAGE_VERSION : self._SetPackageVersion,\r
421ccda3 403 DT.TAB_DEC_DEFINES_PKG_UNI_FILE : self._SetPackageUni,\r
4234283c
LG
404 }\r
405 \r
406 def BlockStart(self):\r
407 self._DefSecNum += 1\r
408 if self._DefSecNum > 1:\r
409 self._LoggerError(ST.ERR_DECPARSE_DEFINE_MULTISEC)\r
410 \r
411 ## CheckRequiredFields\r
412 #\r
413 # Check required fields: DEC_SPECIFICATION, PACKAGE_NAME\r
414 # PACKAGE_GUID, PACKAGE_VERSION\r
415 #\r
416 def CheckRequiredFields(self):\r
417 Ret = False\r
418 if self.ItemObject.GetPackageSpecification() == '':\r
419 Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename, \r
420 ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_DEC_SPECIFICATION)\r
421 elif self.ItemObject.GetPackageName() == '':\r
422 Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename, \r
423 ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_NAME)\r
424 elif self.ItemObject.GetPackageGuid() == '':\r
425 Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename, \r
426 ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_GUID)\r
427 elif self.ItemObject.GetPackageVersion() == '':\r
428 Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename, \r
429 ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_VERSION)\r
430 else:\r
431 Ret = True\r
432 return Ret\r
433 \r
434 def _ParseItem(self):\r
435 Line = self._RawData.CurrentLine\r
436 TokenList = GetSplitValueList(Line, DT.TAB_EQUAL_SPLIT, 1)\r
437 if TokenList[0] == DT.TAB_DEC_DEFINES_PKG_UNI_FILE:\r
421ccda3 438 self.DefineValidation[TokenList[0]](TokenList[1])\r
4234283c
LG
439 elif len(TokenList) < 2:\r
440 self._LoggerError(ST.ERR_DECPARSE_DEFINE_FORMAT)\r
441 elif TokenList[0] not in self.DefineValidation:\r
442 self._LoggerError(ST.ERR_DECPARSE_DEFINE_UNKNOWKEY % TokenList[0])\r
443 else:\r
444 self.DefineValidation[TokenList[0]](TokenList[1])\r
445 \r
446 DefineItem = DecDefineItemObject()\r
421ccda3
HC
447 DefineItem.Key = TokenList[0]\r
448 DefineItem.Value = TokenList[1]\r
449 self.ItemObject.AddItem(DefineItem, self._RawData.CurrentScope)\r
4234283c
LG
450 return DefineItem\r
451 \r
452 def _SetDecSpecification(self, Token):\r
453 if self.ItemObject.GetPackageSpecification():\r
454 self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_DEC_SPECIFICATION)\r
455 if not IsValidToken('0[xX][0-9a-fA-F]{8}', Token):\r
48b77f5e
HC
456 if not IsValidDecVersionVal(Token):\r
457 self._LoggerError(ST.ERR_DECPARSE_DEFINE_SPEC)\r
4234283c
LG
458 self.ItemObject.SetPackageSpecification(Token)\r
459 \r
460 def _SetPackageName(self, Token):\r
461 if self.ItemObject.GetPackageName():\r
462 self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_NAME)\r
463 if not IsValidWord(Token):\r
464 self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGNAME)\r
465 self.ItemObject.SetPackageName(Token)\r
466 \r
467 def _SetPackageGuid(self, Token):\r
468 if self.ItemObject.GetPackageGuid():\r
469 self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_GUID)\r
470 if not CheckGuidRegFormat(Token):\r
471 self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGGUID)\r
472 self.ItemObject.SetPackageGuid(Token)\r
473 \r
474 def _SetPackageVersion(self, Token):\r
475 if self.ItemObject.GetPackageVersion():\r
476 self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_VERSION)\r
477 if not IsValidToken(VERSION_PATTERN, Token):\r
478 self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGVERSION)\r
479 else:\r
480 if not DT.TAB_SPLIT in Token:\r
481 Token = Token + '.0'\r
421ccda3
HC
482 self.ItemObject.SetPackageVersion(Token)\r
483 \r
484 def _SetPackageUni(self, Token):\r
485 if self.ItemObject.GetPackageUniFile():\r
486 self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PKG_UNI_FILE)\r
487 self.ItemObject.SetPackageUniFile(Token)\r
4234283c
LG
488\r
489## _DecInclude\r
490#\r
491# Parse include section\r
492#\r
493class _DecInclude(_DecBase):\r
494 def __init__(self, RawData):\r
495 _DecBase.__init__(self, RawData)\r
496 self.ItemObject = DecIncludeObject(RawData.Filename)\r
497 \r
498 def _ParseItem(self):\r
499 Line = self._RawData.CurrentLine\r
500 \r
501 if not IsValidPath(Line, self._RawData.PackagePath):\r
502 self._LoggerError(ST.ERR_DECPARSE_INCLUDE % Line) \r
503 \r
504 Item = DecIncludeItemObject(StripRoot(self._RawData.PackagePath, Line), self._RawData.PackagePath)\r
505 self.ItemObject.AddItem(Item, self._RawData.CurrentScope)\r
506 return Item\r
507\r
508## _DecLibraryclass\r
509#\r
510# Parse library class section\r
511#\r
512class _DecLibraryclass(_DecBase):\r
513 def __init__(self, RawData):\r
514 _DecBase.__init__(self, RawData)\r
515 self.ItemObject = DecLibraryclassObject(RawData.Filename)\r
516 \r
517 def _ParseItem(self):\r
518 Line = self._RawData.CurrentLine\r
519 TokenList = GetSplitValueList(Line, DT.TAB_VALUE_SPLIT)\r
520 if len(TokenList) != 2:\r
521 self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_SPLIT) \r
522 if TokenList[0] == '' or TokenList[1] == '':\r
523 self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_EMPTY)\r
524 if not IsValidToken('[A-Z][0-9A-Za-z]*', TokenList[0]):\r
525 self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_LIB)\r
526 \r
527 self._CheckReDefine(TokenList[0])\r
528 \r
529 Value = TokenList[1]\r
530 #\r
531 # Must end with .h\r
532 #\r
533 if not Value.endswith('.h'):\r
534 self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_PATH_EXT)\r
535 \r
536 #\r
537 # Path must be existed\r
538 #\r
539 if not IsValidPath(Value, self._RawData.PackagePath):\r
540 self._LoggerError(ST.ERR_DECPARSE_INCLUDE % Value)\r
541 \r
542 Item = DecLibraryclassItemObject(TokenList[0], StripRoot(self._RawData.PackagePath, Value),\r
543 self._RawData.PackagePath)\r
544 self.ItemObject.AddItem(Item, self._RawData.CurrentScope)\r
545 return Item\r
546\r
547## _DecPcd\r
548#\r
549# Parse PCD section\r
550#\r
551class _DecPcd(_DecBase):\r
552 def __init__(self, RawData):\r
553 _DecBase.__init__(self, RawData)\r
554 self.ItemObject = DecPcdObject(RawData.Filename)\r
555 #\r
556 # Used to check duplicate token\r
557 # Key is token space and token number (integer), value is C name\r
558 #\r
559 self.TokenMap = {}\r
560 \r
561 def _ParseItem(self):\r
562 Line = self._RawData.CurrentLine\r
563 TokenList = Line.split(DT.TAB_VALUE_SPLIT)\r
564 if len(TokenList) < 4:\r
565 self._LoggerError(ST.ERR_DECPARSE_PCD_SPLIT)\r
566 \r
567 #\r
568 # Token space guid C name\r
569 #\r
570 PcdName = GetSplitValueList(TokenList[0], DT.TAB_SPLIT)\r
571 if len(PcdName) != 2 or PcdName[0] == '' or PcdName[1] == '':\r
572 self._LoggerError(ST.ERR_DECPARSE_PCD_NAME)\r
573 \r
574 Guid = PcdName[0]\r
575 if not IsValidToken(CVAR_PATTERN, Guid):\r
576 self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_GUID)\r
577 \r
578 #\r
579 # PCD C name\r
580 #\r
581 CName = PcdName[1]\r
582 if not IsValidToken(CVAR_PATTERN, CName):\r
583 self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_PCDCNAME)\r
584 \r
585 self._CheckReDefine(Guid + DT.TAB_SPLIT + CName)\r
586 \r
587 #\r
588 # Default value, may be C array, string or number\r
589 #\r
590 Data = DT.TAB_VALUE_SPLIT.join(TokenList[1:-2]).strip()\r
591 \r
592 #\r
593 # PCD data type\r
594 #\r
595 DataType = TokenList[-2].strip()\r
596 Valid, Cause = IsValidPcdDatum(DataType, Data)\r
597 if not Valid:\r
598 self._LoggerError(Cause)\r
599 PcdType = self._RawData.CurrentScope[0][0]\r
600 if PcdType == DT.TAB_PCDS_FEATURE_FLAG_NULL.upper() and DataType != 'BOOLEAN':\r
601 self._LoggerError(ST.ERR_DECPARSE_PCD_FEATUREFLAG)\r
602 #\r
603 # Token value is the last element in list.\r
604 #\r
605 Token = TokenList[-1].strip()\r
606 if not IsValidToken(PCD_TOKEN_PATTERN, Token):\r
607 self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN % Token)\r
608 elif not Token.startswith('0x') and not Token.startswith('0X'):\r
609 if long(Token) > 4294967295:\r
610 self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN_INT % Token)\r
611 Token = hex(long(Token))[:-1]\r
612 \r
613 IntToken = long(Token, 0)\r
614 if (Guid, IntToken) in self.TokenMap:\r
615 if self.TokenMap[Guid, IntToken] != CName:\r
616 self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN_UNIQUE%(Token))\r
617 else:\r
618 self.TokenMap[Guid, IntToken] = CName\r
619 \r
620 Item = DecPcdItemObject(Guid, CName, Data, DataType, Token)\r
621 self.ItemObject.AddItem(Item, self._RawData.CurrentScope)\r
622 return Item\r
623 \r
624## _DecGuid\r
625#\r
626# Parse GUID, PPI, Protocol section\r
627#\r
628class _DecGuid(_DecBase):\r
629 def __init__(self, RawData):\r
630 _DecBase.__init__(self, RawData)\r
631 self.GuidObj = DecGuidObject(RawData.Filename)\r
632 self.PpiObj = DecPpiObject(RawData.Filename)\r
633 self.ProtocolObj = DecProtocolObject(RawData.Filename)\r
634 self.ObjectDict = \\r
635 {\r
636 DT.TAB_GUIDS.upper() : self.GuidObj,\r
637 DT.TAB_PPIS.upper() : self.PpiObj,\r
638 DT.TAB_PROTOCOLS.upper() : self.ProtocolObj\r
639 }\r
640 \r
641 def GetDataObject(self):\r
642 if self._RawData.CurrentScope:\r
643 return self.ObjectDict[self._RawData.CurrentScope[0][0]]\r
644 return None\r
645 \r
646 def GetGuidObject(self):\r
647 return self.GuidObj\r
648 \r
649 def GetPpiObject(self):\r
650 return self.PpiObj\r
651 \r
652 def GetProtocolObject(self):\r
653 return self.ProtocolObj\r
654 \r
655 def _ParseItem(self):\r
656 Line = self._RawData.CurrentLine\r
657 TokenList = GetSplitValueList(Line, DT.TAB_EQUAL_SPLIT, 1)\r
658 if len(TokenList) < 2:\r
659 self._LoggerError(ST.ERR_DECPARSE_CGUID)\r
660 if TokenList[0] == '':\r
661 self._LoggerError(ST.ERR_DECPARSE_CGUID_NAME)\r
662 if TokenList[1] == '':\r
663 self._LoggerError(ST.ERR_DECPARSE_CGUID_GUID)\r
664 if not IsValidToken(CVAR_PATTERN, TokenList[0]):\r
665 self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_GUID)\r
666 \r
667 self._CheckReDefine(TokenList[0])\r
668 \r
669 if TokenList[1][0] != '{':\r
670 if not CheckGuidRegFormat(TokenList[1]):\r
671 self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGGUID)\r
672 GuidString = TokenList[1]\r
673 else:\r
674 #\r
675 # Convert C format GUID to GUID string and Simple error check\r
676 #\r
677 GuidString = GuidStructureStringToGuidString(TokenList[1])\r
678 if TokenList[1][0] != '{' or TokenList[1][-1] != '}' or GuidString == '':\r
679 self._LoggerError(ST.ERR_DECPARSE_CGUID_GUIDFORMAT)\r
680 \r
681 #\r
682 # Check C format GUID\r
683 #\r
684 if not IsValidCFormatGuid(TokenList[1]):\r
685 self._LoggerError(ST.ERR_DECPARSE_CGUID_GUIDFORMAT)\r
686\r
687 Item = DecGuidItemObject(TokenList[0], TokenList[1], GuidString)\r
688 ItemObject = self.ObjectDict[self._RawData.CurrentScope[0][0]]\r
689 ItemObject.AddItem(Item, self._RawData.CurrentScope)\r
690 return Item\r
691\r
692## _DecUserExtension\r
693#\r
694# Parse user extention section\r
695#\r
696class _DecUserExtension(_DecBase):\r
697 def __init__(self, RawData):\r
698 _DecBase.__init__(self, RawData)\r
699 self.ItemObject = DecUserExtensionObject(RawData.Filename)\r
700 self._Headers = []\r
701 self._CurItems = []\r
702 \r
703 def BlockStart(self):\r
704 self._CurItems = []\r
705 for Header in self._RawData.CurrentScope:\r
706 if Header in self._Headers:\r
707 self._LoggerError(ST.ERR_DECPARSE_UE_DUPLICATE)\r
708 else:\r
709 self._Headers.append(Header)\r
710 \r
711 for Item in self._CurItems:\r
712 if Item.UserId == Header[1] and Item.IdString == Header[2]:\r
713 Item.ArchAndModuleType.append(Header[3])\r
714 break\r
715 else:\r
716 Item = DecUserExtensionItemObject()\r
717 Item.UserId = Header[1]\r
718 Item.IdString = Header[2]\r
719 Item.ArchAndModuleType.append(Header[3])\r
720 self._CurItems.append(Item)\r
721 self.ItemObject.AddItem(Item, None)\r
722 self._LocalMacro = {}\r
723 \r
724 def _ParseItem(self):\r
725 Line = self._RawData.CurrentLine\r
726 Item = None\r
727 for Item in self._CurItems:\r
728 if Item.UserString:\r
729 Item.UserString = '\n'.join([Item.UserString, Line])\r
730 else:\r
731 Item.UserString = Line\r
732 return Item\r
733\r
734## Dec\r
735#\r
736# Top dec parser\r
737#\r
738class Dec(_DecBase, _DecComments): \r
739 def __init__(self, DecFile, Parse = True): \r
740 try:\r
421ccda3 741 Content = ConvertSpecialChar(open(DecFile, 'rb').readlines())\r
4234283c
LG
742 except BaseException:\r
743 Logger.Error(TOOL_NAME, FILE_OPEN_FAILURE, File=DecFile,\r
744 ExtraData=ST.ERR_DECPARSE_FILEOPEN % DecFile)\r
645a5128
HC
745\r
746 #\r
747 # Pre-parser for Private section\r
748 #\r
749 self._Private = ''\r
750 __IsFoundPrivate = False\r
751 NewContent = []\r
752 for Line in Content:\r
753 Line = Line.strip()\r
754 if Line.startswith(DT.TAB_SECTION_START) and Line.endswith(DT.TAB_PRIVATE + DT.TAB_SECTION_END):\r
755 __IsFoundPrivate = True\r
756 if Line.startswith(DT.TAB_SECTION_START) and Line.endswith(DT.TAB_SECTION_END)\\r
757 and not Line.endswith(DT.TAB_PRIVATE + DT.TAB_SECTION_END):\r
758 __IsFoundPrivate = False\r
759 if __IsFoundPrivate:\r
760 self._Private += Line + '\r'\r
761 if not __IsFoundPrivate:\r
762 NewContent.append(Line + '\r')\r
763\r
764 RawData = FileContent(DecFile, NewContent)\r
4234283c
LG
765 \r
766 _DecComments.__init__(self)\r
767 _DecBase.__init__(self, RawData)\r
768 \r
421ccda3
HC
769 self.BinaryHeadComment = []\r
770 self.PcdErrorCommentDict = {}\r
771 \r
4234283c
LG
772 self._Define = _DecDefine(RawData)\r
773 self._Include = _DecInclude(RawData)\r
774 self._Guid = _DecGuid(RawData)\r
775 self._LibClass = _DecLibraryclass(RawData)\r
776 self._Pcd = _DecPcd(RawData)\r
777 self._UserEx = _DecUserExtension(RawData)\r
778 \r
779 #\r
780 # DEC file supported data types (one type per section)\r
781 #\r
782 self._SectionParser = {\r
783 DT.TAB_DEC_DEFINES.upper() : self._Define,\r
784 DT.TAB_INCLUDES.upper() : self._Include,\r
785 DT.TAB_LIBRARY_CLASSES.upper() : self._LibClass,\r
786 DT.TAB_GUIDS.upper() : self._Guid,\r
787 DT.TAB_PPIS.upper() : self._Guid,\r
788 DT.TAB_PROTOCOLS.upper() : self._Guid,\r
789 DT.TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : self._Pcd,\r
790 DT.TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : self._Pcd,\r
791 DT.TAB_PCDS_FEATURE_FLAG_NULL.upper() : self._Pcd,\r
792 DT.TAB_PCDS_DYNAMIC_NULL.upper() : self._Pcd,\r
793 DT.TAB_PCDS_DYNAMIC_EX_NULL.upper() : self._Pcd,\r
794 DT.TAB_USER_EXTENSIONS.upper() : self._UserEx\r
795 }\r
796\r
797 if Parse:\r
798 self.ParseDecComment()\r
799 self.Parse()\r
800 #\r
801 # Parsing done, check required fields\r
802 #\r
803 self.CheckRequiredFields()\r
804 \r
805 def CheckRequiredFields(self):\r
806 for SectionParser in self._SectionParser.values():\r
807 if not SectionParser.CheckRequiredFields():\r
808 return False\r
809 return True\r
421ccda3 810\r
4234283c
LG
811 ##\r
812 # Parse DEC file\r
813 #\r
814 def ParseDecComment(self):\r
2bc3256c
LG
815 IsFileHeader = False\r
816 IsBinaryHeader = False\r
817 FileHeaderLineIndex = -1\r
818 BinaryHeaderLineIndex = -1\r
421ccda3
HC
819 TokenSpaceGuidCName = ''\r
820 \r
821 #\r
822 # Parse PCD error comment section\r
823 #\r
4234283c 824 while not self._RawData.IsEndOfFile():\r
421ccda3
HC
825 self._RawData.CurrentLine = self._RawData.GetNextLine()\r
826 if self._RawData.CurrentLine.startswith(DT.TAB_COMMENT_SPLIT) and \\r
827 DT.TAB_SECTION_START in self._RawData.CurrentLine and \\r
828 DT.TAB_SECTION_END in self._RawData.CurrentLine:\r
829 self._RawData.CurrentLine = self._RawData.CurrentLine.replace(DT.TAB_COMMENT_SPLIT, '').strip()\r
2bc3256c 830\r
421ccda3
HC
831 if self._RawData.CurrentLine[0] == DT.TAB_SECTION_START and \\r
832 self._RawData.CurrentLine[-1] == DT.TAB_SECTION_END:\r
833 RawSection = self._RawData.CurrentLine[1:-1].strip()\r
834 if RawSection.upper().startswith(DT.TAB_PCD_ERROR.upper()+'.'):\r
835 TokenSpaceGuidCName = RawSection.split(DT.TAB_PCD_ERROR+'.')[1].strip()\r
836 continue\r
837\r
838 if TokenSpaceGuidCName and self._RawData.CurrentLine.startswith(DT.TAB_COMMENT_SPLIT):\r
839 self._RawData.CurrentLine = self._RawData.CurrentLine.replace(DT.TAB_COMMENT_SPLIT, '').strip()\r
840 if self._RawData.CurrentLine != '':\r
841 if DT.TAB_VALUE_SPLIT not in self._RawData.CurrentLine:\r
842 self._LoggerError(ST.ERR_DECPARSE_PCDERRORMSG_MISS_VALUE_SPLIT) \r
843 \r
844 PcdErrorNumber, PcdErrorMsg = GetSplitValueList(self._RawData.CurrentLine, DT.TAB_VALUE_SPLIT, 1)\r
845 PcdErrorNumber = ParsePcdErrorCode(PcdErrorNumber, self._RawData.Filename, self._RawData.LineIndex)\r
846 if not PcdErrorMsg.strip():\r
847 self._LoggerError(ST.ERR_DECPARSE_PCD_MISS_ERRORMSG)\r
848 \r
849 self.PcdErrorCommentDict[(TokenSpaceGuidCName, PcdErrorNumber)] = PcdErrorMsg.strip()\r
850 else:\r
851 TokenSpaceGuidCName = ''\r
852\r
853 self._RawData.LineIndex = 0\r
854 self._RawData.CurrentLine = ''\r
855 self._RawData.NextLine = ''\r
856\r
857 while not self._RawData.IsEndOfFile():\r
858 Line, Comment = CleanString(self._RawData.GetNextLine())\r
859 \r
4234283c
LG
860 #\r
861 # Header must be pure comment\r
862 #\r
863 if Line != '':\r
864 self._RawData.UndoNextLine()\r
865 break\r
866 \r
2bc3256c
LG
867 if Comment and Comment.startswith(DT.TAB_SPECIAL_COMMENT) and Comment.find(DT.TAB_HEADER_COMMENT) > 0 \\r
868 and not Comment[2:Comment.find(DT.TAB_HEADER_COMMENT)].strip():\r
869 IsFileHeader = True\r
870 IsBinaryHeader = False\r
871 FileHeaderLineIndex = self._RawData.LineIndex\r
872 \r
873 #\r
874 # Get license information before '@file' \r
875 # \r
876 if not IsFileHeader and not IsBinaryHeader and Comment and Comment.startswith(DT.TAB_COMMENT_SPLIT) and \\r
877 DT.TAB_BINARY_HEADER_COMMENT not in Comment:\r
4234283c 878 self._HeadComment.append((Comment, self._RawData.LineIndex))\r
2bc3256c
LG
879 \r
880 if Comment and IsFileHeader and \\r
881 not(Comment.startswith(DT.TAB_SPECIAL_COMMENT) \\r
882 and Comment.find(DT.TAB_BINARY_HEADER_COMMENT) > 0):\r
883 self._HeadComment.append((Comment, self._RawData.LineIndex))\r
884 #\r
885 # Double '#' indicates end of header comments\r
886 #\r
887 if (not Comment or Comment == DT.TAB_SPECIAL_COMMENT) and IsFileHeader:\r
888 IsFileHeader = False \r
889 continue\r
890 \r
891 if Comment and Comment.startswith(DT.TAB_SPECIAL_COMMENT) \\r
892 and Comment.find(DT.TAB_BINARY_HEADER_COMMENT) > 0:\r
893 IsBinaryHeader = True\r
894 IsFileHeader = False\r
895 BinaryHeaderLineIndex = self._RawData.LineIndex\r
896 \r
897 if Comment and IsBinaryHeader:\r
898 self.BinaryHeadComment.append((Comment, self._RawData.LineIndex))\r
4234283c
LG
899 #\r
900 # Double '#' indicates end of header comments\r
901 #\r
2bc3256c
LG
902 if (not Comment or Comment == DT.TAB_SPECIAL_COMMENT) and IsBinaryHeader:\r
903 IsBinaryHeader = False\r
4234283c 904 break\r
2bc3256c
LG
905 \r
906 if FileHeaderLineIndex > -1 and not IsFileHeader and not IsBinaryHeader:\r
907 break\r
908\r
909 if FileHeaderLineIndex > BinaryHeaderLineIndex and FileHeaderLineIndex > -1 and BinaryHeaderLineIndex > -1:\r
910 self._LoggerError(ST.ERR_BINARY_HEADER_ORDER)\r
911 \r
912 if FileHeaderLineIndex == -1:\r
421ccda3 913# self._LoggerError(ST.ERR_NO_SOURCE_HEADER)\r
2bc3256c
LG
914 Logger.Error(TOOL_NAME, FORMAT_INVALID, \r
915 ST.ERR_NO_SOURCE_HEADER,\r
421ccda3 916 File=self._RawData.Filename)\r
4234283c
LG
917 return\r
918 \r
919 def _StopCurrentParsing(self, Line):\r
920 return False\r
921 \r
922 def _ParseItem(self):\r
923 self._SectionHeaderParser()\r
924 if len(self._RawData.CurrentScope) == 0:\r
925 self._LoggerError(ST.ERR_DECPARSE_SECTION_EMPTY)\r
4234283c 926 SectionObj = self._SectionParser[self._RawData.CurrentScope[0][0]]\r
4234283c
LG
927 SectionObj.BlockStart()\r
928 SectionObj.Parse()\r
4234283c
LG
929 return SectionObj.GetDataObject()\r
930\r
931 def _UserExtentionSectionParser(self):\r
932 self._RawData.CurrentScope = []\r
933 ArchList = set()\r
934 Section = self._RawData.CurrentLine[1:-1]\r
4234283c
LG
935 Par = ParserHelper(Section, self._RawData.Filename)\r
936 while not Par.End():\r
937 #\r
938 # User extention\r
939 #\r
940 Token = Par.GetToken()\r
941 if Token.upper() != DT.TAB_USER_EXTENSIONS.upper():\r
942 self._LoggerError(ST.ERR_DECPARSE_SECTION_UE)\r
943 UserExtension = Token.upper()\r
421ccda3
HC
944 Par.AssertChar(DT.TAB_SPLIT, ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex) \r
945 \r
4234283c
LG
946 #\r
947 # UserID\r
948 #\r
949 Token = Par.GetToken()\r
950 if not IsValidUserId(Token):\r
951 self._LoggerError(ST.ERR_DECPARSE_SECTION_UE_USERID)\r
952 UserId = Token\r
4234283c
LG
953 Par.AssertChar(DT.TAB_SPLIT, ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)\r
954 #\r
955 # IdString\r
956 #\r
957 Token = Par.GetToken()\r
958 if not IsValidIdString(Token):\r
959 self._LoggerError(ST.ERR_DECPARSE_SECTION_UE_IDSTRING)\r
960 IdString = Token\r
4234283c
LG
961 Arch = 'COMMON'\r
962 if Par.Expect(DT.TAB_SPLIT):\r
963 Token = Par.GetToken()\r
964 Arch = Token.upper()\r
965 if not IsValidArch(Arch):\r
966 self._LoggerError(ST.ERR_DECPARSE_ARCH)\r
967 ArchList.add(Arch)\r
4234283c
LG
968 if [UserExtension, UserId, IdString, Arch] not in \\r
969 self._RawData.CurrentScope:\r
970 self._RawData.CurrentScope.append(\r
971 [UserExtension, UserId, IdString, Arch]\r
972 )\r
4234283c
LG
973 if not Par.Expect(DT.TAB_COMMA_SPLIT):\r
974 break\r
975 elif Par.End():\r
976 self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMA)\r
4234283c 977 Par.AssertEnd(ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)\r
4234283c
LG
978 if 'COMMON' in ArchList and len(ArchList) > 1:\r
979 self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMON)\r
980 \r
981 ## Section header parser\r
982 #\r
983 # The section header is always in following format:\r
984 #\r
985 # [section_name.arch<.platform|module_type>]\r
986 #\r
987 def _SectionHeaderParser(self):\r
988 if self._RawData.CurrentLine[0] != DT.TAB_SECTION_START or self._RawData.CurrentLine[-1] != DT.TAB_SECTION_END:\r
989 self._LoggerError(ST.ERR_DECPARSE_SECTION_IDENTIFY)\r
990 \r
991 RawSection = self._RawData.CurrentLine[1:-1].strip().upper()\r
4234283c
LG
992 #\r
993 # Check defines section which is only allowed to occur once and\r
994 # no arch can be followed\r
995 #\r
996 if RawSection.startswith(DT.TAB_DEC_DEFINES.upper()):\r
997 if RawSection != DT.TAB_DEC_DEFINES.upper():\r
998 self._LoggerError(ST.ERR_DECPARSE_DEFINE_SECNAME)\r
4234283c
LG
999 #\r
1000 # Check user extension section\r
1001 #\r
1002 if RawSection.startswith(DT.TAB_USER_EXTENSIONS.upper()):\r
1003 return self._UserExtentionSectionParser()\r
4234283c
LG
1004 self._RawData.CurrentScope = []\r
1005 SectionNames = []\r
1006 ArchList = set()\r
1007 for Item in GetSplitValueList(RawSection, DT.TAB_COMMA_SPLIT):\r
1008 if Item == '':\r
1009 self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBEMPTY % self._RawData.CurrentLine)\r
1010\r
1011 ItemList = GetSplitValueList(Item, DT.TAB_SPLIT)\r
4234283c
LG
1012 #\r
1013 # different types of PCD are permissible in one section\r
1014 #\r
1015 SectionName = ItemList[0]\r
1016 if SectionName not in self._SectionParser:\r
1017 self._LoggerError(ST.ERR_DECPARSE_SECTION_UNKNOW % SectionName)\r
4234283c
LG
1018 if SectionName not in SectionNames:\r
1019 SectionNames.append(SectionName)\r
4234283c
LG
1020 #\r
1021 # In DEC specification, all section headers have at most two part:\r
1022 # SectionName.Arch except UserExtention\r
1023 #\r
1024 if len(ItemList) > 2:\r
1025 self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBTOOMANY % Item)\r
1026\r
1027 if DT.TAB_PCDS_FEATURE_FLAG_NULL.upper() in SectionNames and len(SectionNames) > 1:\r
1028 self._LoggerError(ST.ERR_DECPARSE_SECTION_FEATUREFLAG % DT.TAB_PCDS_FEATURE_FLAG_NULL) \r
1029 #\r
1030 # S1 is always Arch\r
1031 #\r
1032 if len(ItemList) > 1:\r
1033 Str1 = ItemList[1]\r
1034 if not IsValidArch(Str1):\r
1035 self._LoggerError(ST.ERR_DECPARSE_ARCH)\r
1036 else:\r
1037 Str1 = 'COMMON'\r
1038 ArchList.add(Str1)\r
1039\r
1040 if [SectionName, Str1] not in self._RawData.CurrentScope:\r
1041 self._RawData.CurrentScope.append([SectionName, Str1])\r
1042 #\r
1043 # 'COMMON' must not be used with specific ARCHs at the same section\r
1044 #\r
1045 if 'COMMON' in ArchList and len(ArchList) > 1:\r
1046 self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMON)\r
4234283c
LG
1047 if len(SectionNames) == 0:\r
1048 self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBEMPTY % self._RawData.CurrentLine)\r
1049 if len(SectionNames) != 1:\r
1050 for Sec in SectionNames:\r
1051 if not Sec.startswith(DT.TAB_PCDS.upper()):\r
1052 self._LoggerError(ST.ERR_DECPARSE_SECTION_NAME % str(SectionNames))\r
1053 \r
421ccda3
HC
1054 def GetDefineSectionMacro(self):\r
1055 return self._Define.GetLocalMacro()\r
4234283c
LG
1056 def GetDefineSectionObject(self):\r
1057 return self._Define.GetDataObject()\r
4234283c
LG
1058 def GetIncludeSectionObject(self):\r
1059 return self._Include.GetDataObject()\r
4234283c
LG
1060 def GetGuidSectionObject(self):\r
1061 return self._Guid.GetGuidObject()\r
4234283c
LG
1062 def GetProtocolSectionObject(self):\r
1063 return self._Guid.GetProtocolObject()\r
4234283c
LG
1064 def GetPpiSectionObject(self):\r
1065 return self._Guid.GetPpiObject()\r
4234283c
LG
1066 def GetLibraryClassSectionObject(self):\r
1067 return self._LibClass.GetDataObject()\r
4234283c
LG
1068 def GetPcdSectionObject(self):\r
1069 return self._Pcd.GetDataObject()\r
4234283c
LG
1070 def GetUserExtensionSectionObject(self):\r
1071 return self._UserEx.GetDataObject()\r
4234283c 1072 def GetPackageSpecification(self):\r
421ccda3 1073 return self._Define.GetDataObject().GetPackageSpecification() \r
4234283c 1074 def GetPackageName(self):\r
421ccda3 1075 return self._Define.GetDataObject().GetPackageName() \r
4234283c 1076 def GetPackageGuid(self):\r
421ccda3 1077 return self._Define.GetDataObject().GetPackageGuid() \r
4234283c
LG
1078 def GetPackageVersion(self):\r
1079 return self._Define.GetDataObject().GetPackageVersion()\r
4234283c
LG
1080 def GetPackageUniFile(self):\r
1081 return self._Define.GetDataObject().GetPackageUniFile()\r
645a5128
HC
1082 def GetPrivateSections(self):\r
1083 return self._Private\r