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