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
)
85 self
._Macros
["WORKSPACE"] = os
.environ
["WORKSPACE"]
87 # for recursive parsing
91 # parsr status for parsing
93 self
._ValueList
= ['', '', '', '', '']
96 self
._CurrentLine
= ''
97 self
._SectionType
= MODEL_UNKNOWN
98 self
._SectionName
= ''
99 self
._InSubsection
= False
100 self
._SubsectionType
= MODEL_UNKNOWN
101 self
._SubsectionName
= ''
104 self
._Finished
= False
106 ## Store the parsed data in table
107 def _Store(self
, *Args
):
108 return self
._Table
.Insert(*Args
)
110 ## Virtual method for starting parse
112 raise NotImplementedError
114 ## Set parsing complete flag in both class and table
116 self
._Finished
= True
117 ## Do not set end flag when processing included files
119 self
._Table
.SetEndFlag()
121 ## Return the table containg parsed data
123 # If the parse complete flag is not set, this method will try to parse the
124 # file before return the table
127 if not self
._Finished
:
131 ## Get the parse complete flag
132 def _GetFinished(self
):
133 return self
._Finished
135 ## Set the complete flag
136 def _SetFinished(self
, Value
):
137 self
._Finished
= Value
139 ## Use [] style to query data in table, just for readability
141 # DataInfo = [data_type, scope1(arch), scope2(platform,moduletype)]
143 def __getitem__(self
, DataInfo
):
144 if type(DataInfo
) != type(()):
145 DataInfo
= (DataInfo
,)
146 return self
.Table
.Query(*DataInfo
)
148 ## Data parser for the common format in different type of file
150 # The common format in the meatfile is like
154 def _CommonParser(self
):
155 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
156 self
._ValueList
[0:len(TokenList
)] = TokenList
158 ## Data parser for the format in which there's path
160 # Only path can have macro used. So we need to replace them before use.
162 def _PathParser(self
):
163 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
164 self
._ValueList
[0:len(TokenList
)] = TokenList
165 if len(self
._Macros
) > 0:
166 for Index
in range(0, len(self
._ValueList
)):
167 Value
= self
._ValueList
[Index
]
168 if Value
== None or Value
== '':
170 self
._ValueList
[Index
] = NormPath(Value
, self
._Macros
)
172 ## Skip unsupported data
174 EdkLogger
.warn("Parser", "Unrecognized content", File
=self
.MetaFile
,
175 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
);
176 self
._ValueList
[0:1] = [self
._CurrentLine
]
178 ## Section header parser
180 # The section header is always in following format:
182 # [section_name.arch<.platform|module_type>]
184 def _SectionHeaderParser(self
):
186 self
._SectionName
= ''
188 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
191 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
)
192 # different section should not mix in one section
193 if self
._SectionName
!= '' and self
._SectionName
!= ItemList
[0].upper():
194 EdkLogger
.error('Parser', FORMAT_INVALID
, "Different section names in the same section",
195 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
196 self
._SectionName
= ItemList
[0].upper()
197 if self
._SectionName
in self
.DataType
:
198 self
._SectionType
= self
.DataType
[self
._SectionName
]
200 self
._SectionType
= MODEL_UNKNOWN
201 EdkLogger
.warn("Parser", "Unrecognized section", File
=self
.MetaFile
,
202 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
204 if len(ItemList
) > 1:
205 S1
= ItemList
[1].upper()
209 # S2 may be Platform or ModuleType
210 if len(ItemList
) > 2:
211 S2
= ItemList
[2].upper()
214 self
._Scope
.append([S1
, S2
])
216 # 'COMMON' must not be used with specific ARCHs at the same section
217 if 'COMMON' in ArchList
and len(ArchList
) > 1:
218 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
219 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
221 ## [defines] section parser
222 def _DefineParser(self
):
223 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
224 self
._ValueList
[0:len(TokenList
)] = TokenList
225 if self
._ValueList
[1] == '':
226 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
227 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
229 ## DEFINE name=value parser
230 def _MacroParser(self
):
231 TokenList
= GetSplitValueList(self
._CurrentLine
, ' ', 1)
232 MacroType
= TokenList
[0]
233 if len(TokenList
) < 2 or TokenList
[1] == '':
234 EdkLogger
.error('Parser', FORMAT_INVALID
, "No macro name/value given",
235 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
236 TokenList
= GetSplitValueList(TokenList
[1], TAB_EQUAL_SPLIT
, 1)
237 if TokenList
[0] == '':
238 EdkLogger
.error('Parser', FORMAT_INVALID
, "No macro name given",
239 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
241 # Macros defined in the command line override ones defined in the meta-data file
242 if not TokenList
[0] in self
._Macros
:
243 if len(TokenList
) == 1:
244 self
._Macros
[TokenList
[0]] = ''
246 # keep the macro definition for later use
247 self
._Macros
[TokenList
[0]] = ReplaceMacro(TokenList
[1], self
._Macros
, False)
249 return TokenList
[0], self
._Macros
[TokenList
[0]]
251 ## [BuildOptions] section parser
252 def _BuildOptionParser(self
):
253 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
254 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
255 if len(TokenList2
) == 2:
256 self
._ValueList
[0] = TokenList2
[0] # toolchain family
257 self
._ValueList
[1] = TokenList2
[1] # keys
259 self
._ValueList
[1] = TokenList
[0]
260 if len(TokenList
) == 2: # value
261 self
._ValueList
[2] = ReplaceMacro(TokenList
[1], self
._Macros
)
263 if self
._ValueList
[1].count('_') != 4:
267 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
268 ExtraData
=self
._CurrentLine
,
270 Line
=self
._LineIndex
+1
274 Table
= property(_GetTable
)
275 Finished
= property(_GetFinished
, _SetFinished
)
278 ## INF file parser class
280 # @param FilePath The path of platform description file
281 # @param FileType The raw data of DSC file
282 # @param Table Database used to retrieve module/package information
283 # @param Macros Macros used for replacement in file
285 class InfParser(MetaFileParser
):
286 # INF file supported data types (one type per section)
288 TAB_UNKNOWN
.upper() : MODEL_UNKNOWN
,
289 TAB_INF_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
290 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
291 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
292 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
293 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
294 TAB_PACKAGES
.upper() : MODEL_META_DATA_PACKAGE
,
295 TAB_NMAKE
.upper() : MODEL_META_DATA_NMAKE
,
296 TAB_INF_FIXED_PCD
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
297 TAB_INF_PATCH_PCD
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
298 TAB_INF_FEATURE_PCD
.upper() : MODEL_PCD_FEATURE_FLAG
,
299 TAB_INF_PCD_EX
.upper() : MODEL_PCD_DYNAMIC_EX
,
300 TAB_INF_PCD
.upper() : MODEL_PCD_DYNAMIC
,
301 TAB_SOURCES
.upper() : MODEL_EFI_SOURCE_FILE
,
302 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
303 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
304 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
305 TAB_DEPEX
.upper() : MODEL_EFI_DEPEX
,
306 TAB_BINARIES
.upper() : MODEL_EFI_BINARY_FILE
,
307 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
310 ## Constructor of InfParser
312 # Initialize object of InfParser
314 # @param FilePath The path of module description file
315 # @param FileType The raw data of DSC file
316 # @param Table Database used to retrieve module/package information
317 # @param Macros Macros used for replacement in file
319 def __init__(self
, FilePath
, FileType
, Table
, Macros
=None):
320 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
, Macros
)
326 self
._Content
= open(self
.MetaFile
, 'r').readlines()
328 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
330 # parse the file line by line
331 IsFindBlockComment
= False
333 for Index
in range(0, len(self
._Content
)):
334 # skip empty, commented, block commented lines
335 Line
= CleanString(self
._Content
[Index
], AllowCppStyleComment
=True)
337 if Index
+ 1 < len(self
._Content
):
338 NextLine
= CleanString(self
._Content
[Index
+ 1])
341 if Line
.find(DataType
.TAB_COMMENT_R8_START
) > -1:
342 IsFindBlockComment
= True
344 if Line
.find(DataType
.TAB_COMMENT_R8_END
) > -1:
345 IsFindBlockComment
= False
347 if IsFindBlockComment
:
350 self
._LineIndex
= Index
351 self
._CurrentLine
= Line
354 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
355 self
._SectionHeaderParser
()
357 # merge two lines specified by '\' in section NMAKE
358 elif self
._SectionType
== MODEL_META_DATA_NMAKE
:
361 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
364 if NextLine
[0] == TAB_SECTION_START
and NextLine
[-1] == TAB_SECTION_END
:
365 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
368 NmakeLine
= NmakeLine
+ ' ' + Line
[0:-1]
371 self
._CurrentLine
= NmakeLine
+ Line
373 elif Line
.upper().startswith('DEFINE '):
374 # file private macros
379 self
._ValueList
= ['','','']
380 # parse current line, result will be put in self._ValueList
381 self
._SectionParser
[self
._SectionType
](self
)
382 if self
._ValueList
== None:
385 # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
386 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
388 for Arch
, Platform
in self
._Scope
:
389 self
._Store
(self
._SectionType
,
402 if IsFindBlockComment
:
403 EdkLogger
.error("Parser", FORMAT_INVALID
, "Open block comments (starting with /*) are expected to end with */",
407 ## Data parser for the format in which there's path
409 # Only path can have macro used. So we need to replace them before use.
411 def _IncludeParser(self
):
412 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
413 self
._ValueList
[0:len(TokenList
)] = TokenList
414 if len(self
._Macros
) > 0:
415 for Index
in range(0, len(self
._ValueList
)):
416 Value
= self
._ValueList
[Index
]
417 if Value
.upper().find('$(EFI_SOURCE)\Edk'.upper()) > -1 or Value
.upper().find('$(EFI_SOURCE)/Edk'.upper()) > -1:
418 Value
= '$(EDK_SOURCE)' + Value
[17:]
419 if Value
.find('$(EFI_SOURCE)') > -1 or Value
.find('$(EDK_SOURCE)') > -1:
421 elif Value
.startswith('.'):
423 elif Value
.startswith('$('):
426 Value
= '$(EFI_SOURCE)/' + Value
428 if Value
== None or Value
== '':
430 self
._ValueList
[Index
] = NormPath(Value
, self
._Macros
)
432 ## Parse [Sources] section
434 # Only path can have macro used. So we need to replace them before use.
436 def _SourceFileParser(self
):
437 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
438 self
._ValueList
[0:len(TokenList
)] = TokenList
439 # For Acpi tables, remove macro like ' TABLE_NAME=Sata1'
440 if 'COMPONENT_TYPE' in self
._Macros
:
441 if self
._Macros
['COMPONENT_TYPE'].upper() == 'ACPITABLE':
442 self
._ValueList
[0] = GetSplitValueList(self
._ValueList
[0], ' ', 1)[0]
443 if self
._Macros
['BASE_NAME'] == 'Microcode':
445 if len(self
._Macros
) > 0:
446 for Index
in range(0, len(self
._ValueList
)):
447 Value
= self
._ValueList
[Index
]
448 if Value
== None or Value
== '':
450 self
._ValueList
[Index
] = NormPath(Value
, self
._Macros
)
452 ## Parse [Binaries] section
454 # Only path can have macro used. So we need to replace them before use.
456 def _BinaryFileParser(self
):
457 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 2)
458 if len(TokenList
) < 2:
459 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type or path specified",
460 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
461 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
463 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type specified",
464 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
465 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
467 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file path specified",
468 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
469 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
470 self
._ValueList
[0:len(TokenList
)] = TokenList
471 self
._ValueList
[1] = NormPath(self
._ValueList
[1], self
._Macros
)
473 ## [defines] section parser
474 def _DefineParser(self
):
475 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
476 self
._ValueList
[0:len(TokenList
)] = TokenList
477 self
._Macros
[TokenList
[0]] = ReplaceMacro(TokenList
[1], self
._Macros
, False)
478 if self
._ValueList
[1] == '':
479 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
480 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
482 ## [nmake] section parser (R8.x style only)
483 def _NmakeParser(self
):
484 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
485 self
._ValueList
[0:len(TokenList
)] = TokenList
487 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
, False)
488 # remove self-reference in macro setting
489 #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
491 ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
492 def _PcdParser(self
):
493 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
494 ValueList
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
495 if len(ValueList
) != 2:
496 EdkLogger
.error('Parser', FORMAT_INVALID
, "Illegal token space GUID and PCD name format",
497 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
498 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
499 self
._ValueList
[0:1] = ValueList
500 if len(TokenList
) > 1:
501 self
._ValueList
[2] = TokenList
[1]
502 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
503 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
504 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
505 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
507 ## [depex] section parser
508 def _DepexParser(self
):
509 self
._ValueList
[0:1] = [self
._CurrentLine
]
512 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
513 MODEL_META_DATA_HEADER
: _DefineParser
,
514 MODEL_META_DATA_BUILD_OPTION
: MetaFileParser
._BuildOptionParser
,
515 MODEL_EFI_INCLUDE
: _IncludeParser
, # for R8.x modules
516 MODEL_EFI_LIBRARY_INSTANCE
: MetaFileParser
._CommonParser
, # for R8.x modules
517 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
518 MODEL_META_DATA_PACKAGE
: MetaFileParser
._PathParser
,
519 MODEL_META_DATA_NMAKE
: _NmakeParser
, # for R8.x modules
520 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
521 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
522 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
523 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
524 MODEL_PCD_DYNAMIC
: _PcdParser
,
525 MODEL_EFI_SOURCE_FILE
: _SourceFileParser
,
526 MODEL_EFI_GUID
: MetaFileParser
._CommonParser
,
527 MODEL_EFI_PROTOCOL
: MetaFileParser
._CommonParser
,
528 MODEL_EFI_PPI
: MetaFileParser
._CommonParser
,
529 MODEL_EFI_DEPEX
: _DepexParser
,
530 MODEL_EFI_BINARY_FILE
: _BinaryFileParser
,
531 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
534 ## DSC file parser class
536 # @param FilePath The path of platform description file
537 # @param FileType The raw data of DSC file
538 # @param Table Database used to retrieve module/package information
539 # @param Macros Macros used for replacement in file
540 # @param Owner Owner ID (for sub-section parsing)
541 # @param From ID from which the data comes (for !INCLUDE directive)
543 class DscParser(MetaFileParser
):
544 # DSC file supported data types (one type per section)
546 TAB_SKUIDS
.upper() : MODEL_EFI_SKU_ID
,
547 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
548 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
549 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
550 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
551 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
552 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
553 TAB_PCDS_DYNAMIC_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_DEFAULT
,
554 TAB_PCDS_DYNAMIC_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_HII
,
555 TAB_PCDS_DYNAMIC_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_VPD
,
556 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT
,
557 TAB_PCDS_DYNAMIC_EX_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_HII
,
558 TAB_PCDS_DYNAMIC_EX_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_VPD
,
559 TAB_COMPONENTS
.upper() : MODEL_META_DATA_COMPONENT
,
560 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
.upper() : MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
,
561 TAB_DSC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
562 TAB_INCLUDE
.upper() : MODEL_META_DATA_INCLUDE
,
563 TAB_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
564 TAB_IF_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
565 TAB_IF_N_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
,
566 TAB_ELSE_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
,
567 TAB_ELSE
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
,
568 TAB_END_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
,
571 # sections which allow "!include" directive
572 _IncludeAllowedSection
= [
573 TAB_COMMON_DEFINES
.upper(),
574 TAB_LIBRARIES
.upper(),
575 TAB_LIBRARY_CLASSES
.upper(),
577 TAB_COMPONENTS
.upper(),
578 TAB_BUILD_OPTIONS
.upper(),
579 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper(),
580 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper(),
581 TAB_PCDS_FEATURE_FLAG_NULL
.upper(),
582 TAB_PCDS_DYNAMIC_DEFAULT_NULL
.upper(),
583 TAB_PCDS_DYNAMIC_HII_NULL
.upper(),
584 TAB_PCDS_DYNAMIC_VPD_NULL
.upper(),
585 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
.upper(),
586 TAB_PCDS_DYNAMIC_EX_HII_NULL
.upper(),
587 TAB_PCDS_DYNAMIC_EX_VPD_NULL
.upper(),
590 # operators which can be used in "!if/!ifdef/!ifndef" directives
592 "!" : lambda a
: not a
,
593 "!=" : lambda a
,b
: a
!=b
,
594 "==" : lambda a
,b
: a
==b
,
595 ">" : lambda a
,b
: a
>b
,
596 "<" : lambda a
,b
: a
<b
,
597 "=>" : lambda a
,b
: a
>=b
,
598 ">=" : lambda a
,b
: a
>=b
,
599 "<=" : lambda a
,b
: a
<=b
,
600 "=<" : lambda a
,b
: a
<=b
,
603 ## Constructor of DscParser
605 # Initialize object of DscParser
607 # @param FilePath The path of platform description file
608 # @param FileType The raw data of DSC file
609 # @param Table Database used to retrieve module/package information
610 # @param Macros Macros used for replacement in file
611 # @param Owner Owner ID (for sub-section parsing)
612 # @param From ID from which the data comes (for !INCLUDE directive)
614 def __init__(self
, FilePath
, FileType
, Table
, Macros
=None, Owner
=-1, From
=-1):
615 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
, Macros
, Owner
, From
)
616 # to store conditional directive evaluation result
622 if self
._Content
== None:
623 self
._Content
= open(self
.MetaFile
, 'r').readlines()
625 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
627 for Index
in range(0, len(self
._Content
)):
628 Line
= CleanString(self
._Content
[Index
])
632 self
._CurrentLine
= Line
633 self
._LineIndex
= Index
634 if self
._InSubsection
and self
._Owner
== -1:
635 self
._Owner
= self
._LastItem
638 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
639 self
._SectionHeaderParser
()
643 self
._InSubsection
= False
644 self
._SubsectionType
= MODEL_UNKNOWN
645 self
._SubsectionName
= ''
649 elif Line
[0] == TAB_OPTION_START
and Line
[-1] == TAB_OPTION_END
:
650 self
._SubsectionHeaderParser
()
654 self
._DirectiveParser
()
656 # file private macros
657 elif Line
.upper().startswith('DEFINE '):
658 (Name
, Value
) = self
._MacroParser
()
659 # Make the defined macro in DSC [Defines] section also
660 # available for FDF file.
661 if self
._SectionName
== TAB_COMMON_DEFINES
.upper():
662 self
._LastItem
= self
._Store
(
663 MODEL_META_DATA_GLOBAL_DEFINE
,
678 elif Line
.upper().startswith('EDK_GLOBAL '):
679 (Name
, Value
) = self
._MacroParser
()
680 for Arch
, ModuleType
in self
._Scope
:
681 self
._LastItem
= self
._Store
(
682 MODEL_META_DATA_DEFINE
,
699 if self
._InSubsection
:
700 SectionType
= self
._SubsectionType
701 SectionName
= self
._SubsectionName
703 SectionType
= self
._SectionType
704 SectionName
= self
._SectionName
706 self
._ValueList
= ['', '', '']
707 self
._SectionParser
[SectionType
](self
)
708 if self
._ValueList
== None:
712 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
713 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
715 for Arch
, ModuleType
in self
._Scope
:
716 self
._LastItem
= self
._Store
(
733 ## [defines] section parser
734 def _DefineParser(self
):
735 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
736 if len(TokenList
) < 2:
737 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
738 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
739 # 'FLASH_DEFINITION', 'OUTPUT_DIRECTORY' need special processing
740 if TokenList
[0] in ['FLASH_DEFINITION', 'OUTPUT_DIRECTORY']:
741 TokenList
[1] = NormPath(TokenList
[1], self
._Macros
)
742 self
._ValueList
[0:len(TokenList
)] = TokenList
743 # Treat elements in the [defines] section as global macros for FDF file.
744 self
._LastItem
= self
._Store
(
745 MODEL_META_DATA_GLOBAL_DEFINE
,
760 ## <subsection_header> parser
761 def _SubsectionHeaderParser(self
):
762 self
._SubsectionName
= self
._CurrentLine
[1:-1].upper()
763 if self
._SubsectionName
in self
.DataType
:
764 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
766 self
._SubsectionType
= MODEL_UNKNOWN
767 EdkLogger
.warn("Parser", "Unrecognized sub-section", File
=self
.MetaFile
,
768 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
770 ## Directive statement parser
771 def _DirectiveParser(self
):
772 self
._ValueList
= ['','','']
773 TokenList
= GetSplitValueList(self
._CurrentLine
, ' ', 1)
774 self
._ValueList
[0:len(TokenList
)] = TokenList
775 DirectiveName
= self
._ValueList
[0].upper()
776 if DirectiveName
not in self
.DataType
:
777 EdkLogger
.error("Parser", FORMAT_INVALID
, "Unknown directive [%s]" % DirectiveName
,
778 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
779 if DirectiveName
in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self
._ValueList
[1] == '':
780 EdkLogger
.error("Parser", FORMAT_INVALID
, "Missing expression",
781 File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
782 ExtraData
=self
._CurrentLine
)
783 # keep the directive in database first
784 self
._LastItem
= self
._Store
(
785 self
.DataType
[DirectiveName
],
800 # process the directive
801 if DirectiveName
== "!INCLUDE":
802 if not self
._SectionName
in self
._IncludeAllowedSection
:
803 EdkLogger
.error("Parser", FORMAT_INVALID
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
804 ExtraData
="'!include' is not allowed under section [%s]" % self
._SectionName
)
805 # the included file must be relative to the parsing file
806 IncludedFile
= os
.path
.join(self
._FileDir
, NormPath(self
._ValueList
[1], self
._Macros
))
807 Parser
= DscParser(IncludedFile
, self
._FileType
, self
._Table
, self
._Macros
, From
=self
._LastItem
)
808 # set the parser status with current status
809 Parser
._SectionName
= self
._SectionName
810 Parser
._SectionType
= self
._SectionType
811 Parser
._Scope
= self
._Scope
812 Parser
._Enabled
= self
._Enabled
816 EdkLogger
.error("Parser", PARSER_ERROR
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
817 ExtraData
="Failed to parse content in file %s" % IncludedFile
)
818 # insert an imaginary token in the DSC table to indicate its external dependency on another file
819 self
._Store
(MODEL_EXTERNAL_DEPENDENCY
, IncludedFile
, str(os
.stat(IncludedFile
)[8]), "")
820 # update current status with sub-parser's status
821 self
._SectionName
= Parser
._SectionName
822 self
._SectionType
= Parser
._SectionType
823 self
._Scope
= Parser
._Scope
824 self
._Enabled
= Parser
._Enabled
825 self
._Macros
.update(Parser
._Macros
)
827 if DirectiveName
in ["!IF", "!IFDEF", "!IFNDEF"]:
828 # evaluate the expression
829 Result
= self
._Evaluate
(self
._ValueList
[1])
830 if DirectiveName
== "!IFNDEF":
832 self
._Eval
.append(Result
)
833 elif DirectiveName
in ["!ELSEIF"]:
834 # evaluate the expression
835 self
._Eval
[-1] = (not self
._Eval
[-1]) & self
._Evaluate
(self
._ValueList
[1])
836 elif DirectiveName
in ["!ELSE"]:
837 self
._Eval
[-1] = not self
._Eval
[-1]
838 elif DirectiveName
in ["!ENDIF"]:
839 if len(self
._Eval
) > 0:
842 EdkLogger
.error("Parser", FORMAT_INVALID
, "!IF..[!ELSE]..!ENDIF doesn't match",
843 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
844 if self
._Eval
.Result
== False:
845 self
._Enabled
= 0 - len(self
._Eval
)
847 self
._Enabled
= len(self
._Eval
)
849 ## Evaluate the Token for its value; for now only macros are supported.
850 def _EvaluateToken(self
, TokenName
, Expression
):
851 if TokenName
.startswith("$(") and TokenName
.endswith(")"):
852 Name
= TokenName
[2:-1]
853 return self
._Macros
.get(Name
)
855 EdkLogger
.error('Parser', FORMAT_INVALID
, "Unknown operand '%(Token)s', "
856 "please use '$(%(Token)s)' if '%(Token)s' is a macro" % {"Token" : TokenName
},
857 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=Expression
)
859 ## Evaluate the value of expression in "if/ifdef/ifndef" directives
860 def _Evaluate(self
, Expression
):
861 TokenList
= Expression
.split()
862 TokenNumber
= len(TokenList
)
863 # one operand, guess it's just a macro name
865 TokenValue
= self
._EvaluateToken
(TokenList
[0], Expression
)
866 return TokenValue
!= None
867 # two operands, suppose it's "!xxx" format
868 elif TokenNumber
== 2:
870 if Op
not in self
._OP
_:
871 EdkLogger
.error('Parser', FORMAT_INVALID
, "Unsupported operator [%s]" % Op
, File
=self
.MetaFile
,
872 Line
=self
._LineIndex
+1, ExtraData
=Expression
)
873 if TokenList
[1].upper() == 'TRUE':
877 return self
._OP
_[Op
](Value
)
879 elif TokenNumber
== 3:
880 TokenValue
= self
._EvaluateToken
(TokenList
[0], Expression
)
881 if TokenValue
== None:
884 if Value
[0] in ["'", '"'] and Value
[-1] in ["'", '"']:
887 if Op
not in self
._OP
_:
888 EdkLogger
.error('Parser', FORMAT_INVALID
, "Unsupported operator [%s]" % Op
, File
=self
.MetaFile
,
889 Line
=self
._LineIndex
+1, ExtraData
=Expression
)
890 return self
._OP
_[Op
](TokenValue
, Value
)
892 EdkLogger
.error('Parser', FORMAT_INVALID
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
893 ExtraData
=Expression
)
895 ## PCD sections parser
898 # [PcdsPatchableInModule]
901 # [PcdsDynamicExDefault]
905 # [PcdsDynamicDefault]
909 def _PcdParser(self
):
910 TokenList
= GetSplitValueList(ReplaceMacro(self
._CurrentLine
, self
._Macros
), TAB_VALUE_SPLIT
, 1)
911 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
912 if len(TokenList
) == 2:
913 self
._ValueList
[2] = TokenList
[1]
914 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
915 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
916 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
917 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
918 if self
._ValueList
[2] == '':
919 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD value given",
920 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
921 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
923 ## [components] section parser
924 def _ComponentParser(self
):
925 if self
._CurrentLine
[-1] == '{':
926 self
._ValueList
[0] = self
._CurrentLine
[0:-1].strip()
927 self
._InSubsection
= True
929 self
._ValueList
[0] = self
._CurrentLine
930 if len(self
._Macros
) > 0:
931 self
._ValueList
[0] = NormPath(self
._ValueList
[0], self
._Macros
)
933 def _LibraryClassParser(self
):
934 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
935 if len(TokenList
) < 2:
936 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class or instance specified",
937 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
938 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
939 if TokenList
[0] == '':
940 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class specified",
941 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
942 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
943 if TokenList
[1] == '':
944 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library instance specified",
945 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
946 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
947 self
._ValueList
[0:len(TokenList
)] = TokenList
948 if len(self
._Macros
) > 0:
949 self
._ValueList
[1] = NormPath(self
._ValueList
[1], self
._Macros
)
951 def _CompponentSourceOverridePathParser(self
):
952 if len(self
._Macros
) > 0:
953 self
._ValueList
[0] = NormPath(self
._CurrentLine
, self
._Macros
)
956 MODEL_META_DATA_HEADER
: _DefineParser
,
957 MODEL_EFI_SKU_ID
: MetaFileParser
._CommonParser
,
958 MODEL_EFI_LIBRARY_INSTANCE
: MetaFileParser
._PathParser
,
959 MODEL_EFI_LIBRARY_CLASS
: _LibraryClassParser
,
960 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
961 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
962 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
963 MODEL_PCD_DYNAMIC_DEFAULT
: _PcdParser
,
964 MODEL_PCD_DYNAMIC_HII
: _PcdParser
,
965 MODEL_PCD_DYNAMIC_VPD
: _PcdParser
,
966 MODEL_PCD_DYNAMIC_EX_DEFAULT
: _PcdParser
,
967 MODEL_PCD_DYNAMIC_EX_HII
: _PcdParser
,
968 MODEL_PCD_DYNAMIC_EX_VPD
: _PcdParser
,
969 MODEL_META_DATA_COMPONENT
: _ComponentParser
,
970 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: _CompponentSourceOverridePathParser
,
971 MODEL_META_DATA_BUILD_OPTION
: MetaFileParser
._BuildOptionParser
,
972 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
973 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
976 ## DEC file parser class
978 # @param FilePath The path of platform description file
979 # @param FileType The raw data of DSC file
980 # @param Table Database used to retrieve module/package information
981 # @param Macros Macros used for replacement in file
983 class DecParser(MetaFileParser
):
984 # DEC file supported data types (one type per section)
986 TAB_DEC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
987 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
988 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
989 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
990 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
991 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
992 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
993 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
994 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
995 TAB_PCDS_DYNAMIC_NULL
.upper() : MODEL_PCD_DYNAMIC
,
996 TAB_PCDS_DYNAMIC_EX_NULL
.upper() : MODEL_PCD_DYNAMIC_EX
,
999 ## Constructor of DecParser
1001 # Initialize object of DecParser
1003 # @param FilePath The path of platform description file
1004 # @param FileType The raw data of DSC file
1005 # @param Table Database used to retrieve module/package information
1006 # @param Macros Macros used for replacement in file
1008 def __init__(self
, FilePath
, FileType
, Table
, Macro
=None):
1009 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
, Macro
, -1)
1015 if self
._Content
== None:
1016 self
._Content
= open(self
.MetaFile
, 'r').readlines()
1018 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
1020 for Index
in range(0, len(self
._Content
)):
1021 Line
, Comment
= CleanString2(self
._Content
[Index
])
1022 self
._CurrentLine
= Line
1023 self
._LineIndex
= Index
1025 # save comment for later use
1027 self
._Comments
.append((Comment
, self
._LineIndex
+1))
1033 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
1034 self
._SectionHeaderParser
()
1037 elif Line
.startswith('DEFINE '):
1040 elif len(self
._SectionType
) == 0:
1045 self
._ValueList
= ['','','']
1046 self
._SectionParser
[self
._SectionType
[0]](self
)
1047 if self
._ValueList
== None:
1052 # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,
1053 # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1
1055 for Arch
, ModuleType
, Type
in self
._Scope
:
1056 self
._LastItem
= self
._Store
(
1070 for Comment
, LineNo
in self
._Comments
:
1072 MODEL_META_DATA_COMMENT
,
1088 ## Section header parser
1090 # The section header is always in following format:
1092 # [section_name.arch<.platform|module_type>]
1094 def _SectionHeaderParser(self
):
1096 self
._SectionName
= ''
1097 self
._SectionType
= []
1099 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
1102 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
)
1104 # different types of PCD are permissible in one section
1105 self
._SectionName
= ItemList
[0].upper()
1106 if self
._SectionName
in self
.DataType
:
1107 if self
.DataType
[self
._SectionName
] not in self
._SectionType
:
1108 self
._SectionType
.append(self
.DataType
[self
._SectionName
])
1110 EdkLogger
.warn("Parser", "Unrecognized section", File
=self
.MetaFile
,
1111 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
1114 if MODEL_PCD_FEATURE_FLAG
in self
._SectionType
and len(self
._SectionType
) > 1:
1118 "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL
,
1120 Line
=self
._LineIndex
+1,
1121 ExtraData
=self
._CurrentLine
1124 if len(ItemList
) > 1:
1125 S1
= ItemList
[1].upper()
1129 # S2 may be Platform or ModuleType
1130 if len(ItemList
) > 2:
1131 S2
= ItemList
[2].upper()
1134 if [S1
, S2
, self
.DataType
[self
._SectionName
]] not in self
._Scope
:
1135 self
._Scope
.append([S1
, S2
, self
.DataType
[self
._SectionName
]])
1137 # 'COMMON' must not be used with specific ARCHs at the same section
1138 if 'COMMON' in ArchList
and len(ArchList
) > 1:
1139 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
1140 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
1142 ## [guids], [ppis] and [protocols] section parser
1143 def _GuidParser(self
):
1144 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1145 if len(TokenList
) < 2:
1146 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name or value specified",
1147 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1148 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1149 if TokenList
[0] == '':
1150 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name specified",
1151 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1152 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1153 if TokenList
[1] == '':
1154 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID value specified",
1155 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1156 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1157 if TokenList
[1][0] != '{' or TokenList
[1][-1] != '}' or GuidStructureStringToGuidString(TokenList
[1]) == '':
1158 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid GUID value format",
1159 ExtraData
=self
._CurrentLine
+ \
1160 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
1161 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1162 self
._ValueList
[0] = TokenList
[0]
1163 self
._ValueList
[1] = TokenList
[1]
1165 ## PCD sections parser
1167 # [PcdsFixedAtBuild]
1168 # [PcdsPatchableInModule]
1173 def _PcdParser(self
):
1174 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1175 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1176 # check PCD information
1177 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1178 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1179 ExtraData
=self
._CurrentLine
+ \
1180 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1181 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1182 # check PCD datum information
1183 if len(TokenList
) < 2 or TokenList
[1] == '':
1184 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD Datum information given",
1185 ExtraData
=self
._CurrentLine
+ \
1186 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1187 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1189 ValueList
= GetSplitValueList(TokenList
[1])
1190 # check if there's enough datum information given
1191 if len(ValueList
) != 3:
1192 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid PCD Datum information given",
1193 ExtraData
=self
._CurrentLine
+ \
1194 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1195 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1196 # check default value
1197 if ValueList
[0] == '':
1198 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DefaultValue in PCD Datum information",
1199 ExtraData
=self
._CurrentLine
+ \
1200 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1201 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1203 if ValueList
[1] == '':
1204 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DatumType in PCD Datum information",
1205 ExtraData
=self
._CurrentLine
+ \
1206 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1207 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1208 # check token of the PCD
1209 if ValueList
[2] == '':
1210 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing Token in PCD Datum information",
1211 ExtraData
=self
._CurrentLine
+ \
1212 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1213 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1214 # check format of default value against the datum type
1215 IsValid
, Cause
= CheckPcdDatum(ValueList
[1], ValueList
[0])
1217 EdkLogger
.error('Parser', FORMAT_INVALID
, Cause
, ExtraData
=self
._CurrentLine
,
1218 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1220 self
._ValueList
[2] = ValueList
[0].strip() + '|' + ValueList
[1].strip() + '|' + ValueList
[2].strip()
1223 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
1224 MODEL_EFI_INCLUDE
: MetaFileParser
._PathParser
,
1225 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
1226 MODEL_EFI_GUID
: _GuidParser
,
1227 MODEL_EFI_PPI
: _GuidParser
,
1228 MODEL_EFI_PROTOCOL
: _GuidParser
,
1229 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1230 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1231 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1232 MODEL_PCD_DYNAMIC
: _PcdParser
,
1233 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
1234 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1235 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
1240 # This acts like the main() function for the script, unless it is 'import'ed into another
1243 if __name__
== '__main__':