2 # This file is used to parse meta files
4 # Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
22 import Common
.EdkLogger
as EdkLogger
23 import Common
.GlobalData
as GlobalData
25 from CommonDataClass
.DataClass
import *
26 from Common
.DataType
import *
27 from Common
.String
import *
28 from Common
.Misc
import GuidStructureStringToGuidString
, CheckPcdDatum
, PathClass
, AnalyzePcdData
29 from Common
.Expression
import *
30 from CommonDataClass
.Exceptions
import *
32 from MetaFileTable
import MetaFileStorage
34 ## A decorator used to parse macro definition
35 def ParseMacro(Parser
):
36 def MacroParser(self
):
37 Match
= gMacroDefPattern
.match(self
._CurrentLine
)
39 # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method
43 TokenList
= GetSplitValueList(self
._CurrentLine
[Match
.end(1):], TAB_EQUAL_SPLIT
, 1)
46 EdkLogger
.error('Parser', FORMAT_INVALID
, "No macro name given",
47 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
48 if len(TokenList
) < 2:
52 Name
, Value
= TokenList
53 # Global macros can be only defined via environment variable
54 if Name
in GlobalData
.gGlobalDefines
:
55 EdkLogger
.error('Parser', FORMAT_INVALID
, "%s can only be defined via environment variable" % Name
,
56 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
57 # Only upper case letters, digit and '_' are allowed
58 if not gMacroNamePattern
.match(Name
):
59 EdkLogger
.error('Parser', FORMAT_INVALID
, "The macro name must be in the pattern [A-Z][A-Z0-9_]*",
60 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
62 Value
= ReplaceMacro(Value
, self
._Macros
)
63 if Type
in self
.DataType
:
64 self
._ItemType
= self
.DataType
[Type
]
66 self
._ItemType
= MODEL_META_DATA_DEFINE
67 # DEFINE defined macros
68 if Type
== TAB_DSC_DEFINES_DEFINE
:
70 # First judge whether this DEFINE is in conditional directive statements or not.
72 if type(self
) == DscParser
and self
._InDirective
> -1:
75 if type(self
) == DecParser
:
76 if MODEL_META_DATA_HEADER
in self
._SectionType
:
77 self
._FileLocalMacros
[Name
] = Value
79 self
._ConstructSectionMacroDict
(Name
, Value
)
80 elif self
._SectionType
== MODEL_META_DATA_HEADER
:
81 self
._FileLocalMacros
[Name
] = Value
83 self
._ConstructSectionMacroDict
(Name
, Value
)
85 # EDK_GLOBAL defined macros
86 elif type(self
) != DscParser
:
87 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL can only be used in .dsc file",
88 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
89 elif self
._SectionType
!= MODEL_META_DATA_HEADER
:
90 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL can only be used under [Defines] section",
91 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
92 elif (Name
in self
._FileLocalMacros
) and (self
._FileLocalMacros
[Name
] != Value
):
93 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL defined a macro with the same name and different value as one defined by 'DEFINE'",
94 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
96 self
._ValueList
= [Type
, Name
, Value
]
100 ## Base class of parser
102 # This class is used for derivation purpose. The specific parser for one kind
103 # type file must derive this class and implement some public interfaces.
105 # @param FilePath The path of platform description file
106 # @param FileType The raw data of DSC file
107 # @param Table Database used to retrieve module/package information
108 # @param Macros Macros used for replacement in file
109 # @param Owner Owner ID (for sub-section parsing)
110 # @param From ID from which the data comes (for !INCLUDE directive)
112 class MetaFileParser(object):
113 # data type (file content) for specific file type
116 # Parser objects used to implement singleton
121 # One file, one parser object. This factory method makes sure that there's
122 # only one object constructed for one meta file.
124 # @param Class class object of real AutoGen class
125 # (InfParser, DecParser or DscParser)
126 # @param FilePath The path of meta file
127 # @param *args The specific class related parameters
128 # @param **kwargs The specific class related dict parameters
130 def __new__(Class
, FilePath
, *args
, **kwargs
):
131 if FilePath
in Class
.MetaFiles
:
132 return Class
.MetaFiles
[FilePath
]
134 ParserObject
= super(MetaFileParser
, Class
).__new
__(Class
)
135 Class
.MetaFiles
[FilePath
] = ParserObject
138 ## Constructor of MetaFileParser
140 # Initialize object of MetaFileParser
142 # @param FilePath The path of platform description file
143 # @param FileType The raw data of DSC file
144 # @param Table Database used to retrieve module/package information
145 # @param Macros Macros used for replacement in file
146 # @param Owner Owner ID (for sub-section parsing)
147 # @param From ID from which the data comes (for !INCLUDE directive)
149 def __init__(self
, FilePath
, FileType
, Table
, Owner
=-1, From
=-1):
151 self
._RawTable
= Table
152 self
._FileType
= FileType
153 self
.MetaFile
= FilePath
154 self
._FileDir
= self
.MetaFile
.Dir
156 self
._FileLocalMacros
= {}
157 self
._SectionsMacroDict
= {}
159 # for recursive parsing
160 self
._Owner
= [Owner
]
163 # parsr status for parsing
164 self
._ValueList
= ['', '', '', '', '']
167 self
._CurrentLine
= ''
168 self
._SectionType
= MODEL_UNKNOWN
169 self
._SectionName
= ''
170 self
._InSubsection
= False
171 self
._SubsectionType
= MODEL_UNKNOWN
172 self
._SubsectionName
= ''
173 self
._ItemType
= MODEL_UNKNOWN
176 self
._Finished
= False
177 self
._PostProcessed
= False
178 # Different version of meta-file has different way to parse.
181 ## Store the parsed data in table
182 def _Store(self
, *Args
):
183 return self
._Table
.Insert(*Args
)
185 ## Virtual method for starting parse
187 raise NotImplementedError
189 ## Notify a post-process is needed
190 def DoPostProcess(self
):
191 self
._PostProcessed
= False
193 ## Set parsing complete flag in both class and table
195 self
._Finished
= True
196 ## Do not set end flag when processing included files
198 self
._Table
.SetEndFlag()
200 def _PostProcess(self
):
201 self
._PostProcessed
= True
203 ## Get the parse complete flag
204 def _GetFinished(self
):
205 return self
._Finished
207 ## Set the complete flag
208 def _SetFinished(self
, Value
):
209 self
._Finished
= Value
211 ## Use [] style to query data in table, just for readability
213 # DataInfo = [data_type, scope1(arch), scope2(platform/moduletype)]
215 def __getitem__(self
, DataInfo
):
216 if type(DataInfo
) != type(()):
217 DataInfo
= (DataInfo
,)
219 # Parse the file first, if necessary
220 if not self
._Finished
:
221 if self
._RawTable
.IsIntegrity():
222 self
._Finished
= True
224 self
._Table
= self
._RawTable
225 self
._PostProcessed
= False
228 # No specific ARCH or Platform given, use raw data
229 if self
._RawTable
and (len(DataInfo
) == 1 or DataInfo
[1] == None):
230 return self
._RawTable
.Query(*DataInfo
)
232 # Do post-process if necessary
233 if not self
._PostProcessed
:
236 return self
._Table
.Query(*DataInfo
)
238 ## Data parser for the common format in different type of file
240 # The common format in the meatfile is like
245 def _CommonParser(self
):
246 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
247 self
._ValueList
[0:len(TokenList
)] = TokenList
249 ## Data parser for the format in which there's path
251 # Only path can have macro used. So we need to replace them before use.
254 def _PathParser(self
):
255 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
256 self
._ValueList
[0:len(TokenList
)] = TokenList
257 # Don't do macro replacement for dsc file at this point
258 if type(self
) != DscParser
:
259 Macros
= self
._Macros
260 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
262 ## Skip unsupported data
264 EdkLogger
.warn("Parser", "Unrecognized content", File
=self
.MetaFile
,
265 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
);
266 self
._ValueList
[0:1] = [self
._CurrentLine
]
268 ## Section header parser
270 # The section header is always in following format:
272 # [section_name.arch<.platform|module_type>]
274 def _SectionHeaderParser(self
):
276 self
._SectionName
= ''
278 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
281 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
)
282 # different section should not mix in one section
283 if self
._SectionName
!= '' and self
._SectionName
!= ItemList
[0].upper():
284 EdkLogger
.error('Parser', FORMAT_INVALID
, "Different section names in the same section",
285 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
286 self
._SectionName
= ItemList
[0].upper()
287 if self
._SectionName
in self
.DataType
:
288 self
._SectionType
= self
.DataType
[self
._SectionName
]
290 self
._SectionType
= MODEL_UNKNOWN
291 EdkLogger
.warn("Parser", "Unrecognized section", File
=self
.MetaFile
,
292 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
294 if len(ItemList
) > 1:
295 S1
= ItemList
[1].upper()
299 # S2 may be Platform or ModuleType
300 if len(ItemList
) > 2:
301 S2
= ItemList
[2].upper()
304 self
._Scope
.append([S1
, S2
])
306 # 'COMMON' must not be used with specific ARCHs at the same section
307 if 'COMMON' in ArchList
and len(ArchList
) > 1:
308 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
309 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
310 # If the section information is needed later, it should be stored in database
311 self
._ValueList
[0] = self
._SectionName
313 ## [defines] section parser
315 def _DefineParser(self
):
316 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
317 self
._ValueList
[1:len(TokenList
)] = TokenList
318 if not self
._ValueList
[1]:
319 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
320 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
321 if not self
._ValueList
[2]:
322 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
323 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
325 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
326 Name
, Value
= self
._ValueList
[1], self
._ValueList
[2]
327 # Sometimes, we need to make differences between EDK and EDK2 modules
328 if Name
== 'INF_VERSION':
330 self
._Version
= int(Value
, 0)
332 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid version number",
333 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
335 if type(self
) == InfParser
and self
._Version
< 0x00010005:
336 # EDK module allows using defines as macros
337 self
._FileLocalMacros
[Name
] = Value
338 self
._Defines
[Name
] = Value
340 ## [BuildOptions] section parser
342 def _BuildOptionParser(self
):
343 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
344 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
345 if len(TokenList2
) == 2:
346 self
._ValueList
[0] = TokenList2
[0] # toolchain family
347 self
._ValueList
[1] = TokenList2
[1] # keys
349 self
._ValueList
[1] = TokenList
[0]
350 if len(TokenList
) == 2 and type(self
) != DscParser
: # value
351 self
._ValueList
[2] = ReplaceMacro(TokenList
[1], self
._Macros
)
353 if self
._ValueList
[1].count('_') != 4:
357 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
358 ExtraData
=self
._CurrentLine
,
360 Line
=self
._LineIndex
+1
363 def _GetMacros(self
):
365 Macros
.update(self
._FileLocalMacros
)
366 Macros
.update(self
._GetApplicableSectionMacro
())
369 ## Construct section Macro dict
370 def _ConstructSectionMacroDict(self
, Name
, Value
):
371 ScopeKey
= [(Scope
[0], Scope
[1]) for Scope
in self
._Scope
]
372 ScopeKey
= tuple(ScopeKey
)
373 SectionDictKey
= self
._SectionType
, ScopeKey
375 # DecParser SectionType is a list, will contain more than one item only in Pcd Section
376 # As Pcd section macro usage is not alllowed, so here it is safe
378 if type(self
) == DecParser
:
379 SectionDictKey
= self
._SectionType
[0], ScopeKey
380 if SectionDictKey
not in self
._SectionsMacroDict
:
381 self
._SectionsMacroDict
[SectionDictKey
] = {}
382 SectionLocalMacros
= self
._SectionsMacroDict
[SectionDictKey
]
383 SectionLocalMacros
[Name
] = Value
385 ## Get section Macros that are applicable to current line, which may come from other sections
386 ## that share the same name while scope is wider
387 def _GetApplicableSectionMacro(self
):
394 ActiveSectionType
= self
._SectionType
395 if type(self
) == DecParser
:
396 ActiveSectionType
= self
._SectionType
[0]
398 for (SectionType
, Scope
) in self
._SectionsMacroDict
:
399 if SectionType
!= ActiveSectionType
:
402 for ActiveScope
in self
._Scope
:
403 Scope0
, Scope1
= ActiveScope
[0], ActiveScope
[1]
404 if(Scope0
, Scope1
) not in Scope
:
407 SpeSpeMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
409 for ActiveScope
in self
._Scope
:
410 Scope0
, Scope1
= ActiveScope
[0], ActiveScope
[1]
411 if(Scope0
, Scope1
) not in Scope
and (Scope0
, "COMMON") not in Scope
and ("COMMON", Scope1
) not in Scope
:
414 ComSpeMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
416 if ("COMMON", "COMMON") in Scope
:
417 ComComMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
419 Macros
.update(ComComMacroDict
)
420 Macros
.update(ComSpeMacroDict
)
421 Macros
.update(SpeSpeMacroDict
)
426 Finished
= property(_GetFinished
, _SetFinished
)
427 _Macros
= property(_GetMacros
)
430 ## INF file parser class
432 # @param FilePath The path of platform description file
433 # @param FileType The raw data of DSC file
434 # @param Table Database used to retrieve module/package information
435 # @param Macros Macros used for replacement in file
437 class InfParser(MetaFileParser
):
438 # INF file supported data types (one type per section)
440 TAB_UNKNOWN
.upper() : MODEL_UNKNOWN
,
441 TAB_INF_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
442 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
443 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
444 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
445 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
446 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
447 TAB_PACKAGES
.upper() : MODEL_META_DATA_PACKAGE
,
448 TAB_NMAKE
.upper() : MODEL_META_DATA_NMAKE
,
449 TAB_INF_FIXED_PCD
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
450 TAB_INF_PATCH_PCD
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
451 TAB_INF_FEATURE_PCD
.upper() : MODEL_PCD_FEATURE_FLAG
,
452 TAB_INF_PCD_EX
.upper() : MODEL_PCD_DYNAMIC_EX
,
453 TAB_INF_PCD
.upper() : MODEL_PCD_DYNAMIC
,
454 TAB_SOURCES
.upper() : MODEL_EFI_SOURCE_FILE
,
455 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
456 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
457 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
458 TAB_DEPEX
.upper() : MODEL_EFI_DEPEX
,
459 TAB_BINARIES
.upper() : MODEL_EFI_BINARY_FILE
,
460 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
463 ## Constructor of InfParser
465 # Initialize object of InfParser
467 # @param FilePath The path of module description file
468 # @param FileType The raw data of DSC file
469 # @param Table Database used to retrieve module/package information
470 # @param Macros Macros used for replacement in file
472 def __init__(self
, FilePath
, FileType
, Table
):
473 # prevent re-initialization
474 if hasattr(self
, "_Table"):
476 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
)
483 Content
= open(str(self
.MetaFile
), 'r').readlines()
485 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
487 # parse the file line by line
488 IsFindBlockComment
= False
490 for Index
in range(0, len(Content
)):
491 # skip empty, commented, block commented lines
492 Line
= CleanString(Content
[Index
], AllowCppStyleComment
=True)
494 if Index
+ 1 < len(Content
):
495 NextLine
= CleanString(Content
[Index
+ 1])
498 if Line
.find(DataType
.TAB_COMMENT_EDK_START
) > -1:
499 IsFindBlockComment
= True
501 if Line
.find(DataType
.TAB_COMMENT_EDK_END
) > -1:
502 IsFindBlockComment
= False
504 if IsFindBlockComment
:
507 self
._LineIndex
= Index
508 self
._CurrentLine
= Line
511 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
512 self
._SectionHeaderParser
()
513 # Check invalid sections
514 if self
._Version
< 0x00010005:
515 if self
._SectionType
in [MODEL_META_DATA_BUILD_OPTION
,
516 MODEL_EFI_LIBRARY_CLASS
,
517 MODEL_META_DATA_PACKAGE
,
518 MODEL_PCD_FIXED_AT_BUILD
,
519 MODEL_PCD_PATCHABLE_IN_MODULE
,
520 MODEL_PCD_FEATURE_FLAG
,
521 MODEL_PCD_DYNAMIC_EX
,
526 MODEL_META_DATA_USER_EXTENSION
]:
527 EdkLogger
.error('Parser', FORMAT_INVALID
,
528 "Section [%s] is not allowed in inf file without version" % (self
._SectionName
),
529 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
530 elif self
._SectionType
in [MODEL_EFI_INCLUDE
,
531 MODEL_EFI_LIBRARY_INSTANCE
,
532 MODEL_META_DATA_NMAKE
]:
533 EdkLogger
.error('Parser', FORMAT_INVALID
,
534 "Section [%s] is not allowed in inf file with version 0x%08x" % (self
._SectionName
, self
._Version
),
535 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
537 # merge two lines specified by '\' in section NMAKE
538 elif self
._SectionType
== MODEL_META_DATA_NMAKE
:
541 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
544 if NextLine
[0] == TAB_SECTION_START
and NextLine
[-1] == TAB_SECTION_END
:
545 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
548 NmakeLine
= NmakeLine
+ ' ' + Line
[0:-1]
551 self
._CurrentLine
= NmakeLine
+ Line
555 self
._ValueList
= ['','','']
556 # parse current line, result will be put in self._ValueList
557 self
._SectionParser
[self
._SectionType
](self
)
558 if self
._ValueList
== None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
562 # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
563 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
565 for Arch
, Platform
in self
._Scope
:
566 self
._Store
(self
._SectionType
,
579 if IsFindBlockComment
:
580 EdkLogger
.error("Parser", FORMAT_INVALID
, "Open block comments (starting with /*) are expected to end with */",
584 ## Data parser for the format in which there's path
586 # Only path can have macro used. So we need to replace them before use.
588 def _IncludeParser(self
):
589 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
590 self
._ValueList
[0:len(TokenList
)] = TokenList
591 Macros
= self
._Macros
593 for Index
in range(0, len(self
._ValueList
)):
594 Value
= self
._ValueList
[Index
]
598 if Value
.upper().find('$(EFI_SOURCE)\Edk'.upper()) > -1 or Value
.upper().find('$(EFI_SOURCE)/Edk'.upper()) > -1:
599 Value
= '$(EDK_SOURCE)' + Value
[17:]
600 if Value
.find('$(EFI_SOURCE)') > -1 or Value
.find('$(EDK_SOURCE)') > -1:
602 elif Value
.startswith('.'):
604 elif Value
.startswith('$('):
607 Value
= '$(EFI_SOURCE)/' + Value
609 self
._ValueList
[Index
] = ReplaceMacro(Value
, Macros
)
611 ## Parse [Sources] section
613 # Only path can have macro used. So we need to replace them before use.
616 def _SourceFileParser(self
):
617 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
618 self
._ValueList
[0:len(TokenList
)] = TokenList
619 Macros
= self
._Macros
620 # For Acpi tables, remove macro like ' TABLE_NAME=Sata1'
621 if 'COMPONENT_TYPE' in Macros
:
622 if self
._Defines
['COMPONENT_TYPE'].upper() == 'ACPITABLE':
623 self
._ValueList
[0] = GetSplitValueList(self
._ValueList
[0], ' ', 1)[0]
624 if self
._Defines
['BASE_NAME'] == 'Microcode':
626 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
628 ## Parse [Binaries] section
630 # Only path can have macro used. So we need to replace them before use.
633 def _BinaryFileParser(self
):
634 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 2)
635 if len(TokenList
) < 2:
636 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type or path specified",
637 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
638 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
640 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type specified",
641 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
642 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
644 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file path specified",
645 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
646 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
647 self
._ValueList
[0:len(TokenList
)] = TokenList
648 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
650 ## [nmake] section parser (Edk.x style only)
651 def _NmakeParser(self
):
652 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
653 self
._ValueList
[0:len(TokenList
)] = TokenList
655 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
656 # remove self-reference in macro setting
657 #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
659 ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
661 def _PcdParser(self
):
662 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
663 ValueList
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
664 if len(ValueList
) != 2:
665 EdkLogger
.error('Parser', FORMAT_INVALID
, "Illegal token space GUID and PCD name format",
666 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
667 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
668 self
._ValueList
[0:1] = ValueList
669 if len(TokenList
) > 1:
670 self
._ValueList
[2] = TokenList
[1]
671 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
672 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
673 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
674 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
676 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
677 if self
._ValueList
[2] != '':
678 InfPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
679 if InfPcdValueList
[0] in ['True', 'true', 'TRUE']:
680 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '1', 1);
681 elif InfPcdValueList
[0] in ['False', 'false', 'FALSE']:
682 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '0', 1);
684 ## [depex] section parser
686 def _DepexParser(self
):
687 self
._ValueList
[0:1] = [self
._CurrentLine
]
690 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
691 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
692 MODEL_META_DATA_BUILD_OPTION
: MetaFileParser
._BuildOptionParser
,
693 MODEL_EFI_INCLUDE
: _IncludeParser
, # for Edk.x modules
694 MODEL_EFI_LIBRARY_INSTANCE
: MetaFileParser
._CommonParser
, # for Edk.x modules
695 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
696 MODEL_META_DATA_PACKAGE
: MetaFileParser
._PathParser
,
697 MODEL_META_DATA_NMAKE
: _NmakeParser
, # for Edk.x modules
698 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
699 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
700 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
701 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
702 MODEL_PCD_DYNAMIC
: _PcdParser
,
703 MODEL_EFI_SOURCE_FILE
: _SourceFileParser
,
704 MODEL_EFI_GUID
: MetaFileParser
._CommonParser
,
705 MODEL_EFI_PROTOCOL
: MetaFileParser
._CommonParser
,
706 MODEL_EFI_PPI
: MetaFileParser
._CommonParser
,
707 MODEL_EFI_DEPEX
: _DepexParser
,
708 MODEL_EFI_BINARY_FILE
: _BinaryFileParser
,
709 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
712 ## DSC file parser class
714 # @param FilePath The path of platform description file
715 # @param FileType The raw data of DSC file
716 # @param Table Database used to retrieve module/package information
717 # @param Macros Macros used for replacement in file
718 # @param Owner Owner ID (for sub-section parsing)
719 # @param From ID from which the data comes (for !INCLUDE directive)
721 class DscParser(MetaFileParser
):
722 # DSC file supported data types (one type per section)
724 TAB_SKUIDS
.upper() : MODEL_EFI_SKU_ID
,
725 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
726 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
727 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
728 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
729 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
730 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
731 TAB_PCDS_DYNAMIC_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_DEFAULT
,
732 TAB_PCDS_DYNAMIC_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_HII
,
733 TAB_PCDS_DYNAMIC_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_VPD
,
734 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT
,
735 TAB_PCDS_DYNAMIC_EX_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_HII
,
736 TAB_PCDS_DYNAMIC_EX_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_VPD
,
737 TAB_COMPONENTS
.upper() : MODEL_META_DATA_COMPONENT
,
738 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
.upper() : MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
,
739 TAB_DSC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
740 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
741 TAB_DSC_DEFINES_EDKGLOBAL
: MODEL_META_DATA_GLOBAL_DEFINE
,
742 TAB_INCLUDE
.upper() : MODEL_META_DATA_INCLUDE
,
743 TAB_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
744 TAB_IF_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
745 TAB_IF_N_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
,
746 TAB_ELSE_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
,
747 TAB_ELSE
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
,
748 TAB_END_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
,
751 # Valid names in define section
758 "SUPPORTED_ARCHITECTURES",
767 "FIX_LOAD_TOP_MEMORY_ADDRESS"
770 SymbolPattern
= ValueExpression
.SymbolPattern
772 ## Constructor of DscParser
774 # Initialize object of DscParser
776 # @param FilePath The path of platform description file
777 # @param FileType The raw data of DSC file
778 # @param Table Database used to retrieve module/package information
779 # @param Macros Macros used for replacement in file
780 # @param Owner Owner ID (for sub-section parsing)
781 # @param From ID from which the data comes (for !INCLUDE directive)
783 def __init__(self
, FilePath
, FileType
, Table
, Owner
=-1, From
=-1):
784 # prevent re-initialization
785 if hasattr(self
, "_Table"):
787 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
, Owner
, From
)
788 self
._Version
= 0x00010005 # Only EDK2 dsc file is supported
789 # to store conditional directive evaluation result
790 self
._DirectiveStack
= []
791 self
._DirectiveEvalStack
= []
795 # Specify whether current line is in uncertain condition
797 self
._InDirective
= -1
799 # Final valid replacable symbols
802 # Map the ID between the original table and new table to track
805 self
._IdMapping
= {-1:-1}
811 Content
= open(str(self
.MetaFile
), 'r').readlines()
813 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
815 for Index
in range(0, len(Content
)):
816 Line
= CleanString(Content
[Index
])
821 self
._CurrentLine
= Line
822 self
._LineIndex
= Index
823 if self
._InSubsection
and self
._Owner
[-1] == -1:
824 self
._Owner
.append(self
._LastItem
)
827 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
828 self
._SectionType
= MODEL_META_DATA_SECTION_HEADER
830 elif Line
[0] == '}' and self
._InSubsection
:
831 self
._InSubsection
= False
832 self
._SubsectionType
= MODEL_UNKNOWN
833 self
._SubsectionName
= ''
837 elif Line
[0] == TAB_OPTION_START
and Line
[-1] == TAB_OPTION_END
:
838 self
._SubsectionType
= MODEL_META_DATA_SUBSECTION_HEADER
841 self
._DirectiveParser
()
844 if self
._InSubsection
:
845 SectionType
= self
._SubsectionType
847 SectionType
= self
._SectionType
848 self
._ItemType
= SectionType
850 self
._ValueList
= ['', '', '']
851 self
._SectionParser
[SectionType
](self
)
852 if self
._ValueList
== None:
855 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
856 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
858 for Arch
, ModuleType
in self
._Scope
:
859 self
._LastItem
= self
._Store
(
875 if self
._DirectiveStack
:
876 Type
, Line
, Text
= self
._DirectiveStack
[-1]
877 EdkLogger
.error('Parser', FORMAT_INVALID
, "No matching '!endif' found",
878 ExtraData
=Text
, File
=self
.MetaFile
, Line
=Line
)
881 ## <subsection_header> parser
882 def _SubsectionHeaderParser(self
):
883 self
._SubsectionName
= self
._CurrentLine
[1:-1].upper()
884 if self
._SubsectionName
in self
.DataType
:
885 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
887 self
._SubsectionType
= MODEL_UNKNOWN
888 EdkLogger
.warn("Parser", "Unrecognized sub-section", File
=self
.MetaFile
,
889 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
890 self
._ValueList
[0] = self
._SubsectionName
892 ## Directive statement parser
893 def _DirectiveParser(self
):
894 self
._ValueList
= ['','','']
895 TokenList
= GetSplitValueList(self
._CurrentLine
, ' ', 1)
896 self
._ValueList
[0:len(TokenList
)] = TokenList
899 DirectiveName
= self
._ValueList
[0].upper()
900 if DirectiveName
not in self
.DataType
:
901 EdkLogger
.error("Parser", FORMAT_INVALID
, "Unknown directive [%s]" % DirectiveName
,
902 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
904 if DirectiveName
in ['!IF', '!IFDEF', '!IFNDEF']:
905 self
._InDirective
+= 1
907 if DirectiveName
in ['!ENDIF']:
908 self
._InDirective
-= 1
910 if DirectiveName
in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self
._ValueList
[1] == '':
911 EdkLogger
.error("Parser", FORMAT_INVALID
, "Missing expression",
912 File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
913 ExtraData
=self
._CurrentLine
)
915 ItemType
= self
.DataType
[DirectiveName
]
916 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
917 # Remove all directives between !if and !endif, including themselves
918 while self
._DirectiveStack
:
919 # Remove any !else or !elseif
920 DirectiveInfo
= self
._DirectiveStack
.pop()
921 if DirectiveInfo
[0] in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
922 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
923 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
926 EdkLogger
.error("Parser", FORMAT_INVALID
, "Redundant '!endif'",
927 File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
928 ExtraData
=self
._CurrentLine
)
929 elif ItemType
!= MODEL_META_DATA_INCLUDE
:
930 # Break if there's a !else is followed by a !elseif
931 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
and \
932 self
._DirectiveStack
and \
933 self
._DirectiveStack
[-1][0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
934 EdkLogger
.error("Parser", FORMAT_INVALID
, "'!elseif' after '!else'",
935 File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
936 ExtraData
=self
._CurrentLine
)
937 self
._DirectiveStack
.append((ItemType
, self
._LineIndex
+1, self
._CurrentLine
))
939 EdkLogger
.error('Parser', FORMAT_INVALID
,
940 "No '!include' allowed in included file",
941 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
,
942 Line
=self
._LineIndex
+1)
945 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
946 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
948 self
._LastItem
= self
._Store
(
964 ## [defines] section parser
966 def _DefineParser(self
):
967 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
968 self
._ValueList
[1:len(TokenList
)] = TokenList
971 if not self
._ValueList
[1]:
972 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
973 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
974 if not self
._ValueList
[2]:
975 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
976 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
977 if not self
._ValueList
[1] in self
.DefineKeywords
:
978 EdkLogger
.error('Parser', FORMAT_INVALID
,
979 "Unknown keyword found: %s. "
980 "If this is a macro you must "
981 "add it as a DEFINE in the DSC" % self
._ValueList
[1],
982 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
983 self
._Defines
[self
._ValueList
[1]] = self
._ValueList
[2]
984 self
._ItemType
= self
.DataType
[TAB_DSC_DEFINES
.upper()]
987 def _SkuIdParser(self
):
988 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
989 if len(TokenList
) != 2:
990 EdkLogger
.error('Parser', FORMAT_INVALID
, "Correct format is '<Integer>|<UiName>'",
991 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
992 self
._ValueList
[0:len(TokenList
)] = TokenList
994 ## Parse Edk style of library modules
996 def _LibraryInstanceParser(self
):
997 self
._ValueList
[0] = self
._CurrentLine
999 ## PCD sections parser
1001 # [PcdsFixedAtBuild]
1002 # [PcdsPatchableInModule]
1005 # [PcdsDynamicExDefault]
1006 # [PcdsDynamicExVpd]
1007 # [PcdsDynamicExHii]
1009 # [PcdsDynamicDefault]
1014 def _PcdParser(self
):
1015 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1016 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1017 if len(TokenList
) == 2:
1018 self
._ValueList
[2] = TokenList
[1]
1019 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1020 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1021 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1022 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1023 if self
._ValueList
[2] == '':
1024 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD value given",
1025 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1026 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1027 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
1028 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
1029 if DscPcdValueList
[0] in ['True', 'true', 'TRUE']:
1030 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '1', 1);
1031 elif DscPcdValueList
[0] in ['False', 'false', 'FALSE']:
1032 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '0', 1);
1034 ## [components] section parser
1036 def _ComponentParser(self
):
1037 if self
._CurrentLine
[-1] == '{':
1038 self
._ValueList
[0] = self
._CurrentLine
[0:-1].strip()
1039 self
._InSubsection
= True
1041 self
._ValueList
[0] = self
._CurrentLine
1043 ## [LibraryClasses] section
1045 def _LibraryClassParser(self
):
1046 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1047 if len(TokenList
) < 2:
1048 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class or instance specified",
1049 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1050 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1051 if TokenList
[0] == '':
1052 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class specified",
1053 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1054 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1055 if TokenList
[1] == '':
1056 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library instance specified",
1057 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1058 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1060 self
._ValueList
[0:len(TokenList
)] = TokenList
1062 def _CompponentSourceOverridePathParser(self
):
1063 self
._ValueList
[0] = self
._CurrentLine
1065 ## [BuildOptions] section parser
1067 def _BuildOptionParser(self
):
1068 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1069 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
1070 if len(TokenList2
) == 2:
1071 self
._ValueList
[0] = TokenList2
[0] # toolchain family
1072 self
._ValueList
[1] = TokenList2
[1] # keys
1074 self
._ValueList
[1] = TokenList
[0]
1075 if len(TokenList
) == 2: # value
1076 self
._ValueList
[2] = TokenList
[1]
1078 if self
._ValueList
[1].count('_') != 4:
1082 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
1083 ExtraData
=self
._CurrentLine
,
1085 Line
=self
._LineIndex
+1
1088 ## Override parent's method since we'll do all macro replacements in parser
1089 def _GetMacros(self
):
1091 Macros
.update(self
._FileLocalMacros
)
1092 Macros
.update(self
._GetApplicableSectionMacro
())
1093 Macros
.update(GlobalData
.gEdkGlobal
)
1094 Macros
.update(GlobalData
.gPlatformDefines
)
1095 Macros
.update(GlobalData
.gCommandLineDefines
)
1096 # PCD cannot be referenced in macro definition
1097 if self
._ItemType
not in [MODEL_META_DATA_DEFINE
, MODEL_META_DATA_GLOBAL_DEFINE
]:
1098 Macros
.update(self
._Symbols
)
1101 def _PostProcess(self
):
1103 MODEL_META_DATA_SECTION_HEADER
: self
.__ProcessSectionHeader
,
1104 MODEL_META_DATA_SUBSECTION_HEADER
: self
.__ProcessSubsectionHeader
,
1105 MODEL_META_DATA_HEADER
: self
.__ProcessDefine
,
1106 MODEL_META_DATA_DEFINE
: self
.__ProcessDefine
,
1107 MODEL_META_DATA_GLOBAL_DEFINE
: self
.__ProcessDefine
,
1108 MODEL_META_DATA_INCLUDE
: self
.__ProcessDirective
,
1109 MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
: self
.__ProcessDirective
,
1110 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
: self
.__ProcessDirective
,
1111 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
: self
.__ProcessDirective
,
1112 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
: self
.__ProcessDirective
,
1113 MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
: self
.__ProcessDirective
,
1114 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
: self
.__ProcessDirective
,
1115 MODEL_EFI_SKU_ID
: self
.__ProcessSkuId
,
1116 MODEL_EFI_LIBRARY_INSTANCE
: self
.__ProcessLibraryInstance
,
1117 MODEL_EFI_LIBRARY_CLASS
: self
.__ProcessLibraryClass
,
1118 MODEL_PCD_FIXED_AT_BUILD
: self
.__ProcessPcd
,
1119 MODEL_PCD_PATCHABLE_IN_MODULE
: self
.__ProcessPcd
,
1120 MODEL_PCD_FEATURE_FLAG
: self
.__ProcessPcd
,
1121 MODEL_PCD_DYNAMIC_DEFAULT
: self
.__ProcessPcd
,
1122 MODEL_PCD_DYNAMIC_HII
: self
.__ProcessPcd
,
1123 MODEL_PCD_DYNAMIC_VPD
: self
.__ProcessPcd
,
1124 MODEL_PCD_DYNAMIC_EX_DEFAULT
: self
.__ProcessPcd
,
1125 MODEL_PCD_DYNAMIC_EX_HII
: self
.__ProcessPcd
,
1126 MODEL_PCD_DYNAMIC_EX_VPD
: self
.__ProcessPcd
,
1127 MODEL_META_DATA_COMPONENT
: self
.__ProcessComponent
,
1128 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: self
.__ProcessSourceOverridePath
,
1129 MODEL_META_DATA_BUILD_OPTION
: self
.__ProcessBuildOption
,
1130 MODEL_UNKNOWN
: self
._Skip
,
1131 MODEL_META_DATA_USER_EXTENSION
: self
._Skip
,
1134 self
._Table
= MetaFileStorage(self
._RawTable
.Cur
, self
.MetaFile
, MODEL_FILE_DSC
, True)
1135 self
._Table
.Create()
1136 self
._DirectiveStack
= []
1137 self
._DirectiveEvalStack
= []
1138 self
._FileWithError
= self
.MetaFile
1139 self
._FileLocalMacros
= {}
1140 self
._SectionsMacroDict
= {}
1141 GlobalData
.gPlatformDefines
= {}
1143 # Get all macro and PCD which has straitforward value
1144 self
.__RetrievePcdValue
()
1145 self
._Content
= self
._RawTable
.GetAll()
1146 self
._ContentIndex
= 0
1147 while self
._ContentIndex
< len(self
._Content
) :
1148 Id
, self
._ItemType
, V1
, V2
, V3
, S1
, S2
, Owner
, self
._From
, \
1149 LineStart
, ColStart
, LineEnd
, ColEnd
, Enabled
= self
._Content
[self
._ContentIndex
]
1152 self
._FileWithError
= self
.MetaFile
1154 self
._ContentIndex
+= 1
1156 self
._Scope
= [[S1
, S2
]]
1157 self
._LineIndex
= LineStart
- 1
1158 self
._ValueList
= [V1
, V2
, V3
]
1161 Processer
[self
._ItemType
]()
1162 except EvaluationException
, Excpt
:
1164 # Only catch expression evaluation error here. We need to report
1165 # the precise number of line on which the error occurred
1167 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
1168 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1169 Line
=self
._LineIndex
+1)
1170 except MacroException
, Excpt
:
1171 EdkLogger
.error('Parser', FORMAT_INVALID
, str(Excpt
),
1172 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1173 Line
=self
._LineIndex
+1)
1175 if self
._ValueList
== None:
1178 NewOwner
= self
._IdMapping
.get(Owner
, -1)
1179 self
._Enabled
= int((not self
._DirectiveEvalStack
) or (False not in self
._DirectiveEvalStack
))
1180 self
._LastItem
= self
._Store
(
1195 self
._IdMapping
[Id
] = self
._LastItem
1197 GlobalData
.gPlatformDefines
.update(self
._FileLocalMacros
)
1198 self
._PostProcessed
= True
1199 self
._Content
= None
1201 def __ProcessSectionHeader(self
):
1202 self
._SectionName
= self
._ValueList
[0]
1203 if self
._SectionName
in self
.DataType
:
1204 self
._SectionType
= self
.DataType
[self
._SectionName
]
1206 self
._SectionType
= MODEL_UNKNOWN
1208 def __ProcessSubsectionHeader(self
):
1209 self
._SubsectionName
= self
._ValueList
[0]
1210 if self
._SubsectionName
in self
.DataType
:
1211 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
1213 self
._SubsectionType
= MODEL_UNKNOWN
1215 def __RetrievePcdValue(self
):
1216 Records
= self
._RawTable
.Query(MODEL_PCD_FEATURE_FLAG
, BelongsToItem
=-1.0)
1217 for TokenSpaceGuid
,PcdName
,Value
,Dummy2
,Dummy3
,ID
,Line
in Records
:
1218 Value
, DatumType
, MaxDatumSize
= AnalyzePcdData(Value
)
1219 Name
= TokenSpaceGuid
+ '.' + PcdName
1220 self
._Symbols
[Name
] = Value
1222 Records
= self
._RawTable
.Query(MODEL_PCD_FIXED_AT_BUILD
, BelongsToItem
=-1.0)
1223 for TokenSpaceGuid
,PcdName
,Value
,Dummy2
,Dummy3
,ID
,Line
in Records
:
1224 Value
, DatumType
, MaxDatumSize
= AnalyzePcdData(Value
)
1225 Name
= TokenSpaceGuid
+ '.' + PcdName
1226 self
._Symbols
[Name
] = Value
1228 def __ProcessDefine(self
):
1229 if not self
._Enabled
:
1232 Type
, Name
, Value
= self
._ValueList
1233 Value
= ReplaceMacro(Value
, self
._Macros
, False)
1234 if self
._ItemType
== MODEL_META_DATA_DEFINE
:
1235 if self
._SectionType
== MODEL_META_DATA_HEADER
:
1236 self
._FileLocalMacros
[Name
] = Value
1238 self
._ConstructSectionMacroDict
(Name
, Value
)
1239 elif self
._ItemType
== MODEL_META_DATA_GLOBAL_DEFINE
:
1240 GlobalData
.gEdkGlobal
[Name
] = Value
1243 # Keyword in [Defines] section can be used as Macros
1245 if (self
._ItemType
== MODEL_META_DATA_HEADER
) and (self
._SectionType
== MODEL_META_DATA_HEADER
):
1246 self
._FileLocalMacros
[Name
] = Value
1248 self
._ValueList
= [Type
, Name
, Value
]
1250 def __ProcessDirective(self
):
1252 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1253 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
]:
1254 Macros
= self
._Macros
1255 Macros
.update(GlobalData
.gGlobalDefines
)
1257 Result
= ValueExpression(self
._ValueList
[1], Macros
)()
1258 except SymbolNotFound
, Exc
:
1259 EdkLogger
.debug(EdkLogger
.DEBUG_5
, str(Exc
), self
._ValueList
[1])
1261 except WrnExpression
, Excpt
:
1263 # Catch expression evaluation warning here. We need to report
1264 # the precise number of line and return the evaluation result
1266 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
1267 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1268 Line
=self
._LineIndex
+1)
1269 Result
= Excpt
.result
1271 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1272 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1273 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1274 self
._DirectiveStack
.append(self
._ItemType
)
1275 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
:
1276 Result
= bool(Result
)
1278 Macro
= self
._ValueList
[1]
1279 Macro
= Macro
[2:-1] if (Macro
.startswith("$(") and Macro
.endswith(")")) else Macro
1280 Result
= Macro
in self
._Macros
1281 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
:
1283 self
._DirectiveEvalStack
.append(Result
)
1284 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
:
1285 self
._DirectiveStack
.append(self
._ItemType
)
1286 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1287 self
._DirectiveEvalStack
.append(bool(Result
))
1288 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1289 self
._DirectiveStack
.append(self
._ItemType
)
1290 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1291 self
._DirectiveEvalStack
.append(True)
1292 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1293 # Back to the nearest !if/!ifdef/!ifndef
1294 while self
._DirectiveStack
:
1295 self
._DirectiveEvalStack
.pop()
1296 Directive
= self
._DirectiveStack
.pop()
1297 if Directive
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1298 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1299 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1301 elif self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1302 # The included file must be relative to workspace or same directory as DSC file
1303 __IncludeMacros
= {}
1305 # Allow using system environment variables in path after !include
1307 __IncludeMacros
['WORKSPACE'] = GlobalData
.gGlobalDefines
['WORKSPACE']
1308 if "ECP_SOURCE" in GlobalData
.gGlobalDefines
.keys():
1309 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gGlobalDefines
['ECP_SOURCE']
1311 # During GenFds phase call DSC parser, will go into this branch.
1313 elif "ECP_SOURCE" in GlobalData
.gCommandLineDefines
.keys():
1314 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gCommandLineDefines
['ECP_SOURCE']
1316 __IncludeMacros
['EFI_SOURCE'] = GlobalData
.gGlobalDefines
['EFI_SOURCE']
1317 __IncludeMacros
['EDK_SOURCE'] = GlobalData
.gGlobalDefines
['EDK_SOURCE']
1319 # Allow using MACROs comes from [Defines] section to keep compatible.
1321 __IncludeMacros
.update(self
._Macros
)
1323 IncludedFile
= NormPath(ReplaceMacro(self
._ValueList
[1], __IncludeMacros
, RaiseError
=True))
1325 # First search the include file under the same directory as DSC file
1327 IncludedFile1
= PathClass(IncludedFile
, self
.MetaFile
.Dir
)
1328 ErrorCode
, ErrorInfo1
= IncludedFile1
.Validate()
1331 # Also search file under the WORKSPACE directory
1333 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
1334 ErrorCode
, ErrorInfo2
= IncludedFile1
.Validate()
1336 EdkLogger
.error('parser', ErrorCode
, File
=self
._FileWithError
,
1337 Line
=self
._LineIndex
+1, ExtraData
=ErrorInfo1
+ "\n"+ ErrorInfo2
)
1339 self
._FileWithError
= IncludedFile1
1341 IncludedFileTable
= MetaFileStorage(self
._Table
.Cur
, IncludedFile1
, MODEL_FILE_DSC
, False)
1342 Owner
= self
._Content
[self
._ContentIndex
-1][0]
1343 Parser
= DscParser(IncludedFile1
, self
._FileType
, IncludedFileTable
,
1344 Owner
=Owner
, From
=Owner
)
1346 # set the parser status with current status
1347 Parser
._SectionName
= self
._SectionName
1348 Parser
._SectionType
= self
._SectionType
1349 Parser
._Scope
= self
._Scope
1350 Parser
._Enabled
= self
._Enabled
1351 # Parse the included file
1354 # update current status with sub-parser's status
1355 self
._SectionName
= Parser
._SectionName
1356 self
._SectionType
= Parser
._SectionType
1357 self
._Scope
= Parser
._Scope
1358 self
._Enabled
= Parser
._Enabled
1360 # Insert all records in the table for the included file into dsc file table
1361 Records
= IncludedFileTable
.GetAll()
1363 self
._Content
[self
._ContentIndex
:self
._ContentIndex
] = Records
1364 self
._Content
.pop(self
._ContentIndex
-1)
1365 self
._ValueList
= None
1366 self
._ContentIndex
-= 1
1368 def __ProcessSkuId(self
):
1369 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=True)
1370 for Value
in self
._ValueList
]
1372 def __ProcessLibraryInstance(self
):
1373 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
1375 def __ProcessLibraryClass(self
):
1376 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
, RaiseError
=True)
1378 def __ProcessPcd(self
):
1380 ValueList
= GetSplitValueList(self
._ValueList
[2])
1382 # PCD value can be an expression
1384 if len(ValueList
) > 1 and ValueList
[1] == 'VOID*':
1385 PcdValue
= ValueList
[0]
1387 ValueList
[0] = ValueExpression(PcdValue
, self
._Macros
)(True)
1388 except WrnExpression
, Value
:
1389 ValueList
[0] = Value
.result
1392 # Int*/Boolean VPD PCD
1393 # TokenSpace | PcdCName | Offset | [Value]
1396 # TokenSpace | PcdCName | Offset | [Size] | [Value]
1398 if self
._ItemType
== MODEL_PCD_DYNAMIC_VPD
:
1399 if len(ValueList
) >= 4:
1400 PcdValue
= ValueList
[-1]
1402 PcdValue
= ValueList
[-1]
1404 # For the VPD PCD, there may not have PcdValue data in DSC file
1408 ValueList
[-1] = ValueExpression(PcdValue
, self
._Macros
)(True)
1409 except WrnExpression
, Value
:
1410 ValueList
[-1] = Value
.result
1412 if ValueList
[-1] == 'True':
1414 if ValueList
[-1] == 'False':
1417 self
._ValueList
[2] = '|'.join(ValueList
)
1419 def __ProcessComponent(self
):
1420 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1422 def __ProcessSourceOverridePath(self
):
1423 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1425 def __ProcessBuildOption(self
):
1426 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=False)
1427 for Value
in self
._ValueList
]
1430 MODEL_META_DATA_HEADER
: _DefineParser
,
1431 MODEL_EFI_SKU_ID
: _SkuIdParser
,
1432 MODEL_EFI_LIBRARY_INSTANCE
: _LibraryInstanceParser
,
1433 MODEL_EFI_LIBRARY_CLASS
: _LibraryClassParser
,
1434 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1435 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1436 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1437 MODEL_PCD_DYNAMIC_DEFAULT
: _PcdParser
,
1438 MODEL_PCD_DYNAMIC_HII
: _PcdParser
,
1439 MODEL_PCD_DYNAMIC_VPD
: _PcdParser
,
1440 MODEL_PCD_DYNAMIC_EX_DEFAULT
: _PcdParser
,
1441 MODEL_PCD_DYNAMIC_EX_HII
: _PcdParser
,
1442 MODEL_PCD_DYNAMIC_EX_VPD
: _PcdParser
,
1443 MODEL_META_DATA_COMPONENT
: _ComponentParser
,
1444 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: _CompponentSourceOverridePathParser
,
1445 MODEL_META_DATA_BUILD_OPTION
: _BuildOptionParser
,
1446 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1447 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
1448 MODEL_META_DATA_SECTION_HEADER
: MetaFileParser
._SectionHeaderParser
,
1449 MODEL_META_DATA_SUBSECTION_HEADER
: _SubsectionHeaderParser
,
1452 _Macros
= property(_GetMacros
)
1454 ## DEC file parser class
1456 # @param FilePath The path of platform description file
1457 # @param FileType The raw data of DSC file
1458 # @param Table Database used to retrieve module/package information
1459 # @param Macros Macros used for replacement in file
1461 class DecParser(MetaFileParser
):
1462 # DEC file supported data types (one type per section)
1464 TAB_DEC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
1465 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
1466 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
1467 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
1468 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
1469 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
1470 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
1471 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
1472 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
1473 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
1474 TAB_PCDS_DYNAMIC_NULL
.upper() : MODEL_PCD_DYNAMIC
,
1475 TAB_PCDS_DYNAMIC_EX_NULL
.upper() : MODEL_PCD_DYNAMIC_EX
,
1478 ## Constructor of DecParser
1480 # Initialize object of DecParser
1482 # @param FilePath The path of platform description file
1483 # @param FileType The raw data of DSC file
1484 # @param Table Database used to retrieve module/package information
1485 # @param Macros Macros used for replacement in file
1487 def __init__(self
, FilePath
, FileType
, Table
):
1488 # prevent re-initialization
1489 if hasattr(self
, "_Table"):
1491 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
, -1)
1493 self
._Version
= 0x00010005 # Only EDK2 dec file is supported
1499 Content
= open(str(self
.MetaFile
), 'r').readlines()
1501 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
1503 for Index
in range(0, len(Content
)):
1504 Line
, Comment
= CleanString2(Content
[Index
])
1505 self
._CurrentLine
= Line
1506 self
._LineIndex
= Index
1508 # save comment for later use
1510 self
._Comments
.append((Comment
, self
._LineIndex
+1))
1516 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
1517 self
._SectionHeaderParser
()
1520 elif len(self
._SectionType
) == 0:
1525 self
._ValueList
= ['','','']
1526 self
._SectionParser
[self
._SectionType
[0]](self
)
1527 if self
._ValueList
== None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
1533 # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,
1534 # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1
1536 for Arch
, ModuleType
, Type
in self
._Scope
:
1537 self
._LastItem
= self
._Store
(
1551 for Comment
, LineNo
in self
._Comments
:
1553 MODEL_META_DATA_COMMENT
,
1570 ## Section header parser
1572 # The section header is always in following format:
1574 # [section_name.arch<.platform|module_type>]
1576 def _SectionHeaderParser(self
):
1578 self
._SectionName
= ''
1579 self
._SectionType
= []
1581 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
1584 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
)
1586 # different types of PCD are permissible in one section
1587 self
._SectionName
= ItemList
[0].upper()
1588 if self
._SectionName
in self
.DataType
:
1589 if self
.DataType
[self
._SectionName
] not in self
._SectionType
:
1590 self
._SectionType
.append(self
.DataType
[self
._SectionName
])
1592 EdkLogger
.warn("Parser", "Unrecognized section", File
=self
.MetaFile
,
1593 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
1596 if MODEL_PCD_FEATURE_FLAG
in self
._SectionType
and len(self
._SectionType
) > 1:
1600 "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL
,
1602 Line
=self
._LineIndex
+1,
1603 ExtraData
=self
._CurrentLine
1606 if len(ItemList
) > 1:
1607 S1
= ItemList
[1].upper()
1611 # S2 may be Platform or ModuleType
1612 if len(ItemList
) > 2:
1613 S2
= ItemList
[2].upper()
1616 if [S1
, S2
, self
.DataType
[self
._SectionName
]] not in self
._Scope
:
1617 self
._Scope
.append([S1
, S2
, self
.DataType
[self
._SectionName
]])
1619 # 'COMMON' must not be used with specific ARCHs at the same section
1620 if 'COMMON' in ArchList
and len(ArchList
) > 1:
1621 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
1622 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
1624 ## [guids], [ppis] and [protocols] section parser
1626 def _GuidParser(self
):
1627 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1628 if len(TokenList
) < 2:
1629 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name or value specified",
1630 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1631 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1632 if TokenList
[0] == '':
1633 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name specified",
1634 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1635 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1636 if TokenList
[1] == '':
1637 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID value specified",
1638 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1639 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1640 if TokenList
[1][0] != '{' or TokenList
[1][-1] != '}' or GuidStructureStringToGuidString(TokenList
[1]) == '':
1641 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid GUID value format",
1642 ExtraData
=self
._CurrentLine
+ \
1643 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
1644 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1645 self
._ValueList
[0] = TokenList
[0]
1646 self
._ValueList
[1] = TokenList
[1]
1648 ## PCD sections parser
1650 # [PcdsFixedAtBuild]
1651 # [PcdsPatchableInModule]
1657 def _PcdParser(self
):
1658 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1659 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1660 # check PCD information
1661 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1662 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1663 ExtraData
=self
._CurrentLine
+ \
1664 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1665 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1666 # check PCD datum information
1667 if len(TokenList
) < 2 or TokenList
[1] == '':
1668 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD Datum information given",
1669 ExtraData
=self
._CurrentLine
+ \
1670 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1671 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1674 ValueRe
= re
.compile(r
'^\s*L?\".*\|.*\"')
1675 PtrValue
= ValueRe
.findall(TokenList
[1])
1677 # Has VOID* type string, may contain "|" character in the string.
1678 if len(PtrValue
) != 0:
1679 ptrValueList
= re
.sub(ValueRe
, '', TokenList
[1])
1680 ValueList
= GetSplitValueList(ptrValueList
)
1681 ValueList
[0] = PtrValue
[0]
1683 ValueList
= GetSplitValueList(TokenList
[1])
1686 # check if there's enough datum information given
1687 if len(ValueList
) != 3:
1688 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid PCD Datum information given",
1689 ExtraData
=self
._CurrentLine
+ \
1690 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1691 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1692 # check default value
1693 if ValueList
[0] == '':
1694 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DefaultValue in PCD Datum information",
1695 ExtraData
=self
._CurrentLine
+ \
1696 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1697 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1699 if ValueList
[1] == '':
1700 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DatumType in PCD Datum information",
1701 ExtraData
=self
._CurrentLine
+ \
1702 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1703 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1704 # check token of the PCD
1705 if ValueList
[2] == '':
1706 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing Token in PCD Datum information",
1707 ExtraData
=self
._CurrentLine
+ \
1708 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1709 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1710 # check format of default value against the datum type
1711 IsValid
, Cause
= CheckPcdDatum(ValueList
[1], ValueList
[0])
1713 EdkLogger
.error('Parser', FORMAT_INVALID
, Cause
, ExtraData
=self
._CurrentLine
,
1714 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1716 if ValueList
[0] in ['True', 'true', 'TRUE']:
1718 elif ValueList
[0] in ['False', 'false', 'FALSE']:
1721 self
._ValueList
[2] = ValueList
[0].strip() + '|' + ValueList
[1].strip() + '|' + ValueList
[2].strip()
1724 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
1725 MODEL_EFI_INCLUDE
: MetaFileParser
._PathParser
,
1726 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
1727 MODEL_EFI_GUID
: _GuidParser
,
1728 MODEL_EFI_PPI
: _GuidParser
,
1729 MODEL_EFI_PROTOCOL
: _GuidParser
,
1730 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1731 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1732 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1733 MODEL_PCD_DYNAMIC
: _PcdParser
,
1734 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
1735 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1736 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
1741 # This acts like the main() function for the script, unless it is 'import'ed into another
1744 if __name__
== '__main__':