2 # This file is used to parse meta files
4 # Copyright (c) 2008 - 2014, 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.
17 import Common
.LongFilePathOs
as os
22 import Common
.EdkLogger
as EdkLogger
23 import Common
.GlobalData
as GlobalData
26 from CommonDataClass
.DataClass
import *
27 from Common
.DataType
import *
28 from Common
.String
import *
29 from Common
.Misc
import GuidStructureStringToGuidString
, CheckPcdDatum
, PathClass
, AnalyzePcdData
30 from Common
.Expression
import *
31 from CommonDataClass
.Exceptions
import *
33 from MetaFileTable
import MetaFileStorage
34 from GenFds
.FdfParser
import FdfParser
35 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
37 ## A decorator used to parse macro definition
38 def ParseMacro(Parser
):
39 def MacroParser(self
):
40 Match
= gMacroDefPattern
.match(self
._CurrentLine
)
42 # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method
46 TokenList
= GetSplitValueList(self
._CurrentLine
[Match
.end(1):], TAB_EQUAL_SPLIT
, 1)
49 EdkLogger
.error('Parser', FORMAT_INVALID
, "No macro name given",
50 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
51 if len(TokenList
) < 2:
55 Name
, Value
= TokenList
56 # Global macros can be only defined via environment variable
57 if Name
in GlobalData
.gGlobalDefines
:
58 EdkLogger
.error('Parser', FORMAT_INVALID
, "%s can only be defined via environment variable" % Name
,
59 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
60 # Only upper case letters, digit and '_' are allowed
61 if not gMacroNamePattern
.match(Name
):
62 EdkLogger
.error('Parser', FORMAT_INVALID
, "The macro name must be in the pattern [A-Z][A-Z0-9_]*",
63 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
65 Value
= ReplaceMacro(Value
, self
._Macros
)
66 self
._ItemType
= MODEL_META_DATA_DEFINE
67 # DEFINE defined macros
68 if Type
== TAB_DSC_DEFINES_DEFINE
:
69 if type(self
) == DecParser
:
70 if MODEL_META_DATA_HEADER
in self
._SectionType
:
71 self
._FileLocalMacros
[Name
] = Value
73 for Scope
in self
._Scope
:
74 self
._SectionsMacroDict
.setdefault((Scope
[2], Scope
[0], Scope
[1]), {})[Name
] = Value
75 elif self
._SectionType
== MODEL_META_DATA_HEADER
:
76 self
._FileLocalMacros
[Name
] = Value
78 SectionDictKey
= self
._SectionType
, self
._Scope
[0][0], self
._Scope
[0][1]
79 if SectionDictKey
not in self
._SectionsMacroDict
:
80 self
._SectionsMacroDict
[SectionDictKey
] = {}
81 SectionLocalMacros
= self
._SectionsMacroDict
[SectionDictKey
]
82 SectionLocalMacros
[Name
] = Value
83 # EDK_GLOBAL defined macros
84 elif type(self
) != DscParser
:
85 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL can only be used in .dsc file",
86 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
87 elif self
._SectionType
!= MODEL_META_DATA_HEADER
:
88 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL can only be used under [Defines] section",
89 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
90 elif (Name
in self
._FileLocalMacros
) and (self
._FileLocalMacros
[Name
] != Value
):
91 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL defined a macro with the same name and different value as one defined by 'DEFINE'",
92 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
94 self
._ValueList
= [Type
, Name
, Value
]
98 ## Base class of parser
100 # This class is used for derivation purpose. The specific parser for one kind
101 # type file must derive this class and implement some public interfaces.
103 # @param FilePath The path of platform description file
104 # @param FileType The raw data of DSC file
105 # @param Table Database used to retrieve module/package information
106 # @param Macros Macros used for replacement in file
107 # @param Owner Owner ID (for sub-section parsing)
108 # @param From ID from which the data comes (for !INCLUDE directive)
110 class MetaFileParser(object):
111 # data type (file content) for specific file type
114 # Parser objects used to implement singleton
119 # One file, one parser object. This factory method makes sure that there's
120 # only one object constructed for one meta file.
122 # @param Class class object of real AutoGen class
123 # (InfParser, DecParser or DscParser)
124 # @param FilePath The path of meta file
125 # @param *args The specific class related parameters
126 # @param **kwargs The specific class related dict parameters
128 def __new__(Class
, FilePath
, *args
, **kwargs
):
129 if FilePath
in Class
.MetaFiles
:
130 return Class
.MetaFiles
[FilePath
]
132 ParserObject
= super(MetaFileParser
, Class
).__new
__(Class
)
133 Class
.MetaFiles
[FilePath
] = ParserObject
136 ## Constructor of MetaFileParser
138 # Initialize object of MetaFileParser
140 # @param FilePath The path of platform description file
141 # @param FileType The raw data of DSC file
142 # @param Table Database used to retrieve module/package information
143 # @param Macros Macros used for replacement in file
144 # @param Owner Owner ID (for sub-section parsing)
145 # @param From ID from which the data comes (for !INCLUDE directive)
147 def __init__(self
, FilePath
, FileType
, Table
, Owner
=-1, From
=-1):
149 self
._RawTable
= Table
150 self
._FileType
= FileType
151 self
.MetaFile
= FilePath
153 self
._FileLocalMacros
= {}
154 self
._SectionsMacroDict
= {}
156 # for recursive parsing
157 self
._Owner
= [Owner
]
160 # parsr status for parsing
161 self
._ValueList
= ['', '', '', '', '']
164 self
._CurrentLine
= ''
165 self
._SectionType
= MODEL_UNKNOWN
166 self
._SectionName
= ''
167 self
._InSubsection
= False
168 self
._SubsectionType
= MODEL_UNKNOWN
169 self
._SubsectionName
= ''
170 self
._ItemType
= MODEL_UNKNOWN
173 self
._Finished
= False
174 self
._PostProcessed
= False
175 # Different version of meta-file has different way to parse.
178 ## Store the parsed data in table
179 def _Store(self
, *Args
):
180 return self
._Table
.Insert(*Args
)
182 ## Virtual method for starting parse
184 raise NotImplementedError
186 ## Notify a post-process is needed
187 def DoPostProcess(self
):
188 self
._PostProcessed
= False
190 ## Set parsing complete flag in both class and table
192 self
._Finished
= True
193 ## Do not set end flag when processing included files
195 self
._Table
.SetEndFlag()
197 def _PostProcess(self
):
198 self
._PostProcessed
= True
200 ## Get the parse complete flag
201 def _GetFinished(self
):
202 return self
._Finished
204 ## Set the complete flag
205 def _SetFinished(self
, Value
):
206 self
._Finished
= Value
208 ## Use [] style to query data in table, just for readability
210 # DataInfo = [data_type, scope1(arch), scope2(platform/moduletype)]
212 def __getitem__(self
, DataInfo
):
213 if type(DataInfo
) != type(()):
214 DataInfo
= (DataInfo
,)
216 # Parse the file first, if necessary
217 if not self
._Finished
:
218 if self
._RawTable
.IsIntegrity():
219 self
._Finished
= True
221 self
._Table
= self
._RawTable
222 self
._PostProcessed
= False
225 # No specific ARCH or Platform given, use raw data
226 if self
._RawTable
and (len(DataInfo
) == 1 or DataInfo
[1] == None):
227 return self
._RawTable
.Query(*DataInfo
)
229 # Do post-process if necessary
230 if not self
._PostProcessed
:
233 return self
._Table
.Query(*DataInfo
)
235 ## Data parser for the common format in different type of file
237 # The common format in the meatfile is like
242 def _CommonParser(self
):
243 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
244 self
._ValueList
[0:len(TokenList
)] = TokenList
246 ## Data parser for the format in which there's path
248 # Only path can have macro used. So we need to replace them before use.
251 def _PathParser(self
):
252 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
253 self
._ValueList
[0:len(TokenList
)] = TokenList
254 # Don't do macro replacement for dsc file at this point
255 if type(self
) != DscParser
:
256 Macros
= self
._Macros
257 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
259 ## Skip unsupported data
261 EdkLogger
.warn("Parser", "Unrecognized content", File
=self
.MetaFile
,
262 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
);
263 self
._ValueList
[0:1] = [self
._CurrentLine
]
265 ## Section header parser
267 # The section header is always in following format:
269 # [section_name.arch<.platform|module_type>]
271 def _SectionHeaderParser(self
):
273 self
._SectionName
= ''
275 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
278 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
)
279 # different section should not mix in one section
280 if self
._SectionName
!= '' and self
._SectionName
!= ItemList
[0].upper():
281 EdkLogger
.error('Parser', FORMAT_INVALID
, "Different section names in the same section",
282 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
283 self
._SectionName
= ItemList
[0].upper()
284 if self
._SectionName
in self
.DataType
:
285 self
._SectionType
= self
.DataType
[self
._SectionName
]
287 self
._SectionType
= MODEL_UNKNOWN
288 EdkLogger
.warn("Parser", "Unrecognized section", File
=self
.MetaFile
,
289 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
291 if len(ItemList
) > 1:
292 S1
= ItemList
[1].upper()
296 # S2 may be Platform or ModuleType
297 if len(ItemList
) > 2:
298 S2
= ItemList
[2].upper()
301 self
._Scope
.append([S1
, S2
])
303 # 'COMMON' must not be used with specific ARCHs at the same section
304 if 'COMMON' in ArchList
and len(ArchList
) > 1:
305 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
306 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
307 # If the section information is needed later, it should be stored in database
308 self
._ValueList
[0] = self
._SectionName
310 ## [defines] section parser
312 def _DefineParser(self
):
313 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
314 self
._ValueList
[1:len(TokenList
)] = TokenList
315 if not self
._ValueList
[1]:
316 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
317 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
318 if not self
._ValueList
[2]:
319 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
320 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
322 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
323 Name
, Value
= self
._ValueList
[1], self
._ValueList
[2]
324 # Sometimes, we need to make differences between EDK and EDK2 modules
325 if Name
== 'INF_VERSION':
327 self
._Version
= int(Value
, 0)
329 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid version number",
330 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
332 if type(self
) == InfParser
and self
._Version
< 0x00010005:
333 # EDK module allows using defines as macros
334 self
._FileLocalMacros
[Name
] = Value
335 self
._Defines
[Name
] = Value
337 ## [BuildOptions] section parser
339 def _BuildOptionParser(self
):
340 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
341 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
342 if len(TokenList2
) == 2:
343 self
._ValueList
[0] = TokenList2
[0] # toolchain family
344 self
._ValueList
[1] = TokenList2
[1] # keys
346 self
._ValueList
[1] = TokenList
[0]
347 if len(TokenList
) == 2 and type(self
) != DscParser
: # value
348 self
._ValueList
[2] = ReplaceMacro(TokenList
[1], self
._Macros
)
350 if self
._ValueList
[1].count('_') != 4:
354 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
355 ExtraData
=self
._CurrentLine
,
357 Line
=self
._LineIndex
+1
360 def _GetMacros(self
):
362 Macros
.update(self
._FileLocalMacros
)
363 Macros
.update(self
._GetApplicableSectionMacro
())
367 ## Get section Macros that are applicable to current line, which may come from other sections
368 ## that share the same name while scope is wider
369 def _GetApplicableSectionMacro(self
):
371 for Scope1
, Scope2
in [("COMMON", "COMMON"), ("COMMON", self
._Scope
[0][1]),
372 (self
._Scope
[0][0], "COMMON"), (self
._Scope
[0][0], self
._Scope
[0][1])]:
373 if (self
._SectionType
, Scope1
, Scope2
) in self
._SectionsMacroDict
:
374 Macros
.update(self
._SectionsMacroDict
[(self
._SectionType
, Scope1
, Scope2
)])
378 Finished
= property(_GetFinished
, _SetFinished
)
379 _Macros
= property(_GetMacros
)
382 ## INF file parser class
384 # @param FilePath The path of platform description file
385 # @param FileType The raw data of DSC file
386 # @param Table Database used to retrieve module/package information
387 # @param Macros Macros used for replacement in file
389 class InfParser(MetaFileParser
):
390 # INF file supported data types (one type per section)
392 TAB_UNKNOWN
.upper() : MODEL_UNKNOWN
,
393 TAB_INF_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
394 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
395 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
396 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
397 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
398 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
399 TAB_PACKAGES
.upper() : MODEL_META_DATA_PACKAGE
,
400 TAB_NMAKE
.upper() : MODEL_META_DATA_NMAKE
,
401 TAB_INF_FIXED_PCD
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
402 TAB_INF_PATCH_PCD
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
403 TAB_INF_FEATURE_PCD
.upper() : MODEL_PCD_FEATURE_FLAG
,
404 TAB_INF_PCD_EX
.upper() : MODEL_PCD_DYNAMIC_EX
,
405 TAB_INF_PCD
.upper() : MODEL_PCD_DYNAMIC
,
406 TAB_SOURCES
.upper() : MODEL_EFI_SOURCE_FILE
,
407 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
408 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
409 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
410 TAB_DEPEX
.upper() : MODEL_EFI_DEPEX
,
411 TAB_BINARIES
.upper() : MODEL_EFI_BINARY_FILE
,
412 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
415 ## Constructor of InfParser
417 # Initialize object of InfParser
419 # @param FilePath The path of module description file
420 # @param FileType The raw data of DSC file
421 # @param Table Database used to retrieve module/package information
422 # @param Macros Macros used for replacement in file
424 def __init__(self
, FilePath
, FileType
, Table
):
425 # prevent re-initialization
426 if hasattr(self
, "_Table"):
428 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
)
429 self
.TblFile
= EccGlobalData
.gDb
.TblFile
437 Content
= open(str(self
.MetaFile
), 'r').readlines()
439 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
441 # Insert a record for file
443 Filename
= NormPath(self
.MetaFile
)
444 FileID
= self
.TblFile
.GetFileId(Filename
)
448 self
.FileID
= self
.TblFile
.InsertFile(Filename
, MODEL_FILE_INF
)
450 # parse the file line by line
451 IsFindBlockComment
= False
453 for Index
in range(0, len(Content
)):
454 # skip empty, commented, block commented lines
455 Line
= CleanString(Content
[Index
], AllowCppStyleComment
=True)
457 if Index
+ 1 < len(Content
):
458 NextLine
= CleanString(Content
[Index
+ 1])
461 if Line
.find(DataType
.TAB_COMMENT_EDK_START
) > -1:
462 IsFindBlockComment
= True
464 if Line
.find(DataType
.TAB_COMMENT_EDK_END
) > -1:
465 IsFindBlockComment
= False
467 if IsFindBlockComment
:
470 self
._LineIndex
= Index
471 self
._CurrentLine
= Line
474 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
475 self
._SectionHeaderParser
()
476 # Check invalid sections
477 if self
._Version
< 0x00010005:
478 if self
._SectionType
in [MODEL_META_DATA_BUILD_OPTION
,
479 MODEL_EFI_LIBRARY_CLASS
,
480 MODEL_META_DATA_PACKAGE
,
481 MODEL_PCD_FIXED_AT_BUILD
,
482 MODEL_PCD_PATCHABLE_IN_MODULE
,
483 MODEL_PCD_FEATURE_FLAG
,
484 MODEL_PCD_DYNAMIC_EX
,
489 MODEL_META_DATA_USER_EXTENSION
]:
490 EdkLogger
.error('Parser', FORMAT_INVALID
,
491 "Section [%s] is not allowed in inf file without version" % (self
._SectionName
),
492 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
493 elif self
._SectionType
in [MODEL_EFI_INCLUDE
,
494 MODEL_EFI_LIBRARY_INSTANCE
,
495 MODEL_META_DATA_NMAKE
]:
496 EdkLogger
.error('Parser', FORMAT_INVALID
,
497 "Section [%s] is not allowed in inf file with version 0x%08x" % (self
._SectionName
, self
._Version
),
498 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
500 # merge two lines specified by '\' in section NMAKE
501 elif self
._SectionType
== MODEL_META_DATA_NMAKE
:
504 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
507 if NextLine
[0] == TAB_SECTION_START
and NextLine
[-1] == TAB_SECTION_END
:
508 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
511 NmakeLine
= NmakeLine
+ ' ' + Line
[0:-1]
514 self
._CurrentLine
= NmakeLine
+ Line
518 self
._ValueList
= ['','','']
519 # parse current line, result will be put in self._ValueList
520 self
._SectionParser
[self
._SectionType
](self
)
521 if self
._ValueList
== None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
525 # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
526 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
528 self
._ValueList
[0] = self
._ValueList
[0].replace('/', '\\')
529 for Arch
, Platform
in self
._Scope
:
530 self
._Store
(self
._SectionType
,
544 if IsFindBlockComment
:
545 EdkLogger
.error("Parser", FORMAT_INVALID
, "Open block comments (starting with /*) are expected to end with */",
549 ## Data parser for the format in which there's path
551 # Only path can have macro used. So we need to replace them before use.
553 def _IncludeParser(self
):
554 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
555 self
._ValueList
[0:len(TokenList
)] = TokenList
556 Macros
= self
._Macros
558 for Index
in range(0, len(self
._ValueList
)):
559 Value
= self
._ValueList
[Index
]
563 if Value
.upper().find('$(EFI_SOURCE)\Edk'.upper()) > -1 or Value
.upper().find('$(EFI_SOURCE)/Edk'.upper()) > -1:
564 Value
= '$(EDK_SOURCE)' + Value
[17:]
565 if Value
.find('$(EFI_SOURCE)') > -1 or Value
.find('$(EDK_SOURCE)') > -1:
567 elif Value
.startswith('.'):
569 elif Value
.startswith('$('):
572 Value
= '$(EFI_SOURCE)/' + Value
574 self
._ValueList
[Index
] = ReplaceMacro(Value
, Macros
)
576 ## Parse [Sources] section
578 # Only path can have macro used. So we need to replace them before use.
581 def _SourceFileParser(self
):
582 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
583 self
._ValueList
[0:len(TokenList
)] = TokenList
584 Macros
= self
._Macros
585 # For Acpi tables, remove macro like ' TABLE_NAME=Sata1'
586 if 'COMPONENT_TYPE' in Macros
:
587 if self
._Defines
['COMPONENT_TYPE'].upper() == 'ACPITABLE':
588 self
._ValueList
[0] = GetSplitValueList(self
._ValueList
[0], ' ', 1)[0]
589 if self
._Defines
['BASE_NAME'] == 'Microcode':
591 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
593 ## Parse [Binaries] section
595 # Only path can have macro used. So we need to replace them before use.
598 def _BinaryFileParser(self
):
599 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 2)
600 if len(TokenList
) < 2:
601 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type or path specified",
602 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
603 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
605 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type specified",
606 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
607 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
609 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file path specified",
610 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
611 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
612 self
._ValueList
[0:len(TokenList
)] = TokenList
613 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
615 ## [nmake] section parser (Edk.x style only)
616 def _NmakeParser(self
):
617 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
618 self
._ValueList
[0:len(TokenList
)] = TokenList
620 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
621 # remove self-reference in macro setting
622 #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
624 ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
626 def _PcdParser(self
):
627 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
628 ValueList
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
629 if len(ValueList
) != 2:
630 EdkLogger
.error('Parser', FORMAT_INVALID
, "Illegal token space GUID and PCD name format",
631 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
632 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
633 self
._ValueList
[0:1] = ValueList
634 if len(TokenList
) > 1:
635 self
._ValueList
[2] = TokenList
[1]
636 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
637 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
638 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
639 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
641 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
642 if self
._ValueList
[2] != '':
643 InfPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
644 if InfPcdValueList
[0] in ['True', 'true', 'TRUE']:
645 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '1', 1);
646 elif InfPcdValueList
[0] in ['False', 'false', 'FALSE']:
647 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '0', 1);
649 ## [depex] section parser
651 def _DepexParser(self
):
652 self
._ValueList
[0:1] = [self
._CurrentLine
]
655 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
656 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
657 MODEL_META_DATA_BUILD_OPTION
: MetaFileParser
._BuildOptionParser
,
658 MODEL_EFI_INCLUDE
: _IncludeParser
, # for Edk.x modules
659 MODEL_EFI_LIBRARY_INSTANCE
: MetaFileParser
._CommonParser
, # for Edk.x modules
660 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
661 MODEL_META_DATA_PACKAGE
: MetaFileParser
._PathParser
,
662 MODEL_META_DATA_NMAKE
: _NmakeParser
, # for Edk.x modules
663 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
664 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
665 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
666 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
667 MODEL_PCD_DYNAMIC
: _PcdParser
,
668 MODEL_EFI_SOURCE_FILE
: _SourceFileParser
,
669 MODEL_EFI_GUID
: MetaFileParser
._CommonParser
,
670 MODEL_EFI_PROTOCOL
: MetaFileParser
._CommonParser
,
671 MODEL_EFI_PPI
: MetaFileParser
._CommonParser
,
672 MODEL_EFI_DEPEX
: _DepexParser
,
673 MODEL_EFI_BINARY_FILE
: _BinaryFileParser
,
674 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
677 ## DSC file parser class
679 # @param FilePath The path of platform description file
680 # @param FileType The raw data of DSC file
681 # @param Table Database used to retrieve module/package information
682 # @param Macros Macros used for replacement in file
683 # @param Owner Owner ID (for sub-section parsing)
684 # @param From ID from which the data comes (for !INCLUDE directive)
686 class DscParser(MetaFileParser
):
687 # DSC file supported data types (one type per section)
689 TAB_SKUIDS
.upper() : MODEL_EFI_SKU_ID
,
690 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
691 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
692 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
693 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
694 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
695 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
696 TAB_PCDS_DYNAMIC_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_DEFAULT
,
697 TAB_PCDS_DYNAMIC_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_HII
,
698 TAB_PCDS_DYNAMIC_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_VPD
,
699 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT
,
700 TAB_PCDS_DYNAMIC_EX_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_HII
,
701 TAB_PCDS_DYNAMIC_EX_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_VPD
,
702 TAB_COMPONENTS
.upper() : MODEL_META_DATA_COMPONENT
,
703 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
.upper() : MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
,
704 TAB_DSC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
705 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
706 TAB_DSC_DEFINES_EDKGLOBAL
: MODEL_META_DATA_GLOBAL_DEFINE
,
707 TAB_INCLUDE
.upper() : MODEL_META_DATA_INCLUDE
,
708 TAB_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
709 TAB_IF_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
710 TAB_IF_N_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
,
711 TAB_ELSE_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
,
712 TAB_ELSE
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
,
713 TAB_END_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
,
716 # Valid names in define section
723 "PCD_INFO_GENERATION",
724 "SUPPORTED_ARCHITECTURES",
733 "FIX_LOAD_TOP_MEMORY_ADDRESS"
736 SymbolPattern
= ValueExpression
.SymbolPattern
738 ## Constructor of DscParser
740 # Initialize object of DscParser
742 # @param FilePath The path of platform description file
743 # @param FileType The raw data of DSC file
744 # @param Table Database used to retrieve module/package information
745 # @param Macros Macros used for replacement in file
746 # @param Owner Owner ID (for sub-section parsing)
747 # @param From ID from which the data comes (for !INCLUDE directive)
749 def __init__(self
, FilePath
, FileType
, Table
, Owner
=-1, From
=-1):
750 # prevent re-initialization
751 if hasattr(self
, "_Table"):
753 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
, Owner
, From
)
754 self
._Version
= 0x00010005 # Only EDK2 dsc file is supported
755 # to store conditional directive evaluation result
756 self
._DirectiveStack
= []
757 self
._DirectiveEvalStack
= []
760 # Final valid replacable symbols
763 # Map the ID between the original table and new table to track
766 self
._IdMapping
= {-1:-1}
768 self
.TblFile
= EccGlobalData
.gDb
.TblFile
775 Content
= open(str(self
.MetaFile
.Path
), 'r').readlines()
777 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
779 # Insert a record for file
781 Filename
= NormPath(self
.MetaFile
.Path
)
782 FileID
= self
.TblFile
.GetFileId(Filename
)
786 self
.FileID
= self
.TblFile
.InsertFile(Filename
, MODEL_FILE_DSC
)
789 for Index
in range(0, len(Content
)):
790 Line
= CleanString(Content
[Index
])
795 self
._CurrentLine
= Line
796 self
._LineIndex
= Index
797 if self
._InSubsection
and self
._Owner
[-1] == -1:
798 self
._Owner
.append(self
._LastItem
)
801 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
802 self
._SectionType
= MODEL_META_DATA_SECTION_HEADER
804 elif Line
[0] == '}' and self
._InSubsection
:
805 self
._InSubsection
= False
806 self
._SubsectionType
= MODEL_UNKNOWN
807 self
._SubsectionName
= ''
811 elif Line
[0] == TAB_OPTION_START
and Line
[-1] == TAB_OPTION_END
:
812 self
._SubsectionType
= MODEL_META_DATA_SUBSECTION_HEADER
815 self
._DirectiveParser
()
818 if self
._InSubsection
:
819 SectionType
= self
._SubsectionType
821 SectionType
= self
._SectionType
822 self
._ItemType
= SectionType
824 self
._ValueList
= ['', '', '']
825 self
._SectionParser
[SectionType
](self
)
826 if self
._ValueList
== None:
829 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
830 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
832 for Arch
, ModuleType
in self
._Scope
:
833 self
._LastItem
= self
._Store
(
850 if self
._DirectiveStack
:
851 Type
, Line
, Text
= self
._DirectiveStack
[-1]
852 EdkLogger
.error('Parser', FORMAT_INVALID
, "No matching '!endif' found",
853 ExtraData
=Text
, File
=self
.MetaFile
, Line
=Line
)
856 ## <subsection_header> parser
857 def _SubsectionHeaderParser(self
):
858 self
._SubsectionName
= self
._CurrentLine
[1:-1].upper()
859 if self
._SubsectionName
in self
.DataType
:
860 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
862 self
._SubsectionType
= MODEL_UNKNOWN
863 EdkLogger
.warn("Parser", "Unrecognized sub-section", File
=self
.MetaFile
,
864 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
865 self
._ValueList
[0] = self
._SubsectionName
867 ## Directive statement parser
868 def _DirectiveParser(self
):
869 self
._ValueList
= ['','','']
870 TokenList
= GetSplitValueList(self
._CurrentLine
, ' ', 1)
871 self
._ValueList
[0:len(TokenList
)] = TokenList
874 DirectiveName
= self
._ValueList
[0].upper()
875 if DirectiveName
not in self
.DataType
:
876 EdkLogger
.error("Parser", FORMAT_INVALID
, "Unknown directive [%s]" % DirectiveName
,
877 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
878 if DirectiveName
in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self
._ValueList
[1] == '':
879 EdkLogger
.error("Parser", FORMAT_INVALID
, "Missing expression",
880 File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
881 ExtraData
=self
._CurrentLine
)
883 ItemType
= self
.DataType
[DirectiveName
]
884 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
885 # Remove all directives between !if and !endif, including themselves
886 while self
._DirectiveStack
:
887 # Remove any !else or !elseif
888 DirectiveInfo
= self
._DirectiveStack
.pop()
889 if DirectiveInfo
[0] in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
890 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
891 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
894 EdkLogger
.error("Parser", FORMAT_INVALID
, "Redundant '!endif'",
895 File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
896 ExtraData
=self
._CurrentLine
)
897 elif ItemType
!= MODEL_META_DATA_INCLUDE
:
898 # Break if there's a !else is followed by a !elseif
899 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
and \
900 self
._DirectiveStack
and \
901 self
._DirectiveStack
[-1][0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
902 EdkLogger
.error("Parser", FORMAT_INVALID
, "'!elseif' after '!else'",
903 File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
904 ExtraData
=self
._CurrentLine
)
905 self
._DirectiveStack
.append((ItemType
, self
._LineIndex
+1, self
._CurrentLine
))
907 EdkLogger
.error('Parser', FORMAT_INVALID
,
908 "No '!include' allowed in included file",
909 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
,
910 Line
=self
._LineIndex
+1)
913 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
914 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
916 self
._LastItem
= self
._Store
(
933 ## [defines] section parser
935 def _DefineParser(self
):
936 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
937 self
._ValueList
[1:len(TokenList
)] = TokenList
940 if not self
._ValueList
[1]:
941 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
942 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
943 if not self
._ValueList
[2]:
944 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
945 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
946 if not self
._ValueList
[1] in self
.DefineKeywords
:
947 EdkLogger
.error('Parser', FORMAT_INVALID
,
948 "Unknown keyword found: %s. "
949 "If this is a macro you must "
950 "add it as a DEFINE in the DSC" % self
._ValueList
[1],
951 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
952 self
._Defines
[self
._ValueList
[1]] = self
._ValueList
[2]
953 self
._ItemType
= self
.DataType
[TAB_DSC_DEFINES
.upper()]
956 def _SkuIdParser(self
):
957 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
958 if len(TokenList
) != 2:
959 EdkLogger
.error('Parser', FORMAT_INVALID
, "Correct format is '<Integer>|<UiName>'",
960 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
961 self
._ValueList
[0:len(TokenList
)] = TokenList
963 ## Parse Edk style of library modules
964 def _LibraryInstanceParser(self
):
965 self
._ValueList
[0] = self
._CurrentLine
967 ## PCD sections parser
970 # [PcdsPatchableInModule]
973 # [PcdsDynamicExDefault]
977 # [PcdsDynamicDefault]
982 def _PcdParser(self
):
983 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
984 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
985 if len(TokenList
) == 2:
986 self
._ValueList
[2] = TokenList
[1]
987 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
988 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
989 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
990 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
991 if self
._ValueList
[2] == '':
992 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD value given",
993 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
994 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
995 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
996 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
997 if DscPcdValueList
[0] in ['True', 'true', 'TRUE']:
998 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '1', 1);
999 elif DscPcdValueList
[0] in ['False', 'false', 'FALSE']:
1000 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '0', 1);
1002 ## [components] section parser
1004 def _ComponentParser(self
):
1005 if self
._CurrentLine
[-1] == '{':
1006 self
._ValueList
[0] = self
._CurrentLine
[0:-1].strip()
1007 self
._InSubsection
= True
1009 self
._ValueList
[0] = self
._CurrentLine
1011 ## [LibraryClasses] section
1013 def _LibraryClassParser(self
):
1014 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1015 if len(TokenList
) < 2:
1016 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class or instance specified",
1017 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1018 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1019 if TokenList
[0] == '':
1020 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class specified",
1021 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1022 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1023 if TokenList
[1] == '':
1024 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library instance specified",
1025 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1026 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1028 self
._ValueList
[0:len(TokenList
)] = TokenList
1030 def _CompponentSourceOverridePathParser(self
):
1031 self
._ValueList
[0] = self
._CurrentLine
1033 ## [BuildOptions] section parser
1035 def _BuildOptionParser(self
):
1036 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1037 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
1038 if len(TokenList2
) == 2:
1039 self
._ValueList
[0] = TokenList2
[0] # toolchain family
1040 self
._ValueList
[1] = TokenList2
[1] # keys
1042 self
._ValueList
[1] = TokenList
[0]
1043 if len(TokenList
) == 2: # value
1044 self
._ValueList
[2] = TokenList
[1]
1046 if self
._ValueList
[1].count('_') != 4:
1050 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
1051 ExtraData
=self
._CurrentLine
,
1053 Line
=self
._LineIndex
+1
1056 ## Override parent's method since we'll do all macro replacements in parser
1057 def _GetMacros(self
):
1058 Macros
= dict( [('ARCH','IA32'), ('FAMILY','MSFT'),('TOOL_CHAIN_TAG','VS2008x86'),('TARGET','DEBUG')])
1059 Macros
.update(self
._FileLocalMacros
)
1060 Macros
.update(self
._GetApplicableSectionMacro
())
1061 Macros
.update(GlobalData
.gEdkGlobal
)
1062 Macros
.update(GlobalData
.gPlatformDefines
)
1063 Macros
.update(GlobalData
.gCommandLineDefines
)
1064 # PCD cannot be referenced in macro definition
1065 if self
._ItemType
not in [MODEL_META_DATA_DEFINE
, MODEL_META_DATA_GLOBAL_DEFINE
]:
1066 Macros
.update(self
._Symbols
)
1069 def _PostProcess(self
):
1071 MODEL_META_DATA_SECTION_HEADER
: self
.__ProcessSectionHeader
,
1072 MODEL_META_DATA_SUBSECTION_HEADER
: self
.__ProcessSubsectionHeader
,
1073 MODEL_META_DATA_HEADER
: self
.__ProcessDefine
,
1074 MODEL_META_DATA_DEFINE
: self
.__ProcessDefine
,
1075 MODEL_META_DATA_GLOBAL_DEFINE
: self
.__ProcessDefine
,
1076 MODEL_META_DATA_INCLUDE
: self
.__ProcessDirective
,
1077 MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
: self
.__ProcessDirective
,
1078 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
: self
.__ProcessDirective
,
1079 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
: self
.__ProcessDirective
,
1080 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
: self
.__ProcessDirective
,
1081 MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
: self
.__ProcessDirective
,
1082 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
: self
.__ProcessDirective
,
1083 MODEL_EFI_SKU_ID
: self
.__ProcessSkuId
,
1084 MODEL_EFI_LIBRARY_INSTANCE
: self
.__ProcessLibraryInstance
,
1085 MODEL_EFI_LIBRARY_CLASS
: self
.__ProcessLibraryClass
,
1086 MODEL_PCD_FIXED_AT_BUILD
: self
.__ProcessPcd
,
1087 MODEL_PCD_PATCHABLE_IN_MODULE
: self
.__ProcessPcd
,
1088 MODEL_PCD_FEATURE_FLAG
: self
.__ProcessPcd
,
1089 MODEL_PCD_DYNAMIC_DEFAULT
: self
.__ProcessPcd
,
1090 MODEL_PCD_DYNAMIC_HII
: self
.__ProcessPcd
,
1091 MODEL_PCD_DYNAMIC_VPD
: self
.__ProcessPcd
,
1092 MODEL_PCD_DYNAMIC_EX_DEFAULT
: self
.__ProcessPcd
,
1093 MODEL_PCD_DYNAMIC_EX_HII
: self
.__ProcessPcd
,
1094 MODEL_PCD_DYNAMIC_EX_VPD
: self
.__ProcessPcd
,
1095 MODEL_META_DATA_COMPONENT
: self
.__ProcessComponent
,
1096 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: self
.__ProcessSourceOverridePath
,
1097 MODEL_META_DATA_BUILD_OPTION
: self
.__ProcessBuildOption
,
1098 MODEL_UNKNOWN
: self
._Skip
,
1099 MODEL_META_DATA_USER_EXTENSION
: self
._Skip
,
1102 self
._RawTable
= self
._Table
1103 self
._Table
= MetaFileStorage(self
._RawTable
.Cur
, self
.MetaFile
, MODEL_FILE_DSC
, True)
1104 self
._DirectiveStack
= []
1105 self
._DirectiveEvalStack
= []
1106 self
._FileWithError
= self
.MetaFile
1107 self
._FileLocalMacros
= {}
1108 self
._SectionsMacroDict
= {}
1109 GlobalData
.gPlatformDefines
= {}
1111 # Get all macro and PCD which has straitforward value
1112 self
.__RetrievePcdValue
()
1113 self
._Content
= self
._RawTable
.GetAll()
1114 self
._ContentIndex
= 0
1115 while self
._ContentIndex
< len(self
._Content
) :
1116 Id
, self
._ItemType
, V1
, V2
, V3
, S1
, S2
, Owner
, BelongsToFile
, self
._From
, \
1117 LineStart
, ColStart
, LineEnd
, ColEnd
, Enabled
= self
._Content
[self
._ContentIndex
]
1120 self
._FileWithError
= self
.MetaFile
1122 self
._ContentIndex
+= 1
1124 self
._Scope
= [[S1
, S2
]]
1125 self
._LineIndex
= LineStart
- 1
1126 self
._ValueList
= [V1
, V2
, V3
]
1129 Processer
[self
._ItemType
]()
1130 except EvaluationException
, Excpt
:
1132 # Only catch expression evaluation error here. We need to report
1133 # the precise number of line on which the error occurred
1135 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
1136 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1137 Line
=self
._LineIndex
+1)
1138 except MacroException
, Excpt
:
1139 EdkLogger
.error('Parser', FORMAT_INVALID
, str(Excpt
),
1140 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1141 Line
=self
._LineIndex
+1)
1143 if self
._ValueList
== None:
1146 NewOwner
= self
._IdMapping
.get(Owner
, -1)
1147 self
._Enabled
= int((not self
._DirectiveEvalStack
) or (False not in self
._DirectiveEvalStack
))
1148 self
._LastItem
= self
._Store
(
1164 self
._IdMapping
[Id
] = self
._LastItem
1166 RecordList
= self
._Table
.GetAll()
1168 self
._RawTable
.Drop()
1170 for Record
in RecordList
:
1171 EccGlobalData
.gDb
.TblDsc
.Insert(Record
[1],Record
[2],Record
[3],Record
[4],Record
[5],Record
[6],Record
[7],Record
[8],Record
[9],Record
[10],Record
[11],Record
[12],Record
[13],Record
[14])
1172 GlobalData
.gPlatformDefines
.update(self
._FileLocalMacros
)
1173 self
._PostProcessed
= True
1174 self
._Content
= None
1176 def __ProcessSectionHeader(self
):
1177 self
._SectionName
= self
._ValueList
[0]
1178 if self
._SectionName
in self
.DataType
:
1179 self
._SectionType
= self
.DataType
[self
._SectionName
]
1181 self
._SectionType
= MODEL_UNKNOWN
1183 def __ProcessSubsectionHeader(self
):
1184 self
._SubsectionName
= self
._ValueList
[0]
1185 if self
._SubsectionName
in self
.DataType
:
1186 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
1188 self
._SubsectionType
= MODEL_UNKNOWN
1190 def __RetrievePcdValue(self
):
1191 Records
= self
._RawTable
.Query(MODEL_PCD_FEATURE_FLAG
, BelongsToItem
=-1.0)
1192 for TokenSpaceGuid
,PcdName
,Value
,Dummy2
,Dummy3
,ID
,Line
in Records
:
1193 Value
, DatumType
, MaxDatumSize
= AnalyzePcdData(Value
)
1194 # Only use PCD whose value is straitforward (no macro and PCD)
1195 if self
.SymbolPattern
.findall(Value
):
1197 Name
= TokenSpaceGuid
+ '.' + PcdName
1198 # Don't use PCD with different values.
1199 if Name
in self
._Symbols
and self
._Symbols
[Name
] != Value
:
1200 self
._Symbols
.pop(Name
)
1202 self
._Symbols
[Name
] = Value
1204 Records
= self
._RawTable
.Query(MODEL_PCD_FIXED_AT_BUILD
, BelongsToItem
=-1.0)
1205 for TokenSpaceGuid
,PcdName
,Value
,Dummy2
,Dummy3
,ID
,Line
in Records
:
1206 Value
, DatumType
, MaxDatumSize
= AnalyzePcdData(Value
)
1207 # Only use PCD whose value is straitforward (no macro and PCD)
1208 if self
.SymbolPattern
.findall(Value
):
1210 Name
= TokenSpaceGuid
+'.'+PcdName
1211 # Don't use PCD with different values.
1212 if Name
in self
._Symbols
and self
._Symbols
[Name
] != Value
:
1213 self
._Symbols
.pop(Name
)
1215 self
._Symbols
[Name
] = Value
1217 def __ProcessDefine(self
):
1218 if not self
._Enabled
:
1221 Type
, Name
, Value
= self
._ValueList
1222 Value
= ReplaceMacro(Value
, self
._Macros
, False)
1223 if self
._ItemType
== MODEL_META_DATA_DEFINE
:
1224 if self
._SectionType
== MODEL_META_DATA_HEADER
:
1225 self
._FileLocalMacros
[Name
] = Value
1227 SectionDictKey
= self
._SectionType
, self
._Scope
[0][0], self
._Scope
[0][1]
1228 if SectionDictKey
not in self
._SectionsMacroDict
:
1229 self
._SectionsMacroDict
[SectionDictKey
] = {}
1230 SectionLocalMacros
= self
._SectionsMacroDict
[SectionDictKey
]
1231 SectionLocalMacros
[Name
] = Value
1232 elif self
._ItemType
== MODEL_META_DATA_GLOBAL_DEFINE
:
1233 GlobalData
.gEdkGlobal
[Name
] = Value
1236 # Keyword in [Defines] section can be used as Macros
1238 if (self
._ItemType
== MODEL_META_DATA_HEADER
) and (self
._SectionType
== MODEL_META_DATA_HEADER
):
1239 self
._FileLocalMacros
[Name
] = Value
1241 self
._ValueList
= [Type
, Name
, Value
]
1243 def __ProcessDirective(self
):
1245 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1246 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
]:
1247 Macros
= self
._Macros
1248 Macros
.update(GlobalData
.gGlobalDefines
)
1250 Result
= ValueExpression(self
._ValueList
[1], Macros
)()
1251 except SymbolNotFound
, Exc
:
1252 EdkLogger
.debug(EdkLogger
.DEBUG_5
, str(Exc
), self
._ValueList
[1])
1254 except WrnExpression
, Excpt
:
1256 # Catch expression evaluation warning here. We need to report
1257 # the precise number of line and return the evaluation result
1259 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
1260 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1261 Line
=self
._LineIndex
+1)
1262 Result
= Excpt
.result
1264 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1265 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1266 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1267 self
._DirectiveStack
.append(self
._ItemType
)
1268 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
:
1269 Result
= bool(Result
)
1271 Macro
= self
._ValueList
[1]
1272 Macro
= Macro
[2:-1] if (Macro
.startswith("$(") and Macro
.endswith(")")) else Macro
1273 Result
= Macro
in self
._Macros
1274 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
:
1276 self
._DirectiveEvalStack
.append(Result
)
1277 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
:
1278 self
._DirectiveStack
.append(self
._ItemType
)
1279 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1280 self
._DirectiveEvalStack
.append(bool(Result
))
1281 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1282 self
._DirectiveStack
[-1] = self
._ItemType
1283 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1284 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1285 # Back to the nearest !if/!ifdef/!ifndef
1286 while self
._DirectiveStack
:
1287 self
._DirectiveEvalStack
.pop()
1288 Directive
= self
._DirectiveStack
.pop()
1289 if Directive
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1290 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1291 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
,
1292 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1294 elif self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1295 # The included file must be relative to workspace or same directory as DSC file
1296 __IncludeMacros
= {}
1298 # Allow using system environment variables in path after !include
1300 __IncludeMacros
['WORKSPACE'] = GlobalData
.gGlobalDefines
['WORKSPACE']
1301 if "ECP_SOURCE" in GlobalData
.gGlobalDefines
.keys():
1302 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gGlobalDefines
['ECP_SOURCE']
1304 # During GenFds phase call DSC parser, will go into this branch.
1306 elif "ECP_SOURCE" in GlobalData
.gCommandLineDefines
.keys():
1307 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gCommandLineDefines
['ECP_SOURCE']
1309 __IncludeMacros
['EFI_SOURCE'] = GlobalData
.gGlobalDefines
['EFI_SOURCE']
1310 __IncludeMacros
['EDK_SOURCE'] = GlobalData
.gGlobalDefines
['EDK_SOURCE']
1312 # Allow using MACROs comes from [Defines] section to keep compatible.
1314 __IncludeMacros
.update(self
._Macros
)
1316 IncludedFile
= NormPath(ReplaceMacro(self
._ValueList
[1], __IncludeMacros
, RaiseError
=True))
1318 # First search the include file under the same directory as DSC file
1320 IncludedFile1
= PathClass(IncludedFile
, self
.MetaFile
.Dir
)
1321 ErrorCode
, ErrorInfo1
= IncludedFile1
.Validate()
1324 # Also search file under the WORKSPACE directory
1326 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
1327 ErrorCode
, ErrorInfo2
= IncludedFile1
.Validate()
1329 EdkLogger
.error('parser', ErrorCode
, File
=self
._FileWithError
,
1330 Line
=self
._LineIndex
+1, ExtraData
=ErrorInfo1
+ "\n"+ ErrorInfo2
)
1332 self
._FileWithError
= IncludedFile1
1334 IncludedFileTable
= MetaFileStorage(self
._Table
.Cur
, IncludedFile1
, MODEL_FILE_DSC
, True)
1335 Owner
= self
._Content
[self
._ContentIndex
-1][0]
1336 Parser
= DscParser(IncludedFile1
, self
._FileType
, IncludedFileTable
,
1337 Owner
=Owner
, From
=Owner
)
1339 # set the parser status with current status
1340 Parser
._SectionName
= self
._SectionName
1341 Parser
._SectionType
= self
._SectionType
1342 Parser
._Scope
= self
._Scope
1343 Parser
._Enabled
= self
._Enabled
1344 # Parse the included file
1347 # update current status with sub-parser's status
1348 self
._SectionName
= Parser
._SectionName
1349 self
._SectionType
= Parser
._SectionType
1350 self
._Scope
= Parser
._Scope
1351 self
._Enabled
= Parser
._Enabled
1353 # Insert all records in the table for the included file into dsc file table
1354 Records
= IncludedFileTable
.GetAll()
1356 self
._Content
[self
._ContentIndex
:self
._ContentIndex
] = Records
1357 self
._Content
.pop(self
._ContentIndex
-1)
1358 self
._ValueList
= None
1359 self
._ContentIndex
-= 1
1361 def __ProcessSkuId(self
):
1362 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=True)
1363 for Value
in self
._ValueList
]
1365 def __ProcessLibraryInstance(self
):
1366 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
1368 def __ProcessLibraryClass(self
):
1369 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
, RaiseError
=True)
1371 def __ProcessPcd(self
):
1372 ValueList
= GetSplitValueList(self
._ValueList
[2])
1374 # PCD value can be an expression
1376 if len(ValueList
) > 1 and ValueList
[1] == 'VOID*':
1377 PcdValue
= ValueList
[0]
1379 ValueList
[0] = ValueExpression(PcdValue
, self
._Macros
)(True)
1380 except WrnExpression
, Value
:
1381 ValueList
[0] = Value
.result
1383 PcdValue
= ValueList
[-1]
1385 ValueList
[-1] = ValueExpression(PcdValue
, self
._Macros
)(True)
1386 except WrnExpression
, Value
:
1387 ValueList
[-1] = Value
.result
1389 if ValueList
[-1] == 'True':
1391 if ValueList
[-1] == 'False':
1394 self
._ValueList
[2] = '|'.join(ValueList
)
1396 def __ProcessComponent(self
):
1397 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1399 def __ProcessSourceOverridePath(self
):
1400 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1402 def __ProcessBuildOption(self
):
1403 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=False)
1404 for Value
in self
._ValueList
]
1407 MODEL_META_DATA_HEADER
: _DefineParser
,
1408 MODEL_EFI_SKU_ID
: _SkuIdParser
,
1409 MODEL_EFI_LIBRARY_INSTANCE
: _LibraryInstanceParser
,
1410 MODEL_EFI_LIBRARY_CLASS
: _LibraryClassParser
,
1411 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1412 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1413 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1414 MODEL_PCD_DYNAMIC_DEFAULT
: _PcdParser
,
1415 MODEL_PCD_DYNAMIC_HII
: _PcdParser
,
1416 MODEL_PCD_DYNAMIC_VPD
: _PcdParser
,
1417 MODEL_PCD_DYNAMIC_EX_DEFAULT
: _PcdParser
,
1418 MODEL_PCD_DYNAMIC_EX_HII
: _PcdParser
,
1419 MODEL_PCD_DYNAMIC_EX_VPD
: _PcdParser
,
1420 MODEL_META_DATA_COMPONENT
: _ComponentParser
,
1421 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: _CompponentSourceOverridePathParser
,
1422 MODEL_META_DATA_BUILD_OPTION
: _BuildOptionParser
,
1423 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1424 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
1425 MODEL_META_DATA_SECTION_HEADER
: MetaFileParser
._SectionHeaderParser
,
1426 MODEL_META_DATA_SUBSECTION_HEADER
: _SubsectionHeaderParser
,
1429 _Macros
= property(_GetMacros
)
1431 ## DEC file parser class
1433 # @param FilePath The path of platform description file
1434 # @param FileType The raw data of DSC file
1435 # @param Table Database used to retrieve module/package information
1436 # @param Macros Macros used for replacement in file
1438 class DecParser(MetaFileParser
):
1439 # DEC file supported data types (one type per section)
1441 TAB_DEC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
1442 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
1443 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
1444 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
1445 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
1446 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
1447 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
1448 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
1449 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
1450 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
1451 TAB_PCDS_DYNAMIC_NULL
.upper() : MODEL_PCD_DYNAMIC
,
1452 TAB_PCDS_DYNAMIC_EX_NULL
.upper() : MODEL_PCD_DYNAMIC_EX
,
1455 ## Constructor of DecParser
1457 # Initialize object of DecParser
1459 # @param FilePath The path of platform description file
1460 # @param FileType The raw data of DSC file
1461 # @param Table Database used to retrieve module/package information
1462 # @param Macros Macros used for replacement in file
1464 def __init__(self
, FilePath
, FileType
, Table
):
1465 # prevent re-initialization
1466 if hasattr(self
, "_Table"):
1468 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
)
1470 self
._Version
= 0x00010005 # Only EDK2 dec file is supported
1471 self
.TblFile
= EccGlobalData
.gDb
.TblFile
1478 Content
= open(str(self
.MetaFile
), 'r').readlines()
1480 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
1483 # Insert a record for file
1485 Filename
= NormPath(self
.MetaFile
)
1486 FileID
= self
.TblFile
.GetFileId(Filename
)
1488 self
.FileID
= FileID
1490 self
.FileID
= self
.TblFile
.InsertFile(Filename
, MODEL_FILE_DEC
)
1492 for Index
in range(0, len(Content
)):
1493 Line
, Comment
= CleanString2(Content
[Index
])
1494 self
._CurrentLine
= Line
1495 self
._LineIndex
= Index
1497 # save comment for later use
1499 self
._Comments
.append((Comment
, self
._LineIndex
+1))
1505 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
1506 self
._SectionHeaderParser
()
1509 elif len(self
._SectionType
) == 0:
1514 self
._ValueList
= ['','','']
1515 self
._SectionParser
[self
._SectionType
[0]](self
)
1516 if self
._ValueList
== None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
1522 # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,
1523 # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1
1525 for Arch
, ModuleType
, Type
in self
._Scope
:
1526 self
._LastItem
= self
._Store
(
1541 for Comment
, LineNo
in self
._Comments
:
1543 MODEL_META_DATA_COMMENT
,
1560 def _GetApplicableSectionMacro(self
):
1562 for S1
, S2
, SectionType
in self
._Scope
:
1563 for Scope1
, Scope2
in [("COMMON", "COMMON"), ("COMMON", S2
), (S1
, "COMMON"), (S1
, S2
)]:
1564 if (SectionType
, Scope1
, Scope2
) in self
._SectionsMacroDict
:
1565 Macros
.update(self
._SectionsMacroDict
[(SectionType
, Scope1
, Scope2
)])
1568 ## Section header parser
1570 # The section header is always in following format:
1572 # [section_name.arch<.platform|module_type>]
1574 def _SectionHeaderParser(self
):
1576 self
._SectionName
= ''
1577 self
._SectionType
= []
1579 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
1582 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
)
1584 # different types of PCD are permissible in one section
1585 self
._SectionName
= ItemList
[0].upper()
1586 if self
._SectionName
in self
.DataType
:
1587 if self
.DataType
[self
._SectionName
] not in self
._SectionType
:
1588 self
._SectionType
.append(self
.DataType
[self
._SectionName
])
1590 EdkLogger
.warn("Parser", "Unrecognized section", File
=self
.MetaFile
,
1591 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
1594 if MODEL_PCD_FEATURE_FLAG
in self
._SectionType
and len(self
._SectionType
) > 1:
1598 "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL
,
1600 Line
=self
._LineIndex
+1,
1601 ExtraData
=self
._CurrentLine
1604 if len(ItemList
) > 1:
1605 S1
= ItemList
[1].upper()
1609 # S2 may be Platform or ModuleType
1610 if len(ItemList
) > 2:
1611 S2
= ItemList
[2].upper()
1614 if [S1
, S2
, self
.DataType
[self
._SectionName
]] not in self
._Scope
:
1615 self
._Scope
.append([S1
, S2
, self
.DataType
[self
._SectionName
]])
1617 # 'COMMON' must not be used with specific ARCHs at the same section
1618 if 'COMMON' in ArchList
and len(ArchList
) > 1:
1619 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
1620 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
1622 ## [guids], [ppis] and [protocols] section parser
1624 def _GuidParser(self
):
1625 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1626 if len(TokenList
) < 2:
1627 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name or value specified",
1628 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1629 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1630 if TokenList
[0] == '':
1631 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name specified",
1632 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1633 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1634 if TokenList
[1] == '':
1635 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID value specified",
1636 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1637 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1638 if TokenList
[1][0] != '{' or TokenList
[1][-1] != '}' or GuidStructureStringToGuidString(TokenList
[1]) == '':
1639 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid GUID value format",
1640 ExtraData
=self
._CurrentLine
+ \
1641 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
1642 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1643 self
._ValueList
[0] = TokenList
[0]
1644 #Parse the Guid value format
1645 GuidValueList
= TokenList
[1].strip(' {}').split(',')
1648 if len(GuidValueList
) == 11:
1649 for GuidValue
in GuidValueList
:
1650 GuidValue
= GuidValue
.strip()
1651 if GuidValue
.startswith('0x') or GuidValue
.startswith('0X'):
1652 HexList
.append('0x' + str(GuidValue
[2:]))
1656 if GuidValue
.startswith('{'):
1657 HexList
.append('0x' + str(GuidValue
[3:]))
1659 self
._ValueList
[1] = "{ %s, %s, %s, { %s, %s, %s, %s, %s, %s, %s, %s }}" % (HexList
[0], HexList
[1], HexList
[2],HexList
[3],HexList
[4],HexList
[5],HexList
[6],HexList
[7],HexList
[8],HexList
[9],HexList
[10])
1661 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid GUID value format",
1662 ExtraData
=self
._CurrentLine
+ \
1663 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
1664 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1665 self
._ValueList
[0] = ''
1667 ## PCD sections parser
1669 # [PcdsFixedAtBuild]
1670 # [PcdsPatchableInModule]
1676 def _PcdParser(self
):
1677 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1678 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1679 # check PCD information
1680 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1681 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1682 ExtraData
=self
._CurrentLine
+ \
1683 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1684 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1685 # check PCD datum information
1686 if len(TokenList
) < 2 or TokenList
[1] == '':
1687 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD Datum information given",
1688 ExtraData
=self
._CurrentLine
+ \
1689 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1690 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1693 ValueRe
= re
.compile(r
'^\s*L?\".*\|.*\"')
1694 PtrValue
= ValueRe
.findall(TokenList
[1])
1696 # Has VOID* type string, may contain "|" character in the string.
1697 if len(PtrValue
) != 0:
1698 ptrValueList
= re
.sub(ValueRe
, '', TokenList
[1])
1699 ValueList
= GetSplitValueList(ptrValueList
)
1700 ValueList
[0] = PtrValue
[0]
1702 ValueList
= GetSplitValueList(TokenList
[1])
1705 # check if there's enough datum information given
1706 if len(ValueList
) != 3:
1707 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid PCD Datum information given",
1708 ExtraData
=self
._CurrentLine
+ \
1709 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1710 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1711 # check default value
1712 if ValueList
[0] == '':
1713 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DefaultValue in PCD Datum information",
1714 ExtraData
=self
._CurrentLine
+ \
1715 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1716 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1718 if ValueList
[1] == '':
1719 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DatumType in PCD Datum information",
1720 ExtraData
=self
._CurrentLine
+ \
1721 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1722 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1723 # check token of the PCD
1724 if ValueList
[2] == '':
1725 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing Token in PCD Datum information",
1726 ExtraData
=self
._CurrentLine
+ \
1727 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1728 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1729 # check format of default value against the datum type
1730 IsValid
, Cause
= CheckPcdDatum(ValueList
[1], ValueList
[0])
1732 EdkLogger
.error('Parser', FORMAT_INVALID
, Cause
, ExtraData
=self
._CurrentLine
,
1733 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1735 if ValueList
[0] in ['True', 'true', 'TRUE']:
1737 elif ValueList
[0] in ['False', 'false', 'FALSE']:
1740 self
._ValueList
[2] = ValueList
[0].strip() + '|' + ValueList
[1].strip() + '|' + ValueList
[2].strip()
1743 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
1744 MODEL_EFI_INCLUDE
: MetaFileParser
._PathParser
,
1745 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
1746 MODEL_EFI_GUID
: _GuidParser
,
1747 MODEL_EFI_PPI
: _GuidParser
,
1748 MODEL_EFI_PROTOCOL
: _GuidParser
,
1749 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1750 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1751 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1752 MODEL_PCD_DYNAMIC
: _PcdParser
,
1753 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
1754 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1755 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
1761 # This class defined basic Fdf object which is used by inheriting
1763 # @param object: Inherited from object class
1765 class FdfObject(object):
1771 # This class defined the structure used in Fdf object
1773 # @param FdfObject: Inherited from FdfObject class
1774 # @param Filename: Input value for Ffilename of Fdf file, default is None
1775 # @param WorkspaceDir: Input value for current workspace directory, default is None
1777 class Fdf(FdfObject
):
1778 def __init__(self
, Filename
= None, IsToDatabase
= False, WorkspaceDir
= None, Database
= None):
1779 self
.WorkspaceDir
= WorkspaceDir
1780 self
.IsToDatabase
= IsToDatabase
1782 self
.Cur
= Database
.Cur
1783 self
.TblFile
= Database
.TblFile
1784 self
.TblFdf
= Database
.TblFdf
1789 # Load Fdf file if filename is not None
1791 if Filename
!= None:
1792 self
.LoadFdfFile(Filename
)
1795 # Insert a FDF file record into database
1797 def InsertFile(self
, Filename
):
1799 Filename
= NormPath(Filename
)
1800 if Filename
not in self
.FileList
:
1801 FileID
= self
.TblFile
.InsertFile(Filename
, MODEL_FILE_FDF
)
1802 self
.FileList
[Filename
] = FileID
1804 return self
.FileList
[Filename
]
1809 # Load the file if it exists
1811 # @param Filename: Input value for filename of Fdf file
1813 def LoadFdfFile(self
, Filename
):
1818 Filename
= NormPath(Filename
)
1819 Fdf
= FdfParser(Filename
)
1823 # Insert inf file and pcd information
1825 if self
.IsToDatabase
:
1826 (Model
, Value1
, Value2
, Value3
, Scope1
, Scope2
, BelongsToItem
, BelongsToFile
, StartLine
, StartColumn
, EndLine
, EndColumn
, Enabled
) = \
1827 (0, '', '', '', 'COMMON', 'COMMON', -1, -1, -1, -1, -1, -1, 0)
1828 for Index
in range(0, len(Fdf
.Profile
.PcdDict
)):
1830 for Key
in Fdf
.Profile
.PcdDict
.keys():
1834 FileName
= Fdf
.Profile
.PcdFileLineDict
[Key
][0]
1835 StartLine
= Fdf
.Profile
.PcdFileLineDict
[Key
][1]
1836 BelongsToFile
= self
.InsertFile(FileName
)
1837 self
.TblFdf
.Insert(Model
, Value1
, Value2
, Value3
, Scope1
, Scope2
, BelongsToItem
, BelongsToFile
, StartLine
, StartColumn
, EndLine
, EndColumn
, Enabled
)
1838 for Index
in range(0, len(Fdf
.Profile
.InfList
)):
1839 Model
= MODEL_META_DATA_COMPONENT
1840 Value1
= Fdf
.Profile
.InfList
[Index
]
1842 FileName
= Fdf
.Profile
.InfFileLineList
[Index
][0]
1843 StartLine
= Fdf
.Profile
.InfFileLineList
[Index
][1]
1844 BelongsToFile
= self
.InsertFile(FileName
)
1845 self
.TblFdf
.Insert(Model
, Value1
, Value2
, Value3
, Scope1
, Scope2
, BelongsToItem
, BelongsToFile
, StartLine
, StartColumn
, EndLine
, EndColumn
, Enabled
)
1849 # This acts like the main() function for the script, unless it is 'import'ed into another
1852 if __name__
== '__main__':