]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Workspace/MetaFileParser.py
BaseTools: fix imports
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / MetaFileParser.py
CommitLineData
f51461c8
LG
1## @file\r
2# This file is used to parse meta files\r
3#\r
e6b10112 4# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>\r
5163d893 5# (C) Copyright 2015-2018 Hewlett Packard Enterprise Development LP<BR>\r
f51461c8
LG
6# This program and the accompanying materials\r
7# are licensed and made available under the terms and conditions of the BSD License\r
8# which accompanies this 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
14\r
15##\r
16# Import Modules\r
17#\r
1ccc4d89
LG
18from __future__ import print_function\r
19from __future__ import absolute_import\r
1be2ed90 20import Common.LongFilePathOs as os\r
f51461c8
LG
21import re\r
22import time\r
23import copy\r
fcb1af1b 24from hashlib import md5\r
f51461c8
LG
25\r
26import Common.EdkLogger as EdkLogger\r
27import Common.GlobalData as GlobalData\r
28\r
29from CommonDataClass.DataClass import *\r
30from Common.DataType import *\r
5a57246e 31from Common.StringUtils import *\r
ff4d0f85 32from Common.Misc import GuidStructureStringToGuidString, CheckPcdDatum, PathClass, AnalyzePcdData, AnalyzeDscPcd, AnalyzePcdExpression, ParseFieldValue, StructPattern\r
f51461c8
LG
33from Common.Expression import *\r
34from CommonDataClass.Exceptions import *\r
1be2ed90 35from Common.LongFilePathSupport import OpenLongFilePath as open\r
50874612 36from collections import defaultdict\r
1100bc5a
GL
37from .MetaFileTable import MetaFileStorage\r
38from .MetaFileCommentParser import CheckInfComment\r
938cf4c3 39from Common.DataType import TAB_COMMENT_EDK_START, TAB_COMMENT_EDK_END\r
f51461c8 40\r
3e4faa26
CJ
41## RegEx for finding file versions\r
42hexVersionPattern = re.compile(r'0[xX][\da-f-A-F]{5,8}')\r
43decVersionPattern = re.compile(r'\d+\.\d+')\r
72a1d776 44CODEPattern = re.compile(r"{CODE\([a-fA-F0-9Xx\{\},\s]*\)}")\r
3e4faa26 45\r
f51461c8
LG
46## A decorator used to parse macro definition\r
47def ParseMacro(Parser):\r
48 def MacroParser(self):\r
938cf4c3 49 Match = GlobalData.gMacroDefPattern.match(self._CurrentLine)\r
f51461c8
LG
50 if not Match:\r
51 # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method\r
52 Parser(self)\r
53 return\r
54\r
55 TokenList = GetSplitValueList(self._CurrentLine[Match.end(1):], TAB_EQUAL_SPLIT, 1)\r
56 # Syntax check\r
57 if not TokenList[0]:\r
58 EdkLogger.error('Parser', FORMAT_INVALID, "No macro name given",\r
59 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
60 if len(TokenList) < 2:\r
61 TokenList.append('')\r
62\r
63 Type = Match.group(1)\r
64 Name, Value = TokenList\r
65 # Global macros can be only defined via environment variable\r
66 if Name in GlobalData.gGlobalDefines:\r
67 EdkLogger.error('Parser', FORMAT_INVALID, "%s can only be defined via environment variable" % Name,\r
68 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
69 # Only upper case letters, digit and '_' are allowed\r
938cf4c3 70 if not GlobalData.gMacroNamePattern.match(Name):\r
f51461c8
LG
71 EdkLogger.error('Parser', FORMAT_INVALID, "The macro name must be in the pattern [A-Z][A-Z0-9_]*",\r
72 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
73\r
74 Value = ReplaceMacro(Value, self._Macros)\r
75 if Type in self.DataType:\r
76 self._ItemType = self.DataType[Type]\r
77 else:\r
78 self._ItemType = MODEL_META_DATA_DEFINE\r
79 # DEFINE defined macros\r
80 if Type == TAB_DSC_DEFINES_DEFINE:\r
81 #\r
82 # First judge whether this DEFINE is in conditional directive statements or not.\r
83 #\r
0d1f5b2b 84 if isinstance(self, DscParser) and self._InDirective > -1:\r
f51461c8
LG
85 pass\r
86 else:\r
0d1f5b2b 87 if isinstance(self, DecParser):\r
f51461c8
LG
88 if MODEL_META_DATA_HEADER in self._SectionType:\r
89 self._FileLocalMacros[Name] = Value\r
90 else:\r
91 self._ConstructSectionMacroDict(Name, Value)\r
92 elif self._SectionType == MODEL_META_DATA_HEADER:\r
93 self._FileLocalMacros[Name] = Value\r
94 else:\r
95 self._ConstructSectionMacroDict(Name, Value)\r
96\r
97 # EDK_GLOBAL defined macros\r
0d1f5b2b 98 elif not isinstance(self, DscParser):\r
f51461c8
LG
99 EdkLogger.error('Parser', FORMAT_INVALID, "EDK_GLOBAL can only be used in .dsc file",\r
100 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
101 elif self._SectionType != MODEL_META_DATA_HEADER:\r
102 EdkLogger.error('Parser', FORMAT_INVALID, "EDK_GLOBAL can only be used under [Defines] section",\r
103 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
104 elif (Name in self._FileLocalMacros) and (self._FileLocalMacros[Name] != Value):\r
105 EdkLogger.error('Parser', FORMAT_INVALID, "EDK_GLOBAL defined a macro with the same name and different value as one defined by 'DEFINE'",\r
106 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
107\r
108 self._ValueList = [Type, Name, Value]\r
109\r
110 return MacroParser\r
111\r
112## Base class of parser\r
113#\r
114# This class is used for derivation purpose. The specific parser for one kind\r
115# type file must derive this class and implement some public interfaces.\r
116#\r
117# @param FilePath The path of platform description file\r
118# @param FileType The raw data of DSC file\r
119# @param Table Database used to retrieve module/package information\r
120# @param Macros Macros used for replacement in file\r
121# @param Owner Owner ID (for sub-section parsing)\r
122# @param From ID from which the data comes (for !INCLUDE directive)\r
123#\r
124class MetaFileParser(object):\r
125 # data type (file content) for specific file type\r
126 DataType = {}\r
127\r
128 # Parser objects used to implement singleton\r
129 MetaFiles = {}\r
130\r
131 ## Factory method\r
132 #\r
133 # One file, one parser object. This factory method makes sure that there's\r
134 # only one object constructed for one meta file.\r
135 #\r
136 # @param Class class object of real AutoGen class\r
137 # (InfParser, DecParser or DscParser)\r
138 # @param FilePath The path of meta file\r
139 # @param *args The specific class related parameters\r
140 # @param **kwargs The specific class related dict parameters\r
141 #\r
142 def __new__(Class, FilePath, *args, **kwargs):\r
143 if FilePath in Class.MetaFiles:\r
144 return Class.MetaFiles[FilePath]\r
145 else:\r
1ccc4d89 146 ParserObject = super(MetaFileParser, Class).__new__(Class)\r
f51461c8
LG
147 Class.MetaFiles[FilePath] = ParserObject\r
148 return ParserObject\r
149\r
150 ## Constructor of MetaFileParser\r
151 #\r
152 # Initialize object of MetaFileParser\r
153 #\r
154 # @param FilePath The path of platform description file\r
155 # @param FileType The raw data of DSC file\r
cdd1b5e5 156 # @param Arch Default Arch value for filtering sections\r
f51461c8 157 # @param Table Database used to retrieve module/package information\r
f51461c8
LG
158 # @param Owner Owner ID (for sub-section parsing)\r
159 # @param From ID from which the data comes (for !INCLUDE directive)\r
160 #\r
cdd1b5e5 161 def __init__(self, FilePath, FileType, Arch, Table, Owner= -1, From= -1):\r
f51461c8
LG
162 self._Table = Table\r
163 self._RawTable = Table\r
cdd1b5e5 164 self._Arch = Arch\r
f51461c8
LG
165 self._FileType = FileType\r
166 self.MetaFile = FilePath\r
167 self._FileDir = self.MetaFile.Dir\r
168 self._Defines = {}\r
169 self._FileLocalMacros = {}\r
50874612 170 self._SectionsMacroDict = defaultdict(dict)\r
f51461c8
LG
171\r
172 # for recursive parsing\r
173 self._Owner = [Owner]\r
174 self._From = From\r
175\r
176 # parsr status for parsing\r
177 self._ValueList = ['', '', '', '', '']\r
178 self._Scope = []\r
179 self._LineIndex = 0\r
180 self._CurrentLine = ''\r
181 self._SectionType = MODEL_UNKNOWN\r
182 self._SectionName = ''\r
183 self._InSubsection = False\r
184 self._SubsectionType = MODEL_UNKNOWN\r
185 self._SubsectionName = ''\r
186 self._ItemType = MODEL_UNKNOWN\r
187 self._LastItem = -1\r
188 self._Enabled = 0\r
189 self._Finished = False\r
190 self._PostProcessed = False\r
191 # Different version of meta-file has different way to parse.\r
192 self._Version = 0\r
726c501c 193 self._GuidDict = {} # for Parser PCD value {GUID(gTokeSpaceGuidName)}\r
f51461c8
LG
194\r
195 ## Store the parsed data in table\r
196 def _Store(self, *Args):\r
197 return self._Table.Insert(*Args)\r
198\r
199 ## Virtual method for starting parse\r
200 def Start(self):\r
201 raise NotImplementedError\r
202\r
203 ## Notify a post-process is needed\r
204 def DoPostProcess(self):\r
205 self._PostProcessed = False\r
206\r
207 ## Set parsing complete flag in both class and table\r
208 def _Done(self):\r
209 self._Finished = True\r
643556fc 210 self._Table.SetEndFlag()\r
f51461c8
LG
211\r
212 def _PostProcess(self):\r
213 self._PostProcessed = True\r
214\r
215 ## Get the parse complete flag\r
71cac3f7
CJ
216 @property\r
217 def Finished(self):\r
f51461c8
LG
218 return self._Finished\r
219\r
220 ## Set the complete flag\r
71cac3f7
CJ
221 @Finished.setter\r
222 def Finished(self, Value):\r
f51461c8
LG
223 self._Finished = Value\r
224\r
cdd1b5e5
TP
225 ## Remove records that do not match given Filter Arch\r
226 def _FilterRecordList(self, RecordList, FilterArch):\r
227 NewRecordList = []\r
228 for Record in RecordList:\r
229 Arch = Record[3]\r
55c84777 230 if Arch == TAB_ARCH_COMMON or Arch == FilterArch:\r
cdd1b5e5
TP
231 NewRecordList.append(Record)\r
232 return NewRecordList\r
233\r
f51461c8
LG
234 ## Use [] style to query data in table, just for readability\r
235 #\r
236 # DataInfo = [data_type, scope1(arch), scope2(platform/moduletype)]\r
237 #\r
238 def __getitem__(self, DataInfo):\r
0d1f5b2b 239 if not isinstance(DataInfo, type(())):\r
f51461c8
LG
240 DataInfo = (DataInfo,)\r
241\r
242 # Parse the file first, if necessary\r
643556fc 243 self.StartParse()\r
f51461c8
LG
244\r
245 # No specific ARCH or Platform given, use raw data\r
4231a819 246 if self._RawTable and (len(DataInfo) == 1 or DataInfo[1] is None):\r
cdd1b5e5 247 return self._FilterRecordList(self._RawTable.Query(*DataInfo), self._Arch)\r
f51461c8
LG
248\r
249 # Do post-process if necessary\r
250 if not self._PostProcessed:\r
251 self._PostProcess()\r
252\r
cdd1b5e5 253 return self._FilterRecordList(self._Table.Query(*DataInfo), DataInfo[1])\r
f51461c8 254\r
643556fc
FB
255 def StartParse(self):\r
256 if not self._Finished:\r
257 if self._RawTable.IsIntegrity():\r
258 self._Finished = True\r
259 else:\r
260 self._Table = self._RawTable\r
261 self._PostProcessed = False\r
262 self.Start()\r
f51461c8
LG
263 ## Data parser for the common format in different type of file\r
264 #\r
265 # The common format in the meatfile is like\r
266 #\r
267 # xxx1 | xxx2 | xxx3\r
268 #\r
269 @ParseMacro\r
270 def _CommonParser(self):\r
271 TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)\r
272 self._ValueList[0:len(TokenList)] = TokenList\r
273\r
274 ## Data parser for the format in which there's path\r
275 #\r
276 # Only path can have macro used. So we need to replace them before use.\r
277 #\r
278 @ParseMacro\r
279 def _PathParser(self):\r
280 TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)\r
281 self._ValueList[0:len(TokenList)] = TokenList\r
282 # Don't do macro replacement for dsc file at this point\r
0d1f5b2b 283 if not isinstance(self, DscParser):\r
f51461c8
LG
284 Macros = self._Macros\r
285 self._ValueList = [ReplaceMacro(Value, Macros) for Value in self._ValueList]\r
286\r
287 ## Skip unsupported data\r
288 def _Skip(self):\r
289 EdkLogger.warn("Parser", "Unrecognized content", File=self.MetaFile,\r
290 Line=self._LineIndex + 1, ExtraData=self._CurrentLine);\r
291 self._ValueList[0:1] = [self._CurrentLine]\r
292\r
0923aa1c
HC
293 ## Skip unsupported data for UserExtension Section\r
294 def _SkipUserExtension(self):\r
295 self._ValueList[0:1] = [self._CurrentLine]\r
296\r
f51461c8
LG
297 ## Section header parser\r
298 #\r
299 # The section header is always in following format:\r
300 #\r
301 # [section_name.arch<.platform|module_type>]\r
302 #\r
303 def _SectionHeaderParser(self):\r
304 self._Scope = []\r
305 self._SectionName = ''\r
306 ArchList = set()\r
307 for Item in GetSplitValueList(self._CurrentLine[1:-1], TAB_COMMA_SPLIT):\r
308 if Item == '':\r
309 continue\r
ccaa7754 310 ItemList = GetSplitValueList(Item, TAB_SPLIT, 3)\r
f51461c8
LG
311 # different section should not mix in one section\r
312 if self._SectionName != '' and self._SectionName != ItemList[0].upper():\r
313 EdkLogger.error('Parser', FORMAT_INVALID, "Different section names in the same section",\r
314 File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)\r
315 self._SectionName = ItemList[0].upper()\r
316 if self._SectionName in self.DataType:\r
317 self._SectionType = self.DataType[self._SectionName]\r
318 # Check if the section name is valid\r
eece4292 319 if self._SectionName not in SECTIONS_HAVE_ITEM_AFTER_ARCH_SET and len(ItemList) > 3:\r
f51461c8
LG
320 EdkLogger.error("Parser", FORMAT_UNKNOWN_ERROR, "%s is not a valid section name" % Item,\r
321 self.MetaFile, self._LineIndex + 1, self._CurrentLine)\r
322 elif self._Version >= 0x00010005:\r
323 EdkLogger.error("Parser", FORMAT_UNKNOWN_ERROR, "%s is not a valid section name" % Item,\r
324 self.MetaFile, self._LineIndex + 1, self._CurrentLine)\r
325 else:\r
326 self._SectionType = MODEL_UNKNOWN\r
327\r
328 # S1 is always Arch\r
329 if len(ItemList) > 1:\r
330 S1 = ItemList[1].upper()\r
331 else:\r
55c84777 332 S1 = TAB_ARCH_COMMON\r
f51461c8
LG
333 ArchList.add(S1)\r
334\r
335 # S2 may be Platform or ModuleType\r
336 if len(ItemList) > 2:\r
eece4292 337 if self._SectionName.upper() in SECTIONS_HAVE_ITEM_PCD_SET:\r
f51461c8
LG
338 S2 = ItemList[2]\r
339 else:\r
340 S2 = ItemList[2].upper()\r
341 else:\r
55c84777 342 S2 = TAB_COMMON\r
8518bf0b
LG
343 if len(ItemList) > 3:\r
344 S3 = ItemList[3]\r
345 else:\r
55c84777 346 S3 = TAB_COMMON\r
8518bf0b 347 self._Scope.append([S1, S2, S3])\r
f51461c8
LG
348\r
349 # 'COMMON' must not be used with specific ARCHs at the same section\r
55c84777 350 if TAB_ARCH_COMMON in ArchList and len(ArchList) > 1:\r
f51461c8
LG
351 EdkLogger.error('Parser', FORMAT_INVALID, "'common' ARCH must not be used with specific ARCHs",\r
352 File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)\r
353 # If the section information is needed later, it should be stored in database\r
354 self._ValueList[0] = self._SectionName\r
355\r
356 ## [defines] section parser\r
357 @ParseMacro\r
358 def _DefineParser(self):\r
359 TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
360 self._ValueList[1:len(TokenList)] = TokenList\r
361 if not self._ValueList[1]:\r
362 EdkLogger.error('Parser', FORMAT_INVALID, "No name specified",\r
363 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
364 if not self._ValueList[2]:\r
365 EdkLogger.error('Parser', FORMAT_INVALID, "No value specified",\r
366 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
367\r
368 self._ValueList = [ReplaceMacro(Value, self._Macros) for Value in self._ValueList]\r
369 Name, Value = self._ValueList[1], self._ValueList[2]\r
dc4c7707
YZ
370 MacroUsed = GlobalData.gMacroRefPattern.findall(Value)\r
371 if len(MacroUsed) != 0:\r
372 for Macro in MacroUsed:\r
373 if Macro in GlobalData.gGlobalDefines:\r
374 EdkLogger.error("Parser", FORMAT_INVALID, "Global macro %s is not permitted." % (Macro), ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
375 else:\r
376 EdkLogger.error("Parser", FORMAT_INVALID, "%s not defined" % (Macro), ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
f7496d71 377 # Sometimes, we need to make differences between EDK and EDK2 modules\r
f51461c8 378 if Name == 'INF_VERSION':\r
3e4faa26 379 if hexVersionPattern.match(Value):\r
f7496d71 380 self._Version = int(Value, 0)\r
3e4faa26 381 elif decVersionPattern.match(Value):\r
3ab1434a 382 ValueList = Value.split('.')\r
f413763b
YF
383 Major = int(ValueList[0], 0)\r
384 Minor = int(ValueList[1], 0)\r
385 if Major > 0xffff or Minor > 0xffff:\r
386 EdkLogger.error('Parser', FORMAT_INVALID, "Invalid version number",\r
387 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
388 self._Version = int('0x{0:04x}{1:04x}'.format(Major, Minor), 0)\r
3ab1434a 389 else:\r
f51461c8
LG
390 EdkLogger.error('Parser', FORMAT_INVALID, "Invalid version number",\r
391 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
392\r
0d1f5b2b 393 if isinstance(self, InfParser) and self._Version < 0x00010005:\r
f51461c8
LG
394 # EDK module allows using defines as macros\r
395 self._FileLocalMacros[Name] = Value\r
396 self._Defines[Name] = Value\r
397\r
398 ## [BuildOptions] section parser\r
399 @ParseMacro\r
400 def _BuildOptionParser(self):\r
401 self._CurrentLine = CleanString(self._CurrentLine, BuildOption=True)\r
402 TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
403 TokenList2 = GetSplitValueList(TokenList[0], ':', 1)\r
404 if len(TokenList2) == 2:\r
405 self._ValueList[0] = TokenList2[0] # toolchain family\r
406 self._ValueList[1] = TokenList2[1] # keys\r
407 else:\r
408 self._ValueList[1] = TokenList[0]\r
0d1f5b2b 409 if len(TokenList) == 2 and not isinstance(self, DscParser): # value\r
f51461c8
LG
410 self._ValueList[2] = ReplaceMacro(TokenList[1], self._Macros)\r
411\r
412 if self._ValueList[1].count('_') != 4:\r
413 EdkLogger.error(\r
414 'Parser',\r
415 FORMAT_INVALID,\r
416 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self._ValueList[1],\r
417 ExtraData=self._CurrentLine,\r
418 File=self.MetaFile,\r
419 Line=self._LineIndex + 1\r
420 )\r
82a6a960
BF
421 def GetValidExpression(self, TokenSpaceGuid, PcdCName):\r
422 return self._Table.GetValidExpression(TokenSpaceGuid, PcdCName)\r
71cac3f7
CJ
423\r
424 @property\r
425 def _Macros(self):\r
f51461c8
LG
426 Macros = {}\r
427 Macros.update(self._FileLocalMacros)\r
428 Macros.update(self._GetApplicableSectionMacro())\r
429 return Macros\r
430\r
f7496d71 431 ## Construct section Macro dict\r
f51461c8 432 def _ConstructSectionMacroDict(self, Name, Value):\r
ccaa7754 433 ScopeKey = [(Scope[0], Scope[1], Scope[2]) for Scope in self._Scope]\r
f51461c8 434 ScopeKey = tuple(ScopeKey)\r
f51461c8
LG
435 #\r
436 # DecParser SectionType is a list, will contain more than one item only in Pcd Section\r
437 # As Pcd section macro usage is not alllowed, so here it is safe\r
438 #\r
0d1f5b2b 439 if isinstance(self, DecParser):\r
f51461c8 440 SectionDictKey = self._SectionType[0], ScopeKey\r
50874612
CJ
441 else:\r
442 SectionDictKey = self._SectionType, ScopeKey\r
443\r
444 self._SectionsMacroDict[SectionDictKey][Name] = Value\r
f51461c8 445\r
f7496d71 446 ## Get section Macros that are applicable to current line, which may come from other sections\r
f51461c8
LG
447 ## that share the same name while scope is wider\r
448 def _GetApplicableSectionMacro(self):\r
449 Macros = {}\r
450\r
451 ComComMacroDict = {}\r
452 ComSpeMacroDict = {}\r
453 SpeSpeMacroDict = {}\r
454\r
455 ActiveSectionType = self._SectionType\r
0d1f5b2b 456 if isinstance(self, DecParser):\r
f51461c8
LG
457 ActiveSectionType = self._SectionType[0]\r
458\r
459 for (SectionType, Scope) in self._SectionsMacroDict:\r
460 if SectionType != ActiveSectionType:\r
461 continue\r
462\r
463 for ActiveScope in self._Scope:\r
ccaa7754
GL
464 Scope0, Scope1, Scope2= ActiveScope[0], ActiveScope[1], ActiveScope[2]\r
465 if(Scope0, Scope1, Scope2) not in Scope:\r
f51461c8
LG
466 break\r
467 else:\r
468 SpeSpeMacroDict.update(self._SectionsMacroDict[(SectionType, Scope)])\r
469\r
470 for ActiveScope in self._Scope:\r
ccaa7754
GL
471 Scope0, Scope1, Scope2 = ActiveScope[0], ActiveScope[1], ActiveScope[2]\r
472 if(Scope0, Scope1, Scope2) not in Scope and (Scope0, TAB_COMMON, TAB_COMMON) not in Scope and (TAB_COMMON, Scope1, TAB_COMMON) not in Scope:\r
f51461c8
LG
473 break\r
474 else:\r
475 ComSpeMacroDict.update(self._SectionsMacroDict[(SectionType, Scope)])\r
476\r
55c84777 477 if (TAB_COMMON, TAB_COMMON, TAB_COMMON) in Scope:\r
f51461c8
LG
478 ComComMacroDict.update(self._SectionsMacroDict[(SectionType, Scope)])\r
479\r
480 Macros.update(ComComMacroDict)\r
481 Macros.update(ComSpeMacroDict)\r
482 Macros.update(SpeSpeMacroDict)\r
483\r
484 return Macros\r
485\r
486 _SectionParser = {}\r
f51461c8
LG
487\r
488## INF file parser class\r
489#\r
490# @param FilePath The path of platform description file\r
491# @param FileType The raw data of DSC file\r
492# @param Table Database used to retrieve module/package information\r
493# @param Macros Macros used for replacement in file\r
494#\r
495class InfParser(MetaFileParser):\r
496 # INF file supported data types (one type per section)\r
497 DataType = {\r
498 TAB_UNKNOWN.upper() : MODEL_UNKNOWN,\r
499 TAB_INF_DEFINES.upper() : MODEL_META_DATA_HEADER,\r
500 TAB_DSC_DEFINES_DEFINE : MODEL_META_DATA_DEFINE,\r
501 TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION,\r
502 TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE,\r
503 TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE,\r
504 TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS,\r
505 TAB_PACKAGES.upper() : MODEL_META_DATA_PACKAGE,\r
506 TAB_NMAKE.upper() : MODEL_META_DATA_NMAKE,\r
507 TAB_INF_FIXED_PCD.upper() : MODEL_PCD_FIXED_AT_BUILD,\r
508 TAB_INF_PATCH_PCD.upper() : MODEL_PCD_PATCHABLE_IN_MODULE,\r
509 TAB_INF_FEATURE_PCD.upper() : MODEL_PCD_FEATURE_FLAG,\r
510 TAB_INF_PCD_EX.upper() : MODEL_PCD_DYNAMIC_EX,\r
511 TAB_INF_PCD.upper() : MODEL_PCD_DYNAMIC,\r
512 TAB_SOURCES.upper() : MODEL_EFI_SOURCE_FILE,\r
513 TAB_GUIDS.upper() : MODEL_EFI_GUID,\r
514 TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL,\r
515 TAB_PPIS.upper() : MODEL_EFI_PPI,\r
516 TAB_DEPEX.upper() : MODEL_EFI_DEPEX,\r
517 TAB_BINARIES.upper() : MODEL_EFI_BINARY_FILE,\r
518 TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION\r
519 }\r
520\r
521 ## Constructor of InfParser\r
522 #\r
523 # Initialize object of InfParser\r
524 #\r
525 # @param FilePath The path of module description file\r
526 # @param FileType The raw data of DSC file\r
cdd1b5e5 527 # @param Arch Default Arch value for filtering sections\r
f51461c8 528 # @param Table Database used to retrieve module/package information\r
f51461c8 529 #\r
cdd1b5e5 530 def __init__(self, FilePath, FileType, Arch, Table):\r
f51461c8
LG
531 # prevent re-initialization\r
532 if hasattr(self, "_Table"):\r
533 return\r
cdd1b5e5 534 MetaFileParser.__init__(self, FilePath, FileType, Arch, Table)\r
f51461c8
LG
535 self.PcdsDict = {}\r
536\r
537 ## Parser starter\r
538 def Start(self):\r
539 NmakeLine = ''\r
540 Content = ''\r
541 try:\r
542 Content = open(str(self.MetaFile), 'r').readlines()\r
543 except:\r
544 EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile)\r
545\r
546 # parse the file line by line\r
547 IsFindBlockComment = False\r
548 GetHeaderComment = False\r
549 TailComments = []\r
550 SectionComments = []\r
551 Comments = []\r
552\r
553 for Index in range(0, len(Content)):\r
554 # skip empty, commented, block commented lines\r
555 Line, Comment = CleanString2(Content[Index], AllowCppStyleComment=True)\r
556 NextLine = ''\r
557 if Index + 1 < len(Content):\r
558 NextLine, NextComment = CleanString2(Content[Index + 1])\r
559 if Line == '':\r
560 if Comment:\r
561 Comments.append((Comment, Index + 1))\r
562 elif GetHeaderComment:\r
563 SectionComments.extend(Comments)\r
564 Comments = []\r
565 continue\r
938cf4c3 566 if Line.find(TAB_COMMENT_EDK_START) > -1:\r
f51461c8
LG
567 IsFindBlockComment = True\r
568 continue\r
938cf4c3 569 if Line.find(TAB_COMMENT_EDK_END) > -1:\r
f51461c8
LG
570 IsFindBlockComment = False\r
571 continue\r
572 if IsFindBlockComment:\r
573 continue\r
574\r
575 self._LineIndex = Index\r
576 self._CurrentLine = Line\r
577\r
578 # section header\r
579 if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:\r
580 if not GetHeaderComment:\r
581 for Cmt, LNo in Comments:\r
55c84777
CJ
582 self._Store(MODEL_META_DATA_HEADER_COMMENT, Cmt, '', '', TAB_COMMON,\r
583 TAB_COMMON, self._Owner[-1], LNo, -1, LNo, -1, 0)\r
f51461c8
LG
584 GetHeaderComment = True\r
585 else:\r
586 TailComments.extend(SectionComments + Comments)\r
587 Comments = []\r
588 self._SectionHeaderParser()\r
589 # Check invalid sections\r
590 if self._Version < 0x00010005:\r
591 if self._SectionType in [MODEL_META_DATA_BUILD_OPTION,\r
592 MODEL_EFI_LIBRARY_CLASS,\r
593 MODEL_META_DATA_PACKAGE,\r
594 MODEL_PCD_FIXED_AT_BUILD,\r
595 MODEL_PCD_PATCHABLE_IN_MODULE,\r
596 MODEL_PCD_FEATURE_FLAG,\r
597 MODEL_PCD_DYNAMIC_EX,\r
598 MODEL_PCD_DYNAMIC,\r
599 MODEL_EFI_GUID,\r
600 MODEL_EFI_PROTOCOL,\r
601 MODEL_EFI_PPI,\r
602 MODEL_META_DATA_USER_EXTENSION]:\r
603 EdkLogger.error('Parser', FORMAT_INVALID,\r
604 "Section [%s] is not allowed in inf file without version" % (self._SectionName),\r
605 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
606 elif self._SectionType in [MODEL_EFI_INCLUDE,\r
607 MODEL_EFI_LIBRARY_INSTANCE,\r
608 MODEL_META_DATA_NMAKE]:\r
609 EdkLogger.error('Parser', FORMAT_INVALID,\r
610 "Section [%s] is not allowed in inf file with version 0x%08x" % (self._SectionName, self._Version),\r
611 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
612 continue\r
613 # merge two lines specified by '\' in section NMAKE\r
614 elif self._SectionType == MODEL_META_DATA_NMAKE:\r
615 if Line[-1] == '\\':\r
616 if NextLine == '':\r
617 self._CurrentLine = NmakeLine + Line[0:-1]\r
618 NmakeLine = ''\r
619 else:\r
620 if NextLine[0] == TAB_SECTION_START and NextLine[-1] == TAB_SECTION_END:\r
621 self._CurrentLine = NmakeLine + Line[0:-1]\r
622 NmakeLine = ''\r
623 else:\r
624 NmakeLine = NmakeLine + ' ' + Line[0:-1]\r
625 continue\r
626 else:\r
627 self._CurrentLine = NmakeLine + Line\r
628 NmakeLine = ''\r
629\r
630 # section content\r
631 self._ValueList = ['', '', '']\r
632 # parse current line, result will be put in self._ValueList\r
633 self._SectionParser[self._SectionType](self)\r
4231a819 634 if self._ValueList is None or self._ItemType == MODEL_META_DATA_DEFINE:\r
f51461c8
LG
635 self._ItemType = -1\r
636 Comments = []\r
637 continue\r
638 if Comment:\r
639 Comments.append((Comment, Index + 1))\r
97fa0ee9
YL
640 if GlobalData.gOptions and GlobalData.gOptions.CheckUsage:\r
641 CheckInfComment(self._SectionType, Comments, str(self.MetaFile), Index + 1, self._ValueList)\r
f51461c8
LG
642 #\r
643 # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,\r
644 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1\r
645 #\r
ccaa7754 646 for Arch, Platform, _ in self._Scope:\r
f51461c8
LG
647 LastItem = self._Store(self._SectionType,\r
648 self._ValueList[0],\r
649 self._ValueList[1],\r
650 self._ValueList[2],\r
651 Arch,\r
652 Platform,\r
653 self._Owner[-1],\r
654 self._LineIndex + 1,\r
655 - 1,\r
656 self._LineIndex + 1,\r
657 - 1,\r
658 0\r
659 )\r
660 for Comment, LineNo in Comments:\r
661 self._Store(MODEL_META_DATA_COMMENT, Comment, '', '', Arch, Platform,\r
662 LastItem, LineNo, -1, LineNo, -1, 0)\r
663 Comments = []\r
664 SectionComments = []\r
665 TailComments.extend(SectionComments + Comments)\r
666 if IsFindBlockComment:\r
667 EdkLogger.error("Parser", FORMAT_INVALID, "Open block comments (starting with /*) are expected to end with */",\r
668 File=self.MetaFile)\r
669\r
670 # If there are tail comments in INF file, save to database whatever the comments are\r
671 for Comment in TailComments:\r
55c84777
CJ
672 self._Store(MODEL_META_DATA_TAIL_COMMENT, Comment[0], '', '', TAB_COMMON,\r
673 TAB_COMMON, self._Owner[-1], -1, -1, -1, -1, 0)\r
f51461c8
LG
674 self._Done()\r
675\r
676 ## Data parser for the format in which there's path\r
677 #\r
678 # Only path can have macro used. So we need to replace them before use.\r
679 #\r
680 def _IncludeParser(self):\r
681 TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)\r
682 self._ValueList[0:len(TokenList)] = TokenList\r
683 Macros = self._Macros\r
684 if Macros:\r
685 for Index in range(0, len(self._ValueList)):\r
686 Value = self._ValueList[Index]\r
687 if not Value:\r
688 continue\r
689\r
690 if Value.upper().find('$(EFI_SOURCE)\Edk'.upper()) > -1 or Value.upper().find('$(EFI_SOURCE)/Edk'.upper()) > -1:\r
691 Value = '$(EDK_SOURCE)' + Value[17:]\r
692 if Value.find('$(EFI_SOURCE)') > -1 or Value.find('$(EDK_SOURCE)') > -1:\r
693 pass\r
694 elif Value.startswith('.'):\r
695 pass\r
696 elif Value.startswith('$('):\r
697 pass\r
698 else:\r
699 Value = '$(EFI_SOURCE)/' + Value\r
700\r
701 self._ValueList[Index] = ReplaceMacro(Value, Macros)\r
702\r
703 ## Parse [Sources] section\r
704 #\r
705 # Only path can have macro used. So we need to replace them before use.\r
706 #\r
707 @ParseMacro\r
708 def _SourceFileParser(self):\r
709 TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)\r
710 self._ValueList[0:len(TokenList)] = TokenList\r
711 Macros = self._Macros\r
712 # For Acpi tables, remove macro like ' TABLE_NAME=Sata1'\r
713 if 'COMPONENT_TYPE' in Macros:\r
714 if self._Defines['COMPONENT_TYPE'].upper() == 'ACPITABLE':\r
715 self._ValueList[0] = GetSplitValueList(self._ValueList[0], ' ', 1)[0]\r
716 if self._Defines['BASE_NAME'] == 'Microcode':\r
717 pass\r
718 self._ValueList = [ReplaceMacro(Value, Macros) for Value in self._ValueList]\r
719\r
720 ## Parse [Binaries] section\r
721 #\r
722 # Only path can have macro used. So we need to replace them before use.\r
723 #\r
724 @ParseMacro\r
725 def _BinaryFileParser(self):\r
726 TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 2)\r
727 if len(TokenList) < 2:\r
728 EdkLogger.error('Parser', FORMAT_INVALID, "No file type or path specified",\r
729 ExtraData=self._CurrentLine + " (<FileType> | <FilePath> [| <Target>])",\r
730 File=self.MetaFile, Line=self._LineIndex + 1)\r
731 if not TokenList[0]:\r
732 EdkLogger.error('Parser', FORMAT_INVALID, "No file type specified",\r
733 ExtraData=self._CurrentLine + " (<FileType> | <FilePath> [| <Target>])",\r
734 File=self.MetaFile, Line=self._LineIndex + 1)\r
735 if not TokenList[1]:\r
736 EdkLogger.error('Parser', FORMAT_INVALID, "No file path specified",\r
737 ExtraData=self._CurrentLine + " (<FileType> | <FilePath> [| <Target>])",\r
738 File=self.MetaFile, Line=self._LineIndex + 1)\r
739 self._ValueList[0:len(TokenList)] = TokenList\r
740 self._ValueList[1] = ReplaceMacro(self._ValueList[1], self._Macros)\r
741\r
742 ## [nmake] section parser (Edk.x style only)\r
743 def _NmakeParser(self):\r
744 TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
745 self._ValueList[0:len(TokenList)] = TokenList\r
746 # remove macros\r
747 self._ValueList[1] = ReplaceMacro(self._ValueList[1], self._Macros)\r
748 # remove self-reference in macro setting\r
749 #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})\r
750\r
751 ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser\r
752 @ParseMacro\r
753 def _PcdParser(self):\r
754 TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)\r
755 ValueList = GetSplitValueList(TokenList[0], TAB_SPLIT)\r
756 if len(ValueList) != 2:\r
757 EdkLogger.error('Parser', FORMAT_INVALID, "Illegal token space GUID and PCD name format",\r
758 ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<PcdCName>)",\r
759 File=self.MetaFile, Line=self._LineIndex + 1)\r
760 self._ValueList[0:1] = ValueList\r
761 if len(TokenList) > 1:\r
762 self._ValueList[2] = TokenList[1]\r
763 if self._ValueList[0] == '' or self._ValueList[1] == '':\r
764 EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",\r
765 ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<PcdCName>)",\r
766 File=self.MetaFile, Line=self._LineIndex + 1)\r
767\r
768 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.\r
769 if self._ValueList[2] != '':\r
770 InfPcdValueList = GetSplitValueList(TokenList[1], TAB_VALUE_SPLIT, 1)\r
771 if InfPcdValueList[0] in ['True', 'true', 'TRUE']:\r
772 self._ValueList[2] = TokenList[1].replace(InfPcdValueList[0], '1', 1);\r
773 elif InfPcdValueList[0] in ['False', 'false', 'FALSE']:\r
774 self._ValueList[2] = TokenList[1].replace(InfPcdValueList[0], '0', 1);\r
775 if (self._ValueList[0], self._ValueList[1]) not in self.PcdsDict:\r
776 self.PcdsDict[self._ValueList[0], self._ValueList[1]] = self._SectionType\r
777 elif self.PcdsDict[self._ValueList[0], self._ValueList[1]] != self._SectionType:\r
778 EdkLogger.error('Parser', FORMAT_INVALID, "It is not permissible to list a specified PCD in different PCD type sections.",\r
779 ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<PcdCName>)",\r
780 File=self.MetaFile, Line=self._LineIndex + 1)\r
781\r
782 ## [depex] section parser\r
783 @ParseMacro\r
784 def _DepexParser(self):\r
785 self._ValueList[0:1] = [self._CurrentLine]\r
786\r
787 _SectionParser = {\r
788 MODEL_UNKNOWN : MetaFileParser._Skip,\r
789 MODEL_META_DATA_HEADER : MetaFileParser._DefineParser,\r
790 MODEL_META_DATA_BUILD_OPTION : MetaFileParser._BuildOptionParser,\r
791 MODEL_EFI_INCLUDE : _IncludeParser, # for Edk.x modules\r
792 MODEL_EFI_LIBRARY_INSTANCE : MetaFileParser._CommonParser, # for Edk.x modules\r
793 MODEL_EFI_LIBRARY_CLASS : MetaFileParser._PathParser,\r
794 MODEL_META_DATA_PACKAGE : MetaFileParser._PathParser,\r
795 MODEL_META_DATA_NMAKE : _NmakeParser, # for Edk.x modules\r
796 MODEL_PCD_FIXED_AT_BUILD : _PcdParser,\r
797 MODEL_PCD_PATCHABLE_IN_MODULE : _PcdParser,\r
798 MODEL_PCD_FEATURE_FLAG : _PcdParser,\r
799 MODEL_PCD_DYNAMIC_EX : _PcdParser,\r
800 MODEL_PCD_DYNAMIC : _PcdParser,\r
801 MODEL_EFI_SOURCE_FILE : _SourceFileParser,\r
802 MODEL_EFI_GUID : MetaFileParser._CommonParser,\r
803 MODEL_EFI_PROTOCOL : MetaFileParser._CommonParser,\r
804 MODEL_EFI_PPI : MetaFileParser._CommonParser,\r
805 MODEL_EFI_DEPEX : _DepexParser,\r
806 MODEL_EFI_BINARY_FILE : _BinaryFileParser,\r
0923aa1c 807 MODEL_META_DATA_USER_EXTENSION : MetaFileParser._SkipUserExtension,\r
f51461c8
LG
808 }\r
809\r
810## DSC file parser class\r
811#\r
812# @param FilePath The path of platform description file\r
813# @param FileType The raw data of DSC file\r
814# @param Table Database used to retrieve module/package information\r
815# @param Macros Macros used for replacement in file\r
816# @param Owner Owner ID (for sub-section parsing)\r
817# @param From ID from which the data comes (for !INCLUDE directive)\r
818#\r
819class DscParser(MetaFileParser):\r
820 # DSC file supported data types (one type per section)\r
821 DataType = {\r
822 TAB_SKUIDS.upper() : MODEL_EFI_SKU_ID,\r
8518bf0b 823 TAB_DEFAULT_STORES.upper() : MODEL_EFI_DEFAULT_STORES,\r
f51461c8
LG
824 TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE,\r
825 TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS,\r
826 TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION,\r
827 TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : MODEL_PCD_FIXED_AT_BUILD,\r
828 TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : MODEL_PCD_PATCHABLE_IN_MODULE,\r
829 TAB_PCDS_FEATURE_FLAG_NULL.upper() : MODEL_PCD_FEATURE_FLAG,\r
830 TAB_PCDS_DYNAMIC_DEFAULT_NULL.upper() : MODEL_PCD_DYNAMIC_DEFAULT,\r
831 TAB_PCDS_DYNAMIC_HII_NULL.upper() : MODEL_PCD_DYNAMIC_HII,\r
832 TAB_PCDS_DYNAMIC_VPD_NULL.upper() : MODEL_PCD_DYNAMIC_VPD,\r
833 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT,\r
834 TAB_PCDS_DYNAMIC_EX_HII_NULL.upper() : MODEL_PCD_DYNAMIC_EX_HII,\r
835 TAB_PCDS_DYNAMIC_EX_VPD_NULL.upper() : MODEL_PCD_DYNAMIC_EX_VPD,\r
836 TAB_COMPONENTS.upper() : MODEL_META_DATA_COMPONENT,\r
837 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH.upper() : MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH,\r
838 TAB_DSC_DEFINES.upper() : MODEL_META_DATA_HEADER,\r
839 TAB_DSC_DEFINES_DEFINE : MODEL_META_DATA_DEFINE,\r
840 TAB_DSC_DEFINES_EDKGLOBAL : MODEL_META_DATA_GLOBAL_DEFINE,\r
841 TAB_INCLUDE.upper() : MODEL_META_DATA_INCLUDE,\r
842 TAB_IF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,\r
843 TAB_IF_DEF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,\r
844 TAB_IF_N_DEF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF,\r
845 TAB_ELSE_IF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF,\r
846 TAB_ELSE.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE,\r
847 TAB_END_IF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF,\r
0923aa1c 848 TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION,\r
09ef8e92 849 TAB_ERROR.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR,\r
f51461c8
LG
850 }\r
851\r
852 # Valid names in define section\r
853 DefineKeywords = [\r
854 "DSC_SPECIFICATION",\r
855 "PLATFORM_NAME",\r
856 "PLATFORM_GUID",\r
857 "PLATFORM_VERSION",\r
858 "SKUID_IDENTIFIER",\r
859 "PCD_INFO_GENERATION",\r
82a6a960 860 "PCD_VAR_CHECK_GENERATION",\r
f51461c8
LG
861 "SUPPORTED_ARCHITECTURES",\r
862 "BUILD_TARGETS",\r
863 "OUTPUT_DIRECTORY",\r
864 "FLASH_DEFINITION",\r
865 "BUILD_NUMBER",\r
866 "RFC_LANGUAGES",\r
867 "ISO_LANGUAGES",\r
868 "TIME_STAMP_FILE",\r
869 "VPD_TOOL_GUID",\r
f0dc69e6
YZ
870 "FIX_LOAD_TOP_MEMORY_ADDRESS",\r
871 "PREBUILD",\r
872 "POSTBUILD"\r
f51461c8
LG
873 ]\r
874\r
97fa0ee9
YL
875 SubSectionDefineKeywords = [\r
876 "FILE_GUID"\r
877 ]\r
878\r
f51461c8
LG
879 SymbolPattern = ValueExpression.SymbolPattern\r
880\r
c17956e0
DL
881 IncludedFiles = set()\r
882\r
f51461c8
LG
883 ## Constructor of DscParser\r
884 #\r
885 # Initialize object of DscParser\r
886 #\r
887 # @param FilePath The path of platform description file\r
888 # @param FileType The raw data of DSC file\r
cdd1b5e5 889 # @param Arch Default Arch value for filtering sections\r
f51461c8 890 # @param Table Database used to retrieve module/package information\r
f51461c8
LG
891 # @param Owner Owner ID (for sub-section parsing)\r
892 # @param From ID from which the data comes (for !INCLUDE directive)\r
893 #\r
cdd1b5e5 894 def __init__(self, FilePath, FileType, Arch, Table, Owner= -1, From= -1):\r
f51461c8 895 # prevent re-initialization\r
395f3336 896 if hasattr(self, "_Table") and self._Table is Table:\r
f51461c8 897 return\r
cdd1b5e5 898 MetaFileParser.__init__(self, FilePath, FileType, Arch, Table, Owner, From)\r
f51461c8
LG
899 self._Version = 0x00010005 # Only EDK2 dsc file is supported\r
900 # to store conditional directive evaluation result\r
901 self._DirectiveStack = []\r
902 self._DirectiveEvalStack = []\r
903 self._Enabled = 1\r
904\r
905 #\r
906 # Specify whether current line is in uncertain condition\r
907 #\r
908 self._InDirective = -1\r
909\r
910 # Final valid replacable symbols\r
911 self._Symbols = {}\r
912 #\r
913 # Map the ID between the original table and new table to track\r
914 # the owner item\r
915 #\r
916 self._IdMapping = {-1:-1}\r
917\r
72a1d776 918 self._PcdCodeValue = ""\r
919 self._PcdDataTypeCODE = False\r
920 self._CurrentPcdName = ""\r
643556fc 921 self._Content = None\r
72a1d776 922\r
f51461c8
LG
923 ## Parser starter\r
924 def Start(self):\r
925 Content = ''\r
926 try:\r
927 Content = open(str(self.MetaFile), 'r').readlines()\r
928 except:\r
929 EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile)\r
930\r
931 OwnerId = {}\r
72a1d776 932\r
933 Content = self.ProcessMultipleLineCODEValue(Content)\r
934\r
f51461c8
LG
935 for Index in range(0, len(Content)):\r
936 Line = CleanString(Content[Index])\r
937 # skip empty line\r
938 if Line == '':\r
939 continue\r
940\r
941 self._CurrentLine = Line\r
942 self._LineIndex = Index\r
943 if self._InSubsection and self._Owner[-1] == -1:\r
944 self._Owner.append(self._LastItem)\r
945\r
946 # section header\r
947 if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:\r
948 self._SectionType = MODEL_META_DATA_SECTION_HEADER\r
949 # subsection ending\r
950 elif Line[0] == '}' and self._InSubsection:\r
951 self._InSubsection = False\r
952 self._SubsectionType = MODEL_UNKNOWN\r
953 self._SubsectionName = ''\r
954 self._Owner[-1] = -1\r
50874612 955 OwnerId.clear()\r
f51461c8
LG
956 continue\r
957 # subsection header\r
958 elif Line[0] == TAB_OPTION_START and Line[-1] == TAB_OPTION_END:\r
959 self._SubsectionType = MODEL_META_DATA_SUBSECTION_HEADER\r
960 # directive line\r
961 elif Line[0] == '!':\r
cd7bd491
YF
962 TokenList = GetSplitValueList(Line, ' ', 1)\r
963 if TokenList[0] == TAB_INCLUDE:\r
964 for Arch, ModuleType, DefaultStore in self._Scope:\r
965 if self._SubsectionType != MODEL_UNKNOWN and Arch in OwnerId:\r
966 self._Owner[-1] = OwnerId[Arch]\r
967 self._DirectiveParser()\r
968 else:\r
969 self._DirectiveParser()\r
f51461c8 970 continue\r
d429fcd0 971 if Line[0] == TAB_OPTION_START and not self._InSubsection:\r
ccaa7754 972 EdkLogger.error("Parser", FILE_READ_FAILURE, "Missing the '{' before %s in Line %s" % (Line, Index+1), ExtraData=self.MetaFile)\r
f51461c8
LG
973\r
974 if self._InSubsection:\r
975 SectionType = self._SubsectionType\r
976 else:\r
977 SectionType = self._SectionType\r
978 self._ItemType = SectionType\r
979\r
980 self._ValueList = ['', '', '']\r
981 self._SectionParser[SectionType](self)\r
4231a819 982 if self._ValueList is None:\r
f51461c8
LG
983 continue\r
984 #\r
985 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,\r
986 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1\r
987 #\r
8518bf0b 988 for Arch, ModuleType, DefaultStore in self._Scope:\r
f51461c8 989 Owner = self._Owner[-1]\r
cd7bd491 990 if self._SubsectionType != MODEL_UNKNOWN and Arch in OwnerId:\r
f51461c8
LG
991 Owner = OwnerId[Arch]\r
992 self._LastItem = self._Store(\r
993 self._ItemType,\r
994 self._ValueList[0],\r
995 self._ValueList[1],\r
996 self._ValueList[2],\r
997 Arch,\r
998 ModuleType,\r
8518bf0b 999 DefaultStore,\r
f51461c8
LG
1000 Owner,\r
1001 self._From,\r
1002 self._LineIndex + 1,\r
1003 - 1,\r
1004 self._LineIndex + 1,\r
1005 - 1,\r
1006 self._Enabled\r
1007 )\r
1008 if self._SubsectionType == MODEL_UNKNOWN and self._InSubsection:\r
1009 OwnerId[Arch] = self._LastItem\r
1010\r
1011 if self._DirectiveStack:\r
1012 Type, Line, Text = self._DirectiveStack[-1]\r
1013 EdkLogger.error('Parser', FORMAT_INVALID, "No matching '!endif' found",\r
1014 ExtraData=Text, File=self.MetaFile, Line=Line)\r
1015 self._Done()\r
1016\r
1017 ## <subsection_header> parser\r
1018 def _SubsectionHeaderParser(self):\r
1019 self._SubsectionName = self._CurrentLine[1:-1].upper()\r
1020 if self._SubsectionName in self.DataType:\r
1021 self._SubsectionType = self.DataType[self._SubsectionName]\r
1022 else:\r
1023 self._SubsectionType = MODEL_UNKNOWN\r
1024 EdkLogger.warn("Parser", "Unrecognized sub-section", File=self.MetaFile,\r
1025 Line=self._LineIndex + 1, ExtraData=self._CurrentLine)\r
1026 self._ValueList[0] = self._SubsectionName\r
1027\r
1028 ## Directive statement parser\r
1029 def _DirectiveParser(self):\r
1030 self._ValueList = ['', '', '']\r
1031 TokenList = GetSplitValueList(self._CurrentLine, ' ', 1)\r
1032 self._ValueList[0:len(TokenList)] = TokenList\r
1033\r
1034 # Syntax check\r
1035 DirectiveName = self._ValueList[0].upper()\r
1036 if DirectiveName not in self.DataType:\r
1037 EdkLogger.error("Parser", FORMAT_INVALID, "Unknown directive [%s]" % DirectiveName,\r
1038 File=self.MetaFile, Line=self._LineIndex + 1)\r
1039\r
1040 if DirectiveName in ['!IF', '!IFDEF', '!IFNDEF']:\r
1041 self._InDirective += 1\r
1042\r
1043 if DirectiveName in ['!ENDIF']:\r
1044 self._InDirective -= 1\r
1045\r
1046 if DirectiveName in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self._ValueList[1] == '':\r
1047 EdkLogger.error("Parser", FORMAT_INVALID, "Missing expression",\r
1048 File=self.MetaFile, Line=self._LineIndex + 1,\r
1049 ExtraData=self._CurrentLine)\r
1050\r
1051 ItemType = self.DataType[DirectiveName]\r
55c84777 1052 Scope = [[TAB_COMMON, TAB_COMMON, TAB_COMMON]]\r
f51461c8
LG
1053 if ItemType == MODEL_META_DATA_INCLUDE:\r
1054 Scope = self._Scope\r
09ef8e92
YF
1055 elif ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR:\r
1056 Scope = self._Scope\r
f51461c8
LG
1057 if ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF:\r
1058 # Remove all directives between !if and !endif, including themselves\r
1059 while self._DirectiveStack:\r
1060 # Remove any !else or !elseif\r
1061 DirectiveInfo = self._DirectiveStack.pop()\r
1062 if DirectiveInfo[0] in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,\r
1063 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,\r
1064 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF]:\r
1065 break\r
1066 else:\r
1067 EdkLogger.error("Parser", FORMAT_INVALID, "Redundant '!endif'",\r
1068 File=self.MetaFile, Line=self._LineIndex + 1,\r
1069 ExtraData=self._CurrentLine)\r
09ef8e92 1070 elif ItemType not in {MODEL_META_DATA_INCLUDE, MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR}:\r
f51461c8
LG
1071 # Break if there's a !else is followed by a !elseif\r
1072 if ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF and \\r
1073 self._DirectiveStack and \\r
1074 self._DirectiveStack[-1][0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE:\r
1075 EdkLogger.error("Parser", FORMAT_INVALID, "'!elseif' after '!else'",\r
1076 File=self.MetaFile, Line=self._LineIndex + 1,\r
1077 ExtraData=self._CurrentLine)\r
1078 self._DirectiveStack.append((ItemType, self._LineIndex + 1, self._CurrentLine))\r
f51461c8
LG
1079\r
1080 #\r
1081 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,\r
1082 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1\r
1083 #\r
8518bf0b 1084 for Arch, ModuleType, DefaultStore in Scope:\r
f51461c8
LG
1085 self._LastItem = self._Store(\r
1086 ItemType,\r
1087 self._ValueList[0],\r
1088 self._ValueList[1],\r
1089 self._ValueList[2],\r
1090 Arch,\r
1091 ModuleType,\r
8518bf0b 1092 DefaultStore,\r
f51461c8
LG
1093 self._Owner[-1],\r
1094 self._From,\r
1095 self._LineIndex + 1,\r
1096 - 1,\r
1097 self._LineIndex + 1,\r
1098 - 1,\r
1099 0\r
1100 )\r
1101\r
1102 ## [defines] section parser\r
1103 @ParseMacro\r
1104 def _DefineParser(self):\r
1105 TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
1106 self._ValueList[1:len(TokenList)] = TokenList\r
1107\r
1108 # Syntax check\r
1109 if not self._ValueList[1]:\r
1110 EdkLogger.error('Parser', FORMAT_INVALID, "No name specified",\r
1111 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
1112 if not self._ValueList[2]:\r
1113 EdkLogger.error('Parser', FORMAT_INVALID, "No value specified",\r
1114 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
97fa0ee9
YL
1115 if (not self._ValueList[1] in self.DefineKeywords and\r
1116 (self._InSubsection and self._ValueList[1] not in self.SubSectionDefineKeywords)):\r
f51461c8
LG
1117 EdkLogger.error('Parser', FORMAT_INVALID,\r
1118 "Unknown keyword found: %s. "\r
1119 "If this is a macro you must "\r
1120 "add it as a DEFINE in the DSC" % self._ValueList[1],\r
1121 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
97fa0ee9
YL
1122 if not self._InSubsection:\r
1123 self._Defines[self._ValueList[1]] = self._ValueList[2]\r
f51461c8
LG
1124 self._ItemType = self.DataType[TAB_DSC_DEFINES.upper()]\r
1125\r
1126 @ParseMacro\r
1127 def _SkuIdParser(self):\r
8518bf0b 1128 TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)\r
ccaa7754 1129 if len(TokenList) not in (2, 3):\r
e6b10112 1130 EdkLogger.error('Parser', FORMAT_INVALID, "Correct format is '<Number>|<UiName>[|<UiName>]'",\r
8518bf0b
LG
1131 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
1132 self._ValueList[0:len(TokenList)] = TokenList\r
1133 @ParseMacro\r
1134 def _DefaultStoresParser(self):\r
f51461c8
LG
1135 TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)\r
1136 if len(TokenList) != 2:\r
767ddbe8 1137 EdkLogger.error('Parser', FORMAT_INVALID, "Correct format is '<Number>|<UiName>'",\r
f51461c8
LG
1138 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
1139 self._ValueList[0:len(TokenList)] = TokenList\r
1140\r
1141 ## Parse Edk style of library modules\r
1142 @ParseMacro\r
1143 def _LibraryInstanceParser(self):\r
1144 self._ValueList[0] = self._CurrentLine\r
1145\r
72a1d776 1146 def ProcessMultipleLineCODEValue(self,Content):\r
1147 CODEBegin = False\r
1148 CODELine = ""\r
1149 continuelinecount = 0\r
1150 newContent = []\r
1151 for Index in range(0, len(Content)):\r
1152 Line = Content[Index]\r
1153 if CODEBegin:\r
1154 CODELine = CODELine + Line\r
1155 continuelinecount +=1\r
1156 if ")}" in Line:\r
1157 newContent.append(CODELine)\r
1158 for _ in range(continuelinecount):\r
1159 newContent.append("")\r
1160 CODEBegin = False\r
1161 CODELine = ""\r
1162 continuelinecount = 0\r
1163 else:\r
1164 if not Line:\r
1165 newContent.append(Line)\r
1166 continue\r
1167 if "{CODE(" not in Line:\r
1168 newContent.append(Line)\r
1169 continue\r
1170 elif CODEPattern.findall(Line):\r
1171 newContent.append(Line)\r
1172 continue\r
1173 else:\r
1174 CODEBegin = True\r
1175 CODELine = Line\r
1176\r
1177 return newContent\r
1178\r
1179 def _DecodeCODEData(self):\r
1180 pass\r
f51461c8
LG
1181 ## PCD sections parser\r
1182 #\r
1183 # [PcdsFixedAtBuild]\r
1184 # [PcdsPatchableInModule]\r
1185 # [PcdsFeatureFlag]\r
1186 # [PcdsDynamicEx\r
1187 # [PcdsDynamicExDefault]\r
1188 # [PcdsDynamicExVpd]\r
1189 # [PcdsDynamicExHii]\r
1190 # [PcdsDynamic]\r
1191 # [PcdsDynamicDefault]\r
1192 # [PcdsDynamicVpd]\r
1193 # [PcdsDynamicHii]\r
1194 #\r
1195 @ParseMacro\r
1196 def _PcdParser(self):\r
72a1d776 1197 if self._PcdDataTypeCODE:\r
1198 self._PcdCodeValue = self._PcdCodeValue + "\n " + self._CurrentLine\r
1199 if self._CurrentLine.endswith(")}"):\r
1200 self._CurrentLine = "|".join((self._CurrentPcdName, self._PcdCodeValue))\r
1201 self._PcdDataTypeCODE = False\r
1202 self._PcdCodeValue = ""\r
1203 else:\r
1204 self._ValueList = None\r
1205 return\r
f51461c8 1206 TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)\r
72a1d776 1207 self._CurrentPcdName = TokenList[0]\r
48e89045 1208 if len(TokenList) == 2 and TokenList[1].strip().startswith("{CODE"):\r
72a1d776 1209 self._PcdDataTypeCODE = True\r
1210 self._PcdCodeValue = TokenList[1].strip()\r
1211\r
1212 if self._PcdDataTypeCODE:\r
1213 if self._CurrentLine.endswith(")}"):\r
1214 self._PcdDataTypeCODE = False\r
1215 self._PcdCodeValue = ""\r
1216 else:\r
1217 self._ValueList = None\r
1218 return\r
f51461c8 1219 self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)\r
ae7b6df8
LG
1220 PcdNameTockens = GetSplitValueList(TokenList[0], TAB_SPLIT)\r
1221 if len(PcdNameTockens) == 2:\r
1222 self._ValueList[0], self._ValueList[1] = PcdNameTockens[0], PcdNameTockens[1]\r
1223 elif len(PcdNameTockens) == 3:\r
1224 self._ValueList[0], self._ValueList[1] = ".".join((PcdNameTockens[0], PcdNameTockens[1])), PcdNameTockens[2]\r
a0939593
LG
1225 elif len(PcdNameTockens) > 3:\r
1226 self._ValueList[0], self._ValueList[1] = ".".join((PcdNameTockens[0], PcdNameTockens[1])), ".".join(PcdNameTockens[2:])\r
f51461c8
LG
1227 if len(TokenList) == 2:\r
1228 self._ValueList[2] = TokenList[1]\r
1229 if self._ValueList[0] == '' or self._ValueList[1] == '':\r
1230 EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",\r
1231 ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",\r
1232 File=self.MetaFile, Line=self._LineIndex + 1)\r
1233 if self._ValueList[2] == '':\r
1234 #\r
e651d06c 1235 # The PCD values are optional for FIXEDATBUILD, PATCHABLEINMODULE, Dynamic/DynamicEx default\r
f51461c8 1236 #\r
e651d06c 1237 if self._SectionType in (MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT):\r
f51461c8
LG
1238 return\r
1239 EdkLogger.error('Parser', FORMAT_INVALID, "No PCD value given",\r
1240 ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",\r
1241 File=self.MetaFile, Line=self._LineIndex + 1)\r
1242\r
1243 # Validate the datum type of Dynamic Defaul PCD and DynamicEx Default PCD\r
1244 ValueList = GetSplitValueList(self._ValueList[2])\r
ccaa7754 1245 if len(ValueList) > 1 and ValueList[1] in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64] \\r
f51461c8
LG
1246 and self._ItemType in [MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT]:\r
1247 EdkLogger.error('Parser', FORMAT_INVALID, "The datum type '%s' of PCD is wrong" % ValueList[1],\r
1248 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
1249\r
9f14de3b
YZ
1250 # Validate the VariableName of DynamicHii and DynamicExHii for PCD Entry must not be an empty string\r
1251 if self._ItemType in [MODEL_PCD_DYNAMIC_HII, MODEL_PCD_DYNAMIC_EX_HII]:\r
1252 DscPcdValueList = GetSplitValueList(TokenList[1], TAB_VALUE_SPLIT, 1)\r
ccaa7754 1253 if len(DscPcdValueList[0].replace('L', '').replace('"', '').strip()) == 0:\r
9f14de3b
YZ
1254 EdkLogger.error('Parser', FORMAT_INVALID, "The VariableName field in the HII format PCD entry must not be an empty string",\r
1255 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
1256\r
f51461c8
LG
1257 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.\r
1258 DscPcdValueList = GetSplitValueList(TokenList[1], TAB_VALUE_SPLIT, 1)\r
1259 if DscPcdValueList[0] in ['True', 'true', 'TRUE']:\r
1260 self._ValueList[2] = TokenList[1].replace(DscPcdValueList[0], '1', 1);\r
1261 elif DscPcdValueList[0] in ['False', 'false', 'FALSE']:\r
1262 self._ValueList[2] = TokenList[1].replace(DscPcdValueList[0], '0', 1);\r
1263\r
1264\r
1265 ## [components] section parser\r
1266 @ParseMacro\r
1267 def _ComponentParser(self):\r
1268 if self._CurrentLine[-1] == '{':\r
1269 self._ValueList[0] = self._CurrentLine[0:-1].strip()\r
1270 self._InSubsection = True\r
cd7bd491 1271 self._SubsectionType = MODEL_UNKNOWN\r
f51461c8
LG
1272 else:\r
1273 self._ValueList[0] = self._CurrentLine\r
1274\r
1275 ## [LibraryClasses] section\r
1276 @ParseMacro\r
1277 def _LibraryClassParser(self):\r
1278 TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)\r
1279 if len(TokenList) < 2:\r
1280 EdkLogger.error('Parser', FORMAT_INVALID, "No library class or instance specified",\r
1281 ExtraData=self._CurrentLine + " (<LibraryClassName>|<LibraryInstancePath>)",\r
1282 File=self.MetaFile, Line=self._LineIndex + 1)\r
1283 if TokenList[0] == '':\r
1284 EdkLogger.error('Parser', FORMAT_INVALID, "No library class specified",\r
1285 ExtraData=self._CurrentLine + " (<LibraryClassName>|<LibraryInstancePath>)",\r
1286 File=self.MetaFile, Line=self._LineIndex + 1)\r
1287 if TokenList[1] == '':\r
1288 EdkLogger.error('Parser', FORMAT_INVALID, "No library instance specified",\r
1289 ExtraData=self._CurrentLine + " (<LibraryClassName>|<LibraryInstancePath>)",\r
1290 File=self.MetaFile, Line=self._LineIndex + 1)\r
1291\r
1292 self._ValueList[0:len(TokenList)] = TokenList\r
1293\r
1294 def _CompponentSourceOverridePathParser(self):\r
1295 self._ValueList[0] = self._CurrentLine\r
1296\r
1297 ## [BuildOptions] section parser\r
1298 @ParseMacro\r
1299 def _BuildOptionParser(self):\r
1300 self._CurrentLine = CleanString(self._CurrentLine, BuildOption=True)\r
1301 TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
1302 TokenList2 = GetSplitValueList(TokenList[0], ':', 1)\r
1303 if len(TokenList2) == 2:\r
1304 self._ValueList[0] = TokenList2[0] # toolchain family\r
1305 self._ValueList[1] = TokenList2[1] # keys\r
1306 else:\r
1307 self._ValueList[1] = TokenList[0]\r
1308 if len(TokenList) == 2: # value\r
1309 self._ValueList[2] = TokenList[1]\r
1310\r
1311 if self._ValueList[1].count('_') != 4:\r
1312 EdkLogger.error(\r
1313 'Parser',\r
1314 FORMAT_INVALID,\r
1315 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self._ValueList[1],\r
1316 ExtraData=self._CurrentLine,\r
1317 File=self.MetaFile,\r
1318 Line=self._LineIndex + 1\r
1319 )\r
1320\r
1321 ## Override parent's method since we'll do all macro replacements in parser\r
71cac3f7
CJ
1322 @property\r
1323 def _Macros(self):\r
f51461c8
LG
1324 Macros = {}\r
1325 Macros.update(self._FileLocalMacros)\r
1326 Macros.update(self._GetApplicableSectionMacro())\r
1327 Macros.update(GlobalData.gEdkGlobal)\r
1328 Macros.update(GlobalData.gPlatformDefines)\r
1329 Macros.update(GlobalData.gCommandLineDefines)\r
1330 # PCD cannot be referenced in macro definition\r
1331 if self._ItemType not in [MODEL_META_DATA_DEFINE, MODEL_META_DATA_GLOBAL_DEFINE]:\r
1332 Macros.update(self._Symbols)\r
1fa7fdf6
FY
1333 if GlobalData.BuildOptionPcd:\r
1334 for Item in GlobalData.BuildOptionPcd:\r
0d1f5b2b 1335 if isinstance(Item, tuple):\r
705ed563 1336 continue\r
1fa7fdf6 1337 PcdName, TmpValue = Item.split("=")\r
8565b582 1338 TmpValue = BuildOptionValue(TmpValue, self._GuidDict)\r
1fa7fdf6 1339 Macros[PcdName.strip()] = TmpValue\r
f51461c8
LG
1340 return Macros\r
1341\r
1342 def _PostProcess(self):\r
1343 Processer = {\r
1344 MODEL_META_DATA_SECTION_HEADER : self.__ProcessSectionHeader,\r
1345 MODEL_META_DATA_SUBSECTION_HEADER : self.__ProcessSubsectionHeader,\r
1346 MODEL_META_DATA_HEADER : self.__ProcessDefine,\r
1347 MODEL_META_DATA_DEFINE : self.__ProcessDefine,\r
1348 MODEL_META_DATA_GLOBAL_DEFINE : self.__ProcessDefine,\r
1349 MODEL_META_DATA_INCLUDE : self.__ProcessDirective,\r
1350 MODEL_META_DATA_CONDITIONAL_STATEMENT_IF : self.__ProcessDirective,\r
1351 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE : self.__ProcessDirective,\r
1352 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF : self.__ProcessDirective,\r
1353 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF : self.__ProcessDirective,\r
1354 MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF : self.__ProcessDirective,\r
1355 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF : self.__ProcessDirective,\r
1356 MODEL_EFI_SKU_ID : self.__ProcessSkuId,\r
8518bf0b 1357 MODEL_EFI_DEFAULT_STORES : self.__ProcessDefaultStores,\r
f51461c8
LG
1358 MODEL_EFI_LIBRARY_INSTANCE : self.__ProcessLibraryInstance,\r
1359 MODEL_EFI_LIBRARY_CLASS : self.__ProcessLibraryClass,\r
1360 MODEL_PCD_FIXED_AT_BUILD : self.__ProcessPcd,\r
1361 MODEL_PCD_PATCHABLE_IN_MODULE : self.__ProcessPcd,\r
1362 MODEL_PCD_FEATURE_FLAG : self.__ProcessPcd,\r
1363 MODEL_PCD_DYNAMIC_DEFAULT : self.__ProcessPcd,\r
1364 MODEL_PCD_DYNAMIC_HII : self.__ProcessPcd,\r
1365 MODEL_PCD_DYNAMIC_VPD : self.__ProcessPcd,\r
1366 MODEL_PCD_DYNAMIC_EX_DEFAULT : self.__ProcessPcd,\r
1367 MODEL_PCD_DYNAMIC_EX_HII : self.__ProcessPcd,\r
1368 MODEL_PCD_DYNAMIC_EX_VPD : self.__ProcessPcd,\r
1369 MODEL_META_DATA_COMPONENT : self.__ProcessComponent,\r
1370 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH : self.__ProcessSourceOverridePath,\r
1371 MODEL_META_DATA_BUILD_OPTION : self.__ProcessBuildOption,\r
1372 MODEL_UNKNOWN : self._Skip,\r
0923aa1c 1373 MODEL_META_DATA_USER_EXTENSION : self._SkipUserExtension,\r
09ef8e92 1374 MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR : self._ProcessError,\r
f51461c8
LG
1375 }\r
1376\r
2f818ed0 1377 self._Table = MetaFileStorage(self._RawTable.DB, self.MetaFile, MODEL_FILE_DSC, True)\r
f51461c8
LG
1378 self._DirectiveStack = []\r
1379 self._DirectiveEvalStack = []\r
1380 self._FileWithError = self.MetaFile\r
1381 self._FileLocalMacros = {}\r
50874612 1382 self._SectionsMacroDict.clear()\r
f51461c8
LG
1383 GlobalData.gPlatformDefines = {}\r
1384\r
1385 # Get all macro and PCD which has straitforward value\r
1386 self.__RetrievePcdValue()\r
1387 self._Content = self._RawTable.GetAll()\r
1388 self._ContentIndex = 0\r
97fa0ee9 1389 self._InSubsection = False\r
f51461c8 1390 while self._ContentIndex < len(self._Content) :\r
ccaa7754 1391 Id, self._ItemType, V1, V2, V3, S1, S2, S3, Owner, self._From, \\r
f51461c8
LG
1392 LineStart, ColStart, LineEnd, ColEnd, Enabled = self._Content[self._ContentIndex]\r
1393\r
1394 if self._From < 0:\r
1395 self._FileWithError = self.MetaFile\r
1396\r
1397 self._ContentIndex += 1\r
1398\r
8518bf0b 1399 self._Scope = [[S1, S2, S3]]\r
f51461c8
LG
1400 #\r
1401 # For !include directive, handle it specially,\r
1402 # merge arch and module type in case of duplicate items\r
1403 #\r
1404 while self._ItemType == MODEL_META_DATA_INCLUDE:\r
1405 if self._ContentIndex >= len(self._Content):\r
1406 break\r
1407 Record = self._Content[self._ContentIndex]\r
8518bf0b 1408 if LineStart == Record[10] and LineEnd == Record[12]:\r
ccaa7754
GL
1409 if [Record[5], Record[6], Record[7]] not in self._Scope:\r
1410 self._Scope.append([Record[5], Record[6], Record[7]])\r
f51461c8
LG
1411 self._ContentIndex += 1\r
1412 else:\r
1413 break\r
1414\r
1415 self._LineIndex = LineStart - 1\r
1416 self._ValueList = [V1, V2, V3]\r
1417\r
97fa0ee9
YL
1418 if Owner > 0 and Owner in self._IdMapping:\r
1419 self._InSubsection = True\r
1420 else:\r
1421 self._InSubsection = False\r
f51461c8
LG
1422 try:\r
1423 Processer[self._ItemType]()\r
5b0671c1 1424 except EvaluationException as Excpt:\r
f7496d71 1425 #\r
f51461c8
LG
1426 # Only catch expression evaluation error here. We need to report\r
1427 # the precise number of line on which the error occurred\r
1428 #\r
1429 if hasattr(Excpt, 'Pcd'):\r
1430 if Excpt.Pcd in GlobalData.gPlatformOtherPcds:\r
1431 Info = GlobalData.gPlatformOtherPcds[Excpt.Pcd]\r
1432 EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"\r
1433 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"\r
1434 " of the DSC file, and it is currently defined in this section:"\r
1435 " %s, line #: %d." % (Excpt.Pcd, Info[0], Info[1]),\r
1436 File=self._FileWithError, ExtraData=' '.join(self._ValueList),\r
1437 Line=self._LineIndex + 1)\r
1438 else:\r
1439 EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,\r
1440 File=self._FileWithError, ExtraData=' '.join(self._ValueList),\r
1441 Line=self._LineIndex + 1)\r
1442 else:\r
1443 EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),\r
1444 File=self._FileWithError, ExtraData=' '.join(self._ValueList),\r
1445 Line=self._LineIndex + 1)\r
5b0671c1 1446 except MacroException as Excpt:\r
f51461c8
LG
1447 EdkLogger.error('Parser', FORMAT_INVALID, str(Excpt),\r
1448 File=self._FileWithError, ExtraData=' '.join(self._ValueList),\r
1449 Line=self._LineIndex + 1)\r
1450\r
4231a819 1451 if self._ValueList is None:\r
f51461c8
LG
1452 continue\r
1453\r
1454 NewOwner = self._IdMapping.get(Owner, -1)\r
1455 self._Enabled = int((not self._DirectiveEvalStack) or (False not in self._DirectiveEvalStack))\r
1456 self._LastItem = self._Store(\r
1457 self._ItemType,\r
1458 self._ValueList[0],\r
1459 self._ValueList[1],\r
1460 self._ValueList[2],\r
1461 S1,\r
1462 S2,\r
8518bf0b 1463 S3,\r
f51461c8
LG
1464 NewOwner,\r
1465 self._From,\r
1466 self._LineIndex + 1,\r
1467 - 1,\r
1468 self._LineIndex + 1,\r
1469 - 1,\r
1470 self._Enabled\r
1471 )\r
1472 self._IdMapping[Id] = self._LastItem\r
1473\r
1474 GlobalData.gPlatformDefines.update(self._FileLocalMacros)\r
1475 self._PostProcessed = True\r
1476 self._Content = None\r
09ef8e92
YF
1477 def _ProcessError(self):\r
1478 if not self._Enabled:\r
1479 return\r
1480 EdkLogger.error('Parser', ERROR_STATEMENT, self._ValueList[1], File=self.MetaFile, Line=self._LineIndex + 1)\r
f51461c8
LG
1481\r
1482 def __ProcessSectionHeader(self):\r
1483 self._SectionName = self._ValueList[0]\r
1484 if self._SectionName in self.DataType:\r
1485 self._SectionType = self.DataType[self._SectionName]\r
1486 else:\r
1487 self._SectionType = MODEL_UNKNOWN\r
1488\r
1489 def __ProcessSubsectionHeader(self):\r
1490 self._SubsectionName = self._ValueList[0]\r
1491 if self._SubsectionName in self.DataType:\r
1492 self._SubsectionType = self.DataType[self._SubsectionName]\r
1493 else:\r
1494 self._SubsectionType = MODEL_UNKNOWN\r
1495\r
1496 def __RetrievePcdValue(self):\r
f51461c8
LG
1497 Content = open(str(self.MetaFile), 'r').readlines()\r
1498 GlobalData.gPlatformOtherPcds['DSCFILE'] = str(self.MetaFile)\r
1499 for PcdType in (MODEL_PCD_PATCHABLE_IN_MODULE, MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_HII,\r
1500 MODEL_PCD_DYNAMIC_VPD, MODEL_PCD_DYNAMIC_EX_DEFAULT, MODEL_PCD_DYNAMIC_EX_HII,\r
1501 MODEL_PCD_DYNAMIC_EX_VPD):\r
1502 Records = self._RawTable.Query(PcdType, BelongsToItem= -1.0)\r
ccaa7754 1503 for TokenSpaceGuid, PcdName, Value, Dummy2, Dummy3, Dummy4, ID, Line in Records:\r
f51461c8
LG
1504 Name = TokenSpaceGuid + '.' + PcdName\r
1505 if Name not in GlobalData.gPlatformOtherPcds:\r
1506 PcdLine = Line\r
1507 while not Content[Line - 1].lstrip().startswith(TAB_SECTION_START):\r
1508 Line -= 1\r
1509 GlobalData.gPlatformOtherPcds[Name] = (CleanString(Content[Line - 1]), PcdLine, PcdType)\r
1510\r
1511 def __ProcessDefine(self):\r
1512 if not self._Enabled:\r
1513 return\r
1514\r
1515 Type, Name, Value = self._ValueList\r
1516 Value = ReplaceMacro(Value, self._Macros, False)\r
97fa0ee9
YL
1517 #\r
1518 # If it is <Defines>, return\r
1519 #\r
1520 if self._InSubsection:\r
1521 self._ValueList = [Type, Name, Value]\r
1522 return\r
1523\r
f51461c8
LG
1524 if self._ItemType == MODEL_META_DATA_DEFINE:\r
1525 if self._SectionType == MODEL_META_DATA_HEADER:\r
1526 self._FileLocalMacros[Name] = Value\r
1527 else:\r
1528 self._ConstructSectionMacroDict(Name, Value)\r
1529 elif self._ItemType == MODEL_META_DATA_GLOBAL_DEFINE:\r
1530 GlobalData.gEdkGlobal[Name] = Value\r
1531\r
1532 #\r
1533 # Keyword in [Defines] section can be used as Macros\r
1534 #\r
1535 if (self._ItemType == MODEL_META_DATA_HEADER) and (self._SectionType == MODEL_META_DATA_HEADER):\r
1536 self._FileLocalMacros[Name] = Value\r
1537\r
1538 self._ValueList = [Type, Name, Value]\r
1539\r
1540 def __ProcessDirective(self):\r
1541 Result = None\r
1542 if self._ItemType in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,\r
1543 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF]:\r
1544 Macros = self._Macros\r
1545 Macros.update(GlobalData.gGlobalDefines)\r
1546 try:\r
1547 Result = ValueExpression(self._ValueList[1], Macros)()\r
5b0671c1 1548 except SymbolNotFound as Exc:\r
f51461c8
LG
1549 EdkLogger.debug(EdkLogger.DEBUG_5, str(Exc), self._ValueList[1])\r
1550 Result = False\r
5b0671c1 1551 except WrnExpression as Excpt:\r
f7496d71 1552 #\r
f51461c8
LG
1553 # Catch expression evaluation warning here. We need to report\r
1554 # the precise number of line and return the evaluation result\r
1555 #\r
1556 EdkLogger.warn('Parser', "Suspicious expression: %s" % str(Excpt),\r
1557 File=self._FileWithError, ExtraData=' '.join(self._ValueList),\r
1558 Line=self._LineIndex + 1)\r
1559 Result = Excpt.result\r
1560\r
1561 if self._ItemType in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,\r
1562 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,\r
1563 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF]:\r
1564 self._DirectiveStack.append(self._ItemType)\r
1565 if self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_IF:\r
1566 Result = bool(Result)\r
1567 else:\r
1568 Macro = self._ValueList[1]\r
1569 Macro = Macro[2:-1] if (Macro.startswith("$(") and Macro.endswith(")")) else Macro\r
1570 Result = Macro in self._Macros\r
1571 if self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF:\r
1572 Result = not Result\r
1573 self._DirectiveEvalStack.append(Result)\r
1574 elif self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF:\r
1575 self._DirectiveStack.append(self._ItemType)\r
1576 self._DirectiveEvalStack[-1] = not self._DirectiveEvalStack[-1]\r
1577 self._DirectiveEvalStack.append(bool(Result))\r
1578 elif self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE:\r
1579 self._DirectiveStack.append(self._ItemType)\r
1580 self._DirectiveEvalStack[-1] = not self._DirectiveEvalStack[-1]\r
1581 self._DirectiveEvalStack.append(True)\r
1582 elif self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF:\r
1583 # Back to the nearest !if/!ifdef/!ifndef\r
1584 while self._DirectiveStack:\r
1585 self._DirectiveEvalStack.pop()\r
1586 Directive = self._DirectiveStack.pop()\r
1587 if Directive in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,\r
1588 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,\r
1589 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF]:\r
1590 break\r
1591 elif self._ItemType == MODEL_META_DATA_INCLUDE:\r
1592 # The included file must be relative to workspace or same directory as DSC file\r
1593 __IncludeMacros = {}\r
1594 #\r
1595 # Allow using system environment variables in path after !include\r
1596 #\r
1597 __IncludeMacros['WORKSPACE'] = GlobalData.gGlobalDefines['WORKSPACE']\r
9eb87141 1598 if "ECP_SOURCE" in GlobalData.gGlobalDefines:\r
f51461c8
LG
1599 __IncludeMacros['ECP_SOURCE'] = GlobalData.gGlobalDefines['ECP_SOURCE']\r
1600 #\r
1601 # During GenFds phase call DSC parser, will go into this branch.\r
1602 #\r
9eb87141 1603 elif "ECP_SOURCE" in GlobalData.gCommandLineDefines:\r
f51461c8
LG
1604 __IncludeMacros['ECP_SOURCE'] = GlobalData.gCommandLineDefines['ECP_SOURCE']\r
1605\r
1606 __IncludeMacros['EFI_SOURCE'] = GlobalData.gGlobalDefines['EFI_SOURCE']\r
1607 __IncludeMacros['EDK_SOURCE'] = GlobalData.gGlobalDefines['EDK_SOURCE']\r
1608 #\r
f7496d71 1609 # Allow using MACROs comes from [Defines] section to keep compatible.\r
f51461c8
LG
1610 #\r
1611 __IncludeMacros.update(self._Macros)\r
1612\r
1613 IncludedFile = NormPath(ReplaceMacro(self._ValueList[1], __IncludeMacros, RaiseError=True))\r
1614 #\r
1615 # First search the include file under the same directory as DSC file\r
1616 #\r
1617 IncludedFile1 = PathClass(IncludedFile, self.MetaFile.Dir)\r
1618 ErrorCode, ErrorInfo1 = IncludedFile1.Validate()\r
1619 if ErrorCode != 0:\r
1620 #\r
1621 # Also search file under the WORKSPACE directory\r
1622 #\r
1623 IncludedFile1 = PathClass(IncludedFile, GlobalData.gWorkspace)\r
1624 ErrorCode, ErrorInfo2 = IncludedFile1.Validate()\r
1625 if ErrorCode != 0:\r
1626 EdkLogger.error('parser', ErrorCode, File=self._FileWithError,\r
1627 Line=self._LineIndex + 1, ExtraData=ErrorInfo1 + "\n" + ErrorInfo2)\r
1628\r
1629 self._FileWithError = IncludedFile1\r
1630\r
33787826 1631 FromItem = self._Content[self._ContentIndex - 1][0]\r
a802b269 1632 if self._InSubsection:\r
33787826
YF
1633 Owner = self._Content[self._ContentIndex - 1][8]\r
1634 else:\r
1635 Owner = self._Content[self._ContentIndex - 1][0]\r
2f818ed0 1636 IncludedFileTable = MetaFileStorage(self._RawTable.DB, IncludedFile1, MODEL_FILE_DSC, False, FromItem=FromItem)\r
cdd1b5e5 1637 Parser = DscParser(IncludedFile1, self._FileType, self._Arch, IncludedFileTable,\r
33787826 1638 Owner=Owner, From=FromItem)\r
f51461c8 1639\r
c17956e0
DL
1640 self.IncludedFiles.add (IncludedFile1)\r
1641\r
f51461c8
LG
1642 # set the parser status with current status\r
1643 Parser._SectionName = self._SectionName\r
cd7bd491
YF
1644 Parser._SubsectionType = self._SubsectionType\r
1645 Parser._InSubsection = self._InSubsection\r
1646 Parser._SectionType = self._SectionType\r
f51461c8
LG
1647 Parser._Scope = self._Scope\r
1648 Parser._Enabled = self._Enabled\r
1649 # Parse the included file\r
643556fc 1650 Parser.StartParse()\r
f51461c8
LG
1651 # Insert all records in the table for the included file into dsc file table\r
1652 Records = IncludedFileTable.GetAll()\r
1653 if Records:\r
1654 self._Content[self._ContentIndex:self._ContentIndex] = Records\r
1655 self._Content.pop(self._ContentIndex - 1)\r
1656 self._ValueList = None\r
1657 self._ContentIndex -= 1\r
1658\r
1659 def __ProcessSkuId(self):\r
1660 self._ValueList = [ReplaceMacro(Value, self._Macros, RaiseError=True)\r
1661 for Value in self._ValueList]\r
8518bf0b
LG
1662 def __ProcessDefaultStores(self):\r
1663 self._ValueList = [ReplaceMacro(Value, self._Macros, RaiseError=True)\r
1664 for Value in self._ValueList]\r
f51461c8
LG
1665\r
1666 def __ProcessLibraryInstance(self):\r
1667 self._ValueList = [ReplaceMacro(Value, self._Macros) for Value in self._ValueList]\r
1668\r
1669 def __ProcessLibraryClass(self):\r
1670 self._ValueList[1] = ReplaceMacro(self._ValueList[1], self._Macros, RaiseError=True)\r
1671\r
1672 def __ProcessPcd(self):\r
1673 if self._ItemType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:\r
1674 self._ValueList[2] = ReplaceMacro(self._ValueList[2], self._Macros, RaiseError=True)\r
1675 return\r
1676\r
1677 ValList, Valid, Index = AnalyzeDscPcd(self._ValueList[2], self._ItemType)\r
1678 if not Valid:\r
f2cc33d8 1679 if self._ItemType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT, MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE):\r
ff4d0f85
YZ
1680 if ValList[1] != TAB_VOID and StructPattern.match(ValList[1]) is None and ValList[2]:\r
1681 EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect. The datum type info should be VOID* or a valid struct name.", File=self._FileWithError,\r
f2cc33d8 1682 Line=self._LineIndex + 1, ExtraData="%s.%s|%s" % (self._ValueList[0], self._ValueList[1], self._ValueList[2]))\r
47fea6af 1683 EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self._FileWithError, Line=self._LineIndex + 1,\r
f51461c8
LG
1684 ExtraData="%s.%s|%s" % (self._ValueList[0], self._ValueList[1], self._ValueList[2]))\r
1685 PcdValue = ValList[Index]\r
ae7b6df8 1686 if PcdValue and "." not in self._ValueList[0]:\r
f51461c8
LG
1687 try:\r
1688 ValList[Index] = ValueExpression(PcdValue, self._Macros)(True)\r
5b0671c1 1689 except WrnExpression as Value:\r
f51461c8 1690 ValList[Index] = Value.result\r
35f613d9
YF
1691 except:\r
1692 pass\r
f51461c8
LG
1693\r
1694 if ValList[Index] == 'True':\r
1695 ValList[Index] = '1'\r
1696 if ValList[Index] == 'False':\r
1697 ValList[Index] = '0'\r
1698\r
22a99b87
YL
1699 if (not self._DirectiveEvalStack) or (False not in self._DirectiveEvalStack):\r
1700 GlobalData.gPlatformPcds[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue\r
1701 self._Symbols[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue\r
ae7b6df8
LG
1702 try:\r
1703 self._ValueList[2] = '|'.join(ValList)\r
1704 except Exception:\r
72443dd2 1705 print(ValList)\r
f51461c8
LG
1706\r
1707 def __ProcessComponent(self):\r
1708 self._ValueList[0] = ReplaceMacro(self._ValueList[0], self._Macros)\r
1709\r
1710 def __ProcessSourceOverridePath(self):\r
1711 self._ValueList[0] = ReplaceMacro(self._ValueList[0], self._Macros)\r
1712\r
1713 def __ProcessBuildOption(self):\r
1714 self._ValueList = [ReplaceMacro(Value, self._Macros, RaiseError=False)\r
1715 for Value in self._ValueList]\r
1716\r
1717 _SectionParser = {\r
1718 MODEL_META_DATA_HEADER : _DefineParser,\r
1719 MODEL_EFI_SKU_ID : _SkuIdParser,\r
8518bf0b 1720 MODEL_EFI_DEFAULT_STORES : _DefaultStoresParser,\r
f51461c8
LG
1721 MODEL_EFI_LIBRARY_INSTANCE : _LibraryInstanceParser,\r
1722 MODEL_EFI_LIBRARY_CLASS : _LibraryClassParser,\r
1723 MODEL_PCD_FIXED_AT_BUILD : _PcdParser,\r
1724 MODEL_PCD_PATCHABLE_IN_MODULE : _PcdParser,\r
1725 MODEL_PCD_FEATURE_FLAG : _PcdParser,\r
1726 MODEL_PCD_DYNAMIC_DEFAULT : _PcdParser,\r
1727 MODEL_PCD_DYNAMIC_HII : _PcdParser,\r
1728 MODEL_PCD_DYNAMIC_VPD : _PcdParser,\r
1729 MODEL_PCD_DYNAMIC_EX_DEFAULT : _PcdParser,\r
1730 MODEL_PCD_DYNAMIC_EX_HII : _PcdParser,\r
1731 MODEL_PCD_DYNAMIC_EX_VPD : _PcdParser,\r
1732 MODEL_META_DATA_COMPONENT : _ComponentParser,\r
1733 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH : _CompponentSourceOverridePathParser,\r
1734 MODEL_META_DATA_BUILD_OPTION : _BuildOptionParser,\r
1735 MODEL_UNKNOWN : MetaFileParser._Skip,\r
0923aa1c 1736 MODEL_META_DATA_USER_EXTENSION : MetaFileParser._SkipUserExtension,\r
f51461c8
LG
1737 MODEL_META_DATA_SECTION_HEADER : MetaFileParser._SectionHeaderParser,\r
1738 MODEL_META_DATA_SUBSECTION_HEADER : _SubsectionHeaderParser,\r
1739 }\r
1740\r
f51461c8
LG
1741## DEC file parser class\r
1742#\r
1743# @param FilePath The path of platform description file\r
1744# @param FileType The raw data of DSC file\r
1745# @param Table Database used to retrieve module/package information\r
1746# @param Macros Macros used for replacement in file\r
1747#\r
1748class DecParser(MetaFileParser):\r
1749 # DEC file supported data types (one type per section)\r
1750 DataType = {\r
1751 TAB_DEC_DEFINES.upper() : MODEL_META_DATA_HEADER,\r
1752 TAB_DSC_DEFINES_DEFINE : MODEL_META_DATA_DEFINE,\r
1753 TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE,\r
1754 TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS,\r
1755 TAB_GUIDS.upper() : MODEL_EFI_GUID,\r
1756 TAB_PPIS.upper() : MODEL_EFI_PPI,\r
1757 TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL,\r
1758 TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : MODEL_PCD_FIXED_AT_BUILD,\r
1759 TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : MODEL_PCD_PATCHABLE_IN_MODULE,\r
1760 TAB_PCDS_FEATURE_FLAG_NULL.upper() : MODEL_PCD_FEATURE_FLAG,\r
1761 TAB_PCDS_DYNAMIC_NULL.upper() : MODEL_PCD_DYNAMIC,\r
1762 TAB_PCDS_DYNAMIC_EX_NULL.upper() : MODEL_PCD_DYNAMIC_EX,\r
0923aa1c 1763 TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION,\r
f51461c8
LG
1764 }\r
1765\r
1766 ## Constructor of DecParser\r
1767 #\r
1768 # Initialize object of DecParser\r
1769 #\r
1770 # @param FilePath The path of platform description file\r
1771 # @param FileType The raw data of DSC file\r
cdd1b5e5 1772 # @param Arch Default Arch value for filtering sections\r
f51461c8 1773 # @param Table Database used to retrieve module/package information\r
f51461c8 1774 #\r
cdd1b5e5 1775 def __init__(self, FilePath, FileType, Arch, Table):\r
f51461c8
LG
1776 # prevent re-initialization\r
1777 if hasattr(self, "_Table"):\r
1778 return\r
cdd1b5e5 1779 MetaFileParser.__init__(self, FilePath, FileType, Arch, Table, -1)\r
f51461c8
LG
1780 self._Comments = []\r
1781 self._Version = 0x00010005 # Only EDK2 dec file is supported\r
1782 self._AllPCDs = [] # Only for check duplicate PCD\r
67e11e4d 1783 self._AllPcdDict = {}\r
f51461c8 1784\r
ae7b6df8
LG
1785 self._CurrentStructurePcdName = ""\r
1786 self._include_flag = False\r
1787 self._package_flag = False\r
1788\r
f51461c8
LG
1789 ## Parser starter\r
1790 def Start(self):\r
1791 Content = ''\r
1792 try:\r
1793 Content = open(str(self.MetaFile), 'r').readlines()\r
1794 except:\r
1795 EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile)\r
1796\r
778aad47 1797 self._DefinesCount = 0\r
f51461c8
LG
1798 for Index in range(0, len(Content)):\r
1799 Line, Comment = CleanString2(Content[Index])\r
1800 self._CurrentLine = Line\r
1801 self._LineIndex = Index\r
1802\r
1803 # save comment for later use\r
1804 if Comment:\r
1805 self._Comments.append((Comment, self._LineIndex + 1))\r
1806 # skip empty line\r
1807 if Line == '':\r
1808 continue\r
1809\r
1810 # section header\r
1811 if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:\r
1812 self._SectionHeaderParser()\r
778aad47
YF
1813 if self._SectionName == TAB_DEC_DEFINES.upper():\r
1814 self._DefinesCount += 1\r
f51461c8
LG
1815 self._Comments = []\r
1816 continue\r
778aad47
YF
1817 if self._SectionType == MODEL_UNKNOWN:\r
1818 EdkLogger.error("Parser", FORMAT_INVALID,\r
1819 ""\r
1820 "Not able to determine \"%s\" in which section."%self._CurrentLine,\r
1821 self.MetaFile, self._LineIndex + 1)\r
f51461c8
LG
1822 elif len(self._SectionType) == 0:\r
1823 self._Comments = []\r
1824 continue\r
1825\r
1826 # section content\r
1827 self._ValueList = ['', '', '']\r
1828 self._SectionParser[self._SectionType[0]](self)\r
4231a819 1829 if self._ValueList is None or self._ItemType == MODEL_META_DATA_DEFINE:\r
f51461c8
LG
1830 self._ItemType = -1\r
1831 self._Comments = []\r
1832 continue\r
1833\r
1834 #\r
1835 # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,\r
1836 # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1\r
1837 #\r
1838 for Arch, ModuleType, Type in self._Scope:\r
1839 self._LastItem = self._Store(\r
1840 Type,\r
1841 self._ValueList[0],\r
1842 self._ValueList[1],\r
1843 self._ValueList[2],\r
1844 Arch,\r
1845 ModuleType,\r
1846 self._Owner[-1],\r
1847 self._LineIndex + 1,\r
1848 - 1,\r
1849 self._LineIndex + 1,\r
1850 - 1,\r
1851 0\r
1852 )\r
1853 for Comment, LineNo in self._Comments:\r
1854 self._Store(\r
1855 MODEL_META_DATA_COMMENT,\r
1856 Comment,\r
1857 self._ValueList[0],\r
1858 self._ValueList[1],\r
1859 Arch,\r
1860 ModuleType,\r
1861 self._LastItem,\r
1862 LineNo,\r
1863 - 1,\r
1864 LineNo,\r
1865 - 1,\r
1866 0\r
1867 )\r
1868 self._Comments = []\r
778aad47
YF
1869 if self._DefinesCount > 1:\r
1870 EdkLogger.error('Parser', FORMAT_INVALID, 'Multiple [Defines] section is exist.', self.MetaFile )\r
1871 if self._DefinesCount == 0:\r
ccaa7754 1872 EdkLogger.error('Parser', FORMAT_INVALID, 'No [Defines] section exist.', self.MetaFile)\r
f51461c8
LG
1873 self._Done()\r
1874\r
1875\r
1876 ## Section header parser\r
1877 #\r
1878 # The section header is always in following format:\r
1879 #\r
1880 # [section_name.arch<.platform|module_type>]\r
1881 #\r
1882 def _SectionHeaderParser(self):\r
1883 self._Scope = []\r
1884 self._SectionName = ''\r
1885 self._SectionType = []\r
1886 ArchList = set()\r
c28d2e10 1887 PrivateList = set()\r
07959205 1888 Line = re.sub(',[\s]*', TAB_COMMA_SPLIT, self._CurrentLine)\r
f51461c8
LG
1889 for Item in Line[1:-1].split(TAB_COMMA_SPLIT):\r
1890 if Item == '':\r
1891 EdkLogger.error("Parser", FORMAT_UNKNOWN_ERROR,\r
1892 "section name can NOT be empty or incorrectly use separator comma",\r
1893 self.MetaFile, self._LineIndex + 1, self._CurrentLine)\r
1894 ItemList = Item.split(TAB_SPLIT)\r
1895\r
1896 # different types of PCD are permissible in one section\r
1897 self._SectionName = ItemList[0].upper()\r
778aad47
YF
1898 if self._SectionName == TAB_DEC_DEFINES.upper() and (len(ItemList) > 1 or len(Line.split(TAB_COMMA_SPLIT)) > 1):\r
1899 EdkLogger.error("Parser", FORMAT_INVALID, "Defines section format is invalid",\r
1900 self.MetaFile, self._LineIndex + 1, self._CurrentLine)\r
f51461c8
LG
1901 if self._SectionName in self.DataType:\r
1902 if self.DataType[self._SectionName] not in self._SectionType:\r
1903 self._SectionType.append(self.DataType[self._SectionName])\r
1904 else:\r
1905 EdkLogger.error("Parser", FORMAT_UNKNOWN_ERROR, "%s is not a valid section name" % Item,\r
1906 self.MetaFile, self._LineIndex + 1, self._CurrentLine)\r
1907\r
1908 if MODEL_PCD_FEATURE_FLAG in self._SectionType and len(self._SectionType) > 1:\r
1909 EdkLogger.error(\r
1910 'Parser',\r
1911 FORMAT_INVALID,\r
1912 "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL,\r
1913 File=self.MetaFile,\r
1914 Line=self._LineIndex + 1,\r
1915 ExtraData=self._CurrentLine\r
1916 )\r
1917 # S1 is always Arch\r
1918 if len(ItemList) > 1:\r
1919 S1 = ItemList[1].upper()\r
1920 else:\r
55c84777 1921 S1 = TAB_ARCH_COMMON\r
f51461c8
LG
1922 ArchList.add(S1)\r
1923 # S2 may be Platform or ModuleType\r
1924 if len(ItemList) > 2:\r
1925 S2 = ItemList[2].upper()\r
c28d2e10
YZ
1926 # only Includes, GUIDs, PPIs, Protocols section have Private tag\r
1927 if self._SectionName in [TAB_INCLUDES.upper(), TAB_GUIDS.upper(), TAB_PROTOCOLS.upper(), TAB_PPIS.upper()]:\r
1928 if S2 != 'PRIVATE':\r
1929 EdkLogger.error("Parser", FORMAT_INVALID, 'Please use keyword "Private" as section tag modifier.',\r
1930 File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)\r
f51461c8 1931 else:\r
55c84777 1932 S2 = TAB_COMMON\r
c28d2e10 1933 PrivateList.add(S2)\r
f51461c8
LG
1934 if [S1, S2, self.DataType[self._SectionName]] not in self._Scope:\r
1935 self._Scope.append([S1, S2, self.DataType[self._SectionName]])\r
1936\r
1937 # 'COMMON' must not be used with specific ARCHs at the same section\r
55c84777 1938 if TAB_ARCH_COMMON in ArchList and len(ArchList) > 1:\r
f51461c8
LG
1939 EdkLogger.error('Parser', FORMAT_INVALID, "'common' ARCH must not be used with specific ARCHs",\r
1940 File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)\r
c28d2e10
YZ
1941\r
1942 # It is not permissible to mix section tags without the Private attribute with section tags with the Private attribute\r
55c84777 1943 if TAB_COMMON in PrivateList and len(PrivateList) > 1:\r
c28d2e10
YZ
1944 EdkLogger.error('Parser', FORMAT_INVALID, "Can't mix section tags without the Private attribute with section tags with the Private attribute",\r
1945 File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)\r
f51461c8
LG
1946\r
1947 ## [guids], [ppis] and [protocols] section parser\r
1948 @ParseMacro\r
1949 def _GuidParser(self):\r
1950 TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
1951 if len(TokenList) < 2:\r
1952 EdkLogger.error('Parser', FORMAT_INVALID, "No GUID name or value specified",\r
1953 ExtraData=self._CurrentLine + " (<CName> = <GuidValueInCFormat>)",\r
1954 File=self.MetaFile, Line=self._LineIndex + 1)\r
1955 if TokenList[0] == '':\r
1956 EdkLogger.error('Parser', FORMAT_INVALID, "No GUID name specified",\r
1957 ExtraData=self._CurrentLine + " (<CName> = <GuidValueInCFormat>)",\r
1958 File=self.MetaFile, Line=self._LineIndex + 1)\r
1959 if TokenList[1] == '':\r
1960 EdkLogger.error('Parser', FORMAT_INVALID, "No GUID value specified",\r
1961 ExtraData=self._CurrentLine + " (<CName> = <GuidValueInCFormat>)",\r
1962 File=self.MetaFile, Line=self._LineIndex + 1)\r
1963 if TokenList[1][0] != '{' or TokenList[1][-1] != '}' or GuidStructureStringToGuidString(TokenList[1]) == '':\r
1964 EdkLogger.error('Parser', FORMAT_INVALID, "Invalid GUID value format",\r
1965 ExtraData=self._CurrentLine + \\r
1966 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",\r
1967 File=self.MetaFile, Line=self._LineIndex + 1)\r
1968 self._ValueList[0] = TokenList[0]\r
1969 self._ValueList[1] = TokenList[1]\r
726c501c
YZ
1970 if self._ValueList[0] not in self._GuidDict:\r
1971 self._GuidDict[self._ValueList[0]] = self._ValueList[1]\r
f51461c8 1972\r
72a1d776 1973 def ParsePcdName(self,namelist):\r
1974 if "[" in namelist[1]:\r
1975 pcdname = namelist[1][:namelist[1].index("[")]\r
1976 arrayindex = namelist[1][namelist[1].index("["):]\r
1977 namelist[1] = pcdname\r
1978 if len(namelist) == 2:\r
1979 namelist.append(arrayindex)\r
1980 else:\r
1981 namelist[2] = ".".join((arrayindex,namelist[2]))\r
1982 return namelist\r
1983\r
f51461c8
LG
1984 ## PCD sections parser\r
1985 #\r
1986 # [PcdsFixedAtBuild]\r
1987 # [PcdsPatchableInModule]\r
1988 # [PcdsFeatureFlag]\r
1989 # [PcdsDynamicEx\r
1990 # [PcdsDynamic]\r
1991 #\r
1992 @ParseMacro\r
1993 def _PcdParser(self):\r
ae7b6df8
LG
1994 if self._CurrentStructurePcdName:\r
1995 self._ValueList[0] = self._CurrentStructurePcdName\r
1996\r
1997 if "|" not in self._CurrentLine:\r
1998 if "<HeaderFiles>" == self._CurrentLine:\r
1999 self._include_flag = True\r
81add864 2000 self._package_flag = False\r
ae7b6df8
LG
2001 self._ValueList = None\r
2002 return\r
2003 if "<Packages>" == self._CurrentLine:\r
2004 self._package_flag = True\r
2005 self._ValueList = None\r
81add864 2006 self._include_flag = False\r
ae7b6df8
LG
2007 return\r
2008\r
2009 if self._include_flag:\r
1ccc4d89 2010 self._ValueList[1] = "<HeaderFiles>_" + md5(self._CurrentLine).hexdigest()\r
ae7b6df8 2011 self._ValueList[2] = self._CurrentLine\r
ae7b6df8 2012 if self._package_flag and "}" != self._CurrentLine:\r
1ccc4d89 2013 self._ValueList[1] = "<Packages>_" + md5(self._CurrentLine).hexdigest()\r
ae7b6df8
LG
2014 self._ValueList[2] = self._CurrentLine\r
2015 if self._CurrentLine == "}":\r
2016 self._package_flag = False\r
81add864 2017 self._include_flag = False\r
ae7b6df8
LG
2018 self._ValueList = None\r
2019 return\r
2020 else:\r
2021 PcdTockens = self._CurrentLine.split(TAB_VALUE_SPLIT)\r
72a1d776 2022 PcdNames = self.ParsePcdName(PcdTockens[0].split(TAB_SPLIT))\r
ae7b6df8 2023 if len(PcdNames) == 2:\r
72a1d776 2024 if PcdNames[1].strip().endswith("]"):\r
2025 PcdName = PcdNames[1][:PcdNames[1].index('[')]\r
2026 Index = PcdNames[1][PcdNames[1].index('['):]\r
2027 self._ValueList[0] = TAB_SPLIT.join((PcdNames[0],PcdName))\r
2028 self._ValueList[1] = Index\r
2029 self._ValueList[2] = PcdTockens[1]\r
2030 else:\r
2031 self._CurrentStructurePcdName = ""\r
ae7b6df8 2032 else:\r
8e011d83 2033 if self._CurrentStructurePcdName != TAB_SPLIT.join(PcdNames[:2]):\r
ccaa7754 2034 EdkLogger.error('Parser', FORMAT_INVALID, "Pcd Name does not match: %s and %s " % (self._CurrentStructurePcdName, TAB_SPLIT.join(PcdNames[:2])),\r
8e011d83 2035 File=self.MetaFile, Line=self._LineIndex + 1)\r
a0939593 2036 self._ValueList[1] = TAB_SPLIT.join(PcdNames[2:])\r
ae7b6df8
LG
2037 self._ValueList[2] = PcdTockens[1]\r
2038 if not self._CurrentStructurePcdName:\r
2039 TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)\r
2040 self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)\r
2041 ValueRe = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*')\r
2042 # check PCD information\r
2043 if self._ValueList[0] == '' or self._ValueList[1] == '':\r
2044 EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",\r
2045 ExtraData=self._CurrentLine + \\r
2046 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
2047 File=self.MetaFile, Line=self._LineIndex + 1)\r
2048 # check format of token space GUID CName\r
2049 if not ValueRe.match(self._ValueList[0]):\r
2050 EdkLogger.error('Parser', FORMAT_INVALID, "The format of the token space GUID CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",\r
2051 ExtraData=self._CurrentLine + \\r
2052 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
2053 File=self.MetaFile, Line=self._LineIndex + 1)\r
2054 # check format of PCD CName\r
2055 if not ValueRe.match(self._ValueList[1]):\r
2056 EdkLogger.error('Parser', FORMAT_INVALID, "The format of the PCD CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",\r
2057 ExtraData=self._CurrentLine + \\r
2058 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
2059 File=self.MetaFile, Line=self._LineIndex + 1)\r
2060 # check PCD datum information\r
2061 if len(TokenList) < 2 or TokenList[1] == '':\r
2062 EdkLogger.error('Parser', FORMAT_INVALID, "No PCD Datum information given",\r
2063 ExtraData=self._CurrentLine + \\r
2064 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
2065 File=self.MetaFile, Line=self._LineIndex + 1)\r
2066\r
2067\r
2068 ValueRe = re.compile(r'^\s*L?\".*\|.*\"')\r
2069 PtrValue = ValueRe.findall(TokenList[1])\r
2070\r
2071 # Has VOID* type string, may contain "|" character in the string.\r
2072 if len(PtrValue) != 0:\r
2073 ptrValueList = re.sub(ValueRe, '', TokenList[1])\r
2074 ValueList = AnalyzePcdExpression(ptrValueList)\r
2075 ValueList[0] = PtrValue[0]\r
2076 else:\r
2077 ValueList = AnalyzePcdExpression(TokenList[1])\r
2078\r
2079\r
2080 # check if there's enough datum information given\r
2081 if len(ValueList) != 3:\r
2082 EdkLogger.error('Parser', FORMAT_INVALID, "Invalid PCD Datum information given",\r
2083 ExtraData=self._CurrentLine + \\r
2084 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
2085 File=self.MetaFile, Line=self._LineIndex + 1)\r
2086 # check default value\r
2087 if ValueList[0] == '':\r
2088 EdkLogger.error('Parser', FORMAT_INVALID, "Missing DefaultValue in PCD Datum information",\r
2089 ExtraData=self._CurrentLine + \\r
2090 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
2091 File=self.MetaFile, Line=self._LineIndex + 1)\r
2092 # check datum type\r
2093 if ValueList[1] == '':\r
2094 EdkLogger.error('Parser', FORMAT_INVALID, "Missing DatumType in PCD Datum information",\r
2095 ExtraData=self._CurrentLine + \\r
2096 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
2097 File=self.MetaFile, Line=self._LineIndex + 1)\r
2098 # check token of the PCD\r
2099 if ValueList[2] == '':\r
2100 EdkLogger.error('Parser', FORMAT_INVALID, "Missing Token in PCD Datum information",\r
2101 ExtraData=self._CurrentLine + \\r
2102 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",\r
2103 File=self.MetaFile, Line=self._LineIndex + 1)\r
2104\r
2105 PcdValue = ValueList[0]\r
2106 if PcdValue:\r
726c501c 2107 try:\r
9efe8d60 2108 self._GuidDict.update(self._AllPcdDict)\r
726c501c 2109 ValueList[0] = ValueExpressionEx(ValueList[0], ValueList[1], self._GuidDict)(True)\r
5b0671c1 2110 except BadExpression as Value:\r
726c501c 2111 EdkLogger.error('Parser', FORMAT_INVALID, Value, ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
ae7b6df8
LG
2112 # check format of default value against the datum type\r
2113 IsValid, Cause = CheckPcdDatum(ValueList[1], ValueList[0])\r
2114 if not IsValid:\r
2115 EdkLogger.error('Parser', FORMAT_INVALID, Cause, ExtraData=self._CurrentLine,\r
2116 File=self.MetaFile, Line=self._LineIndex + 1)\r
2117\r
2118 if Cause == "StructurePcd":\r
2119 self._CurrentStructurePcdName = TAB_SPLIT.join(self._ValueList[0:2])\r
2120 self._ValueList[0] = self._CurrentStructurePcdName\r
2121 self._ValueList[1] = ValueList[1].strip()\r
2122\r
2123 if ValueList[0] in ['True', 'true', 'TRUE']:\r
2124 ValueList[0] = '1'\r
2125 elif ValueList[0] in ['False', 'false', 'FALSE']:\r
2126 ValueList[0] = '0'\r
2127\r
2128 # check for duplicate PCD definition\r
2129 if (self._Scope[0], self._ValueList[0], self._ValueList[1]) in self._AllPCDs:\r
2130 EdkLogger.error('Parser', FORMAT_INVALID,\r
2131 "The same PCD name and GUID have been already defined",\r
2132 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)\r
2133 else:\r
2134 self._AllPCDs.append((self._Scope[0], self._ValueList[0], self._ValueList[1]))\r
2135 self._AllPcdDict[TAB_SPLIT.join(self._ValueList[0:2])] = ValueList[0]\r
f51461c8 2136\r
ae7b6df8 2137 self._ValueList[2] = ValueList[0].strip() + '|' + ValueList[1].strip() + '|' + ValueList[2].strip()\r
f51461c8
LG
2138\r
2139 _SectionParser = {\r
2140 MODEL_META_DATA_HEADER : MetaFileParser._DefineParser,\r
2141 MODEL_EFI_INCLUDE : MetaFileParser._PathParser,\r
2142 MODEL_EFI_LIBRARY_CLASS : MetaFileParser._PathParser,\r
2143 MODEL_EFI_GUID : _GuidParser,\r
2144 MODEL_EFI_PPI : _GuidParser,\r
2145 MODEL_EFI_PROTOCOL : _GuidParser,\r
2146 MODEL_PCD_FIXED_AT_BUILD : _PcdParser,\r
2147 MODEL_PCD_PATCHABLE_IN_MODULE : _PcdParser,\r
2148 MODEL_PCD_FEATURE_FLAG : _PcdParser,\r
2149 MODEL_PCD_DYNAMIC : _PcdParser,\r
2150 MODEL_PCD_DYNAMIC_EX : _PcdParser,\r
2151 MODEL_UNKNOWN : MetaFileParser._Skip,\r
0923aa1c 2152 MODEL_META_DATA_USER_EXTENSION : MetaFileParser._SkipUserExtension,\r
f51461c8
LG
2153 }\r
2154\r
2155##\r
2156#\r
2157# This acts like the main() function for the script, unless it is 'import'ed into another\r
2158# script.\r
2159#\r
2160if __name__ == '__main__':\r
2161 pass\r
2162\r