2 # This file is used to parse meta files
4 # Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
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
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.
22 import Common
.EdkLogger
as EdkLogger
23 import Common
.GlobalData
as GlobalData
25 from CommonDataClass
.DataClass
import *
26 from Common
.DataType
import *
27 from Common
.String
import *
28 from Common
.Misc
import GuidStructureStringToGuidString
, CheckPcdDatum
, PathClass
, AnalyzePcdData
29 from Common
.Expression
import *
30 from CommonDataClass
.Exceptions
import *
32 from MetaFileTable
import MetaFileStorage
34 ## A decorator used to parse macro definition
35 def ParseMacro(Parser
):
36 def MacroParser(self
):
37 Match
= gMacroDefPattern
.match(self
._CurrentLine
)
39 # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method
43 TokenList
= GetSplitValueList(self
._CurrentLine
[Match
.end(1):], TAB_EQUAL_SPLIT
, 1)
46 EdkLogger
.error('Parser', FORMAT_INVALID
, "No macro name given",
47 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
48 if len(TokenList
) < 2:
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
,
56 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
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_]*",
60 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
62 self
._ItemType
= self
.DataType
[Type
]
63 # DEFINE defined macros
64 if self
._ItemType
== MODEL_META_DATA_DEFINE
:
65 if self
._SectionType
== MODEL_META_DATA_HEADER
:
66 self
._FileLocalMacros
[Name
] = Value
68 SectionDictKey
= self
._SectionType
, self
._Scope
[0][0], self
._Scope
[0][1]
69 if SectionDictKey
not in self
._SectionsMacroDict
:
70 self
._SectionsMacroDict
[SectionDictKey
] = {}
71 SectionLocalMacros
= self
._SectionsMacroDict
[SectionDictKey
]
72 SectionLocalMacros
[Name
] = Value
73 # EDK_GLOBAL defined macros
74 elif type(self
) != DscParser
:
75 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL can only be used in .dsc file",
76 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
77 elif self
._SectionType
!= MODEL_META_DATA_HEADER
:
78 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL can only be used under [Defines] section",
79 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
80 elif (Name
in self
._FileLocalMacros
) and (self
._FileLocalMacros
[Name
] != Value
):
81 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL defined a macro with the same name and different value as one defined by 'DEFINE'",
82 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
84 self
._ValueList
= [Type
, Name
, Value
]
88 ## Base class of parser
90 # This class is used for derivation purpose. The specific parser for one kind
91 # type file must derive this class and implement some public interfaces.
93 # @param FilePath The path of platform description file
94 # @param FileType The raw data of DSC file
95 # @param Table Database used to retrieve module/package information
96 # @param Macros Macros used for replacement in file
97 # @param Owner Owner ID (for sub-section parsing)
98 # @param From ID from which the data comes (for !INCLUDE directive)
100 class MetaFileParser(object):
101 # data type (file content) for specific file type
104 # Parser objects used to implement singleton
109 # One file, one parser object. This factory method makes sure that there's
110 # only one object constructed for one meta file.
112 # @param Class class object of real AutoGen class
113 # (InfParser, DecParser or DscParser)
114 # @param FilePath The path of meta file
115 # @param *args The specific class related parameters
116 # @param **kwargs The specific class related dict parameters
118 def __new__(Class
, FilePath
, *args
, **kwargs
):
119 if FilePath
in Class
.MetaFiles
:
120 return Class
.MetaFiles
[FilePath
]
122 ParserObject
= super(MetaFileParser
, Class
).__new
__(Class
)
123 Class
.MetaFiles
[FilePath
] = ParserObject
126 ## Constructor of MetaFileParser
128 # Initialize object of MetaFileParser
130 # @param FilePath The path of platform description file
131 # @param FileType The raw data of DSC file
132 # @param Table Database used to retrieve module/package information
133 # @param Macros Macros used for replacement in file
134 # @param Owner Owner ID (for sub-section parsing)
135 # @param From ID from which the data comes (for !INCLUDE directive)
137 def __init__(self
, FilePath
, FileType
, Table
, Owner
=-1, From
=-1):
139 self
._RawTable
= Table
140 self
._FileType
= FileType
141 self
.MetaFile
= FilePath
142 self
._FileDir
= self
.MetaFile
.Dir
144 self
._FileLocalMacros
= {}
145 self
._SectionsMacroDict
= {}
147 # for recursive parsing
148 self
._Owner
= [Owner
]
151 # parsr status for parsing
152 self
._ValueList
= ['', '', '', '', '']
155 self
._CurrentLine
= ''
156 self
._SectionType
= MODEL_UNKNOWN
157 self
._SectionName
= ''
158 self
._InSubsection
= False
159 self
._SubsectionType
= MODEL_UNKNOWN
160 self
._SubsectionName
= ''
161 self
._ItemType
= MODEL_UNKNOWN
164 self
._Finished
= False
165 self
._PostProcessed
= False
166 # Different version of meta-file has different way to parse.
169 ## Store the parsed data in table
170 def _Store(self
, *Args
):
171 return self
._Table
.Insert(*Args
)
173 ## Virtual method for starting parse
175 raise NotImplementedError
177 ## Notify a post-process is needed
178 def DoPostProcess(self
):
179 self
._PostProcessed
= False
181 ## Set parsing complete flag in both class and table
183 self
._Finished
= True
184 ## Do not set end flag when processing included files
186 self
._Table
.SetEndFlag()
188 def _PostProcess(self
):
189 self
._PostProcessed
= True
191 ## Get the parse complete flag
192 def _GetFinished(self
):
193 return self
._Finished
195 ## Set the complete flag
196 def _SetFinished(self
, Value
):
197 self
._Finished
= Value
199 ## Use [] style to query data in table, just for readability
201 # DataInfo = [data_type, scope1(arch), scope2(platform/moduletype)]
203 def __getitem__(self
, DataInfo
):
204 if type(DataInfo
) != type(()):
205 DataInfo
= (DataInfo
,)
207 # Parse the file first, if necessary
208 if not self
._Finished
:
209 if self
._RawTable
.IsIntegrity():
210 self
._Finished
= True
212 self
._Table
= self
._RawTable
213 self
._PostProcessed
= False
216 # No specific ARCH or Platform given, use raw data
217 if self
._RawTable
and (len(DataInfo
) == 1 or DataInfo
[1] == None):
218 return self
._RawTable
.Query(*DataInfo
)
220 # Do post-process if necessary
221 if not self
._PostProcessed
:
224 return self
._Table
.Query(*DataInfo
)
226 ## Data parser for the common format in different type of file
228 # The common format in the meatfile is like
233 def _CommonParser(self
):
234 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
235 self
._ValueList
[0:len(TokenList
)] = TokenList
237 ## Data parser for the format in which there's path
239 # Only path can have macro used. So we need to replace them before use.
242 def _PathParser(self
):
243 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
244 self
._ValueList
[0:len(TokenList
)] = TokenList
245 # Don't do macro replacement for dsc file at this point
246 if type(self
) != DscParser
:
247 Macros
= self
._Macros
248 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
250 ## Skip unsupported data
252 EdkLogger
.warn("Parser", "Unrecognized content", File
=self
.MetaFile
,
253 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
);
254 self
._ValueList
[0:1] = [self
._CurrentLine
]
256 ## Section header parser
258 # The section header is always in following format:
260 # [section_name.arch<.platform|module_type>]
262 def _SectionHeaderParser(self
):
264 self
._SectionName
= ''
266 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
269 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
)
270 # different section should not mix in one section
271 if self
._SectionName
!= '' and self
._SectionName
!= ItemList
[0].upper():
272 EdkLogger
.error('Parser', FORMAT_INVALID
, "Different section names in the same section",
273 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
274 self
._SectionName
= ItemList
[0].upper()
275 if self
._SectionName
in self
.DataType
:
276 self
._SectionType
= self
.DataType
[self
._SectionName
]
278 self
._SectionType
= MODEL_UNKNOWN
279 EdkLogger
.warn("Parser", "Unrecognized section", File
=self
.MetaFile
,
280 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
282 if len(ItemList
) > 1:
283 S1
= ItemList
[1].upper()
287 # S2 may be Platform or ModuleType
288 if len(ItemList
) > 2:
289 S2
= ItemList
[2].upper()
292 self
._Scope
.append([S1
, S2
])
294 # 'COMMON' must not be used with specific ARCHs at the same section
295 if 'COMMON' in ArchList
and len(ArchList
) > 1:
296 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
297 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
298 # If the section information is needed later, it should be stored in database
299 self
._ValueList
[0] = self
._SectionName
301 ## [defines] section parser
303 def _DefineParser(self
):
304 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
305 self
._ValueList
[1:len(TokenList
)] = TokenList
306 if not self
._ValueList
[1]:
307 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
308 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
309 if not self
._ValueList
[2]:
310 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
311 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
313 Name
, Value
= self
._ValueList
[1], self
._ValueList
[2]
314 # Sometimes, we need to make differences between EDK and EDK2 modules
315 if Name
== 'INF_VERSION':
317 self
._Version
= int(Value
, 0)
319 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid version number",
320 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
322 Value
= ReplaceMacro(Value
, self
._Macros
)
323 if type(self
) == InfParser
and self
._Version
< 0x00010005:
324 # EDK module allows using defines as macros
325 self
._FileLocalMacros
[Name
] = Value
326 self
._Defines
[Name
] = Value
328 ## [BuildOptions] section parser
330 def _BuildOptionParser(self
):
331 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
332 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
333 if len(TokenList2
) == 2:
334 self
._ValueList
[0] = TokenList2
[0] # toolchain family
335 self
._ValueList
[1] = TokenList2
[1] # keys
337 self
._ValueList
[1] = TokenList
[0]
338 if len(TokenList
) == 2 and type(self
) != DscParser
: # value
339 self
._ValueList
[2] = ReplaceMacro(TokenList
[1], self
._Macros
)
341 if self
._ValueList
[1].count('_') != 4:
345 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
346 ExtraData
=self
._CurrentLine
,
348 Line
=self
._LineIndex
+1
351 def _GetMacros(self
):
353 Macros
.update(self
._FileLocalMacros
)
354 Macros
.update(self
._GetApplicableSectionMacro
())
358 ## Get section Macros that are applicable to current line, which may come from other sections
359 ## that share the same name while scope is wider
360 def _GetApplicableSectionMacro(self
):
363 for SectionType
, Scope1
, Scope2
in self
._SectionsMacroDict
:
364 if (SectionType
== self
._SectionType
) and (Scope1
== self
._Scope
[0][0] or Scope1
== "COMMON") and (Scope2
== self
._Scope
[0][1] or Scope2
== "COMMON"):
365 Macros
.update(self
._SectionsMacroDict
[(SectionType
, Scope1
, Scope2
)])
370 Finished
= property(_GetFinished
, _SetFinished
)
371 _Macros
= property(_GetMacros
)
374 ## INF file parser class
376 # @param FilePath The path of platform description file
377 # @param FileType The raw data of DSC file
378 # @param Table Database used to retrieve module/package information
379 # @param Macros Macros used for replacement in file
381 class InfParser(MetaFileParser
):
382 # INF file supported data types (one type per section)
384 TAB_UNKNOWN
.upper() : MODEL_UNKNOWN
,
385 TAB_INF_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
386 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
387 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
388 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
389 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
390 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
391 TAB_PACKAGES
.upper() : MODEL_META_DATA_PACKAGE
,
392 TAB_NMAKE
.upper() : MODEL_META_DATA_NMAKE
,
393 TAB_INF_FIXED_PCD
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
394 TAB_INF_PATCH_PCD
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
395 TAB_INF_FEATURE_PCD
.upper() : MODEL_PCD_FEATURE_FLAG
,
396 TAB_INF_PCD_EX
.upper() : MODEL_PCD_DYNAMIC_EX
,
397 TAB_INF_PCD
.upper() : MODEL_PCD_DYNAMIC
,
398 TAB_SOURCES
.upper() : MODEL_EFI_SOURCE_FILE
,
399 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
400 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
401 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
402 TAB_DEPEX
.upper() : MODEL_EFI_DEPEX
,
403 TAB_BINARIES
.upper() : MODEL_EFI_BINARY_FILE
,
404 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
407 ## Constructor of InfParser
409 # Initialize object of InfParser
411 # @param FilePath The path of module description file
412 # @param FileType The raw data of DSC file
413 # @param Table Database used to retrieve module/package information
414 # @param Macros Macros used for replacement in file
416 def __init__(self
, FilePath
, FileType
, Table
):
417 # prevent re-initialization
418 if hasattr(self
, "_Table"):
420 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
)
427 Content
= open(str(self
.MetaFile
), 'r').readlines()
429 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
431 # parse the file line by line
432 IsFindBlockComment
= False
434 for Index
in range(0, len(Content
)):
435 # skip empty, commented, block commented lines
436 Line
= CleanString(Content
[Index
], AllowCppStyleComment
=True)
438 if Index
+ 1 < len(Content
):
439 NextLine
= CleanString(Content
[Index
+ 1])
442 if Line
.find(DataType
.TAB_COMMENT_EDK_START
) > -1:
443 IsFindBlockComment
= True
445 if Line
.find(DataType
.TAB_COMMENT_EDK_END
) > -1:
446 IsFindBlockComment
= False
448 if IsFindBlockComment
:
451 self
._LineIndex
= Index
452 self
._CurrentLine
= Line
455 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
456 self
._SectionHeaderParser
()
457 # Check invalid sections
458 if self
._Version
< 0x00010005:
459 if self
._SectionType
in [MODEL_META_DATA_BUILD_OPTION
,
460 MODEL_EFI_LIBRARY_CLASS
,
461 MODEL_META_DATA_PACKAGE
,
462 MODEL_PCD_FIXED_AT_BUILD
,
463 MODEL_PCD_PATCHABLE_IN_MODULE
,
464 MODEL_PCD_FEATURE_FLAG
,
465 MODEL_PCD_DYNAMIC_EX
,
470 MODEL_META_DATA_USER_EXTENSION
]:
471 EdkLogger
.error('Parser', FORMAT_INVALID
,
472 "Section [%s] is not allowed in inf file without version" % (self
._SectionName
),
473 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
474 elif self
._SectionType
in [MODEL_EFI_INCLUDE
,
475 MODEL_EFI_LIBRARY_INSTANCE
,
476 MODEL_META_DATA_NMAKE
]:
477 EdkLogger
.error('Parser', FORMAT_INVALID
,
478 "Section [%s] is not allowed in inf file with version 0x%08x" % (self
._SectionName
, self
._Version
),
479 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
481 # merge two lines specified by '\' in section NMAKE
482 elif self
._SectionType
== MODEL_META_DATA_NMAKE
:
485 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
488 if NextLine
[0] == TAB_SECTION_START
and NextLine
[-1] == TAB_SECTION_END
:
489 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
492 NmakeLine
= NmakeLine
+ ' ' + Line
[0:-1]
495 self
._CurrentLine
= NmakeLine
+ Line
499 self
._ValueList
= ['','','']
500 # parse current line, result will be put in self._ValueList
501 self
._SectionParser
[self
._SectionType
](self
)
502 if self
._ValueList
== None:
505 # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
506 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
508 for Arch
, Platform
in self
._Scope
:
509 self
._Store
(self
._SectionType
,
522 if IsFindBlockComment
:
523 EdkLogger
.error("Parser", FORMAT_INVALID
, "Open block comments (starting with /*) are expected to end with */",
527 ## Data parser for the format in which there's path
529 # Only path can have macro used. So we need to replace them before use.
531 def _IncludeParser(self
):
532 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
533 self
._ValueList
[0:len(TokenList
)] = TokenList
534 Macros
= self
._Macros
536 for Index
in range(0, len(self
._ValueList
)):
537 Value
= self
._ValueList
[Index
]
541 if Value
.upper().find('$(EFI_SOURCE)\Edk'.upper()) > -1 or Value
.upper().find('$(EFI_SOURCE)/Edk'.upper()) > -1:
542 Value
= '$(EDK_SOURCE)' + Value
[17:]
543 if Value
.find('$(EFI_SOURCE)') > -1 or Value
.find('$(EDK_SOURCE)') > -1:
545 elif Value
.startswith('.'):
547 elif Value
.startswith('$('):
550 Value
= '$(EFI_SOURCE)/' + Value
552 self
._ValueList
[Index
] = ReplaceMacro(Value
, Macros
)
554 ## Parse [Sources] section
556 # Only path can have macro used. So we need to replace them before use.
559 def _SourceFileParser(self
):
560 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
561 self
._ValueList
[0:len(TokenList
)] = TokenList
562 Macros
= self
._Macros
563 # For Acpi tables, remove macro like ' TABLE_NAME=Sata1'
564 if 'COMPONENT_TYPE' in Macros
:
565 if self
._Defines
['COMPONENT_TYPE'].upper() == 'ACPITABLE':
566 self
._ValueList
[0] = GetSplitValueList(self
._ValueList
[0], ' ', 1)[0]
567 if self
._Defines
['BASE_NAME'] == 'Microcode':
569 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
571 ## Parse [Binaries] section
573 # Only path can have macro used. So we need to replace them before use.
576 def _BinaryFileParser(self
):
577 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 2)
578 if len(TokenList
) < 2:
579 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type or path specified",
580 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
581 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
583 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type specified",
584 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
585 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
587 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file path specified",
588 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
589 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
590 self
._ValueList
[0:len(TokenList
)] = TokenList
591 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
593 ## [nmake] section parser (Edk.x style only)
594 def _NmakeParser(self
):
595 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
596 self
._ValueList
[0:len(TokenList
)] = TokenList
598 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
599 # remove self-reference in macro setting
600 #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
602 ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
604 def _PcdParser(self
):
605 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
606 ValueList
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
607 if len(ValueList
) != 2:
608 EdkLogger
.error('Parser', FORMAT_INVALID
, "Illegal token space GUID and PCD name format",
609 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
610 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
611 self
._ValueList
[0:1] = ValueList
612 if len(TokenList
) > 1:
613 self
._ValueList
[2] = TokenList
[1]
614 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
615 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
616 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
617 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
619 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
620 if self
._ValueList
[2] != '':
621 InfPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
622 if InfPcdValueList
[0] in ['True', 'true', 'TRUE']:
623 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '1', 1);
624 elif InfPcdValueList
[0] in ['False', 'false', 'FALSE']:
625 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '0', 1);
627 ## [depex] section parser
629 def _DepexParser(self
):
630 self
._ValueList
[0:1] = [self
._CurrentLine
]
633 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
634 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
635 MODEL_META_DATA_BUILD_OPTION
: MetaFileParser
._BuildOptionParser
,
636 MODEL_EFI_INCLUDE
: _IncludeParser
, # for Edk.x modules
637 MODEL_EFI_LIBRARY_INSTANCE
: MetaFileParser
._CommonParser
, # for Edk.x modules
638 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
639 MODEL_META_DATA_PACKAGE
: MetaFileParser
._PathParser
,
640 MODEL_META_DATA_NMAKE
: _NmakeParser
, # for Edk.x modules
641 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
642 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
643 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
644 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
645 MODEL_PCD_DYNAMIC
: _PcdParser
,
646 MODEL_EFI_SOURCE_FILE
: _SourceFileParser
,
647 MODEL_EFI_GUID
: MetaFileParser
._CommonParser
,
648 MODEL_EFI_PROTOCOL
: MetaFileParser
._CommonParser
,
649 MODEL_EFI_PPI
: MetaFileParser
._CommonParser
,
650 MODEL_EFI_DEPEX
: _DepexParser
,
651 MODEL_EFI_BINARY_FILE
: _BinaryFileParser
,
652 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
655 ## DSC file parser class
657 # @param FilePath The path of platform description file
658 # @param FileType The raw data of DSC file
659 # @param Table Database used to retrieve module/package information
660 # @param Macros Macros used for replacement in file
661 # @param Owner Owner ID (for sub-section parsing)
662 # @param From ID from which the data comes (for !INCLUDE directive)
664 class DscParser(MetaFileParser
):
665 # DSC file supported data types (one type per section)
667 TAB_SKUIDS
.upper() : MODEL_EFI_SKU_ID
,
668 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
669 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
670 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
671 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
672 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
673 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
674 TAB_PCDS_DYNAMIC_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_DEFAULT
,
675 TAB_PCDS_DYNAMIC_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_HII
,
676 TAB_PCDS_DYNAMIC_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_VPD
,
677 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT
,
678 TAB_PCDS_DYNAMIC_EX_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_HII
,
679 TAB_PCDS_DYNAMIC_EX_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_VPD
,
680 TAB_COMPONENTS
.upper() : MODEL_META_DATA_COMPONENT
,
681 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
.upper() : MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
,
682 TAB_DSC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
683 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
684 TAB_DSC_DEFINES_EDKGLOBAL
: MODEL_META_DATA_GLOBAL_DEFINE
,
685 TAB_INCLUDE
.upper() : MODEL_META_DATA_INCLUDE
,
686 TAB_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
687 TAB_IF_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
688 TAB_IF_N_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
,
689 TAB_ELSE_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
,
690 TAB_ELSE
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
,
691 TAB_END_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
,
694 # Valid names in define section
701 "SUPPORTED_ARCHITECTURES",
710 "FIX_LOAD_TOP_MEMORY_ADDRESS"
713 SymbolPattern
= ValueExpression
.SymbolPattern
715 ## Constructor of DscParser
717 # Initialize object of DscParser
719 # @param FilePath The path of platform description file
720 # @param FileType The raw data of DSC file
721 # @param Table Database used to retrieve module/package information
722 # @param Macros Macros used for replacement in file
723 # @param Owner Owner ID (for sub-section parsing)
724 # @param From ID from which the data comes (for !INCLUDE directive)
726 def __init__(self
, FilePath
, FileType
, Table
, Owner
=-1, From
=-1):
727 # prevent re-initialization
728 if hasattr(self
, "_Table"):
730 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
, Owner
, From
)
731 self
._Version
= 0x00010005 # Only EDK2 dsc file is supported
732 # to store conditional directive evaluation result
733 self
._DirectiveStack
= []
734 self
._DirectiveEvalStack
= []
737 # Final valid replacable symbols
740 # Map the ID between the original table and new table to track
743 self
._IdMapping
= {-1:-1}
749 Content
= open(str(self
.MetaFile
), 'r').readlines()
751 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
753 for Index
in range(0, len(Content
)):
754 Line
= CleanString(Content
[Index
])
759 self
._CurrentLine
= Line
760 self
._LineIndex
= Index
761 if self
._InSubsection
and self
._Owner
[-1] == -1:
762 self
._Owner
.append(self
._LastItem
)
765 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
766 self
._SectionType
= MODEL_META_DATA_SECTION_HEADER
768 elif Line
[0] == '}' and self
._InSubsection
:
769 self
._InSubsection
= False
770 self
._SubsectionType
= MODEL_UNKNOWN
771 self
._SubsectionName
= ''
775 elif Line
[0] == TAB_OPTION_START
and Line
[-1] == TAB_OPTION_END
:
776 self
._SubsectionType
= MODEL_META_DATA_SUBSECTION_HEADER
779 self
._DirectiveParser
()
782 if self
._InSubsection
:
783 SectionType
= self
._SubsectionType
785 SectionType
= self
._SectionType
786 self
._ItemType
= SectionType
788 self
._ValueList
= ['', '', '']
789 self
._SectionParser
[SectionType
](self
)
790 if self
._ValueList
== None:
793 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
794 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
796 for Arch
, ModuleType
in self
._Scope
:
797 self
._LastItem
= self
._Store
(
813 if self
._DirectiveStack
:
814 Type
, Line
, Text
= self
._DirectiveStack
[-1]
815 EdkLogger
.error('Parser', FORMAT_INVALID
, "No matching '!endif' found",
816 ExtraData
=Text
, File
=self
.MetaFile
, Line
=Line
)
819 ## <subsection_header> parser
820 def _SubsectionHeaderParser(self
):
821 self
._SubsectionName
= self
._CurrentLine
[1:-1].upper()
822 if self
._SubsectionName
in self
.DataType
:
823 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
825 self
._SubsectionType
= MODEL_UNKNOWN
826 EdkLogger
.warn("Parser", "Unrecognized sub-section", File
=self
.MetaFile
,
827 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
828 self
._ValueList
[0] = self
._SubsectionName
830 ## Directive statement parser
831 def _DirectiveParser(self
):
832 self
._ValueList
= ['','','']
833 TokenList
= GetSplitValueList(self
._CurrentLine
, ' ', 1)
834 self
._ValueList
[0:len(TokenList
)] = TokenList
837 DirectiveName
= self
._ValueList
[0].upper()
838 if DirectiveName
not in self
.DataType
:
839 EdkLogger
.error("Parser", FORMAT_INVALID
, "Unknown directive [%s]" % DirectiveName
,
840 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
841 if DirectiveName
in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self
._ValueList
[1] == '':
842 EdkLogger
.error("Parser", FORMAT_INVALID
, "Missing expression",
843 File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
844 ExtraData
=self
._CurrentLine
)
846 ItemType
= self
.DataType
[DirectiveName
]
847 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
848 # Remove all directives between !if and !endif, including themselves
849 while self
._DirectiveStack
:
850 # Remove any !else or !elseif
851 DirectiveInfo
= self
._DirectiveStack
.pop()
852 if DirectiveInfo
[0] in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
853 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
854 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
857 EdkLogger
.error("Parser", FORMAT_INVALID
, "Redundant '!endif'",
858 File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
859 ExtraData
=self
._CurrentLine
)
860 elif ItemType
!= MODEL_META_DATA_INCLUDE
:
861 # Break if there's a !else is followed by a !elseif
862 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
and \
863 self
._DirectiveStack
and \
864 self
._DirectiveStack
[-1][0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
865 EdkLogger
.error("Parser", FORMAT_INVALID
, "'!elseif' after '!else'",
866 File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
867 ExtraData
=self
._CurrentLine
)
868 self
._DirectiveStack
.append((ItemType
, self
._LineIndex
+1, self
._CurrentLine
))
870 EdkLogger
.error('Parser', FORMAT_INVALID
,
871 "No '!include' allowed in included file",
872 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
,
873 Line
=self
._LineIndex
+1)
876 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
877 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
879 self
._LastItem
= self
._Store
(
895 ## [defines] section parser
897 def _DefineParser(self
):
898 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
899 self
._ValueList
[1:len(TokenList
)] = TokenList
902 if not self
._ValueList
[1]:
903 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
904 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
905 if not self
._ValueList
[2]:
906 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
907 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
908 if not self
._ValueList
[1] in self
.DefineKeywords
:
909 EdkLogger
.error('Parser', FORMAT_INVALID
,
910 "Unknown keyword found: %s. "
911 "If this is a macro you must "
912 "add it as a DEFINE in the DSC" % self
._ValueList
[1],
913 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
914 self
._Defines
[self
._ValueList
[1]] = self
._ValueList
[2]
915 self
._ItemType
= self
.DataType
[TAB_DSC_DEFINES
.upper()]
918 def _SkuIdParser(self
):
919 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
920 if len(TokenList
) != 2:
921 EdkLogger
.error('Parser', FORMAT_INVALID
, "Correct format is '<Integer>|<UiName>'",
922 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
923 self
._ValueList
[0:len(TokenList
)] = TokenList
925 ## Parse Edk style of library modules
926 def _LibraryInstanceParser(self
):
927 self
._ValueList
[0] = self
._CurrentLine
929 ## PCD sections parser
932 # [PcdsPatchableInModule]
935 # [PcdsDynamicExDefault]
939 # [PcdsDynamicDefault]
944 def _PcdParser(self
):
945 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
946 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
947 if len(TokenList
) == 2:
948 self
._ValueList
[2] = TokenList
[1]
949 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
950 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
951 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
952 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
953 if self
._ValueList
[2] == '':
954 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD value given",
955 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
956 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
957 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
958 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
959 if DscPcdValueList
[0] in ['True', 'true', 'TRUE']:
960 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '1', 1);
961 elif DscPcdValueList
[0] in ['False', 'false', 'FALSE']:
962 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '0', 1);
964 ## [components] section parser
966 def _ComponentParser(self
):
967 if self
._CurrentLine
[-1] == '{':
968 self
._ValueList
[0] = self
._CurrentLine
[0:-1].strip()
969 self
._InSubsection
= True
971 self
._ValueList
[0] = self
._CurrentLine
973 ## [LibraryClasses] section
975 def _LibraryClassParser(self
):
976 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
977 if len(TokenList
) < 2:
978 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class or instance specified",
979 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
980 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
981 if TokenList
[0] == '':
982 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class specified",
983 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
984 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
985 if TokenList
[1] == '':
986 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library instance specified",
987 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
988 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
990 self
._ValueList
[0:len(TokenList
)] = TokenList
992 def _CompponentSourceOverridePathParser(self
):
993 self
._ValueList
[0] = self
._CurrentLine
995 ## [BuildOptions] section parser
997 def _BuildOptionParser(self
):
998 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
999 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
1000 if len(TokenList2
) == 2:
1001 self
._ValueList
[0] = TokenList2
[0] # toolchain family
1002 self
._ValueList
[1] = TokenList2
[1] # keys
1004 self
._ValueList
[1] = TokenList
[0]
1005 if len(TokenList
) == 2: # value
1006 self
._ValueList
[2] = TokenList
[1]
1008 if self
._ValueList
[1].count('_') != 4:
1012 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
1013 ExtraData
=self
._CurrentLine
,
1015 Line
=self
._LineIndex
+1
1018 ## Override parent's method since we'll do all macro replacements in parser
1019 def _GetMacros(self
):
1021 Macros
.update(self
._FileLocalMacros
)
1022 Macros
.update(self
._GetApplicableSectionMacro
())
1023 Macros
.update(GlobalData
.gEdkGlobal
)
1024 Macros
.update(GlobalData
.gPlatformDefines
)
1025 Macros
.update(GlobalData
.gCommandLineDefines
)
1026 # PCD cannot be referenced in macro definition
1027 if self
._ItemType
not in [MODEL_META_DATA_DEFINE
, MODEL_META_DATA_GLOBAL_DEFINE
]:
1028 Macros
.update(self
._Symbols
)
1031 def _PostProcess(self
):
1033 MODEL_META_DATA_SECTION_HEADER
: self
.__ProcessSectionHeader
,
1034 MODEL_META_DATA_SUBSECTION_HEADER
: self
.__ProcessSubsectionHeader
,
1035 MODEL_META_DATA_HEADER
: self
.__ProcessDefine
,
1036 MODEL_META_DATA_DEFINE
: self
.__ProcessDefine
,
1037 MODEL_META_DATA_GLOBAL_DEFINE
: self
.__ProcessDefine
,
1038 MODEL_META_DATA_INCLUDE
: self
.__ProcessDirective
,
1039 MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
: self
.__ProcessDirective
,
1040 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
: self
.__ProcessDirective
,
1041 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
: self
.__ProcessDirective
,
1042 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
: self
.__ProcessDirective
,
1043 MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
: self
.__ProcessDirective
,
1044 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
: self
.__ProcessDirective
,
1045 MODEL_EFI_SKU_ID
: self
.__ProcessSkuId
,
1046 MODEL_EFI_LIBRARY_INSTANCE
: self
.__ProcessLibraryInstance
,
1047 MODEL_EFI_LIBRARY_CLASS
: self
.__ProcessLibraryClass
,
1048 MODEL_PCD_FIXED_AT_BUILD
: self
.__ProcessPcd
,
1049 MODEL_PCD_PATCHABLE_IN_MODULE
: self
.__ProcessPcd
,
1050 MODEL_PCD_FEATURE_FLAG
: self
.__ProcessPcd
,
1051 MODEL_PCD_DYNAMIC_DEFAULT
: self
.__ProcessPcd
,
1052 MODEL_PCD_DYNAMIC_HII
: self
.__ProcessPcd
,
1053 MODEL_PCD_DYNAMIC_VPD
: self
.__ProcessPcd
,
1054 MODEL_PCD_DYNAMIC_EX_DEFAULT
: self
.__ProcessPcd
,
1055 MODEL_PCD_DYNAMIC_EX_HII
: self
.__ProcessPcd
,
1056 MODEL_PCD_DYNAMIC_EX_VPD
: self
.__ProcessPcd
,
1057 MODEL_META_DATA_COMPONENT
: self
.__ProcessComponent
,
1058 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: self
.__ProcessSourceOverridePath
,
1059 MODEL_META_DATA_BUILD_OPTION
: self
.__ProcessBuildOption
,
1060 MODEL_UNKNOWN
: self
._Skip
,
1061 MODEL_META_DATA_USER_EXTENSION
: self
._Skip
,
1064 self
._Table
= MetaFileStorage(self
._RawTable
.Cur
, self
.MetaFile
, MODEL_FILE_DSC
, True)
1065 self
._Table
.Create()
1066 self
._DirectiveStack
= []
1067 self
._DirectiveEvalStack
= []
1068 self
._FileWithError
= self
.MetaFile
1069 self
._FileLocalMacros
= {}
1070 self
._SectionsMacroDict
= {}
1071 GlobalData
.gPlatformDefines
= {}
1073 # Get all macro and PCD which has straitforward value
1074 self
.__RetrievePcdValue
()
1075 self
._Content
= self
._RawTable
.GetAll()
1076 self
._ContentIndex
= 0
1077 while self
._ContentIndex
< len(self
._Content
) :
1078 Id
, self
._ItemType
, V1
, V2
, V3
, S1
, S2
, Owner
, self
._From
, \
1079 LineStart
, ColStart
, LineEnd
, ColEnd
, Enabled
= self
._Content
[self
._ContentIndex
]
1082 self
._FileWithError
= self
.MetaFile
1084 self
._ContentIndex
+= 1
1086 self
._Scope
= [[S1
, S2
]]
1087 self
._LineIndex
= LineStart
- 1
1088 self
._ValueList
= [V1
, V2
, V3
]
1091 Processer
[self
._ItemType
]()
1092 except EvaluationException
, Excpt
:
1094 # Only catch expression evaluation error here. We need to report
1095 # the precise number of line on which the error occurred
1097 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
1098 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1099 Line
=self
._LineIndex
+1)
1100 except MacroException
, Excpt
:
1101 EdkLogger
.error('Parser', FORMAT_INVALID
, str(Excpt
),
1102 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1103 Line
=self
._LineIndex
+1)
1105 if self
._ValueList
== None:
1108 NewOwner
= self
._IdMapping
.get(Owner
, -1)
1109 self
._Enabled
= int((not self
._DirectiveEvalStack
) or (False not in self
._DirectiveEvalStack
))
1110 self
._LastItem
= self
._Store
(
1125 self
._IdMapping
[Id
] = self
._LastItem
1127 GlobalData
.gPlatformDefines
.update(self
._FileLocalMacros
)
1128 self
._PostProcessed
= True
1129 self
._Content
= None
1131 def __ProcessSectionHeader(self
):
1132 self
._SectionName
= self
._ValueList
[0]
1133 if self
._SectionName
in self
.DataType
:
1134 self
._SectionType
= self
.DataType
[self
._SectionName
]
1136 self
._SectionType
= MODEL_UNKNOWN
1138 def __ProcessSubsectionHeader(self
):
1139 self
._SubsectionName
= self
._ValueList
[0]
1140 if self
._SubsectionName
in self
.DataType
:
1141 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
1143 self
._SubsectionType
= MODEL_UNKNOWN
1145 def __RetrievePcdValue(self
):
1146 Records
= self
._RawTable
.Query(MODEL_PCD_FEATURE_FLAG
, BelongsToItem
=-1.0)
1147 for TokenSpaceGuid
,PcdName
,Value
,Dummy2
,Dummy3
,ID
,Line
in Records
:
1148 Value
, DatumType
, MaxDatumSize
= AnalyzePcdData(Value
)
1149 # Only use PCD whose value is straitforward (no macro and PCD)
1150 if self
.SymbolPattern
.findall(Value
):
1152 Name
= TokenSpaceGuid
+ '.' + PcdName
1153 # Don't use PCD with different values.
1154 if Name
in self
._Symbols
and self
._Symbols
[Name
] != Value
:
1155 self
._Symbols
.pop(Name
)
1157 self
._Symbols
[Name
] = Value
1159 Records
= self
._RawTable
.Query(MODEL_PCD_FIXED_AT_BUILD
, BelongsToItem
=-1.0)
1160 for TokenSpaceGuid
,PcdName
,Value
,Dummy2
,Dummy3
,ID
,Line
in Records
:
1161 Value
, DatumType
, MaxDatumSize
= AnalyzePcdData(Value
)
1162 # Only use PCD whose value is straitforward (no macro and PCD)
1163 if self
.SymbolPattern
.findall(Value
):
1165 Name
= TokenSpaceGuid
+'.'+PcdName
1166 # Don't use PCD with different values.
1167 if Name
in self
._Symbols
and self
._Symbols
[Name
] != Value
:
1168 self
._Symbols
.pop(Name
)
1170 self
._Symbols
[Name
] = Value
1172 def __ProcessDefine(self
):
1173 if not self
._Enabled
:
1176 Type
, Name
, Value
= self
._ValueList
1177 Value
= ReplaceMacro(Value
, self
._Macros
, False)
1178 if self
._ItemType
== MODEL_META_DATA_DEFINE
:
1179 if self
._SectionType
== MODEL_META_DATA_HEADER
:
1180 self
._FileLocalMacros
[Name
] = Value
1182 SectionDictKey
= self
._SectionType
, self
._Scope
[0][0], self
._Scope
[0][1]
1183 if SectionDictKey
not in self
._SectionsMacroDict
:
1184 self
._SectionsMacroDict
[SectionDictKey
] = {}
1185 SectionLocalMacros
= self
._SectionsMacroDict
[SectionDictKey
]
1186 SectionLocalMacros
[Name
] = Value
1187 elif self
._ItemType
== MODEL_META_DATA_GLOBAL_DEFINE
:
1188 GlobalData
.gEdkGlobal
[Name
] = Value
1191 # Keyword in [Defines] section can be used as Macros
1193 if (self
._ItemType
== MODEL_META_DATA_HEADER
) and (self
._SectionType
== MODEL_META_DATA_HEADER
):
1194 self
._FileLocalMacros
[Name
] = Value
1196 self
._ValueList
= [Type
, Name
, Value
]
1198 def __ProcessDirective(self
):
1200 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1201 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
]:
1202 Macros
= self
._Macros
1203 Macros
.update(GlobalData
.gGlobalDefines
)
1205 Result
= ValueExpression(self
._ValueList
[1], Macros
)()
1206 except SymbolNotFound
, Exc
:
1207 EdkLogger
.debug(EdkLogger
.DEBUG_5
, str(Exc
), self
._ValueList
[1])
1209 except WrnExpression
, Excpt
:
1211 # Catch expression evaluation warning here. We need to report
1212 # the precise number of line and return the evaluation result
1214 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
1215 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1216 Line
=self
._LineIndex
+1)
1217 Result
= Excpt
.result
1219 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1220 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1221 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1222 self
._DirectiveStack
.append(self
._ItemType
)
1223 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
:
1224 Result
= bool(Result
)
1226 Macro
= self
._ValueList
[1]
1227 Macro
= Macro
[2:-1] if (Macro
.startswith("$(") and Macro
.endswith(")")) else Macro
1228 Result
= Macro
in self
._Macros
1229 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
:
1231 self
._DirectiveEvalStack
.append(Result
)
1232 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
:
1233 self
._DirectiveStack
.append(self
._ItemType
)
1234 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1235 self
._DirectiveEvalStack
.append(bool(Result
))
1236 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1237 self
._DirectiveStack
[-1] = self
._ItemType
1238 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1239 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1240 # Back to the nearest !if/!ifdef/!ifndef
1241 while self
._DirectiveStack
:
1242 self
._DirectiveEvalStack
.pop()
1243 Directive
= self
._DirectiveStack
.pop()
1244 if Directive
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1245 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1246 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
,
1247 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1249 elif self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1250 # The included file must be relative to workspace or same directory as DSC file
1251 __IncludeMacros
= {}
1253 # Allow using system environment variables in path after !include
1255 __IncludeMacros
['WORKSPACE'] = GlobalData
.gGlobalDefines
['WORKSPACE']
1256 if "ECP_SOURCE" in GlobalData
.gGlobalDefines
.keys():
1257 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gGlobalDefines
['ECP_SOURCE']
1259 # During GenFds phase call DSC parser, will go into this branch.
1261 elif "ECP_SOURCE" in GlobalData
.gCommandLineDefines
.keys():
1262 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gCommandLineDefines
['ECP_SOURCE']
1264 __IncludeMacros
['EFI_SOURCE'] = GlobalData
.gGlobalDefines
['EFI_SOURCE']
1265 __IncludeMacros
['EDK_SOURCE'] = GlobalData
.gGlobalDefines
['EDK_SOURCE']
1267 # Allow using MACROs comes from [Defines] section to keep compatible.
1269 __IncludeMacros
.update(self
._Macros
)
1271 IncludedFile
= NormPath(ReplaceMacro(self
._ValueList
[1], __IncludeMacros
, RaiseError
=True))
1273 # First search the include file under the same directory as DSC file
1275 IncludedFile1
= PathClass(IncludedFile
, self
.MetaFile
.Dir
)
1276 ErrorCode
, ErrorInfo1
= IncludedFile1
.Validate()
1279 # Also search file under the WORKSPACE directory
1281 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
1282 ErrorCode
, ErrorInfo2
= IncludedFile1
.Validate()
1284 EdkLogger
.error('parser', ErrorCode
, File
=self
._FileWithError
,
1285 Line
=self
._LineIndex
+1, ExtraData
=ErrorInfo1
+ "\n"+ ErrorInfo2
)
1287 self
._FileWithError
= IncludedFile1
1289 IncludedFileTable
= MetaFileStorage(self
._Table
.Cur
, IncludedFile1
, MODEL_FILE_DSC
, False)
1290 Owner
= self
._Content
[self
._ContentIndex
-1][0]
1291 Parser
= DscParser(IncludedFile1
, self
._FileType
, IncludedFileTable
,
1292 Owner
=Owner
, From
=Owner
)
1294 # set the parser status with current status
1295 Parser
._SectionName
= self
._SectionName
1296 Parser
._SectionType
= self
._SectionType
1297 Parser
._Scope
= self
._Scope
1298 Parser
._Enabled
= self
._Enabled
1299 # Parse the included file
1302 # update current status with sub-parser's status
1303 self
._SectionName
= Parser
._SectionName
1304 self
._SectionType
= Parser
._SectionType
1305 self
._Scope
= Parser
._Scope
1306 self
._Enabled
= Parser
._Enabled
1308 # Insert all records in the table for the included file into dsc file table
1309 Records
= IncludedFileTable
.GetAll()
1311 self
._Content
[self
._ContentIndex
:self
._ContentIndex
] = Records
1312 self
._Content
.pop(self
._ContentIndex
-1)
1313 self
._ValueList
= None
1314 self
._ContentIndex
-= 1
1316 def __ProcessSkuId(self
):
1317 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=True)
1318 for Value
in self
._ValueList
]
1320 def __ProcessLibraryInstance(self
):
1321 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
1323 def __ProcessLibraryClass(self
):
1324 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
, RaiseError
=True)
1326 def __ProcessPcd(self
):
1327 ValueList
= GetSplitValueList(self
._ValueList
[2])
1328 if len(ValueList
) > 1 and ValueList
[1] == 'VOID*':
1329 PcdValue
= ValueList
[0]
1330 ValueList
[0] = ReplaceMacro(PcdValue
, self
._Macros
)
1332 PcdValue
= ValueList
[-1]
1333 ValueList
[-1] = ReplaceMacro(PcdValue
, self
._Macros
)
1335 self
._ValueList
[2] = '|'.join(ValueList
)
1337 def __ProcessComponent(self
):
1338 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1340 def __ProcessSourceOverridePath(self
):
1341 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1343 def __ProcessBuildOption(self
):
1344 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=False)
1345 for Value
in self
._ValueList
]
1348 MODEL_META_DATA_HEADER
: _DefineParser
,
1349 MODEL_EFI_SKU_ID
: _SkuIdParser
,
1350 MODEL_EFI_LIBRARY_INSTANCE
: _LibraryInstanceParser
,
1351 MODEL_EFI_LIBRARY_CLASS
: _LibraryClassParser
,
1352 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1353 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1354 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1355 MODEL_PCD_DYNAMIC_DEFAULT
: _PcdParser
,
1356 MODEL_PCD_DYNAMIC_HII
: _PcdParser
,
1357 MODEL_PCD_DYNAMIC_VPD
: _PcdParser
,
1358 MODEL_PCD_DYNAMIC_EX_DEFAULT
: _PcdParser
,
1359 MODEL_PCD_DYNAMIC_EX_HII
: _PcdParser
,
1360 MODEL_PCD_DYNAMIC_EX_VPD
: _PcdParser
,
1361 MODEL_META_DATA_COMPONENT
: _ComponentParser
,
1362 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: _CompponentSourceOverridePathParser
,
1363 MODEL_META_DATA_BUILD_OPTION
: _BuildOptionParser
,
1364 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1365 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
1366 MODEL_META_DATA_SECTION_HEADER
: MetaFileParser
._SectionHeaderParser
,
1367 MODEL_META_DATA_SUBSECTION_HEADER
: _SubsectionHeaderParser
,
1370 _Macros
= property(_GetMacros
)
1372 ## DEC file parser class
1374 # @param FilePath The path of platform description file
1375 # @param FileType The raw data of DSC file
1376 # @param Table Database used to retrieve module/package information
1377 # @param Macros Macros used for replacement in file
1379 class DecParser(MetaFileParser
):
1380 # DEC file supported data types (one type per section)
1382 TAB_DEC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
1383 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
1384 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
1385 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
1386 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
1387 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
1388 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
1389 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
1390 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
1391 TAB_PCDS_DYNAMIC_NULL
.upper() : MODEL_PCD_DYNAMIC
,
1392 TAB_PCDS_DYNAMIC_EX_NULL
.upper() : MODEL_PCD_DYNAMIC_EX
,
1395 ## Constructor of DecParser
1397 # Initialize object of DecParser
1399 # @param FilePath The path of platform description file
1400 # @param FileType The raw data of DSC file
1401 # @param Table Database used to retrieve module/package information
1402 # @param Macros Macros used for replacement in file
1404 def __init__(self
, FilePath
, FileType
, Table
):
1405 # prevent re-initialization
1406 if hasattr(self
, "_Table"):
1408 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
, -1)
1410 self
._Version
= 0x00010005 # Only EDK2 dec file is supported
1416 Content
= open(str(self
.MetaFile
), 'r').readlines()
1418 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
1420 for Index
in range(0, len(Content
)):
1421 Line
, Comment
= CleanString2(Content
[Index
])
1422 self
._CurrentLine
= Line
1423 self
._LineIndex
= Index
1425 # save comment for later use
1427 self
._Comments
.append((Comment
, self
._LineIndex
+1))
1433 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
1434 self
._SectionHeaderParser
()
1437 elif len(self
._SectionType
) == 0:
1442 self
._ValueList
= ['','','']
1443 self
._SectionParser
[self
._SectionType
[0]](self
)
1444 if self
._ValueList
== None:
1449 # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,
1450 # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1
1452 for Arch
, ModuleType
, Type
in self
._Scope
:
1453 self
._LastItem
= self
._Store
(
1467 for Comment
, LineNo
in self
._Comments
:
1469 MODEL_META_DATA_COMMENT
,
1485 ## Section header parser
1487 # The section header is always in following format:
1489 # [section_name.arch<.platform|module_type>]
1491 def _SectionHeaderParser(self
):
1493 self
._SectionName
= ''
1494 self
._SectionType
= []
1496 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
1499 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
)
1501 # different types of PCD are permissible in one section
1502 self
._SectionName
= ItemList
[0].upper()
1503 if self
._SectionName
in self
.DataType
:
1504 if self
.DataType
[self
._SectionName
] not in self
._SectionType
:
1505 self
._SectionType
.append(self
.DataType
[self
._SectionName
])
1507 EdkLogger
.warn("Parser", "Unrecognized section", File
=self
.MetaFile
,
1508 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
1511 if MODEL_PCD_FEATURE_FLAG
in self
._SectionType
and len(self
._SectionType
) > 1:
1515 "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL
,
1517 Line
=self
._LineIndex
+1,
1518 ExtraData
=self
._CurrentLine
1521 if len(ItemList
) > 1:
1522 S1
= ItemList
[1].upper()
1526 # S2 may be Platform or ModuleType
1527 if len(ItemList
) > 2:
1528 S2
= ItemList
[2].upper()
1531 if [S1
, S2
, self
.DataType
[self
._SectionName
]] not in self
._Scope
:
1532 self
._Scope
.append([S1
, S2
, self
.DataType
[self
._SectionName
]])
1534 # 'COMMON' must not be used with specific ARCHs at the same section
1535 if 'COMMON' in ArchList
and len(ArchList
) > 1:
1536 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
1537 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
1539 ## [guids], [ppis] and [protocols] section parser
1541 def _GuidParser(self
):
1542 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1543 if len(TokenList
) < 2:
1544 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name or value specified",
1545 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1546 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1547 if TokenList
[0] == '':
1548 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name specified",
1549 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1550 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1551 if TokenList
[1] == '':
1552 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID value specified",
1553 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1554 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1555 if TokenList
[1][0] != '{' or TokenList
[1][-1] != '}' or GuidStructureStringToGuidString(TokenList
[1]) == '':
1556 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid GUID value format",
1557 ExtraData
=self
._CurrentLine
+ \
1558 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
1559 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1560 self
._ValueList
[0] = TokenList
[0]
1561 self
._ValueList
[1] = TokenList
[1]
1563 ## PCD sections parser
1565 # [PcdsFixedAtBuild]
1566 # [PcdsPatchableInModule]
1572 def _PcdParser(self
):
1573 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1574 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1575 # check PCD information
1576 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1577 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1578 ExtraData
=self
._CurrentLine
+ \
1579 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1580 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1581 # check PCD datum information
1582 if len(TokenList
) < 2 or TokenList
[1] == '':
1583 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD Datum information given",
1584 ExtraData
=self
._CurrentLine
+ \
1585 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1586 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1589 ValueRe
= re
.compile(r
'^\s*L?\".*\|.*\"')
1590 PtrValue
= ValueRe
.findall(TokenList
[1])
1592 # Has VOID* type string, may contain "|" character in the string.
1593 if len(PtrValue
) != 0:
1594 ptrValueList
= re
.sub(ValueRe
, '', TokenList
[1])
1595 ValueList
= GetSplitValueList(ptrValueList
)
1596 ValueList
[0] = PtrValue
[0]
1598 ValueList
= GetSplitValueList(TokenList
[1])
1601 # check if there's enough datum information given
1602 if len(ValueList
) != 3:
1603 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid PCD Datum information given",
1604 ExtraData
=self
._CurrentLine
+ \
1605 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1606 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1607 # check default value
1608 if ValueList
[0] == '':
1609 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DefaultValue in PCD Datum information",
1610 ExtraData
=self
._CurrentLine
+ \
1611 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1612 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1614 if ValueList
[1] == '':
1615 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DatumType in PCD Datum information",
1616 ExtraData
=self
._CurrentLine
+ \
1617 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1618 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1619 # check token of the PCD
1620 if ValueList
[2] == '':
1621 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing Token in PCD Datum information",
1622 ExtraData
=self
._CurrentLine
+ \
1623 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1624 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1625 # check format of default value against the datum type
1626 IsValid
, Cause
= CheckPcdDatum(ValueList
[1], ValueList
[0])
1628 EdkLogger
.error('Parser', FORMAT_INVALID
, Cause
, ExtraData
=self
._CurrentLine
,
1629 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1631 if ValueList
[0] in ['True', 'true', 'TRUE']:
1633 elif ValueList
[0] in ['False', 'false', 'FALSE']:
1636 self
._ValueList
[2] = ValueList
[0].strip() + '|' + ValueList
[1].strip() + '|' + ValueList
[2].strip()
1639 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
1640 MODEL_EFI_INCLUDE
: MetaFileParser
._PathParser
,
1641 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
1642 MODEL_EFI_GUID
: _GuidParser
,
1643 MODEL_EFI_PPI
: _GuidParser
,
1644 MODEL_EFI_PROTOCOL
: _GuidParser
,
1645 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1646 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1647 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1648 MODEL_PCD_DYNAMIC
: _PcdParser
,
1649 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
1650 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1651 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
1656 # This acts like the main() function for the script, unless it is 'import'ed into another
1659 if __name__
== '__main__':