2 # This file is used to parse meta files
4 # Copyright (c) 2008, Intel Corporation
5 # All rights reserved. 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.
21 import Common
.EdkLogger
as EdkLogger
22 from CommonDataClass
.DataClass
import *
23 from Common
.DataType
import *
24 from Common
.String
import *
25 from Common
.Misc
import Blist
, GuidStructureStringToGuidString
, CheckPcdDatum
27 ## Base class of parser
29 # This class is used for derivation purpose. The specific parser for one kind
30 # type file must derive this class and implement some public interfaces.
32 # @param FilePath The path of platform description file
33 # @param FileType The raw data of DSC file
34 # @param Table Database used to retrieve module/package information
35 # @param Macros Macros used for replacement in file
36 # @param Owner Owner ID (for sub-section parsing)
37 # @param From ID from which the data comes (for !INCLUDE directive)
39 class MetaFileParser(object):
40 # data type (file content) for specific file type
43 ## Constructor of MetaFileParser
45 # Initialize object of MetaFileParser
47 # @param FilePath The path of platform description file
48 # @param FileType The raw data of DSC file
49 # @param Table Database used to retrieve module/package information
50 # @param Macros Macros used for replacement in file
51 # @param Owner Owner ID (for sub-section parsing)
52 # @param From ID from which the data comes (for !INCLUDE directive)
54 def __init__(self
, FilePath
, FileType
, Table
, Macros
=None, Owner
=-1, From
=-1):
56 self
._FileType
= FileType
57 self
.MetaFile
= FilePath
58 self
._FileDir
= os
.path
.dirname(self
.MetaFile
)
59 self
._Macros
= copy
.copy(Macros
)
61 # for recursive parsing
65 # parsr status for parsing
67 self
._ValueList
= ['', '', '', '', '']
70 self
._CurrentLine
= ''
71 self
._SectionType
= MODEL_UNKNOWN
72 self
._SectionName
= ''
73 self
._InSubsection
= False
74 self
._SubsectionType
= MODEL_UNKNOWN
75 self
._SubsectionName
= ''
78 self
._Finished
= False
80 ## Store the parsed data in table
81 def _Store(self
, *Args
):
82 return self
._Table
.Insert(*Args
)
84 ## Virtual method for starting parse
86 raise NotImplementedError
88 ## Set parsing complete flag in both class and table
91 ## Do not set end flag when processing included files
93 self
._Table
.SetEndFlag()
95 ## Return the table containg parsed data
97 # If the parse complete flag is not set, this method will try to parse the
98 # file before return the table
101 if not self
._Finished
:
105 ## Get the parse complete flag
106 def _GetFinished(self
):
107 return self
._Finished
109 ## Set the complete flag
110 def _SetFinished(self
, Value
):
111 self
._Finished
= Value
113 ## Use [] style to query data in table, just for readability
115 # DataInfo = [data_type, scope1(arch), scope2(platform,moduletype)]
117 def __getitem__(self
, DataInfo
):
118 if type(DataInfo
) != type(()):
119 DataInfo
= (DataInfo
,)
120 return self
.Table
.Query(*DataInfo
)
122 ## Data parser for the common format in different type of file
124 # The common format in the meatfile is like
128 def _CommonParser(self
):
129 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
130 self
._ValueList
[0:len(TokenList
)] = TokenList
132 ## Data parser for the format in which there's path
134 # Only path can have macro used. So we need to replace them before use.
136 def _PathParser(self
):
137 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
138 self
._ValueList
[0:len(TokenList
)] = TokenList
139 if len(self
._Macros
) > 0:
140 for Index
in range(0, len(self
._ValueList
)):
141 Value
= self
._ValueList
[Index
]
142 if Value
== None or Value
== '':
144 self
._ValueList
[Index
] = NormPath(Value
, self
._Macros
)
146 ## Skip unsupported data
148 EdkLogger
.warn("Parser", "Unrecognized content", File
=self
.MetaFile
,
149 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
);
150 self
._ValueList
[0:1] = [self
._CurrentLine
]
152 ## Section header parser
154 # The section header is always in following format:
156 # [section_name.arch<.platform|module_type>]
158 def _SectionHeaderParser(self
):
160 self
._SectionName
= ''
162 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
165 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
)
166 # different section should not mix in one section
167 if self
._SectionName
!= '' and self
._SectionName
!= ItemList
[0].upper():
168 EdkLogger
.error('Parser', FORMAT_INVALID
, "Different section names in the same section",
169 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
170 self
._SectionName
= ItemList
[0].upper()
171 if self
._SectionName
in self
.DataType
:
172 self
._SectionType
= self
.DataType
[self
._SectionName
]
174 self
._SectionType
= MODEL_UNKNOWN
175 EdkLogger
.warn("Parser", "Unrecognized section", File
=self
.MetaFile
,
176 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
178 if len(ItemList
) > 1:
179 S1
= ItemList
[1].upper()
183 # S2 may be Platform or ModuleType
184 if len(ItemList
) > 2:
185 S2
= ItemList
[2].upper()
188 self
._Scope
.append([S1
, S2
])
190 # 'COMMON' must not be used with specific ARCHs at the same section
191 if 'COMMON' in ArchList
and len(ArchList
) > 1:
192 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
193 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
195 ## [defines] section parser
196 def _DefineParser(self
):
197 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
198 self
._ValueList
[0:len(TokenList
)] = TokenList
199 if self
._ValueList
[1] == '':
200 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
201 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
203 ## DEFINE name=value parser
204 def _MacroParser(self
):
205 TokenList
= GetSplitValueList(self
._CurrentLine
, ' ', 1)
206 MacroType
= TokenList
[0]
207 if len(TokenList
) < 2 or TokenList
[1] == '':
208 EdkLogger
.error('Parser', FORMAT_INVALID
, "No macro name/value given",
209 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
210 TokenList
= GetSplitValueList(TokenList
[1], TAB_EQUAL_SPLIT
, 1)
211 if TokenList
[0] == '':
212 EdkLogger
.error('Parser', FORMAT_INVALID
, "No macro name given",
213 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
215 # Macros defined in the command line override ones defined in the meta-data file
216 if not TokenList
[0] in self
._Macros
:
217 if len(TokenList
) == 1:
218 self
._Macros
[TokenList
[0]] = ''
220 # keep the macro definition for later use
221 self
._Macros
[TokenList
[0]] = ReplaceMacro(TokenList
[1], self
._Macros
, False)
223 return TokenList
[0], self
._Macros
[TokenList
[0]]
225 ## [BuildOptions] section parser
226 def _BuildOptionParser(self
):
227 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
228 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
229 if len(TokenList2
) == 2:
230 self
._ValueList
[0] = TokenList2
[0] # toolchain family
231 self
._ValueList
[1] = TokenList2
[1] # keys
233 self
._ValueList
[1] = TokenList
[0]
234 if len(TokenList
) == 2: # value
235 self
._ValueList
[2] = ReplaceMacro(TokenList
[1], self
._Macros
)
237 if self
._ValueList
[1].count('_') != 4:
241 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
242 ExtraData
=self
._CurrentLine
,
244 Line
=self
._LineIndex
+1
248 Table
= property(_GetTable
)
249 Finished
= property(_GetFinished
, _SetFinished
)
252 ## INF file parser class
254 # @param FilePath The path of platform description file
255 # @param FileType The raw data of DSC file
256 # @param Table Database used to retrieve module/package information
257 # @param Macros Macros used for replacement in file
259 class InfParser(MetaFileParser
):
260 # INF file supported data types (one type per section)
262 TAB_UNKNOWN
.upper() : MODEL_UNKNOWN
,
263 TAB_INF_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
264 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
265 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
266 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
267 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
268 TAB_PACKAGES
.upper() : MODEL_META_DATA_PACKAGE
,
269 TAB_NMAKE
.upper() : MODEL_META_DATA_NMAKE
,
270 TAB_INF_FIXED_PCD
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
271 TAB_INF_PATCH_PCD
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
272 TAB_INF_FEATURE_PCD
.upper() : MODEL_PCD_FEATURE_FLAG
,
273 TAB_INF_PCD_EX
.upper() : MODEL_PCD_DYNAMIC_EX
,
274 TAB_INF_PCD
.upper() : MODEL_PCD_DYNAMIC
,
275 TAB_SOURCES
.upper() : MODEL_EFI_SOURCE_FILE
,
276 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
277 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
278 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
279 TAB_DEPEX
.upper() : MODEL_EFI_DEPEX
,
280 TAB_BINARIES
.upper() : MODEL_EFI_BINARY_FILE
,
281 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
284 ## Constructor of InfParser
286 # Initialize object of InfParser
288 # @param FilePath The path of module description file
289 # @param FileType The raw data of DSC file
290 # @param Table Database used to retrieve module/package information
291 # @param Macros Macros used for replacement in file
293 def __init__(self
, FilePath
, FileType
, Table
, Macros
=None):
294 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
, Macros
)
300 self
._Content
= open(self
.MetaFile
, 'r').readlines()
302 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
304 # parse the file line by line
305 IsFindBlockComment
= False
307 for Index
in range(0, len(self
._Content
)):
308 # skip empty, commented, block commented lines
309 Line
= CleanString(self
._Content
[Index
], AllowCppStyleComment
=True)
311 if Index
+ 1 < len(self
._Content
):
312 NextLine
= CleanString(self
._Content
[Index
+ 1])
315 if Line
.find(DataType
.TAB_COMMENT_R8_START
) > -1:
316 IsFindBlockComment
= True
318 if Line
.find(DataType
.TAB_COMMENT_R8_END
) > -1:
319 IsFindBlockComment
= False
321 if IsFindBlockComment
:
324 self
._LineIndex
= Index
325 self
._CurrentLine
= Line
328 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
329 self
._SectionHeaderParser
()
331 # merge two lines specified by '\' in section NMAKE
332 elif self
._SectionType
== MODEL_META_DATA_NMAKE
:
335 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
338 if NextLine
[0] == TAB_SECTION_START
and NextLine
[-1] == TAB_SECTION_END
:
339 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
342 NmakeLine
= NmakeLine
+ ' ' + Line
[0:-1]
345 self
._CurrentLine
= NmakeLine
+ Line
347 elif Line
.upper().startswith('DEFINE '):
348 # file private macros
353 self
._ValueList
= ['','','']
354 # parse current line, result will be put in self._ValueList
355 self
._SectionParser
[self
._SectionType
](self
)
356 if self
._ValueList
== None:
359 # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
360 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
362 for Arch
, Platform
in self
._Scope
:
363 self
._Store
(self
._SectionType
,
378 ## Data parser for the format in which there's path
380 # Only path can have macro used. So we need to replace them before use.
382 def _IncludeParser(self
):
383 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
384 self
._ValueList
[0:len(TokenList
)] = TokenList
385 if len(self
._Macros
) > 0:
386 for Index
in range(0, len(self
._ValueList
)):
387 Value
= self
._ValueList
[Index
]
388 if Value
.upper().find('$(EFI_SOURCE)\Edk'.upper()) > -1 or Value
.upper().find('$(EFI_SOURCE)/Edk'.upper()) > -1:
389 Value
= '$(EDK_SOURCE)' + Value
[17:]
390 if Value
.find('$(EFI_SOURCE)') > -1 or Value
.find('$(EDK_SOURCE)') > -1:
392 elif Value
.startswith('.'):
394 elif Value
.startswith('$('):
397 Value
= '$(EFI_SOURCE)/' + Value
399 if Value
== None or Value
== '':
401 self
._ValueList
[Index
] = NormPath(Value
, self
._Macros
)
403 ## Parse [Sources] section
405 # Only path can have macro used. So we need to replace them before use.
407 def _SourceFileParser(self
):
408 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
409 self
._ValueList
[0:len(TokenList
)] = TokenList
410 # For Acpi tables, remove macro like ' TABLE_NAME=Sata1'
411 if 'COMPONENT_TYPE' in self
._Macros
:
412 if self
._Macros
['COMPONENT_TYPE'].upper() == 'ACPITABLE':
413 self
._ValueList
[0] = GetSplitValueList(self
._ValueList
[0], ' ', 1)[0]
414 if self
._Macros
['BASE_NAME'] == 'Microcode':
416 if len(self
._Macros
) > 0:
417 for Index
in range(0, len(self
._ValueList
)):
418 Value
= self
._ValueList
[Index
]
419 if Value
== None or Value
== '':
421 self
._ValueList
[Index
] = NormPath(Value
, self
._Macros
)
423 ## Parse [Binaries] section
425 # Only path can have macro used. So we need to replace them before use.
427 def _BinaryFileParser(self
):
428 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 2)
429 if len(TokenList
) < 2:
430 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type or path specified",
431 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
432 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
434 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type specified",
435 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
436 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
438 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file path specified",
439 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
440 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
441 self
._ValueList
[0:len(TokenList
)] = TokenList
442 self
._ValueList
[1] = NormPath(self
._ValueList
[1], self
._Macros
)
444 ## [defines] section parser
445 def _DefineParser(self
):
446 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
447 self
._ValueList
[0:len(TokenList
)] = TokenList
448 self
._Macros
[TokenList
[0]] = ReplaceMacro(TokenList
[1], self
._Macros
, False)
449 if self
._ValueList
[1] == '':
450 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
451 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
453 ## [nmake] section parser (R8.x style only)
454 def _NmakeParser(self
):
455 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
456 self
._ValueList
[0:len(TokenList
)] = TokenList
458 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
, False)
459 # remove self-reference in macro setting
460 #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
462 ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
463 def _PcdParser(self
):
464 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
465 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
466 if len(TokenList
) > 1:
467 self
._ValueList
[2] = TokenList
[1]
468 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
469 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
470 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
471 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
473 ## [depex] section parser
474 def _DepexParser(self
):
475 self
._ValueList
[0:1] = [self
._CurrentLine
]
478 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
479 MODEL_META_DATA_HEADER
: _DefineParser
,
480 MODEL_META_DATA_BUILD_OPTION
: MetaFileParser
._BuildOptionParser
,
481 MODEL_EFI_INCLUDE
: _IncludeParser
, # for R8.x modules
482 MODEL_EFI_LIBRARY_INSTANCE
: MetaFileParser
._CommonParser
, # for R8.x modules
483 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
484 MODEL_META_DATA_PACKAGE
: MetaFileParser
._PathParser
,
485 MODEL_META_DATA_NMAKE
: _NmakeParser
, # for R8.x modules
486 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
487 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
488 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
489 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
490 MODEL_PCD_DYNAMIC
: _PcdParser
,
491 MODEL_EFI_SOURCE_FILE
: _SourceFileParser
,
492 MODEL_EFI_GUID
: MetaFileParser
._CommonParser
,
493 MODEL_EFI_PROTOCOL
: MetaFileParser
._CommonParser
,
494 MODEL_EFI_PPI
: MetaFileParser
._CommonParser
,
495 MODEL_EFI_DEPEX
: _DepexParser
,
496 MODEL_EFI_BINARY_FILE
: _BinaryFileParser
,
497 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
500 ## DSC file parser class
502 # @param FilePath The path of platform description file
503 # @param FileType The raw data of DSC file
504 # @param Table Database used to retrieve module/package information
505 # @param Macros Macros used for replacement in file
506 # @param Owner Owner ID (for sub-section parsing)
507 # @param From ID from which the data comes (for !INCLUDE directive)
509 class DscParser(MetaFileParser
):
510 # DSC file supported data types (one type per section)
512 TAB_SKUIDS
.upper() : MODEL_EFI_SKU_ID
,
513 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
514 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
515 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
516 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
517 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
518 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
519 TAB_PCDS_DYNAMIC_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_DEFAULT
,
520 TAB_PCDS_DYNAMIC_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_HII
,
521 TAB_PCDS_DYNAMIC_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_VPD
,
522 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT
,
523 TAB_PCDS_DYNAMIC_EX_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_HII
,
524 TAB_PCDS_DYNAMIC_EX_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_VPD
,
525 TAB_COMPONENTS
.upper() : MODEL_META_DATA_COMPONENT
,
526 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
.upper() : MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
,
527 TAB_DSC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
528 TAB_INCLUDE
.upper() : MODEL_META_DATA_INCLUDE
,
529 TAB_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
530 TAB_IF_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
531 TAB_IF_N_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
,
532 TAB_ELSE_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
,
533 TAB_ELSE
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
,
534 TAB_END_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
,
537 # sections which allow "!include" directive
538 _IncludeAllowedSection
= [
539 TAB_LIBRARIES
.upper(),
540 TAB_LIBRARY_CLASSES
.upper(),
542 TAB_COMPONENTS
.upper(),
543 TAB_BUILD_OPTIONS
.upper(),
544 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper(),
545 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper(),
546 TAB_PCDS_FEATURE_FLAG_NULL
.upper(),
547 TAB_PCDS_DYNAMIC_DEFAULT_NULL
.upper(),
548 TAB_PCDS_DYNAMIC_HII_NULL
.upper(),
549 TAB_PCDS_DYNAMIC_VPD_NULL
.upper(),
550 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
.upper(),
551 TAB_PCDS_DYNAMIC_EX_HII_NULL
.upper(),
552 TAB_PCDS_DYNAMIC_EX_VPD_NULL
.upper(),
555 # operators which can be used in "!if/!ifdef/!ifndef" directives
557 "!" : lambda a
: not a
,
558 "!=" : lambda a
,b
: a
!=b
,
559 "==" : lambda a
,b
: a
==b
,
560 ">" : lambda a
,b
: a
>b
,
561 "<" : lambda a
,b
: a
<b
,
562 "=>" : lambda a
,b
: a
>=b
,
563 ">=" : lambda a
,b
: a
>=b
,
564 "<=" : lambda a
,b
: a
<=b
,
565 "=<" : lambda a
,b
: a
<=b
,
568 ## Constructor of DscParser
570 # Initialize object of DscParser
572 # @param FilePath The path of platform description file
573 # @param FileType The raw data of DSC file
574 # @param Table Database used to retrieve module/package information
575 # @param Macros Macros used for replacement in file
576 # @param Owner Owner ID (for sub-section parsing)
577 # @param From ID from which the data comes (for !INCLUDE directive)
579 def __init__(self
, FilePath
, FileType
, Table
, Macros
=None, Owner
=-1, From
=-1):
580 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
, Macros
, Owner
, From
)
581 # to store conditional directive evaluation result
587 if self
._Content
== None:
588 self
._Content
= open(self
.MetaFile
, 'r').readlines()
590 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
592 for Index
in range(0, len(self
._Content
)):
593 Line
= CleanString(self
._Content
[Index
])
597 self
._CurrentLine
= Line
598 self
._LineIndex
= Index
601 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
602 self
._SectionHeaderParser
()
606 self
._InSubsection
= False
607 self
._SubsectionType
= MODEL_UNKNOWN
608 self
._SubsectionName
= ''
612 elif Line
[0] == TAB_OPTION_START
and Line
[-1] == TAB_OPTION_END
:
613 self
._SubsectionHeaderParser
()
617 self
._DirectiveParser
()
619 # file private macros
620 elif Line
.upper().startswith('DEFINE '):
623 elif Line
.upper().startswith('EDK_GLOBAL '):
624 (Name
, Value
) = self
._MacroParser
()
625 for Arch
, ModuleType
in self
._Scope
:
626 self
._LastItem
= self
._Store
(
627 MODEL_META_DATA_DEFINE
,
644 if self
._InSubsection
:
645 SectionType
= self
._SubsectionType
646 SectionName
= self
._SubsectionName
647 if self
._Owner
== -1:
648 self
._Owner
= self
._LastItem
650 SectionType
= self
._SectionType
651 SectionName
= self
._SectionName
653 self
._ValueList
= ['', '', '']
654 self
._SectionParser
[SectionType
](self
)
655 if self
._ValueList
== None:
659 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
660 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
662 for Arch
, ModuleType
in self
._Scope
:
663 self
._LastItem
= self
._Store
(
680 ## [defines] section parser
681 def _DefineParser(self
):
682 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
683 if len(TokenList
) < 2:
684 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
685 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
686 # 'FLASH_DEFINITION', 'OUTPUT_DIRECTORY' need special processing
687 if TokenList
[0] in ['FLASH_DEFINITION', 'OUTPUT_DIRECTORY']:
688 TokenList
[1] = NormPath(TokenList
[1], self
._Macros
)
689 self
._ValueList
[0:len(TokenList
)] = TokenList
691 ## <subsection_header> parser
692 def _SubsectionHeaderParser(self
):
693 self
._SubsectionName
= self
._CurrentLine
[1:-1].upper()
694 if self
._SubsectionName
in self
.DataType
:
695 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
697 self
._SubsectionType
= MODEL_UNKNOWN
698 EdkLogger
.warn("Parser", "Unrecognized sub-section", File
=self
.MetaFile
,
699 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
701 ## Directive statement parser
702 def _DirectiveParser(self
):
703 self
._ValueList
= ['','','']
704 TokenList
= GetSplitValueList(self
._CurrentLine
, ' ', 1)
705 self
._ValueList
[0:len(TokenList
)] = TokenList
706 DirectiveName
= self
._ValueList
[0].upper()
707 if DirectiveName
not in self
.DataType
:
708 EdkLogger
.error("Parser", FORMAT_INVALID
, "Unknown directive [%s]" % DirectiveName
,
709 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
710 if DirectiveName
in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self
._ValueList
[1] == '':
711 EdkLogger
.error("Parser", FORMAT_INVALID
, "Missing expression",
712 File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
713 ExtraData
=self
._CurrentLine
)
714 # keep the directive in database first
715 self
._LastItem
= self
._Store
(
716 self
.DataType
[DirectiveName
],
731 # process the directive
732 if DirectiveName
== "!INCLUDE":
733 if not self
._SectionName
in self
._IncludeAllowedSection
:
734 EdkLogger
.error("Parser", FORMAT_INVALID
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
735 ExtraData
="'!include' is not allowed under section [%s]" % self
._SectionName
)
736 # the included file must be relative to the parsing file
737 IncludedFile
= os
.path
.join(self
._FileDir
, self
._ValueList
[1])
738 Parser
= DscParser(IncludedFile
, self
._FileType
, self
._Table
, self
._Macros
, From
=self
._LastItem
)
739 # set the parser status with current status
740 Parser
._SectionName
= self
._SectionName
741 Parser
._SectionType
= self
._SectionType
742 Parser
._Scope
= self
._Scope
743 Parser
._Enabled
= self
._Enabled
747 EdkLogger
.error("Parser", PARSER_ERROR
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
748 ExtraData
="Failed to parse content in file %s" % IncludedFile
)
749 # update current status with sub-parser's status
750 self
._SectionName
= Parser
._SectionName
751 self
._SectionType
= Parser
._SectionType
752 self
._Scope
= Parser
._Scope
753 self
._Enabled
= Parser
._Enabled
755 if DirectiveName
in ["!IF", "!IFDEF", "!IFNDEF"]:
756 # evaluate the expression
757 Result
= self
._Evaluate
(self
._ValueList
[1])
758 if DirectiveName
== "!IFNDEF":
760 self
._Eval
.append(Result
)
761 elif DirectiveName
in ["!ELSEIF"]:
762 # evaluate the expression
763 self
._Eval
[-1] = (not self
._Eval
[-1]) & self
._Evaluate
(self
._ValueList
[1])
764 elif DirectiveName
in ["!ELSE"]:
765 self
._Eval
[-1] = not self
._Eval
[-1]
766 elif DirectiveName
in ["!ENDIF"]:
767 if len(self
._Eval
) > 0:
770 EdkLogger
.error("Parser", FORMAT_INVALID
, "!IF..[!ELSE]..!ENDIF doesn't match",
771 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
772 if self
._Eval
.Result
== False:
773 self
._Enabled
= 0 - len(self
._Eval
)
775 self
._Enabled
= len(self
._Eval
)
777 ## Evaludate the value of expression in "if/ifdef/ifndef" directives
778 def _Evaluate(self
, Expression
):
779 TokenList
= Expression
.split()
780 TokenNumber
= len(TokenList
)
781 # one operand, guess it's just a macro name
783 return TokenList
[0] in self
._Macros
784 # two operands, suppose it's "!xxx" format
785 elif TokenNumber
== 2:
787 if Op
not in self
._OP
_:
788 EdkLogger
.error('Parser', FORMAT_INVALID
, "Unsupported operator [%s]" % Op
, File
=self
.MetaFile
,
789 Line
=self
._LineIndex
+1, ExtraData
=Expression
)
790 if TokenList
[1].upper() == 'TRUE':
794 return self
._OP
_[Op
](Value
)
796 elif TokenNumber
== 3:
798 if Name
not in self
._Macros
:
801 if Value
[0] in ["'", '"'] and Value
[-1] in ["'", '"']:
804 if Op
not in self
._OP
_:
805 EdkLogger
.error('Parser', FORMAT_INVALID
, "Unsupported operator [%s]" % Op
, File
=self
.MetaFile
,
806 Line
=self
._LineIndex
+1, ExtraData
=Expression
)
807 return self
._OP
_[Op
](self
._Macros
[Name
], Value
)
809 EdkLogger
.error('Parser', FORMAT_INVALID
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
810 ExtraData
=Expression
)
812 ## PCD sections parser
815 # [PcdsPatchableInModule]
818 # [PcdsDynamicExDefault]
822 # [PcdsDynamicDefault]
826 def _PcdParser(self
):
827 TokenList
= GetSplitValueList(ReplaceMacro(self
._CurrentLine
, self
._Macros
), TAB_VALUE_SPLIT
, 1)
828 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
829 if len(TokenList
) == 2:
830 self
._ValueList
[2] = TokenList
[1]
831 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
832 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
833 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
834 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
835 if self
._ValueList
[2] == '':
836 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD value given",
837 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
838 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
840 ## [components] section parser
841 def _ComponentParser(self
):
842 if self
._CurrentLine
[-1] == '{':
843 self
._ValueList
[0] = self
._CurrentLine
[0:-1].strip()
844 self
._InSubsection
= True
846 self
._ValueList
[0] = self
._CurrentLine
847 if len(self
._Macros
) > 0:
848 self
._ValueList
[0] = NormPath(self
._ValueList
[0], self
._Macros
)
850 def _LibraryClassParser(self
):
851 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
852 if len(TokenList
) < 2:
853 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class or instance specified",
854 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
855 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
856 if TokenList
[0] == '':
857 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class specified",
858 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
859 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
860 if TokenList
[1] == '':
861 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library instance specified",
862 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
863 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
864 self
._ValueList
[0:len(TokenList
)] = TokenList
865 if len(self
._Macros
) > 0:
866 self
._ValueList
[1] = NormPath(self
._ValueList
[1], self
._Macros
)
868 def _CompponentSourceOverridePathParser(self
):
869 if len(self
._Macros
) > 0:
870 self
._ValueList
[0] = NormPath(self
._CurrentLine
, self
._Macros
)
873 MODEL_META_DATA_HEADER
: _DefineParser
,
874 MODEL_EFI_SKU_ID
: MetaFileParser
._CommonParser
,
875 MODEL_EFI_LIBRARY_INSTANCE
: MetaFileParser
._PathParser
,
876 MODEL_EFI_LIBRARY_CLASS
: _LibraryClassParser
,
877 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
878 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
879 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
880 MODEL_PCD_DYNAMIC_DEFAULT
: _PcdParser
,
881 MODEL_PCD_DYNAMIC_HII
: _PcdParser
,
882 MODEL_PCD_DYNAMIC_VPD
: _PcdParser
,
883 MODEL_PCD_DYNAMIC_EX_DEFAULT
: _PcdParser
,
884 MODEL_PCD_DYNAMIC_EX_HII
: _PcdParser
,
885 MODEL_PCD_DYNAMIC_EX_VPD
: _PcdParser
,
886 MODEL_META_DATA_COMPONENT
: _ComponentParser
,
887 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: _CompponentSourceOverridePathParser
,
888 MODEL_META_DATA_BUILD_OPTION
: MetaFileParser
._BuildOptionParser
,
889 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
890 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
893 ## DEC file parser class
895 # @param FilePath The path of platform description file
896 # @param FileType The raw data of DSC file
897 # @param Table Database used to retrieve module/package information
898 # @param Macros Macros used for replacement in file
900 class DecParser(MetaFileParser
):
901 # DEC file supported data types (one type per section)
903 TAB_DEC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
904 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
905 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
906 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
907 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
908 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
909 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
910 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
911 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
912 TAB_PCDS_DYNAMIC_NULL
.upper() : MODEL_PCD_DYNAMIC
,
913 TAB_PCDS_DYNAMIC_EX_NULL
.upper() : MODEL_PCD_DYNAMIC_EX
,
916 ## Constructor of DecParser
918 # Initialize object of DecParser
920 # @param FilePath The path of platform description file
921 # @param FileType The raw data of DSC file
922 # @param Table Database used to retrieve module/package information
923 # @param Macros Macros used for replacement in file
925 def __init__(self
, FilePath
, FileType
, Table
, Macro
=None):
926 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
, Macro
, -1)
931 if self
._Content
== None:
932 self
._Content
= open(self
.MetaFile
, 'r').readlines()
934 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
936 for Index
in range(0, len(self
._Content
)):
937 Line
= CleanString(self
._Content
[Index
])
941 self
._CurrentLine
= Line
942 self
._LineIndex
= Index
945 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
946 self
._SectionHeaderParser
()
948 elif Line
.startswith('DEFINE '):
951 elif len(self
._SectionType
) == 0:
955 self
._ValueList
= ['','','']
956 self
._SectionParser
[self
._SectionType
[0]](self
)
957 if self
._ValueList
== None:
961 # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,
962 # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1
964 for Arch
, ModuleType
, Type
in self
._Scope
:
965 self
._LastItem
= self
._Store
(
981 ## Section header parser
983 # The section header is always in following format:
985 # [section_name.arch<.platform|module_type>]
987 def _SectionHeaderParser(self
):
989 self
._SectionName
= ''
990 self
._SectionType
= []
992 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
995 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
)
997 # different types of PCD are permissible in one section
998 self
._SectionName
= ItemList
[0].upper()
999 if self
._SectionName
in self
.DataType
:
1000 if self
.DataType
[self
._SectionName
] not in self
._SectionType
:
1001 self
._SectionType
.append(self
.DataType
[self
._SectionName
])
1003 EdkLogger
.warn("Parser", "Unrecognized section", File
=self
.MetaFile
,
1004 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
1007 if MODEL_PCD_FEATURE_FLAG
in self
._SectionType
and len(self
._SectionType
) > 1:
1011 "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL
,
1013 Line
=self
._LineIndex
+1,
1014 ExtraData
=self
._CurrentLine
1017 if len(ItemList
) > 1:
1018 S1
= ItemList
[1].upper()
1022 # S2 may be Platform or ModuleType
1023 if len(ItemList
) > 2:
1024 S2
= ItemList
[2].upper()
1027 if [S1
, S2
, self
.DataType
[self
._SectionName
]] not in self
._Scope
:
1028 self
._Scope
.append([S1
, S2
, self
.DataType
[self
._SectionName
]])
1030 # 'COMMON' must not be used with specific ARCHs at the same section
1031 if 'COMMON' in ArchList
and len(ArchList
) > 1:
1032 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
1033 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
1035 ## [guids], [ppis] and [protocols] section parser
1036 def _GuidParser(self
):
1037 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1038 if len(TokenList
) < 2:
1039 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name or value specified",
1040 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1041 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1042 if TokenList
[0] == '':
1043 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name specified",
1044 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1045 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1046 if TokenList
[1] == '':
1047 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID value specified",
1048 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1049 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1050 if TokenList
[1][0] != '{' or TokenList
[1][-1] != '}' or GuidStructureStringToGuidString(TokenList
[1]) == '':
1051 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid GUID value format",
1052 ExtraData
=self
._CurrentLine
+ \
1053 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
1054 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1055 self
._ValueList
[0] = TokenList
[0]
1056 self
._ValueList
[1] = TokenList
[1]
1058 ## PCD sections parser
1060 # [PcdsFixedAtBuild]
1061 # [PcdsPatchableInModule]
1066 def _PcdParser(self
):
1067 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1068 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1069 # check PCD information
1070 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1071 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1072 ExtraData
=self
._CurrentLine
+ \
1073 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1074 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1075 # check PCD datum information
1076 if len(TokenList
) < 2 or TokenList
[1] == '':
1077 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD Datum information given",
1078 ExtraData
=self
._CurrentLine
+ \
1079 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1080 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1082 ValueList
= GetSplitValueList(TokenList
[1])
1083 # check if there's enough datum information given
1084 if len(ValueList
) != 3:
1085 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid PCD Datum information given",
1086 ExtraData
=self
._CurrentLine
+ \
1087 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1088 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1089 # check default value
1090 if ValueList
[0] == '':
1091 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DefaultValue in PCD Datum information",
1092 ExtraData
=self
._CurrentLine
+ \
1093 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1094 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1096 if ValueList
[1] == '':
1097 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DatumType in PCD Datum information",
1098 ExtraData
=self
._CurrentLine
+ \
1099 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1100 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1101 # check token of the PCD
1102 if ValueList
[2] == '':
1103 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing Token in PCD Datum information",
1104 ExtraData
=self
._CurrentLine
+ \
1105 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1106 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1107 # check format of default value against the datum type
1108 IsValid
, Cause
= CheckPcdDatum(ValueList
[1], ValueList
[0])
1110 EdkLogger
.error('Parser', FORMAT_INVALID
, Cause
, ExtraData
=self
._CurrentLine
,
1111 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1113 self
._ValueList
[2] = ValueList
[0].strip() + '|' + ValueList
[1].strip() + '|' + ValueList
[2].strip()
1116 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
1117 MODEL_EFI_INCLUDE
: MetaFileParser
._PathParser
,
1118 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
1119 MODEL_EFI_GUID
: _GuidParser
,
1120 MODEL_EFI_PPI
: _GuidParser
,
1121 MODEL_EFI_PROTOCOL
: _GuidParser
,
1122 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1123 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1124 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1125 MODEL_PCD_DYNAMIC
: _PcdParser
,
1126 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
1127 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1128 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
1133 # This acts like the main() function for the script, unless it is 'import'ed into another
1136 if __name__
== '__main__':