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
438 Content
= open(str(self
.MetaFile
), 'r').readlines()
440 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
442 # Insert a record for file
444 Filename
= NormPath(self
.MetaFile
)
445 FileID
= self
.TblFile
.GetFileId(Filename
)
449 self
.FileID
= self
.TblFile
.InsertFile(Filename
, MODEL_FILE_INF
)
451 # parse the file line by line
452 IsFindBlockComment
= False
454 for Index
in range(0, len(Content
)):
455 if self
._SectionType
in [MODEL_EFI_GUID
,
458 MODEL_PCD_FIXED_AT_BUILD
,
459 MODEL_PCD_PATCHABLE_IN_MODULE
,
460 MODEL_PCD_FEATURE_FLAG
,
461 MODEL_PCD_DYNAMIC_EX
,
463 Line
= Content
[Index
].strip()
464 if Line
.startswith(TAB_SPECIAL_COMMENT
):
465 Usage
+= ' ' + Line
[Line
.find(TAB_SPECIAL_COMMENT
):]
467 elif Line
.startswith(TAB_COMMENT_SPLIT
):
469 elif Line
.find(TAB_COMMENT_SPLIT
) > 0:
470 Usage
+= ' ' + Line
[Line
.find(TAB_COMMENT_SPLIT
):]
471 Line
= Line
[:Line
.find(TAB_COMMENT_SPLIT
)]
473 # skip empty, commented, block commented lines
474 Line
= CleanString(Content
[Index
], AllowCppStyleComment
=True)
477 if Index
+ 1 < len(Content
):
478 NextLine
= CleanString(Content
[Index
+ 1])
481 if Line
.find(DataType
.TAB_COMMENT_EDK_START
) > -1:
482 IsFindBlockComment
= True
484 if Line
.find(DataType
.TAB_COMMENT_EDK_END
) > -1:
485 IsFindBlockComment
= False
487 if IsFindBlockComment
:
490 self
._LineIndex
= Index
491 self
._CurrentLine
= Line
494 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
495 self
._SectionHeaderParser
()
496 # Check invalid sections
497 if self
._Version
< 0x00010005:
498 if self
._SectionType
in [MODEL_META_DATA_BUILD_OPTION
,
499 MODEL_EFI_LIBRARY_CLASS
,
500 MODEL_META_DATA_PACKAGE
,
501 MODEL_PCD_FIXED_AT_BUILD
,
502 MODEL_PCD_PATCHABLE_IN_MODULE
,
503 MODEL_PCD_FEATURE_FLAG
,
504 MODEL_PCD_DYNAMIC_EX
,
509 MODEL_META_DATA_USER_EXTENSION
]:
510 EdkLogger
.error('Parser', FORMAT_INVALID
,
511 "Section [%s] is not allowed in inf file without version" % (self
._SectionName
),
512 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
513 elif self
._SectionType
in [MODEL_EFI_INCLUDE
,
514 MODEL_EFI_LIBRARY_INSTANCE
,
515 MODEL_META_DATA_NMAKE
]:
516 EdkLogger
.error('Parser', FORMAT_INVALID
,
517 "Section [%s] is not allowed in inf file with version 0x%08x" % (self
._SectionName
, self
._Version
),
518 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
520 # merge two lines specified by '\' in section NMAKE
521 elif self
._SectionType
== MODEL_META_DATA_NMAKE
:
524 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
527 if NextLine
[0] == TAB_SECTION_START
and NextLine
[-1] == TAB_SECTION_END
:
528 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
531 NmakeLine
= NmakeLine
+ ' ' + Line
[0:-1]
534 self
._CurrentLine
= NmakeLine
+ Line
538 self
._ValueList
= ['','','']
539 # parse current line, result will be put in self._ValueList
540 self
._SectionParser
[self
._SectionType
](self
)
541 if self
._ValueList
== None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
545 # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
546 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
548 self
._ValueList
[0] = self
._ValueList
[0].replace('/', '\\')
549 Usage
= Usage
.strip()
550 for Arch
, Platform
in self
._Scope
:
551 self
._Store
(self
._SectionType
,
567 if IsFindBlockComment
:
568 EdkLogger
.error("Parser", FORMAT_INVALID
, "Open block comments (starting with /*) are expected to end with */",
572 ## Data parser for the format in which there's path
574 # Only path can have macro used. So we need to replace them before use.
576 def _IncludeParser(self
):
577 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
578 self
._ValueList
[0:len(TokenList
)] = TokenList
579 Macros
= self
._Macros
581 for Index
in range(0, len(self
._ValueList
)):
582 Value
= self
._ValueList
[Index
]
586 if Value
.upper().find('$(EFI_SOURCE)\Edk'.upper()) > -1 or Value
.upper().find('$(EFI_SOURCE)/Edk'.upper()) > -1:
587 Value
= '$(EDK_SOURCE)' + Value
[17:]
588 if Value
.find('$(EFI_SOURCE)') > -1 or Value
.find('$(EDK_SOURCE)') > -1:
590 elif Value
.startswith('.'):
592 elif Value
.startswith('$('):
595 Value
= '$(EFI_SOURCE)/' + Value
597 self
._ValueList
[Index
] = ReplaceMacro(Value
, Macros
)
599 ## Parse [Sources] section
601 # Only path can have macro used. So we need to replace them before use.
604 def _SourceFileParser(self
):
605 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
606 self
._ValueList
[0:len(TokenList
)] = TokenList
607 Macros
= self
._Macros
608 # For Acpi tables, remove macro like ' TABLE_NAME=Sata1'
609 if 'COMPONENT_TYPE' in Macros
:
610 if self
._Defines
['COMPONENT_TYPE'].upper() == 'ACPITABLE':
611 self
._ValueList
[0] = GetSplitValueList(self
._ValueList
[0], ' ', 1)[0]
612 if self
._Defines
['BASE_NAME'] == 'Microcode':
614 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
616 ## Parse [Binaries] section
618 # Only path can have macro used. So we need to replace them before use.
621 def _BinaryFileParser(self
):
622 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 2)
623 if len(TokenList
) < 2:
624 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type or path specified",
625 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
626 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
628 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type specified",
629 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
630 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
632 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file path specified",
633 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
634 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
635 self
._ValueList
[0:len(TokenList
)] = TokenList
636 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
638 ## [nmake] section parser (Edk.x style only)
639 def _NmakeParser(self
):
640 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
641 self
._ValueList
[0:len(TokenList
)] = TokenList
643 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
644 # remove self-reference in macro setting
645 #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
647 ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
649 def _PcdParser(self
):
650 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
651 ValueList
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
652 if len(ValueList
) != 2:
653 EdkLogger
.error('Parser', FORMAT_INVALID
, "Illegal token space GUID and PCD name format",
654 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
655 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
656 self
._ValueList
[0:1] = ValueList
657 if len(TokenList
) > 1:
658 self
._ValueList
[2] = TokenList
[1]
659 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
660 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
661 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
662 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
664 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
665 if self
._ValueList
[2] != '':
666 InfPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
667 if InfPcdValueList
[0] in ['True', 'true', 'TRUE']:
668 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '1', 1);
669 elif InfPcdValueList
[0] in ['False', 'false', 'FALSE']:
670 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '0', 1);
672 ## [depex] section parser
674 def _DepexParser(self
):
675 self
._ValueList
[0:1] = [self
._CurrentLine
]
678 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
679 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
680 MODEL_META_DATA_BUILD_OPTION
: MetaFileParser
._BuildOptionParser
,
681 MODEL_EFI_INCLUDE
: _IncludeParser
, # for Edk.x modules
682 MODEL_EFI_LIBRARY_INSTANCE
: MetaFileParser
._CommonParser
, # for Edk.x modules
683 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
684 MODEL_META_DATA_PACKAGE
: MetaFileParser
._PathParser
,
685 MODEL_META_DATA_NMAKE
: _NmakeParser
, # for Edk.x modules
686 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
687 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
688 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
689 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
690 MODEL_PCD_DYNAMIC
: _PcdParser
,
691 MODEL_EFI_SOURCE_FILE
: _SourceFileParser
,
692 MODEL_EFI_GUID
: MetaFileParser
._CommonParser
,
693 MODEL_EFI_PROTOCOL
: MetaFileParser
._CommonParser
,
694 MODEL_EFI_PPI
: MetaFileParser
._CommonParser
,
695 MODEL_EFI_DEPEX
: _DepexParser
,
696 MODEL_EFI_BINARY_FILE
: _BinaryFileParser
,
697 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
700 ## DSC file parser class
702 # @param FilePath The path of platform description file
703 # @param FileType The raw data of DSC file
704 # @param Table Database used to retrieve module/package information
705 # @param Macros Macros used for replacement in file
706 # @param Owner Owner ID (for sub-section parsing)
707 # @param From ID from which the data comes (for !INCLUDE directive)
709 class DscParser(MetaFileParser
):
710 # DSC file supported data types (one type per section)
712 TAB_SKUIDS
.upper() : MODEL_EFI_SKU_ID
,
713 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
714 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
715 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
716 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
717 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
718 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
719 TAB_PCDS_DYNAMIC_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_DEFAULT
,
720 TAB_PCDS_DYNAMIC_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_HII
,
721 TAB_PCDS_DYNAMIC_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_VPD
,
722 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT
,
723 TAB_PCDS_DYNAMIC_EX_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_HII
,
724 TAB_PCDS_DYNAMIC_EX_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_VPD
,
725 TAB_COMPONENTS
.upper() : MODEL_META_DATA_COMPONENT
,
726 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
.upper() : MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
,
727 TAB_DSC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
728 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
729 TAB_DSC_DEFINES_EDKGLOBAL
: MODEL_META_DATA_GLOBAL_DEFINE
,
730 TAB_INCLUDE
.upper() : MODEL_META_DATA_INCLUDE
,
731 TAB_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
732 TAB_IF_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
733 TAB_IF_N_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
,
734 TAB_ELSE_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
,
735 TAB_ELSE
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
,
736 TAB_END_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
,
737 TAB_ERROR
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR
,
740 # Valid names in define section
747 "PCD_INFO_GENERATION",
748 "SUPPORTED_ARCHITECTURES",
757 "FIX_LOAD_TOP_MEMORY_ADDRESS"
760 SymbolPattern
= ValueExpression
.SymbolPattern
762 ## Constructor of DscParser
764 # Initialize object of DscParser
766 # @param FilePath The path of platform description file
767 # @param FileType The raw data of DSC file
768 # @param Table Database used to retrieve module/package information
769 # @param Macros Macros used for replacement in file
770 # @param Owner Owner ID (for sub-section parsing)
771 # @param From ID from which the data comes (for !INCLUDE directive)
773 def __init__(self
, FilePath
, FileType
, Table
, Owner
=-1, From
=-1):
774 # prevent re-initialization
775 if hasattr(self
, "_Table"):
777 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
, Owner
, From
)
778 self
._Version
= 0x00010005 # Only EDK2 dsc file is supported
779 # to store conditional directive evaluation result
780 self
._DirectiveStack
= []
781 self
._DirectiveEvalStack
= []
784 # Final valid replacable symbols
787 # Map the ID between the original table and new table to track
790 self
._IdMapping
= {-1:-1}
792 self
.TblFile
= EccGlobalData
.gDb
.TblFile
799 Content
= open(str(self
.MetaFile
.Path
), 'r').readlines()
801 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
803 # Insert a record for file
805 Filename
= NormPath(self
.MetaFile
.Path
)
806 FileID
= self
.TblFile
.GetFileId(Filename
)
810 self
.FileID
= self
.TblFile
.InsertFile(Filename
, MODEL_FILE_DSC
)
813 for Index
in range(0, len(Content
)):
814 Line
= CleanString(Content
[Index
])
819 self
._CurrentLine
= Line
820 self
._LineIndex
= Index
821 if self
._InSubsection
and self
._Owner
[-1] == -1:
822 self
._Owner
.append(self
._LastItem
)
825 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
826 self
._SectionType
= MODEL_META_DATA_SECTION_HEADER
828 elif Line
[0] == '}' and self
._InSubsection
:
829 self
._InSubsection
= False
830 self
._SubsectionType
= MODEL_UNKNOWN
831 self
._SubsectionName
= ''
835 elif Line
[0] == TAB_OPTION_START
and Line
[-1] == TAB_OPTION_END
:
836 self
._SubsectionType
= MODEL_META_DATA_SUBSECTION_HEADER
839 self
._DirectiveParser
()
842 if self
._InSubsection
:
843 SectionType
= self
._SubsectionType
845 SectionType
= self
._SectionType
846 self
._ItemType
= SectionType
848 self
._ValueList
= ['', '', '']
849 self
._SectionParser
[SectionType
](self
)
850 if self
._ValueList
== None:
853 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
854 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
856 for Arch
, ModuleType
in self
._Scope
:
857 self
._LastItem
= self
._Store
(
874 if self
._DirectiveStack
:
875 Type
, Line
, Text
= self
._DirectiveStack
[-1]
876 EdkLogger
.error('Parser', FORMAT_INVALID
, "No matching '!endif' found",
877 ExtraData
=Text
, File
=self
.MetaFile
, Line
=Line
)
880 ## <subsection_header> parser
881 def _SubsectionHeaderParser(self
):
882 self
._SubsectionName
= self
._CurrentLine
[1:-1].upper()
883 if self
._SubsectionName
in self
.DataType
:
884 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
886 self
._SubsectionType
= MODEL_UNKNOWN
887 EdkLogger
.warn("Parser", "Unrecognized sub-section", File
=self
.MetaFile
,
888 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
889 self
._ValueList
[0] = self
._SubsectionName
891 ## Directive statement parser
892 def _DirectiveParser(self
):
893 self
._ValueList
= ['','','']
894 TokenList
= GetSplitValueList(self
._CurrentLine
, ' ', 1)
895 self
._ValueList
[0:len(TokenList
)] = TokenList
898 DirectiveName
= self
._ValueList
[0].upper()
899 if DirectiveName
not in self
.DataType
:
900 EdkLogger
.error("Parser", FORMAT_INVALID
, "Unknown directive [%s]" % DirectiveName
,
901 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
902 if DirectiveName
in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self
._ValueList
[1] == '':
903 EdkLogger
.error("Parser", FORMAT_INVALID
, "Missing expression",
904 File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
905 ExtraData
=self
._CurrentLine
)
907 ItemType
= self
.DataType
[DirectiveName
]
908 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
909 # Remove all directives between !if and !endif, including themselves
910 while self
._DirectiveStack
:
911 # Remove any !else or !elseif
912 DirectiveInfo
= self
._DirectiveStack
.pop()
913 if DirectiveInfo
[0] in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
914 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
915 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
918 EdkLogger
.error("Parser", FORMAT_INVALID
, "Redundant '!endif'",
919 File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
920 ExtraData
=self
._CurrentLine
)
921 elif ItemType
!= MODEL_META_DATA_INCLUDE
:
922 # Break if there's a !else is followed by a !elseif
923 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
and \
924 self
._DirectiveStack
and \
925 self
._DirectiveStack
[-1][0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
926 EdkLogger
.error("Parser", FORMAT_INVALID
, "'!elseif' after '!else'",
927 File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
928 ExtraData
=self
._CurrentLine
)
929 self
._DirectiveStack
.append((ItemType
, self
._LineIndex
+1, self
._CurrentLine
))
931 EdkLogger
.error('Parser', FORMAT_INVALID
,
932 "No '!include' allowed in included file",
933 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
,
934 Line
=self
._LineIndex
+1)
937 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
938 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
940 self
._LastItem
= self
._Store
(
957 ## [defines] section parser
959 def _DefineParser(self
):
960 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
961 self
._ValueList
[1:len(TokenList
)] = TokenList
964 if not self
._ValueList
[1]:
965 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
966 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
967 if not self
._ValueList
[2]:
968 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
969 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
970 if not self
._ValueList
[1] in self
.DefineKeywords
:
971 EdkLogger
.error('Parser', FORMAT_INVALID
,
972 "Unknown keyword found: %s. "
973 "If this is a macro you must "
974 "add it as a DEFINE in the DSC" % self
._ValueList
[1],
975 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
976 self
._Defines
[self
._ValueList
[1]] = self
._ValueList
[2]
977 self
._ItemType
= self
.DataType
[TAB_DSC_DEFINES
.upper()]
980 def _SkuIdParser(self
):
981 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
982 if len(TokenList
) != 2:
983 EdkLogger
.error('Parser', FORMAT_INVALID
, "Correct format is '<Integer>|<UiName>'",
984 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
985 self
._ValueList
[0:len(TokenList
)] = TokenList
987 ## Parse Edk style of library modules
988 def _LibraryInstanceParser(self
):
989 self
._ValueList
[0] = self
._CurrentLine
991 ## PCD sections parser
994 # [PcdsPatchableInModule]
997 # [PcdsDynamicExDefault]
1001 # [PcdsDynamicDefault]
1006 def _PcdParser(self
):
1007 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1008 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1009 if len(TokenList
) == 2:
1010 self
._ValueList
[2] = TokenList
[1]
1011 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1012 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1013 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1014 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1015 if self
._ValueList
[2] == '':
1016 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD value given",
1017 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1018 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1019 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
1020 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
1021 if DscPcdValueList
[0] in ['True', 'true', 'TRUE']:
1022 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '1', 1);
1023 elif DscPcdValueList
[0] in ['False', 'false', 'FALSE']:
1024 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '0', 1);
1026 ## [components] section parser
1028 def _ComponentParser(self
):
1029 if self
._CurrentLine
[-1] == '{':
1030 self
._ValueList
[0] = self
._CurrentLine
[0:-1].strip()
1031 self
._InSubsection
= True
1033 self
._ValueList
[0] = self
._CurrentLine
1035 ## [LibraryClasses] section
1037 def _LibraryClassParser(self
):
1038 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1039 if len(TokenList
) < 2:
1040 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class or instance specified",
1041 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1042 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1043 if TokenList
[0] == '':
1044 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class specified",
1045 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1046 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1047 if TokenList
[1] == '':
1048 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library instance specified",
1049 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1050 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1052 self
._ValueList
[0:len(TokenList
)] = TokenList
1054 def _CompponentSourceOverridePathParser(self
):
1055 self
._ValueList
[0] = self
._CurrentLine
1057 ## [BuildOptions] section parser
1059 def _BuildOptionParser(self
):
1060 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1061 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
1062 if len(TokenList2
) == 2:
1063 self
._ValueList
[0] = TokenList2
[0] # toolchain family
1064 self
._ValueList
[1] = TokenList2
[1] # keys
1066 self
._ValueList
[1] = TokenList
[0]
1067 if len(TokenList
) == 2: # value
1068 self
._ValueList
[2] = TokenList
[1]
1070 if self
._ValueList
[1].count('_') != 4:
1074 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
1075 ExtraData
=self
._CurrentLine
,
1077 Line
=self
._LineIndex
+1
1080 ## Override parent's method since we'll do all macro replacements in parser
1081 def _GetMacros(self
):
1082 Macros
= dict( [('ARCH','IA32'), ('FAMILY','MSFT'),('TOOL_CHAIN_TAG','VS2008x86'),('TARGET','DEBUG')])
1083 Macros
.update(self
._FileLocalMacros
)
1084 Macros
.update(self
._GetApplicableSectionMacro
())
1085 Macros
.update(GlobalData
.gEdkGlobal
)
1086 Macros
.update(GlobalData
.gPlatformDefines
)
1087 Macros
.update(GlobalData
.gCommandLineDefines
)
1088 # PCD cannot be referenced in macro definition
1089 if self
._ItemType
not in [MODEL_META_DATA_DEFINE
, MODEL_META_DATA_GLOBAL_DEFINE
]:
1090 Macros
.update(self
._Symbols
)
1093 def _PostProcess(self
):
1095 MODEL_META_DATA_SECTION_HEADER
: self
.__ProcessSectionHeader
,
1096 MODEL_META_DATA_SUBSECTION_HEADER
: self
.__ProcessSubsectionHeader
,
1097 MODEL_META_DATA_HEADER
: self
.__ProcessDefine
,
1098 MODEL_META_DATA_DEFINE
: self
.__ProcessDefine
,
1099 MODEL_META_DATA_GLOBAL_DEFINE
: self
.__ProcessDefine
,
1100 MODEL_META_DATA_INCLUDE
: self
.__ProcessDirective
,
1101 MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
: self
.__ProcessDirective
,
1102 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
: self
.__ProcessDirective
,
1103 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
: self
.__ProcessDirective
,
1104 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
: self
.__ProcessDirective
,
1105 MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
: self
.__ProcessDirective
,
1106 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
: self
.__ProcessDirective
,
1107 MODEL_EFI_SKU_ID
: self
.__ProcessSkuId
,
1108 MODEL_EFI_LIBRARY_INSTANCE
: self
.__ProcessLibraryInstance
,
1109 MODEL_EFI_LIBRARY_CLASS
: self
.__ProcessLibraryClass
,
1110 MODEL_PCD_FIXED_AT_BUILD
: self
.__ProcessPcd
,
1111 MODEL_PCD_PATCHABLE_IN_MODULE
: self
.__ProcessPcd
,
1112 MODEL_PCD_FEATURE_FLAG
: self
.__ProcessPcd
,
1113 MODEL_PCD_DYNAMIC_DEFAULT
: self
.__ProcessPcd
,
1114 MODEL_PCD_DYNAMIC_HII
: self
.__ProcessPcd
,
1115 MODEL_PCD_DYNAMIC_VPD
: self
.__ProcessPcd
,
1116 MODEL_PCD_DYNAMIC_EX_DEFAULT
: self
.__ProcessPcd
,
1117 MODEL_PCD_DYNAMIC_EX_HII
: self
.__ProcessPcd
,
1118 MODEL_PCD_DYNAMIC_EX_VPD
: self
.__ProcessPcd
,
1119 MODEL_META_DATA_COMPONENT
: self
.__ProcessComponent
,
1120 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: self
.__ProcessSourceOverridePath
,
1121 MODEL_META_DATA_BUILD_OPTION
: self
.__ProcessBuildOption
,
1122 MODEL_UNKNOWN
: self
._Skip
,
1123 MODEL_META_DATA_USER_EXTENSION
: self
._Skip
,
1124 MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR
: self
._Skip
,
1127 self
._RawTable
= self
._Table
1128 self
._Table
= MetaFileStorage(self
._RawTable
.Cur
, self
.MetaFile
, MODEL_FILE_DSC
, True)
1129 self
._DirectiveStack
= []
1130 self
._DirectiveEvalStack
= []
1131 self
._FileWithError
= self
.MetaFile
1132 self
._FileLocalMacros
= {}
1133 self
._SectionsMacroDict
= {}
1134 GlobalData
.gPlatformDefines
= {}
1136 # Get all macro and PCD which has straitforward value
1137 self
.__RetrievePcdValue
()
1138 self
._Content
= self
._RawTable
.GetAll()
1139 self
._ContentIndex
= 0
1140 while self
._ContentIndex
< len(self
._Content
) :
1141 Id
, self
._ItemType
, V1
, V2
, V3
, S1
, S2
, Owner
, BelongsToFile
, self
._From
, \
1142 LineStart
, ColStart
, LineEnd
, ColEnd
, Enabled
= self
._Content
[self
._ContentIndex
]
1145 self
._FileWithError
= self
.MetaFile
1147 self
._ContentIndex
+= 1
1149 self
._Scope
= [[S1
, S2
]]
1150 self
._LineIndex
= LineStart
- 1
1151 self
._ValueList
= [V1
, V2
, V3
]
1154 Processer
[self
._ItemType
]()
1155 except EvaluationException
, Excpt
:
1157 # Only catch expression evaluation error here. We need to report
1158 # the precise number of line on which the error occurred
1161 # EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),
1162 # File=self._FileWithError, ExtraData=' '.join(self._ValueList),
1163 # Line=self._LineIndex+1)
1164 except MacroException
, Excpt
:
1165 EdkLogger
.error('Parser', FORMAT_INVALID
, str(Excpt
),
1166 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1167 Line
=self
._LineIndex
+1)
1169 if self
._ValueList
== None:
1172 NewOwner
= self
._IdMapping
.get(Owner
, -1)
1173 self
._Enabled
= int((not self
._DirectiveEvalStack
) or (False not in self
._DirectiveEvalStack
))
1174 self
._LastItem
= self
._Store
(
1190 self
._IdMapping
[Id
] = self
._LastItem
1192 RecordList
= self
._Table
.GetAll()
1194 self
._RawTable
.Drop()
1196 for Record
in RecordList
:
1197 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])
1198 GlobalData
.gPlatformDefines
.update(self
._FileLocalMacros
)
1199 self
._PostProcessed
= True
1200 self
._Content
= None
1202 def __ProcessSectionHeader(self
):
1203 self
._SectionName
= self
._ValueList
[0]
1204 if self
._SectionName
in self
.DataType
:
1205 self
._SectionType
= self
.DataType
[self
._SectionName
]
1207 self
._SectionType
= MODEL_UNKNOWN
1209 def __ProcessSubsectionHeader(self
):
1210 self
._SubsectionName
= self
._ValueList
[0]
1211 if self
._SubsectionName
in self
.DataType
:
1212 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
1214 self
._SubsectionType
= MODEL_UNKNOWN
1216 def __RetrievePcdValue(self
):
1217 Records
= self
._RawTable
.Query(MODEL_PCD_FEATURE_FLAG
, BelongsToItem
=-1.0)
1218 for TokenSpaceGuid
,PcdName
,Value
,Dummy2
,Dummy3
,ID
,Line
in Records
:
1219 Value
, DatumType
, MaxDatumSize
= AnalyzePcdData(Value
)
1220 # Only use PCD whose value is straitforward (no macro and PCD)
1221 if self
.SymbolPattern
.findall(Value
):
1223 Name
= TokenSpaceGuid
+ '.' + PcdName
1224 # Don't use PCD with different values.
1225 if Name
in self
._Symbols
and self
._Symbols
[Name
] != Value
:
1226 self
._Symbols
.pop(Name
)
1228 self
._Symbols
[Name
] = Value
1230 Records
= self
._RawTable
.Query(MODEL_PCD_FIXED_AT_BUILD
, BelongsToItem
=-1.0)
1231 for TokenSpaceGuid
,PcdName
,Value
,Dummy2
,Dummy3
,ID
,Line
in Records
:
1232 Value
, DatumType
, MaxDatumSize
= AnalyzePcdData(Value
)
1233 # Only use PCD whose value is straitforward (no macro and PCD)
1234 if self
.SymbolPattern
.findall(Value
):
1236 Name
= TokenSpaceGuid
+'.'+PcdName
1237 # Don't use PCD with different values.
1238 if Name
in self
._Symbols
and self
._Symbols
[Name
] != Value
:
1239 self
._Symbols
.pop(Name
)
1241 self
._Symbols
[Name
] = Value
1243 def __ProcessDefine(self
):
1244 if not self
._Enabled
:
1247 Type
, Name
, Value
= self
._ValueList
1248 Value
= ReplaceMacro(Value
, self
._Macros
, False)
1249 if self
._ItemType
== MODEL_META_DATA_DEFINE
:
1250 if self
._SectionType
== MODEL_META_DATA_HEADER
:
1251 self
._FileLocalMacros
[Name
] = Value
1253 SectionDictKey
= self
._SectionType
, self
._Scope
[0][0], self
._Scope
[0][1]
1254 if SectionDictKey
not in self
._SectionsMacroDict
:
1255 self
._SectionsMacroDict
[SectionDictKey
] = {}
1256 SectionLocalMacros
= self
._SectionsMacroDict
[SectionDictKey
]
1257 SectionLocalMacros
[Name
] = Value
1258 elif self
._ItemType
== MODEL_META_DATA_GLOBAL_DEFINE
:
1259 GlobalData
.gEdkGlobal
[Name
] = Value
1262 # Keyword in [Defines] section can be used as Macros
1264 if (self
._ItemType
== MODEL_META_DATA_HEADER
) and (self
._SectionType
== MODEL_META_DATA_HEADER
):
1265 self
._FileLocalMacros
[Name
] = Value
1267 self
._ValueList
= [Type
, Name
, Value
]
1269 def __ProcessDirective(self
):
1271 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1272 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
]:
1273 Macros
= self
._Macros
1274 Macros
.update(GlobalData
.gGlobalDefines
)
1276 Result
= ValueExpression(self
._ValueList
[1], Macros
)()
1277 except SymbolNotFound
, Exc
:
1278 EdkLogger
.debug(EdkLogger
.DEBUG_5
, str(Exc
), self
._ValueList
[1])
1280 except WrnExpression
, Excpt
:
1282 # Catch expression evaluation warning here. We need to report
1283 # the precise number of line and return the evaluation result
1285 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
1286 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1287 Line
=self
._LineIndex
+1)
1288 Result
= Excpt
.result
1290 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1291 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1292 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1293 self
._DirectiveStack
.append(self
._ItemType
)
1294 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
:
1295 Result
= bool(Result
)
1297 Macro
= self
._ValueList
[1]
1298 Macro
= Macro
[2:-1] if (Macro
.startswith("$(") and Macro
.endswith(")")) else Macro
1299 Result
= Macro
in self
._Macros
1300 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
:
1302 self
._DirectiveEvalStack
.append(Result
)
1303 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
:
1304 self
._DirectiveStack
.append(self
._ItemType
)
1305 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1306 self
._DirectiveEvalStack
.append(bool(Result
))
1307 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1308 self
._DirectiveStack
[-1] = self
._ItemType
1309 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1310 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1311 # Back to the nearest !if/!ifdef/!ifndef
1312 while self
._DirectiveStack
:
1313 self
._DirectiveEvalStack
.pop()
1314 Directive
= self
._DirectiveStack
.pop()
1315 if Directive
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1316 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1317 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
,
1318 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1320 elif self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1321 # The included file must be relative to workspace or same directory as DSC file
1322 __IncludeMacros
= {}
1324 # Allow using system environment variables in path after !include
1326 __IncludeMacros
['WORKSPACE'] = GlobalData
.gGlobalDefines
['WORKSPACE']
1327 if "ECP_SOURCE" in GlobalData
.gGlobalDefines
.keys():
1328 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gGlobalDefines
['ECP_SOURCE']
1330 # During GenFds phase call DSC parser, will go into this branch.
1332 elif "ECP_SOURCE" in GlobalData
.gCommandLineDefines
.keys():
1333 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gCommandLineDefines
['ECP_SOURCE']
1335 __IncludeMacros
['EFI_SOURCE'] = GlobalData
.gGlobalDefines
['EFI_SOURCE']
1336 __IncludeMacros
['EDK_SOURCE'] = GlobalData
.gGlobalDefines
['EDK_SOURCE']
1338 # Allow using MACROs comes from [Defines] section to keep compatible.
1340 __IncludeMacros
.update(self
._Macros
)
1342 IncludedFile
= NormPath(ReplaceMacro(self
._ValueList
[1], __IncludeMacros
, RaiseError
=True))
1344 # First search the include file under the same directory as DSC file
1346 IncludedFile1
= PathClass(IncludedFile
, self
.MetaFile
.Dir
)
1347 ErrorCode
, ErrorInfo1
= IncludedFile1
.Validate()
1350 # Also search file under the WORKSPACE directory
1352 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
1353 ErrorCode
, ErrorInfo2
= IncludedFile1
.Validate()
1355 EdkLogger
.error('parser', ErrorCode
, File
=self
._FileWithError
,
1356 Line
=self
._LineIndex
+1, ExtraData
=ErrorInfo1
+ "\n"+ ErrorInfo2
)
1358 self
._FileWithError
= IncludedFile1
1360 IncludedFileTable
= MetaFileStorage(self
._Table
.Cur
, IncludedFile1
, MODEL_FILE_DSC
, True)
1361 Owner
= self
._Content
[self
._ContentIndex
-1][0]
1362 Parser
= DscParser(IncludedFile1
, self
._FileType
, IncludedFileTable
,
1363 Owner
=Owner
, From
=Owner
)
1365 # set the parser status with current status
1366 Parser
._SectionName
= self
._SectionName
1367 Parser
._SectionType
= self
._SectionType
1368 Parser
._Scope
= self
._Scope
1369 Parser
._Enabled
= self
._Enabled
1370 # Parse the included file
1373 # update current status with sub-parser's status
1374 self
._SectionName
= Parser
._SectionName
1375 self
._SectionType
= Parser
._SectionType
1376 self
._Scope
= Parser
._Scope
1377 self
._Enabled
= Parser
._Enabled
1379 # Insert all records in the table for the included file into dsc file table
1380 Records
= IncludedFileTable
.GetAll()
1382 self
._Content
[self
._ContentIndex
:self
._ContentIndex
] = Records
1383 self
._Content
.pop(self
._ContentIndex
-1)
1384 self
._ValueList
= None
1385 self
._ContentIndex
-= 1
1387 def __ProcessSkuId(self
):
1388 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=True)
1389 for Value
in self
._ValueList
]
1391 def __ProcessLibraryInstance(self
):
1392 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
1394 def __ProcessLibraryClass(self
):
1395 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
, RaiseError
=True)
1397 def __ProcessPcd(self
):
1398 ValueList
= GetSplitValueList(self
._ValueList
[2])
1400 # PCD value can be an expression
1402 if len(ValueList
) > 1 and ValueList
[1] == 'VOID*':
1403 PcdValue
= ValueList
[0]
1405 ValueList
[0] = ValueExpression(PcdValue
, self
._Macros
)(True)
1406 except WrnExpression
, Value
:
1407 ValueList
[0] = Value
.result
1409 PcdValue
= ValueList
[-1]
1411 ValueList
[-1] = ValueExpression(PcdValue
, self
._Macros
)(True)
1412 except WrnExpression
, Value
:
1413 ValueList
[-1] = Value
.result
1415 if ValueList
[-1] == 'True':
1417 if ValueList
[-1] == 'False':
1420 self
._ValueList
[2] = '|'.join(ValueList
)
1422 def __ProcessComponent(self
):
1423 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1425 def __ProcessSourceOverridePath(self
):
1426 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1428 def __ProcessBuildOption(self
):
1429 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=False)
1430 for Value
in self
._ValueList
]
1433 MODEL_META_DATA_HEADER
: _DefineParser
,
1434 MODEL_EFI_SKU_ID
: _SkuIdParser
,
1435 MODEL_EFI_LIBRARY_INSTANCE
: _LibraryInstanceParser
,
1436 MODEL_EFI_LIBRARY_CLASS
: _LibraryClassParser
,
1437 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1438 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1439 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1440 MODEL_PCD_DYNAMIC_DEFAULT
: _PcdParser
,
1441 MODEL_PCD_DYNAMIC_HII
: _PcdParser
,
1442 MODEL_PCD_DYNAMIC_VPD
: _PcdParser
,
1443 MODEL_PCD_DYNAMIC_EX_DEFAULT
: _PcdParser
,
1444 MODEL_PCD_DYNAMIC_EX_HII
: _PcdParser
,
1445 MODEL_PCD_DYNAMIC_EX_VPD
: _PcdParser
,
1446 MODEL_META_DATA_COMPONENT
: _ComponentParser
,
1447 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: _CompponentSourceOverridePathParser
,
1448 MODEL_META_DATA_BUILD_OPTION
: _BuildOptionParser
,
1449 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1450 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
1451 MODEL_META_DATA_SECTION_HEADER
: MetaFileParser
._SectionHeaderParser
,
1452 MODEL_META_DATA_SUBSECTION_HEADER
: _SubsectionHeaderParser
,
1455 _Macros
= property(_GetMacros
)
1457 ## DEC file parser class
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 class DecParser(MetaFileParser
):
1465 # DEC file supported data types (one type per section)
1467 TAB_DEC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
1468 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
1469 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
1470 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
1471 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
1472 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
1473 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
1474 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
1475 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
1476 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
1477 TAB_PCDS_DYNAMIC_NULL
.upper() : MODEL_PCD_DYNAMIC
,
1478 TAB_PCDS_DYNAMIC_EX_NULL
.upper() : MODEL_PCD_DYNAMIC_EX
,
1481 ## Constructor of DecParser
1483 # Initialize object of DecParser
1485 # @param FilePath The path of platform description file
1486 # @param FileType The raw data of DSC file
1487 # @param Table Database used to retrieve module/package information
1488 # @param Macros Macros used for replacement in file
1490 def __init__(self
, FilePath
, FileType
, Table
):
1491 # prevent re-initialization
1492 if hasattr(self
, "_Table"):
1494 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
)
1496 self
._Version
= 0x00010005 # Only EDK2 dec file is supported
1497 self
.TblFile
= EccGlobalData
.gDb
.TblFile
1504 Content
= open(str(self
.MetaFile
), 'r').readlines()
1506 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
1509 # Insert a record for file
1511 Filename
= NormPath(self
.MetaFile
)
1512 FileID
= self
.TblFile
.GetFileId(Filename
)
1514 self
.FileID
= FileID
1516 self
.FileID
= self
.TblFile
.InsertFile(Filename
, MODEL_FILE_DEC
)
1518 for Index
in range(0, len(Content
)):
1519 Line
, Comment
= CleanString2(Content
[Index
])
1520 self
._CurrentLine
= Line
1521 self
._LineIndex
= Index
1523 # save comment for later use
1525 self
._Comments
.append((Comment
, self
._LineIndex
+1))
1531 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
1532 self
._SectionHeaderParser
()
1535 elif len(self
._SectionType
) == 0:
1540 self
._ValueList
= ['','','']
1541 self
._SectionParser
[self
._SectionType
[0]](self
)
1542 if self
._ValueList
== None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
1548 # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,
1549 # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1
1551 for Arch
, ModuleType
, Type
in self
._Scope
:
1552 self
._LastItem
= self
._Store
(
1567 for Comment
, LineNo
in self
._Comments
:
1569 MODEL_META_DATA_COMMENT
,
1586 def _GetApplicableSectionMacro(self
):
1588 for S1
, S2
, SectionType
in self
._Scope
:
1589 for Scope1
, Scope2
in [("COMMON", "COMMON"), ("COMMON", S2
), (S1
, "COMMON"), (S1
, S2
)]:
1590 if (SectionType
, Scope1
, Scope2
) in self
._SectionsMacroDict
:
1591 Macros
.update(self
._SectionsMacroDict
[(SectionType
, Scope1
, Scope2
)])
1594 ## Section header parser
1596 # The section header is always in following format:
1598 # [section_name.arch<.platform|module_type>]
1600 def _SectionHeaderParser(self
):
1602 self
._SectionName
= ''
1603 self
._SectionType
= []
1605 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
1608 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
)
1610 # different types of PCD are permissible in one section
1611 self
._SectionName
= ItemList
[0].upper()
1612 if self
._SectionName
in self
.DataType
:
1613 if self
.DataType
[self
._SectionName
] not in self
._SectionType
:
1614 self
._SectionType
.append(self
.DataType
[self
._SectionName
])
1616 EdkLogger
.warn("Parser", "Unrecognized section", File
=self
.MetaFile
,
1617 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
1620 if MODEL_PCD_FEATURE_FLAG
in self
._SectionType
and len(self
._SectionType
) > 1:
1624 "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL
,
1626 Line
=self
._LineIndex
+1,
1627 ExtraData
=self
._CurrentLine
1630 if len(ItemList
) > 1:
1631 S1
= ItemList
[1].upper()
1635 # S2 may be Platform or ModuleType
1636 if len(ItemList
) > 2:
1637 S2
= ItemList
[2].upper()
1640 if [S1
, S2
, self
.DataType
[self
._SectionName
]] not in self
._Scope
:
1641 self
._Scope
.append([S1
, S2
, self
.DataType
[self
._SectionName
]])
1643 # 'COMMON' must not be used with specific ARCHs at the same section
1644 if 'COMMON' in ArchList
and len(ArchList
) > 1:
1645 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
1646 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
1648 ## [guids], [ppis] and [protocols] section parser
1650 def _GuidParser(self
):
1651 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1652 if len(TokenList
) < 2:
1653 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name or value specified",
1654 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1655 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1656 if TokenList
[0] == '':
1657 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name specified",
1658 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1659 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1660 if TokenList
[1] == '':
1661 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID value specified",
1662 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1663 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1664 if TokenList
[1][0] != '{' or TokenList
[1][-1] != '}' or GuidStructureStringToGuidString(TokenList
[1]) == '':
1665 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid GUID value format",
1666 ExtraData
=self
._CurrentLine
+ \
1667 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
1668 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1669 self
._ValueList
[0] = TokenList
[0]
1670 #Parse the Guid value format
1671 GuidValueList
= TokenList
[1].strip(' {}').split(',')
1674 if len(GuidValueList
) == 11:
1675 for GuidValue
in GuidValueList
:
1676 GuidValue
= GuidValue
.strip()
1677 if GuidValue
.startswith('0x') or GuidValue
.startswith('0X'):
1678 HexList
.append('0x' + str(GuidValue
[2:]))
1682 if GuidValue
.startswith('{'):
1683 HexList
.append('0x' + str(GuidValue
[3:]))
1685 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])
1687 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid GUID value format",
1688 ExtraData
=self
._CurrentLine
+ \
1689 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
1690 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1691 self
._ValueList
[0] = ''
1693 ## PCD sections parser
1695 # [PcdsFixedAtBuild]
1696 # [PcdsPatchableInModule]
1702 def _PcdParser(self
):
1703 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1704 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1705 # check PCD information
1706 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1707 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1708 ExtraData
=self
._CurrentLine
+ \
1709 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1710 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1711 # check PCD datum information
1712 if len(TokenList
) < 2 or TokenList
[1] == '':
1713 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD Datum information given",
1714 ExtraData
=self
._CurrentLine
+ \
1715 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1716 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1719 ValueRe
= re
.compile(r
'^\s*L?\".*\|.*\"')
1720 PtrValue
= ValueRe
.findall(TokenList
[1])
1722 # Has VOID* type string, may contain "|" character in the string.
1723 if len(PtrValue
) != 0:
1724 ptrValueList
= re
.sub(ValueRe
, '', TokenList
[1])
1725 ValueList
= GetSplitValueList(ptrValueList
)
1726 ValueList
[0] = PtrValue
[0]
1728 ValueList
= GetSplitValueList(TokenList
[1])
1731 # check if there's enough datum information given
1732 if len(ValueList
) != 3:
1733 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid PCD Datum information given",
1734 ExtraData
=self
._CurrentLine
+ \
1735 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1736 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1737 # check default value
1738 if ValueList
[0] == '':
1739 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DefaultValue in PCD Datum information",
1740 ExtraData
=self
._CurrentLine
+ \
1741 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1742 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1744 if ValueList
[1] == '':
1745 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DatumType in PCD Datum information",
1746 ExtraData
=self
._CurrentLine
+ \
1747 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1748 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1749 # check token of the PCD
1750 if ValueList
[2] == '':
1751 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing Token in PCD Datum information",
1752 ExtraData
=self
._CurrentLine
+ \
1753 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1754 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1755 # check format of default value against the datum type
1756 IsValid
, Cause
= CheckPcdDatum(ValueList
[1], ValueList
[0])
1758 EdkLogger
.error('Parser', FORMAT_INVALID
, Cause
, ExtraData
=self
._CurrentLine
,
1759 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1761 if ValueList
[0] in ['True', 'true', 'TRUE']:
1763 elif ValueList
[0] in ['False', 'false', 'FALSE']:
1766 self
._ValueList
[2] = ValueList
[0].strip() + '|' + ValueList
[1].strip() + '|' + ValueList
[2].strip()
1769 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
1770 MODEL_EFI_INCLUDE
: MetaFileParser
._PathParser
,
1771 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
1772 MODEL_EFI_GUID
: _GuidParser
,
1773 MODEL_EFI_PPI
: _GuidParser
,
1774 MODEL_EFI_PROTOCOL
: _GuidParser
,
1775 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1776 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1777 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1778 MODEL_PCD_DYNAMIC
: _PcdParser
,
1779 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
1780 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1781 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
1787 # This class defined basic Fdf object which is used by inheriting
1789 # @param object: Inherited from object class
1791 class FdfObject(object):
1797 # This class defined the structure used in Fdf object
1799 # @param FdfObject: Inherited from FdfObject class
1800 # @param Filename: Input value for Ffilename of Fdf file, default is None
1801 # @param WorkspaceDir: Input value for current workspace directory, default is None
1803 class Fdf(FdfObject
):
1804 def __init__(self
, Filename
= None, IsToDatabase
= False, WorkspaceDir
= None, Database
= None):
1805 self
.WorkspaceDir
= WorkspaceDir
1806 self
.IsToDatabase
= IsToDatabase
1808 self
.Cur
= Database
.Cur
1809 self
.TblFile
= Database
.TblFile
1810 self
.TblFdf
= Database
.TblFdf
1815 # Load Fdf file if filename is not None
1817 if Filename
!= None:
1819 self
.LoadFdfFile(Filename
)
1824 # Insert a FDF file record into database
1826 def InsertFile(self
, Filename
):
1828 Filename
= NormPath(Filename
)
1829 if Filename
not in self
.FileList
:
1830 FileID
= self
.TblFile
.InsertFile(Filename
, MODEL_FILE_FDF
)
1831 self
.FileList
[Filename
] = FileID
1833 return self
.FileList
[Filename
]
1838 # Load the file if it exists
1840 # @param Filename: Input value for filename of Fdf file
1842 def LoadFdfFile(self
, Filename
):
1847 Filename
= NormPath(Filename
)
1848 Fdf
= FdfParser(Filename
)
1852 # Insert inf file and pcd information
1854 if self
.IsToDatabase
:
1855 (Model
, Value1
, Value2
, Value3
, Scope1
, Scope2
, BelongsToItem
, BelongsToFile
, StartLine
, StartColumn
, EndLine
, EndColumn
, Enabled
) = \
1856 (0, '', '', '', 'COMMON', 'COMMON', -1, -1, -1, -1, -1, -1, 0)
1857 for Index
in range(0, len(Fdf
.Profile
.PcdDict
)):
1859 for Key
in Fdf
.Profile
.PcdDict
.keys():
1863 FileName
= Fdf
.Profile
.PcdFileLineDict
[Key
][0]
1864 StartLine
= Fdf
.Profile
.PcdFileLineDict
[Key
][1]
1865 BelongsToFile
= self
.InsertFile(FileName
)
1866 self
.TblFdf
.Insert(Model
, Value1
, Value2
, Value3
, Scope1
, Scope2
, BelongsToItem
, BelongsToFile
, StartLine
, StartColumn
, EndLine
, EndColumn
, Enabled
)
1867 for Index
in range(0, len(Fdf
.Profile
.InfList
)):
1868 Model
= MODEL_META_DATA_COMPONENT
1869 Value1
= Fdf
.Profile
.InfList
[Index
]
1871 FileName
= Fdf
.Profile
.InfFileLineList
[Index
][0]
1872 StartLine
= Fdf
.Profile
.InfFileLineList
[Index
][1]
1873 BelongsToFile
= self
.InsertFile(FileName
)
1874 self
.TblFdf
.Insert(Model
, Value1
, Value2
, Value3
, Scope1
, Scope2
, BelongsToItem
, BelongsToFile
, StartLine
, StartColumn
, EndLine
, EndColumn
, Enabled
)
1878 # This acts like the main() function for the script, unless it is 'import'ed into another
1881 if __name__
== '__main__':