2 # This file is used to parse meta files
4 # Copyright (c) 2008 - 2010, 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 # Parser objects used to implement singleton
48 # One file, one parser object. This factory method makes sure that there's
49 # only one object constructed for one meta file.
51 # @param Class class object of real AutoGen class
52 # (InfParser, DecParser or DscParser)
53 # @param FilePath The path of meta file
54 # @param *args The specific class related parameters
55 # @param **kwargs The specific class related dict parameters
57 def __new__(Class
, FilePath
, *args
, **kwargs
):
58 if FilePath
in Class
.MetaFiles
:
59 return Class
.MetaFiles
[FilePath
]
61 ParserObject
= super(MetaFileParser
, Class
).__new
__(Class
)
62 Class
.MetaFiles
[FilePath
] = ParserObject
65 ## Constructor of MetaFileParser
67 # Initialize object of MetaFileParser
69 # @param FilePath The path of platform description file
70 # @param FileType The raw data of DSC file
71 # @param Table Database used to retrieve module/package information
72 # @param Macros Macros used for replacement in file
73 # @param Owner Owner ID (for sub-section parsing)
74 # @param From ID from which the data comes (for !INCLUDE directive)
76 def __init__(self
, FilePath
, FileType
, Table
, Macros
=None, Owner
=-1, From
=-1):
77 # prevent re-initialization
78 if hasattr(self
, "_Table"):
81 self
._FileType
= FileType
82 self
.MetaFile
= FilePath
83 self
._FileDir
= os
.path
.dirname(self
.MetaFile
)
84 self
._Macros
= copy
.copy(Macros
)
86 # for recursive parsing
90 # parsr status for parsing
92 self
._ValueList
= ['', '', '', '', '']
95 self
._CurrentLine
= ''
96 self
._SectionType
= MODEL_UNKNOWN
97 self
._SectionName
= ''
98 self
._InSubsection
= False
99 self
._SubsectionType
= MODEL_UNKNOWN
100 self
._SubsectionName
= ''
103 self
._Finished
= False
105 ## Store the parsed data in table
106 def _Store(self
, *Args
):
107 return self
._Table
.Insert(*Args
)
109 ## Virtual method for starting parse
111 raise NotImplementedError
113 ## Set parsing complete flag in both class and table
115 self
._Finished
= True
116 ## Do not set end flag when processing included files
118 self
._Table
.SetEndFlag()
120 ## Return the table containg parsed data
122 # If the parse complete flag is not set, this method will try to parse the
123 # file before return the table
126 if not self
._Finished
:
130 ## Get the parse complete flag
131 def _GetFinished(self
):
132 return self
._Finished
134 ## Set the complete flag
135 def _SetFinished(self
, Value
):
136 self
._Finished
= Value
138 ## Use [] style to query data in table, just for readability
140 # DataInfo = [data_type, scope1(arch), scope2(platform,moduletype)]
142 def __getitem__(self
, DataInfo
):
143 if type(DataInfo
) != type(()):
144 DataInfo
= (DataInfo
,)
145 return self
.Table
.Query(*DataInfo
)
147 ## Data parser for the common format in different type of file
149 # The common format in the meatfile is like
153 def _CommonParser(self
):
154 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
155 self
._ValueList
[0:len(TokenList
)] = TokenList
157 ## Data parser for the format in which there's path
159 # Only path can have macro used. So we need to replace them before use.
161 def _PathParser(self
):
162 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
163 self
._ValueList
[0:len(TokenList
)] = TokenList
164 if len(self
._Macros
) > 0:
165 for Index
in range(0, len(self
._ValueList
)):
166 Value
= self
._ValueList
[Index
]
167 if Value
== None or Value
== '':
169 self
._ValueList
[Index
] = NormPath(Value
, self
._Macros
)
171 ## Skip unsupported data
173 EdkLogger
.warn("Parser", "Unrecognized content", File
=self
.MetaFile
,
174 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
);
175 self
._ValueList
[0:1] = [self
._CurrentLine
]
177 ## Section header parser
179 # The section header is always in following format:
181 # [section_name.arch<.platform|module_type>]
183 def _SectionHeaderParser(self
):
185 self
._SectionName
= ''
187 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
190 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
)
191 # different section should not mix in one section
192 if self
._SectionName
!= '' and self
._SectionName
!= ItemList
[0].upper():
193 EdkLogger
.error('Parser', FORMAT_INVALID
, "Different section names in the same section",
194 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
195 self
._SectionName
= ItemList
[0].upper()
196 if self
._SectionName
in self
.DataType
:
197 self
._SectionType
= self
.DataType
[self
._SectionName
]
199 self
._SectionType
= MODEL_UNKNOWN
200 EdkLogger
.warn("Parser", "Unrecognized section", File
=self
.MetaFile
,
201 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
203 if len(ItemList
) > 1:
204 S1
= ItemList
[1].upper()
208 # S2 may be Platform or ModuleType
209 if len(ItemList
) > 2:
210 S2
= ItemList
[2].upper()
213 self
._Scope
.append([S1
, S2
])
215 # 'COMMON' must not be used with specific ARCHs at the same section
216 if 'COMMON' in ArchList
and len(ArchList
) > 1:
217 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
218 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
220 ## [defines] section parser
221 def _DefineParser(self
):
222 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
223 self
._ValueList
[0:len(TokenList
)] = TokenList
224 if self
._ValueList
[1] == '':
225 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
226 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
228 ## DEFINE name=value parser
229 def _MacroParser(self
):
230 TokenList
= GetSplitValueList(self
._CurrentLine
, ' ', 1)
231 MacroType
= TokenList
[0]
232 if len(TokenList
) < 2 or TokenList
[1] == '':
233 EdkLogger
.error('Parser', FORMAT_INVALID
, "No macro name/value given",
234 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
235 TokenList
= GetSplitValueList(TokenList
[1], TAB_EQUAL_SPLIT
, 1)
236 if TokenList
[0] == '':
237 EdkLogger
.error('Parser', FORMAT_INVALID
, "No macro name given",
238 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
240 # Macros defined in the command line override ones defined in the meta-data file
241 if not TokenList
[0] in self
._Macros
:
242 if len(TokenList
) == 1:
243 self
._Macros
[TokenList
[0]] = ''
245 # keep the macro definition for later use
246 self
._Macros
[TokenList
[0]] = ReplaceMacro(TokenList
[1], self
._Macros
, False)
248 return TokenList
[0], self
._Macros
[TokenList
[0]]
250 ## [BuildOptions] section parser
251 def _BuildOptionParser(self
):
252 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
253 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
254 if len(TokenList2
) == 2:
255 self
._ValueList
[0] = TokenList2
[0] # toolchain family
256 self
._ValueList
[1] = TokenList2
[1] # keys
258 self
._ValueList
[1] = TokenList
[0]
259 if len(TokenList
) == 2: # value
260 self
._ValueList
[2] = ReplaceMacro(TokenList
[1], self
._Macros
)
262 if self
._ValueList
[1].count('_') != 4:
266 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
267 ExtraData
=self
._CurrentLine
,
269 Line
=self
._LineIndex
+1
273 Table
= property(_GetTable
)
274 Finished
= property(_GetFinished
, _SetFinished
)
277 ## INF file parser class
279 # @param FilePath The path of platform description file
280 # @param FileType The raw data of DSC file
281 # @param Table Database used to retrieve module/package information
282 # @param Macros Macros used for replacement in file
284 class InfParser(MetaFileParser
):
285 # INF file supported data types (one type per section)
287 TAB_UNKNOWN
.upper() : MODEL_UNKNOWN
,
288 TAB_INF_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
289 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
290 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
291 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
292 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
293 TAB_PACKAGES
.upper() : MODEL_META_DATA_PACKAGE
,
294 TAB_NMAKE
.upper() : MODEL_META_DATA_NMAKE
,
295 TAB_INF_FIXED_PCD
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
296 TAB_INF_PATCH_PCD
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
297 TAB_INF_FEATURE_PCD
.upper() : MODEL_PCD_FEATURE_FLAG
,
298 TAB_INF_PCD_EX
.upper() : MODEL_PCD_DYNAMIC_EX
,
299 TAB_INF_PCD
.upper() : MODEL_PCD_DYNAMIC
,
300 TAB_SOURCES
.upper() : MODEL_EFI_SOURCE_FILE
,
301 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
302 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
303 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
304 TAB_DEPEX
.upper() : MODEL_EFI_DEPEX
,
305 TAB_BINARIES
.upper() : MODEL_EFI_BINARY_FILE
,
306 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
309 ## Constructor of InfParser
311 # Initialize object of InfParser
313 # @param FilePath The path of module description file
314 # @param FileType The raw data of DSC file
315 # @param Table Database used to retrieve module/package information
316 # @param Macros Macros used for replacement in file
318 def __init__(self
, FilePath
, FileType
, Table
, Macros
=None):
319 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
, Macros
)
325 self
._Content
= open(self
.MetaFile
, 'r').readlines()
327 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
329 # parse the file line by line
330 IsFindBlockComment
= False
332 for Index
in range(0, len(self
._Content
)):
333 # skip empty, commented, block commented lines
334 Line
= CleanString(self
._Content
[Index
], AllowCppStyleComment
=True)
336 if Index
+ 1 < len(self
._Content
):
337 NextLine
= CleanString(self
._Content
[Index
+ 1])
340 if Line
.find(DataType
.TAB_COMMENT_R8_START
) > -1:
341 IsFindBlockComment
= True
343 if Line
.find(DataType
.TAB_COMMENT_R8_END
) > -1:
344 IsFindBlockComment
= False
346 if IsFindBlockComment
:
349 self
._LineIndex
= Index
350 self
._CurrentLine
= Line
353 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
354 self
._SectionHeaderParser
()
356 # merge two lines specified by '\' in section NMAKE
357 elif self
._SectionType
== MODEL_META_DATA_NMAKE
:
360 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
363 if NextLine
[0] == TAB_SECTION_START
and NextLine
[-1] == TAB_SECTION_END
:
364 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
367 NmakeLine
= NmakeLine
+ ' ' + Line
[0:-1]
370 self
._CurrentLine
= NmakeLine
+ Line
372 elif Line
.upper().startswith('DEFINE '):
373 # file private macros
378 self
._ValueList
= ['','','']
379 # parse current line, result will be put in self._ValueList
380 self
._SectionParser
[self
._SectionType
](self
)
381 if self
._ValueList
== None:
384 # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
385 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
387 for Arch
, Platform
in self
._Scope
:
388 self
._Store
(self
._SectionType
,
403 ## Data parser for the format in which there's path
405 # Only path can have macro used. So we need to replace them before use.
407 def _IncludeParser(self
):
408 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
409 self
._ValueList
[0:len(TokenList
)] = TokenList
410 if len(self
._Macros
) > 0:
411 for Index
in range(0, len(self
._ValueList
)):
412 Value
= self
._ValueList
[Index
]
413 if Value
.upper().find('$(EFI_SOURCE)\Edk'.upper()) > -1 or Value
.upper().find('$(EFI_SOURCE)/Edk'.upper()) > -1:
414 Value
= '$(EDK_SOURCE)' + Value
[17:]
415 if Value
.find('$(EFI_SOURCE)') > -1 or Value
.find('$(EDK_SOURCE)') > -1:
417 elif Value
.startswith('.'):
419 elif Value
.startswith('$('):
422 Value
= '$(EFI_SOURCE)/' + Value
424 if Value
== None or Value
== '':
426 self
._ValueList
[Index
] = NormPath(Value
, self
._Macros
)
428 ## Parse [Sources] section
430 # Only path can have macro used. So we need to replace them before use.
432 def _SourceFileParser(self
):
433 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
434 self
._ValueList
[0:len(TokenList
)] = TokenList
435 # For Acpi tables, remove macro like ' TABLE_NAME=Sata1'
436 if 'COMPONENT_TYPE' in self
._Macros
:
437 if self
._Macros
['COMPONENT_TYPE'].upper() == 'ACPITABLE':
438 self
._ValueList
[0] = GetSplitValueList(self
._ValueList
[0], ' ', 1)[0]
439 if self
._Macros
['BASE_NAME'] == 'Microcode':
441 if len(self
._Macros
) > 0:
442 for Index
in range(0, len(self
._ValueList
)):
443 Value
= self
._ValueList
[Index
]
444 if Value
== None or Value
== '':
446 self
._ValueList
[Index
] = NormPath(Value
, self
._Macros
)
448 ## Parse [Binaries] section
450 # Only path can have macro used. So we need to replace them before use.
452 def _BinaryFileParser(self
):
453 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 2)
454 if len(TokenList
) < 2:
455 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type or path specified",
456 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
457 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
459 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type specified",
460 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
461 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
463 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file path specified",
464 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
465 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
466 self
._ValueList
[0:len(TokenList
)] = TokenList
467 self
._ValueList
[1] = NormPath(self
._ValueList
[1], self
._Macros
)
469 ## [defines] section parser
470 def _DefineParser(self
):
471 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
472 self
._ValueList
[0:len(TokenList
)] = TokenList
473 self
._Macros
[TokenList
[0]] = ReplaceMacro(TokenList
[1], self
._Macros
, False)
474 if self
._ValueList
[1] == '':
475 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
476 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
478 ## [nmake] section parser (R8.x style only)
479 def _NmakeParser(self
):
480 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
481 self
._ValueList
[0:len(TokenList
)] = TokenList
483 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
, False)
484 # remove self-reference in macro setting
485 #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
487 ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
488 def _PcdParser(self
):
489 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
490 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
491 if len(TokenList
) > 1:
492 self
._ValueList
[2] = TokenList
[1]
493 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
494 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
495 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
496 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
498 ## [depex] section parser
499 def _DepexParser(self
):
500 self
._ValueList
[0:1] = [self
._CurrentLine
]
503 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
504 MODEL_META_DATA_HEADER
: _DefineParser
,
505 MODEL_META_DATA_BUILD_OPTION
: MetaFileParser
._BuildOptionParser
,
506 MODEL_EFI_INCLUDE
: _IncludeParser
, # for R8.x modules
507 MODEL_EFI_LIBRARY_INSTANCE
: MetaFileParser
._CommonParser
, # for R8.x modules
508 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
509 MODEL_META_DATA_PACKAGE
: MetaFileParser
._PathParser
,
510 MODEL_META_DATA_NMAKE
: _NmakeParser
, # for R8.x modules
511 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
512 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
513 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
514 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
515 MODEL_PCD_DYNAMIC
: _PcdParser
,
516 MODEL_EFI_SOURCE_FILE
: _SourceFileParser
,
517 MODEL_EFI_GUID
: MetaFileParser
._CommonParser
,
518 MODEL_EFI_PROTOCOL
: MetaFileParser
._CommonParser
,
519 MODEL_EFI_PPI
: MetaFileParser
._CommonParser
,
520 MODEL_EFI_DEPEX
: _DepexParser
,
521 MODEL_EFI_BINARY_FILE
: _BinaryFileParser
,
522 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
525 ## DSC file parser class
527 # @param FilePath The path of platform description file
528 # @param FileType The raw data of DSC file
529 # @param Table Database used to retrieve module/package information
530 # @param Macros Macros used for replacement in file
531 # @param Owner Owner ID (for sub-section parsing)
532 # @param From ID from which the data comes (for !INCLUDE directive)
534 class DscParser(MetaFileParser
):
535 # DSC file supported data types (one type per section)
537 TAB_SKUIDS
.upper() : MODEL_EFI_SKU_ID
,
538 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
539 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
540 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
541 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
542 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
543 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
544 TAB_PCDS_DYNAMIC_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_DEFAULT
,
545 TAB_PCDS_DYNAMIC_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_HII
,
546 TAB_PCDS_DYNAMIC_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_VPD
,
547 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT
,
548 TAB_PCDS_DYNAMIC_EX_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_HII
,
549 TAB_PCDS_DYNAMIC_EX_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_VPD
,
550 TAB_COMPONENTS
.upper() : MODEL_META_DATA_COMPONENT
,
551 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
.upper() : MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
,
552 TAB_DSC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
553 TAB_INCLUDE
.upper() : MODEL_META_DATA_INCLUDE
,
554 TAB_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
555 TAB_IF_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
556 TAB_IF_N_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
,
557 TAB_ELSE_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
,
558 TAB_ELSE
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
,
559 TAB_END_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
,
562 # sections which allow "!include" directive
563 _IncludeAllowedSection
= [
564 TAB_LIBRARIES
.upper(),
565 TAB_LIBRARY_CLASSES
.upper(),
567 TAB_COMPONENTS
.upper(),
568 TAB_BUILD_OPTIONS
.upper(),
569 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper(),
570 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper(),
571 TAB_PCDS_FEATURE_FLAG_NULL
.upper(),
572 TAB_PCDS_DYNAMIC_DEFAULT_NULL
.upper(),
573 TAB_PCDS_DYNAMIC_HII_NULL
.upper(),
574 TAB_PCDS_DYNAMIC_VPD_NULL
.upper(),
575 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
.upper(),
576 TAB_PCDS_DYNAMIC_EX_HII_NULL
.upper(),
577 TAB_PCDS_DYNAMIC_EX_VPD_NULL
.upper(),
580 # operators which can be used in "!if/!ifdef/!ifndef" directives
582 "!" : lambda a
: not a
,
583 "!=" : lambda a
,b
: a
!=b
,
584 "==" : lambda a
,b
: a
==b
,
585 ">" : lambda a
,b
: a
>b
,
586 "<" : lambda a
,b
: a
<b
,
587 "=>" : lambda a
,b
: a
>=b
,
588 ">=" : lambda a
,b
: a
>=b
,
589 "<=" : lambda a
,b
: a
<=b
,
590 "=<" : lambda a
,b
: a
<=b
,
593 ## Constructor of DscParser
595 # Initialize object of DscParser
597 # @param FilePath The path of platform description file
598 # @param FileType The raw data of DSC file
599 # @param Table Database used to retrieve module/package information
600 # @param Macros Macros used for replacement in file
601 # @param Owner Owner ID (for sub-section parsing)
602 # @param From ID from which the data comes (for !INCLUDE directive)
604 def __init__(self
, FilePath
, FileType
, Table
, Macros
=None, Owner
=-1, From
=-1):
605 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
, Macros
, Owner
, From
)
606 # to store conditional directive evaluation result
612 if self
._Content
== None:
613 self
._Content
= open(self
.MetaFile
, 'r').readlines()
615 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
617 for Index
in range(0, len(self
._Content
)):
618 Line
= CleanString(self
._Content
[Index
])
622 self
._CurrentLine
= Line
623 self
._LineIndex
= Index
624 if self
._InSubsection
and self
._Owner
== -1:
625 self
._Owner
= self
._LastItem
628 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
629 self
._SectionHeaderParser
()
633 self
._InSubsection
= False
634 self
._SubsectionType
= MODEL_UNKNOWN
635 self
._SubsectionName
= ''
639 elif Line
[0] == TAB_OPTION_START
and Line
[-1] == TAB_OPTION_END
:
640 self
._SubsectionHeaderParser
()
644 self
._DirectiveParser
()
646 # file private macros
647 elif Line
.upper().startswith('DEFINE '):
650 elif Line
.upper().startswith('EDK_GLOBAL '):
651 (Name
, Value
) = self
._MacroParser
()
652 for Arch
, ModuleType
in self
._Scope
:
653 self
._LastItem
= self
._Store
(
654 MODEL_META_DATA_DEFINE
,
671 if self
._InSubsection
:
672 SectionType
= self
._SubsectionType
673 SectionName
= self
._SubsectionName
675 SectionType
= self
._SectionType
676 SectionName
= self
._SectionName
678 self
._ValueList
= ['', '', '']
679 self
._SectionParser
[SectionType
](self
)
680 if self
._ValueList
== None:
684 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
685 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
687 for Arch
, ModuleType
in self
._Scope
:
688 self
._LastItem
= self
._Store
(
705 ## [defines] section parser
706 def _DefineParser(self
):
707 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
708 if len(TokenList
) < 2:
709 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
710 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
711 # 'FLASH_DEFINITION', 'OUTPUT_DIRECTORY' need special processing
712 if TokenList
[0] in ['FLASH_DEFINITION', 'OUTPUT_DIRECTORY']:
713 TokenList
[1] = NormPath(TokenList
[1], self
._Macros
)
714 self
._ValueList
[0:len(TokenList
)] = TokenList
716 ## <subsection_header> parser
717 def _SubsectionHeaderParser(self
):
718 self
._SubsectionName
= self
._CurrentLine
[1:-1].upper()
719 if self
._SubsectionName
in self
.DataType
:
720 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
722 self
._SubsectionType
= MODEL_UNKNOWN
723 EdkLogger
.warn("Parser", "Unrecognized sub-section", File
=self
.MetaFile
,
724 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
726 ## Directive statement parser
727 def _DirectiveParser(self
):
728 self
._ValueList
= ['','','']
729 TokenList
= GetSplitValueList(self
._CurrentLine
, ' ', 1)
730 self
._ValueList
[0:len(TokenList
)] = TokenList
731 DirectiveName
= self
._ValueList
[0].upper()
732 if DirectiveName
not in self
.DataType
:
733 EdkLogger
.error("Parser", FORMAT_INVALID
, "Unknown directive [%s]" % DirectiveName
,
734 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
735 if DirectiveName
in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self
._ValueList
[1] == '':
736 EdkLogger
.error("Parser", FORMAT_INVALID
, "Missing expression",
737 File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
738 ExtraData
=self
._CurrentLine
)
739 # keep the directive in database first
740 self
._LastItem
= self
._Store
(
741 self
.DataType
[DirectiveName
],
756 # process the directive
757 if DirectiveName
== "!INCLUDE":
758 if not self
._SectionName
in self
._IncludeAllowedSection
:
759 EdkLogger
.error("Parser", FORMAT_INVALID
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
760 ExtraData
="'!include' is not allowed under section [%s]" % self
._SectionName
)
761 # the included file must be relative to the parsing file
762 IncludedFile
= os
.path
.join(self
._FileDir
, self
._ValueList
[1])
763 Parser
= DscParser(IncludedFile
, self
._FileType
, self
._Table
, self
._Macros
, From
=self
._LastItem
)
764 # set the parser status with current status
765 Parser
._SectionName
= self
._SectionName
766 Parser
._SectionType
= self
._SectionType
767 Parser
._Scope
= self
._Scope
768 Parser
._Enabled
= self
._Enabled
772 EdkLogger
.error("Parser", PARSER_ERROR
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
773 ExtraData
="Failed to parse content in file %s" % IncludedFile
)
774 # update current status with sub-parser's status
775 self
._SectionName
= Parser
._SectionName
776 self
._SectionType
= Parser
._SectionType
777 self
._Scope
= Parser
._Scope
778 self
._Enabled
= Parser
._Enabled
780 if DirectiveName
in ["!IF", "!IFDEF", "!IFNDEF"]:
781 # evaluate the expression
782 Result
= self
._Evaluate
(self
._ValueList
[1])
783 if DirectiveName
== "!IFNDEF":
785 self
._Eval
.append(Result
)
786 elif DirectiveName
in ["!ELSEIF"]:
787 # evaluate the expression
788 self
._Eval
[-1] = (not self
._Eval
[-1]) & self
._Evaluate
(self
._ValueList
[1])
789 elif DirectiveName
in ["!ELSE"]:
790 self
._Eval
[-1] = not self
._Eval
[-1]
791 elif DirectiveName
in ["!ENDIF"]:
792 if len(self
._Eval
) > 0:
795 EdkLogger
.error("Parser", FORMAT_INVALID
, "!IF..[!ELSE]..!ENDIF doesn't match",
796 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
797 if self
._Eval
.Result
== False:
798 self
._Enabled
= 0 - len(self
._Eval
)
800 self
._Enabled
= len(self
._Eval
)
802 ## Evaluate the Token for its value; for now only macros are supported.
803 def _EvaluateToken(self
, TokenName
, Expression
):
804 if TokenName
.startswith("$(") and TokenName
.endswith(")"):
805 Name
= TokenName
[2:-1]
806 return self
._Macros
.get(Name
)
808 EdkLogger
.error('Parser', FORMAT_INVALID
, "Unknown operand '%(Token)s', "
809 "please use '$(%(Token)s)' if '%(Token)s' is a macro" % {"Token" : TokenName
},
810 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=Expression
)
812 ## Evaluate the value of expression in "if/ifdef/ifndef" directives
813 def _Evaluate(self
, Expression
):
814 TokenList
= Expression
.split()
815 TokenNumber
= len(TokenList
)
816 # one operand, guess it's just a macro name
818 TokenValue
= self
._EvaluateToken
(TokenList
[0], Expression
)
819 return TokenValue
!= None
820 # two operands, suppose it's "!xxx" format
821 elif TokenNumber
== 2:
823 if Op
not in self
._OP
_:
824 EdkLogger
.error('Parser', FORMAT_INVALID
, "Unsupported operator [%s]" % Op
, File
=self
.MetaFile
,
825 Line
=self
._LineIndex
+1, ExtraData
=Expression
)
826 if TokenList
[1].upper() == 'TRUE':
830 return self
._OP
_[Op
](Value
)
832 elif TokenNumber
== 3:
833 TokenValue
= self
._EvaluateToken
(TokenList
[0], Expression
)
834 if TokenValue
== None:
837 if Value
[0] in ["'", '"'] and Value
[-1] in ["'", '"']:
840 if Op
not in self
._OP
_:
841 EdkLogger
.error('Parser', FORMAT_INVALID
, "Unsupported operator [%s]" % Op
, File
=self
.MetaFile
,
842 Line
=self
._LineIndex
+1, ExtraData
=Expression
)
843 return self
._OP
_[Op
](TokenValue
, Value
)
845 EdkLogger
.error('Parser', FORMAT_INVALID
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
846 ExtraData
=Expression
)
848 ## PCD sections parser
851 # [PcdsPatchableInModule]
854 # [PcdsDynamicExDefault]
858 # [PcdsDynamicDefault]
862 def _PcdParser(self
):
863 TokenList
= GetSplitValueList(ReplaceMacro(self
._CurrentLine
, self
._Macros
), TAB_VALUE_SPLIT
, 1)
864 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
865 if len(TokenList
) == 2:
866 self
._ValueList
[2] = TokenList
[1]
867 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
868 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
869 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
870 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
871 if self
._ValueList
[2] == '':
872 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD value given",
873 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
874 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
876 ## [components] section parser
877 def _ComponentParser(self
):
878 if self
._CurrentLine
[-1] == '{':
879 self
._ValueList
[0] = self
._CurrentLine
[0:-1].strip()
880 self
._InSubsection
= True
882 self
._ValueList
[0] = self
._CurrentLine
883 if len(self
._Macros
) > 0:
884 self
._ValueList
[0] = NormPath(self
._ValueList
[0], self
._Macros
)
886 def _LibraryClassParser(self
):
887 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
888 if len(TokenList
) < 2:
889 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class or instance specified",
890 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
891 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
892 if TokenList
[0] == '':
893 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class specified",
894 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
895 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
896 if TokenList
[1] == '':
897 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library instance specified",
898 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
899 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
900 self
._ValueList
[0:len(TokenList
)] = TokenList
901 if len(self
._Macros
) > 0:
902 self
._ValueList
[1] = NormPath(self
._ValueList
[1], self
._Macros
)
904 def _CompponentSourceOverridePathParser(self
):
905 if len(self
._Macros
) > 0:
906 self
._ValueList
[0] = NormPath(self
._CurrentLine
, self
._Macros
)
909 MODEL_META_DATA_HEADER
: _DefineParser
,
910 MODEL_EFI_SKU_ID
: MetaFileParser
._CommonParser
,
911 MODEL_EFI_LIBRARY_INSTANCE
: MetaFileParser
._PathParser
,
912 MODEL_EFI_LIBRARY_CLASS
: _LibraryClassParser
,
913 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
914 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
915 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
916 MODEL_PCD_DYNAMIC_DEFAULT
: _PcdParser
,
917 MODEL_PCD_DYNAMIC_HII
: _PcdParser
,
918 MODEL_PCD_DYNAMIC_VPD
: _PcdParser
,
919 MODEL_PCD_DYNAMIC_EX_DEFAULT
: _PcdParser
,
920 MODEL_PCD_DYNAMIC_EX_HII
: _PcdParser
,
921 MODEL_PCD_DYNAMIC_EX_VPD
: _PcdParser
,
922 MODEL_META_DATA_COMPONENT
: _ComponentParser
,
923 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: _CompponentSourceOverridePathParser
,
924 MODEL_META_DATA_BUILD_OPTION
: MetaFileParser
._BuildOptionParser
,
925 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
926 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
929 ## DEC file parser class
931 # @param FilePath The path of platform description file
932 # @param FileType The raw data of DSC file
933 # @param Table Database used to retrieve module/package information
934 # @param Macros Macros used for replacement in file
936 class DecParser(MetaFileParser
):
937 # DEC file supported data types (one type per section)
939 TAB_DEC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
940 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
941 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
942 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
943 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
944 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
945 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
946 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
947 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
948 TAB_PCDS_DYNAMIC_NULL
.upper() : MODEL_PCD_DYNAMIC
,
949 TAB_PCDS_DYNAMIC_EX_NULL
.upper() : MODEL_PCD_DYNAMIC_EX
,
952 ## Constructor of DecParser
954 # Initialize object of DecParser
956 # @param FilePath The path of platform description file
957 # @param FileType The raw data of DSC file
958 # @param Table Database used to retrieve module/package information
959 # @param Macros Macros used for replacement in file
961 def __init__(self
, FilePath
, FileType
, Table
, Macro
=None):
962 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
, Macro
, -1)
967 if self
._Content
== None:
968 self
._Content
= open(self
.MetaFile
, 'r').readlines()
970 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
972 for Index
in range(0, len(self
._Content
)):
973 Line
= CleanString(self
._Content
[Index
])
977 self
._CurrentLine
= Line
978 self
._LineIndex
= Index
981 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
982 self
._SectionHeaderParser
()
984 elif Line
.startswith('DEFINE '):
987 elif len(self
._SectionType
) == 0:
991 self
._ValueList
= ['','','']
992 self
._SectionParser
[self
._SectionType
[0]](self
)
993 if self
._ValueList
== None:
997 # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,
998 # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1
1000 for Arch
, ModuleType
, Type
in self
._Scope
:
1001 self
._LastItem
= self
._Store
(
1017 ## Section header parser
1019 # The section header is always in following format:
1021 # [section_name.arch<.platform|module_type>]
1023 def _SectionHeaderParser(self
):
1025 self
._SectionName
= ''
1026 self
._SectionType
= []
1028 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
1031 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
)
1033 # different types of PCD are permissible in one section
1034 self
._SectionName
= ItemList
[0].upper()
1035 if self
._SectionName
in self
.DataType
:
1036 if self
.DataType
[self
._SectionName
] not in self
._SectionType
:
1037 self
._SectionType
.append(self
.DataType
[self
._SectionName
])
1039 EdkLogger
.warn("Parser", "Unrecognized section", File
=self
.MetaFile
,
1040 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
1043 if MODEL_PCD_FEATURE_FLAG
in self
._SectionType
and len(self
._SectionType
) > 1:
1047 "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL
,
1049 Line
=self
._LineIndex
+1,
1050 ExtraData
=self
._CurrentLine
1053 if len(ItemList
) > 1:
1054 S1
= ItemList
[1].upper()
1058 # S2 may be Platform or ModuleType
1059 if len(ItemList
) > 2:
1060 S2
= ItemList
[2].upper()
1063 if [S1
, S2
, self
.DataType
[self
._SectionName
]] not in self
._Scope
:
1064 self
._Scope
.append([S1
, S2
, self
.DataType
[self
._SectionName
]])
1066 # 'COMMON' must not be used with specific ARCHs at the same section
1067 if 'COMMON' in ArchList
and len(ArchList
) > 1:
1068 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
1069 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
1071 ## [guids], [ppis] and [protocols] section parser
1072 def _GuidParser(self
):
1073 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1074 if len(TokenList
) < 2:
1075 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name or value specified",
1076 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1077 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1078 if TokenList
[0] == '':
1079 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name specified",
1080 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1081 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1082 if TokenList
[1] == '':
1083 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID value specified",
1084 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1085 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1086 if TokenList
[1][0] != '{' or TokenList
[1][-1] != '}' or GuidStructureStringToGuidString(TokenList
[1]) == '':
1087 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid GUID value format",
1088 ExtraData
=self
._CurrentLine
+ \
1089 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
1090 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1091 self
._ValueList
[0] = TokenList
[0]
1092 self
._ValueList
[1] = TokenList
[1]
1094 ## PCD sections parser
1096 # [PcdsFixedAtBuild]
1097 # [PcdsPatchableInModule]
1102 def _PcdParser(self
):
1103 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1104 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1105 # check PCD information
1106 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1107 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1108 ExtraData
=self
._CurrentLine
+ \
1109 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1110 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1111 # check PCD datum information
1112 if len(TokenList
) < 2 or TokenList
[1] == '':
1113 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD Datum information given",
1114 ExtraData
=self
._CurrentLine
+ \
1115 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1116 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1118 ValueList
= GetSplitValueList(TokenList
[1])
1119 # check if there's enough datum information given
1120 if len(ValueList
) != 3:
1121 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid PCD Datum information given",
1122 ExtraData
=self
._CurrentLine
+ \
1123 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1124 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1125 # check default value
1126 if ValueList
[0] == '':
1127 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DefaultValue in PCD Datum information",
1128 ExtraData
=self
._CurrentLine
+ \
1129 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1130 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1132 if ValueList
[1] == '':
1133 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DatumType in PCD Datum information",
1134 ExtraData
=self
._CurrentLine
+ \
1135 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1136 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1137 # check token of the PCD
1138 if ValueList
[2] == '':
1139 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing Token in PCD Datum information",
1140 ExtraData
=self
._CurrentLine
+ \
1141 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1142 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1143 # check format of default value against the datum type
1144 IsValid
, Cause
= CheckPcdDatum(ValueList
[1], ValueList
[0])
1146 EdkLogger
.error('Parser', FORMAT_INVALID
, Cause
, ExtraData
=self
._CurrentLine
,
1147 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1149 self
._ValueList
[2] = ValueList
[0].strip() + '|' + ValueList
[1].strip() + '|' + ValueList
[2].strip()
1152 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
1153 MODEL_EFI_INCLUDE
: MetaFileParser
._PathParser
,
1154 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
1155 MODEL_EFI_GUID
: _GuidParser
,
1156 MODEL_EFI_PPI
: _GuidParser
,
1157 MODEL_EFI_PROTOCOL
: _GuidParser
,
1158 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1159 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1160 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1161 MODEL_PCD_DYNAMIC
: _PcdParser
,
1162 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
1163 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1164 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
1169 # This acts like the main() function for the script, unless it is 'import'ed into another
1172 if __name__
== '__main__':