]>
Commit | Line | Data |
---|---|---|
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 | |
14 | DecParser\r | |
15 | '''\r | |
16 | ## Import modules\r | |
17 | #\r | |
18 | import Logger.Log as Logger\r | |
19 | from Logger.ToolError import FILE_PARSE_FAILURE\r | |
20 | from Logger.ToolError import FILE_OPEN_FAILURE\r | |
21 | from Logger import StringTable as ST\r | |
2bc3256c | 22 | from Logger.ToolError import FORMAT_INVALID\r |
4234283c LG |
23 | \r |
24 | import Library.DataType as DT\r | |
25 | from Library.ParserValidate import IsValidToken\r | |
26 | from Library.ParserValidate import IsValidPath\r | |
27 | from Library.ParserValidate import IsValidCFormatGuid\r | |
28 | from Library.ParserValidate import IsValidIdString\r | |
29 | from Library.ParserValidate import IsValidUserId\r | |
30 | from Library.ParserValidate import IsValidArch\r | |
31 | from Library.ParserValidate import IsValidWord\r | |
48b77f5e | 32 | from Library.ParserValidate import IsValidDecVersionVal\r |
4234283c LG |
33 | from Parser.DecParserMisc import TOOL_NAME\r |
34 | from Parser.DecParserMisc import CleanString\r | |
35 | from Parser.DecParserMisc import IsValidPcdDatum\r | |
36 | from Parser.DecParserMisc import ParserHelper\r | |
37 | from Parser.DecParserMisc import StripRoot\r | |
38 | from Parser.DecParserMisc import VERSION_PATTERN\r | |
39 | from Parser.DecParserMisc import CVAR_PATTERN\r | |
40 | from Parser.DecParserMisc import PCD_TOKEN_PATTERN\r | |
41 | from Parser.DecParserMisc import MACRO_PATTERN\r | |
42 | from Parser.DecParserMisc import FileContent\r | |
43 | from Object.Parser.DecObject import _DecComments\r | |
44 | from Object.Parser.DecObject import DecDefineObject\r | |
45 | from Object.Parser.DecObject import DecDefineItemObject\r | |
46 | from Object.Parser.DecObject import DecIncludeObject\r | |
47 | from Object.Parser.DecObject import DecIncludeItemObject\r | |
48 | from Object.Parser.DecObject import DecLibraryclassObject\r | |
49 | from Object.Parser.DecObject import DecLibraryclassItemObject\r | |
50 | from Object.Parser.DecObject import DecGuidObject\r | |
51 | from Object.Parser.DecObject import DecPpiObject\r | |
52 | from Object.Parser.DecObject import DecProtocolObject\r | |
53 | from Object.Parser.DecObject import DecGuidItemObject\r | |
54 | from Object.Parser.DecObject import DecUserExtensionObject\r | |
55 | from Object.Parser.DecObject import DecUserExtensionItemObject\r | |
56 | from Object.Parser.DecObject import DecPcdObject\r | |
57 | from Object.Parser.DecObject import DecPcdItemObject\r | |
58 | from Library.Misc import GuidStructureStringToGuidString\r | |
59 | from Library.Misc import CheckGuidRegFormat\r | |
64285f15 YZ |
60 | from Library.StringUtils import ReplaceMacro\r |
61 | from Library.StringUtils import GetSplitValueList\r | |
62 | from Library.StringUtils import gMACRO_PATTERN\r | |
63 | from Library.StringUtils import ConvertSpecialChar\r | |
421ccda3 | 64 | from Library.CommentParsing import ParsePcdErrorCode\r |
4234283c LG |
65 | \r |
66 | ##\r | |
67 | # _DecBase class for parsing\r | |
68 | #\r | |
69 | class _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 | |
402 | class _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 | |
507 | class _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 | |
526 | class _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 | |
565 | class _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 | |
1b2e0772 | 623 | if int(Token) > 4294967295:\r |
4234283c | 624 | self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN_INT % Token)\r |
1b2e0772 | 625 | Token = hex(int(Token))\r |
f7496d71 | 626 | \r |
1b2e0772 | 627 | IntToken = int(Token, 0)\r |
4234283c LG |
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 | |
642 | class _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 | |
710 | class _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 |
752 | class Dec(_DecBase, _DecComments):\r |
753 | def __init__(self, DecFile, Parse = True):\r | |
4234283c | 754 | try:\r |
1b2e0772 | 755 | Content = ConvertSpecialChar(open(DecFile, 'r').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 |