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.
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
,
401 if IsFindBlockComment
:
402 EdkLogger
.error("Parser", FORMAT_INVALID
, "Open block comments (starting with /*) are expected to end with */",
406 ## Data parser for the format in which there's path
408 # Only path can have macro used. So we need to replace them before use.
410 def _IncludeParser(self
):
411 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
412 self
._ValueList
[0:len(TokenList
)] = TokenList
413 if len(self
._Macros
) > 0:
414 for Index
in range(0, len(self
._ValueList
)):
415 Value
= self
._ValueList
[Index
]
416 if Value
.upper().find('$(EFI_SOURCE)\Edk'.upper()) > -1 or Value
.upper().find('$(EFI_SOURCE)/Edk'.upper()) > -1:
417 Value
= '$(EDK_SOURCE)' + Value
[17:]
418 if Value
.find('$(EFI_SOURCE)') > -1 or Value
.find('$(EDK_SOURCE)') > -1:
420 elif Value
.startswith('.'):
422 elif Value
.startswith('$('):
425 Value
= '$(EFI_SOURCE)/' + Value
427 if Value
== None or Value
== '':
429 self
._ValueList
[Index
] = NormPath(Value
, self
._Macros
)
431 ## Parse [Sources] section
433 # Only path can have macro used. So we need to replace them before use.
435 def _SourceFileParser(self
):
436 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
437 self
._ValueList
[0:len(TokenList
)] = TokenList
438 # For Acpi tables, remove macro like ' TABLE_NAME=Sata1'
439 if 'COMPONENT_TYPE' in self
._Macros
:
440 if self
._Macros
['COMPONENT_TYPE'].upper() == 'ACPITABLE':
441 self
._ValueList
[0] = GetSplitValueList(self
._ValueList
[0], ' ', 1)[0]
442 if self
._Macros
['BASE_NAME'] == 'Microcode':
444 if len(self
._Macros
) > 0:
445 for Index
in range(0, len(self
._ValueList
)):
446 Value
= self
._ValueList
[Index
]
447 if Value
== None or Value
== '':
449 self
._ValueList
[Index
] = NormPath(Value
, self
._Macros
)
451 ## Parse [Binaries] section
453 # Only path can have macro used. So we need to replace them before use.
455 def _BinaryFileParser(self
):
456 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 2)
457 if len(TokenList
) < 2:
458 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type or path specified",
459 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
460 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
462 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type specified",
463 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
464 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
466 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file path specified",
467 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
468 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
469 self
._ValueList
[0:len(TokenList
)] = TokenList
470 self
._ValueList
[1] = NormPath(self
._ValueList
[1], self
._Macros
)
472 ## [defines] section parser
473 def _DefineParser(self
):
474 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
475 self
._ValueList
[0:len(TokenList
)] = TokenList
476 self
._Macros
[TokenList
[0]] = ReplaceMacro(TokenList
[1], self
._Macros
, False)
477 if self
._ValueList
[1] == '':
478 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
479 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
481 ## [nmake] section parser (R8.x style only)
482 def _NmakeParser(self
):
483 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
484 self
._ValueList
[0:len(TokenList
)] = TokenList
486 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
, False)
487 # remove self-reference in macro setting
488 #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
490 ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
491 def _PcdParser(self
):
492 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
493 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
494 if len(TokenList
) > 1:
495 self
._ValueList
[2] = TokenList
[1]
496 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
497 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
498 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
499 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
501 ## [depex] section parser
502 def _DepexParser(self
):
503 self
._ValueList
[0:1] = [self
._CurrentLine
]
506 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
507 MODEL_META_DATA_HEADER
: _DefineParser
,
508 MODEL_META_DATA_BUILD_OPTION
: MetaFileParser
._BuildOptionParser
,
509 MODEL_EFI_INCLUDE
: _IncludeParser
, # for R8.x modules
510 MODEL_EFI_LIBRARY_INSTANCE
: MetaFileParser
._CommonParser
, # for R8.x modules
511 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
512 MODEL_META_DATA_PACKAGE
: MetaFileParser
._PathParser
,
513 MODEL_META_DATA_NMAKE
: _NmakeParser
, # for R8.x modules
514 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
515 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
516 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
517 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
518 MODEL_PCD_DYNAMIC
: _PcdParser
,
519 MODEL_EFI_SOURCE_FILE
: _SourceFileParser
,
520 MODEL_EFI_GUID
: MetaFileParser
._CommonParser
,
521 MODEL_EFI_PROTOCOL
: MetaFileParser
._CommonParser
,
522 MODEL_EFI_PPI
: MetaFileParser
._CommonParser
,
523 MODEL_EFI_DEPEX
: _DepexParser
,
524 MODEL_EFI_BINARY_FILE
: _BinaryFileParser
,
525 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
528 ## DSC file parser class
530 # @param FilePath The path of platform description file
531 # @param FileType The raw data of DSC file
532 # @param Table Database used to retrieve module/package information
533 # @param Macros Macros used for replacement in file
534 # @param Owner Owner ID (for sub-section parsing)
535 # @param From ID from which the data comes (for !INCLUDE directive)
537 class DscParser(MetaFileParser
):
538 # DSC file supported data types (one type per section)
540 TAB_SKUIDS
.upper() : MODEL_EFI_SKU_ID
,
541 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
542 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
543 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
544 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
545 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
546 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
547 TAB_PCDS_DYNAMIC_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_DEFAULT
,
548 TAB_PCDS_DYNAMIC_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_HII
,
549 TAB_PCDS_DYNAMIC_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_VPD
,
550 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT
,
551 TAB_PCDS_DYNAMIC_EX_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_HII
,
552 TAB_PCDS_DYNAMIC_EX_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_VPD
,
553 TAB_COMPONENTS
.upper() : MODEL_META_DATA_COMPONENT
,
554 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
.upper() : MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
,
555 TAB_DSC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
556 TAB_INCLUDE
.upper() : MODEL_META_DATA_INCLUDE
,
557 TAB_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
558 TAB_IF_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
559 TAB_IF_N_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
,
560 TAB_ELSE_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
,
561 TAB_ELSE
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
,
562 TAB_END_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
,
565 # sections which allow "!include" directive
566 _IncludeAllowedSection
= [
567 TAB_LIBRARIES
.upper(),
568 TAB_LIBRARY_CLASSES
.upper(),
570 TAB_COMPONENTS
.upper(),
571 TAB_BUILD_OPTIONS
.upper(),
572 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper(),
573 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper(),
574 TAB_PCDS_FEATURE_FLAG_NULL
.upper(),
575 TAB_PCDS_DYNAMIC_DEFAULT_NULL
.upper(),
576 TAB_PCDS_DYNAMIC_HII_NULL
.upper(),
577 TAB_PCDS_DYNAMIC_VPD_NULL
.upper(),
578 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
.upper(),
579 TAB_PCDS_DYNAMIC_EX_HII_NULL
.upper(),
580 TAB_PCDS_DYNAMIC_EX_VPD_NULL
.upper(),
583 # operators which can be used in "!if/!ifdef/!ifndef" directives
585 "!" : lambda a
: not a
,
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
,
591 ">=" : lambda a
,b
: a
>=b
,
592 "<=" : lambda a
,b
: a
<=b
,
593 "=<" : lambda a
,b
: a
<=b
,
596 ## Constructor of DscParser
598 # Initialize object of DscParser
600 # @param FilePath The path of platform description file
601 # @param FileType The raw data of DSC file
602 # @param Table Database used to retrieve module/package information
603 # @param Macros Macros used for replacement in file
604 # @param Owner Owner ID (for sub-section parsing)
605 # @param From ID from which the data comes (for !INCLUDE directive)
607 def __init__(self
, FilePath
, FileType
, Table
, Macros
=None, Owner
=-1, From
=-1):
608 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
, Macros
, Owner
, From
)
609 # to store conditional directive evaluation result
615 if self
._Content
== None:
616 self
._Content
= open(self
.MetaFile
, 'r').readlines()
618 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
620 for Index
in range(0, len(self
._Content
)):
621 Line
= CleanString(self
._Content
[Index
])
625 self
._CurrentLine
= Line
626 self
._LineIndex
= Index
627 if self
._InSubsection
and self
._Owner
== -1:
628 self
._Owner
= self
._LastItem
631 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
632 self
._SectionHeaderParser
()
636 self
._InSubsection
= False
637 self
._SubsectionType
= MODEL_UNKNOWN
638 self
._SubsectionName
= ''
642 elif Line
[0] == TAB_OPTION_START
and Line
[-1] == TAB_OPTION_END
:
643 self
._SubsectionHeaderParser
()
647 self
._DirectiveParser
()
649 # file private macros
650 elif Line
.upper().startswith('DEFINE '):
653 elif Line
.upper().startswith('EDK_GLOBAL '):
654 (Name
, Value
) = self
._MacroParser
()
655 for Arch
, ModuleType
in self
._Scope
:
656 self
._LastItem
= self
._Store
(
657 MODEL_META_DATA_DEFINE
,
674 if self
._InSubsection
:
675 SectionType
= self
._SubsectionType
676 SectionName
= self
._SubsectionName
678 SectionType
= self
._SectionType
679 SectionName
= self
._SectionName
681 self
._ValueList
= ['', '', '']
682 self
._SectionParser
[SectionType
](self
)
683 if self
._ValueList
== None:
687 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
688 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
690 for Arch
, ModuleType
in self
._Scope
:
691 self
._LastItem
= self
._Store
(
708 ## [defines] section parser
709 def _DefineParser(self
):
710 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
711 if len(TokenList
) < 2:
712 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
713 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
714 # 'FLASH_DEFINITION', 'OUTPUT_DIRECTORY' need special processing
715 if TokenList
[0] in ['FLASH_DEFINITION', 'OUTPUT_DIRECTORY']:
716 TokenList
[1] = NormPath(TokenList
[1], self
._Macros
)
717 self
._ValueList
[0:len(TokenList
)] = TokenList
719 ## <subsection_header> parser
720 def _SubsectionHeaderParser(self
):
721 self
._SubsectionName
= self
._CurrentLine
[1:-1].upper()
722 if self
._SubsectionName
in self
.DataType
:
723 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
725 self
._SubsectionType
= MODEL_UNKNOWN
726 EdkLogger
.warn("Parser", "Unrecognized sub-section", File
=self
.MetaFile
,
727 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
729 ## Directive statement parser
730 def _DirectiveParser(self
):
731 self
._ValueList
= ['','','']
732 TokenList
= GetSplitValueList(self
._CurrentLine
, ' ', 1)
733 self
._ValueList
[0:len(TokenList
)] = TokenList
734 DirectiveName
= self
._ValueList
[0].upper()
735 if DirectiveName
not in self
.DataType
:
736 EdkLogger
.error("Parser", FORMAT_INVALID
, "Unknown directive [%s]" % DirectiveName
,
737 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
738 if DirectiveName
in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self
._ValueList
[1] == '':
739 EdkLogger
.error("Parser", FORMAT_INVALID
, "Missing expression",
740 File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
741 ExtraData
=self
._CurrentLine
)
742 # keep the directive in database first
743 self
._LastItem
= self
._Store
(
744 self
.DataType
[DirectiveName
],
759 # process the directive
760 if DirectiveName
== "!INCLUDE":
761 if not self
._SectionName
in self
._IncludeAllowedSection
:
762 EdkLogger
.error("Parser", FORMAT_INVALID
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
763 ExtraData
="'!include' is not allowed under section [%s]" % self
._SectionName
)
764 # the included file must be relative to the parsing file
765 IncludedFile
= os
.path
.join(self
._FileDir
, self
._ValueList
[1])
766 Parser
= DscParser(IncludedFile
, self
._FileType
, self
._Table
, self
._Macros
, From
=self
._LastItem
)
767 # set the parser status with current status
768 Parser
._SectionName
= self
._SectionName
769 Parser
._SectionType
= self
._SectionType
770 Parser
._Scope
= self
._Scope
771 Parser
._Enabled
= self
._Enabled
775 EdkLogger
.error("Parser", PARSER_ERROR
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
776 ExtraData
="Failed to parse content in file %s" % IncludedFile
)
777 # insert an imaginary token in the DSC table to indicate its external dependency on another file
778 self
._Store
(MODEL_EXTERNAL_DEPENDENCY
, IncludedFile
, str(os
.stat(IncludedFile
)[8]), "")
779 # update current status with sub-parser's status
780 self
._SectionName
= Parser
._SectionName
781 self
._SectionType
= Parser
._SectionType
782 self
._Scope
= Parser
._Scope
783 self
._Enabled
= Parser
._Enabled
785 if DirectiveName
in ["!IF", "!IFDEF", "!IFNDEF"]:
786 # evaluate the expression
787 Result
= self
._Evaluate
(self
._ValueList
[1])
788 if DirectiveName
== "!IFNDEF":
790 self
._Eval
.append(Result
)
791 elif DirectiveName
in ["!ELSEIF"]:
792 # evaluate the expression
793 self
._Eval
[-1] = (not self
._Eval
[-1]) & self
._Evaluate
(self
._ValueList
[1])
794 elif DirectiveName
in ["!ELSE"]:
795 self
._Eval
[-1] = not self
._Eval
[-1]
796 elif DirectiveName
in ["!ENDIF"]:
797 if len(self
._Eval
) > 0:
800 EdkLogger
.error("Parser", FORMAT_INVALID
, "!IF..[!ELSE]..!ENDIF doesn't match",
801 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
802 if self
._Eval
.Result
== False:
803 self
._Enabled
= 0 - len(self
._Eval
)
805 self
._Enabled
= len(self
._Eval
)
807 ## Evaluate the Token for its value; for now only macros are supported.
808 def _EvaluateToken(self
, TokenName
, Expression
):
809 if TokenName
.startswith("$(") and TokenName
.endswith(")"):
810 Name
= TokenName
[2:-1]
811 return self
._Macros
.get(Name
)
813 EdkLogger
.error('Parser', FORMAT_INVALID
, "Unknown operand '%(Token)s', "
814 "please use '$(%(Token)s)' if '%(Token)s' is a macro" % {"Token" : TokenName
},
815 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=Expression
)
817 ## Evaluate the value of expression in "if/ifdef/ifndef" directives
818 def _Evaluate(self
, Expression
):
819 TokenList
= Expression
.split()
820 TokenNumber
= len(TokenList
)
821 # one operand, guess it's just a macro name
823 TokenValue
= self
._EvaluateToken
(TokenList
[0], Expression
)
824 return TokenValue
!= None
825 # two operands, suppose it's "!xxx" format
826 elif TokenNumber
== 2:
828 if Op
not in self
._OP
_:
829 EdkLogger
.error('Parser', FORMAT_INVALID
, "Unsupported operator [%s]" % Op
, File
=self
.MetaFile
,
830 Line
=self
._LineIndex
+1, ExtraData
=Expression
)
831 if TokenList
[1].upper() == 'TRUE':
835 return self
._OP
_[Op
](Value
)
837 elif TokenNumber
== 3:
838 TokenValue
= self
._EvaluateToken
(TokenList
[0], Expression
)
839 if TokenValue
== None:
842 if Value
[0] in ["'", '"'] and Value
[-1] in ["'", '"']:
845 if Op
not in self
._OP
_:
846 EdkLogger
.error('Parser', FORMAT_INVALID
, "Unsupported operator [%s]" % Op
, File
=self
.MetaFile
,
847 Line
=self
._LineIndex
+1, ExtraData
=Expression
)
848 return self
._OP
_[Op
](TokenValue
, Value
)
850 EdkLogger
.error('Parser', FORMAT_INVALID
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
851 ExtraData
=Expression
)
853 ## PCD sections parser
856 # [PcdsPatchableInModule]
859 # [PcdsDynamicExDefault]
863 # [PcdsDynamicDefault]
867 def _PcdParser(self
):
868 TokenList
= GetSplitValueList(ReplaceMacro(self
._CurrentLine
, self
._Macros
), TAB_VALUE_SPLIT
, 1)
869 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
870 if len(TokenList
) == 2:
871 self
._ValueList
[2] = TokenList
[1]
872 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
873 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
874 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
875 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
876 if self
._ValueList
[2] == '':
877 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD value given",
878 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
879 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
881 ## [components] section parser
882 def _ComponentParser(self
):
883 if self
._CurrentLine
[-1] == '{':
884 self
._ValueList
[0] = self
._CurrentLine
[0:-1].strip()
885 self
._InSubsection
= True
887 self
._ValueList
[0] = self
._CurrentLine
888 if len(self
._Macros
) > 0:
889 self
._ValueList
[0] = NormPath(self
._ValueList
[0], self
._Macros
)
891 def _LibraryClassParser(self
):
892 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
893 if len(TokenList
) < 2:
894 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class or instance specified",
895 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
896 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
897 if TokenList
[0] == '':
898 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class specified",
899 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
900 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
901 if TokenList
[1] == '':
902 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library instance specified",
903 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
904 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
905 self
._ValueList
[0:len(TokenList
)] = TokenList
906 if len(self
._Macros
) > 0:
907 self
._ValueList
[1] = NormPath(self
._ValueList
[1], self
._Macros
)
909 def _CompponentSourceOverridePathParser(self
):
910 if len(self
._Macros
) > 0:
911 self
._ValueList
[0] = NormPath(self
._CurrentLine
, self
._Macros
)
914 MODEL_META_DATA_HEADER
: _DefineParser
,
915 MODEL_EFI_SKU_ID
: MetaFileParser
._CommonParser
,
916 MODEL_EFI_LIBRARY_INSTANCE
: MetaFileParser
._PathParser
,
917 MODEL_EFI_LIBRARY_CLASS
: _LibraryClassParser
,
918 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
919 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
920 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
921 MODEL_PCD_DYNAMIC_DEFAULT
: _PcdParser
,
922 MODEL_PCD_DYNAMIC_HII
: _PcdParser
,
923 MODEL_PCD_DYNAMIC_VPD
: _PcdParser
,
924 MODEL_PCD_DYNAMIC_EX_DEFAULT
: _PcdParser
,
925 MODEL_PCD_DYNAMIC_EX_HII
: _PcdParser
,
926 MODEL_PCD_DYNAMIC_EX_VPD
: _PcdParser
,
927 MODEL_META_DATA_COMPONENT
: _ComponentParser
,
928 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: _CompponentSourceOverridePathParser
,
929 MODEL_META_DATA_BUILD_OPTION
: MetaFileParser
._BuildOptionParser
,
930 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
931 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
934 ## DEC file parser class
936 # @param FilePath The path of platform description file
937 # @param FileType The raw data of DSC file
938 # @param Table Database used to retrieve module/package information
939 # @param Macros Macros used for replacement in file
941 class DecParser(MetaFileParser
):
942 # DEC file supported data types (one type per section)
944 TAB_DEC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
945 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
946 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
947 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
948 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
949 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
950 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
951 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
952 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
953 TAB_PCDS_DYNAMIC_NULL
.upper() : MODEL_PCD_DYNAMIC
,
954 TAB_PCDS_DYNAMIC_EX_NULL
.upper() : MODEL_PCD_DYNAMIC_EX
,
957 ## Constructor of DecParser
959 # Initialize object of DecParser
961 # @param FilePath The path of platform description file
962 # @param FileType The raw data of DSC file
963 # @param Table Database used to retrieve module/package information
964 # @param Macros Macros used for replacement in file
966 def __init__(self
, FilePath
, FileType
, Table
, Macro
=None):
967 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
, Macro
, -1)
972 if self
._Content
== None:
973 self
._Content
= open(self
.MetaFile
, 'r').readlines()
975 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
977 for Index
in range(0, len(self
._Content
)):
978 Line
= CleanString(self
._Content
[Index
])
982 self
._CurrentLine
= Line
983 self
._LineIndex
= Index
986 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
987 self
._SectionHeaderParser
()
989 elif Line
.startswith('DEFINE '):
992 elif len(self
._SectionType
) == 0:
996 self
._ValueList
= ['','','']
997 self
._SectionParser
[self
._SectionType
[0]](self
)
998 if self
._ValueList
== None:
1002 # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,
1003 # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1
1005 for Arch
, ModuleType
, Type
in self
._Scope
:
1006 self
._LastItem
= self
._Store
(
1022 ## Section header parser
1024 # The section header is always in following format:
1026 # [section_name.arch<.platform|module_type>]
1028 def _SectionHeaderParser(self
):
1030 self
._SectionName
= ''
1031 self
._SectionType
= []
1033 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
1036 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
)
1038 # different types of PCD are permissible in one section
1039 self
._SectionName
= ItemList
[0].upper()
1040 if self
._SectionName
in self
.DataType
:
1041 if self
.DataType
[self
._SectionName
] not in self
._SectionType
:
1042 self
._SectionType
.append(self
.DataType
[self
._SectionName
])
1044 EdkLogger
.warn("Parser", "Unrecognized section", File
=self
.MetaFile
,
1045 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
1048 if MODEL_PCD_FEATURE_FLAG
in self
._SectionType
and len(self
._SectionType
) > 1:
1052 "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL
,
1054 Line
=self
._LineIndex
+1,
1055 ExtraData
=self
._CurrentLine
1058 if len(ItemList
) > 1:
1059 S1
= ItemList
[1].upper()
1063 # S2 may be Platform or ModuleType
1064 if len(ItemList
) > 2:
1065 S2
= ItemList
[2].upper()
1068 if [S1
, S2
, self
.DataType
[self
._SectionName
]] not in self
._Scope
:
1069 self
._Scope
.append([S1
, S2
, self
.DataType
[self
._SectionName
]])
1071 # 'COMMON' must not be used with specific ARCHs at the same section
1072 if 'COMMON' in ArchList
and len(ArchList
) > 1:
1073 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
1074 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
1076 ## [guids], [ppis] and [protocols] section parser
1077 def _GuidParser(self
):
1078 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1079 if len(TokenList
) < 2:
1080 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name or value specified",
1081 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1082 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1083 if TokenList
[0] == '':
1084 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name specified",
1085 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1086 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1087 if TokenList
[1] == '':
1088 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID value specified",
1089 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1090 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1091 if TokenList
[1][0] != '{' or TokenList
[1][-1] != '}' or GuidStructureStringToGuidString(TokenList
[1]) == '':
1092 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid GUID value format",
1093 ExtraData
=self
._CurrentLine
+ \
1094 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
1095 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1096 self
._ValueList
[0] = TokenList
[0]
1097 self
._ValueList
[1] = TokenList
[1]
1099 ## PCD sections parser
1101 # [PcdsFixedAtBuild]
1102 # [PcdsPatchableInModule]
1107 def _PcdParser(self
):
1108 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1109 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1110 # check PCD information
1111 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1112 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1113 ExtraData
=self
._CurrentLine
+ \
1114 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1115 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1116 # check PCD datum information
1117 if len(TokenList
) < 2 or TokenList
[1] == '':
1118 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD Datum information given",
1119 ExtraData
=self
._CurrentLine
+ \
1120 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1121 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1123 ValueList
= GetSplitValueList(TokenList
[1])
1124 # check if there's enough datum information given
1125 if len(ValueList
) != 3:
1126 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid PCD Datum information given",
1127 ExtraData
=self
._CurrentLine
+ \
1128 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1129 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1130 # check default value
1131 if ValueList
[0] == '':
1132 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DefaultValue in PCD Datum information",
1133 ExtraData
=self
._CurrentLine
+ \
1134 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1135 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1137 if ValueList
[1] == '':
1138 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DatumType in PCD Datum information",
1139 ExtraData
=self
._CurrentLine
+ \
1140 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1141 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1142 # check token of the PCD
1143 if ValueList
[2] == '':
1144 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing Token in PCD Datum information",
1145 ExtraData
=self
._CurrentLine
+ \
1146 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1147 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1148 # check format of default value against the datum type
1149 IsValid
, Cause
= CheckPcdDatum(ValueList
[1], ValueList
[0])
1151 EdkLogger
.error('Parser', FORMAT_INVALID
, Cause
, ExtraData
=self
._CurrentLine
,
1152 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1154 self
._ValueList
[2] = ValueList
[0].strip() + '|' + ValueList
[1].strip() + '|' + ValueList
[2].strip()
1157 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
1158 MODEL_EFI_INCLUDE
: MetaFileParser
._PathParser
,
1159 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
1160 MODEL_EFI_GUID
: _GuidParser
,
1161 MODEL_EFI_PPI
: _GuidParser
,
1162 MODEL_EFI_PROTOCOL
: _GuidParser
,
1163 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1164 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1165 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1166 MODEL_PCD_DYNAMIC
: _PcdParser
,
1167 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
1168 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1169 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
1174 # This acts like the main() function for the script, unless it is 'import'ed into another
1177 if __name__
== '__main__':