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_COMMENT_SPLIT
):
466 elif Line
.find(TAB_COMMENT_SPLIT
) > 0:
467 Usage
= Line
[Line
.find(TAB_COMMENT_SPLIT
):]
468 Line
= Line
[:Line
.find(TAB_COMMENT_SPLIT
)]
472 # skip empty, commented, block commented lines
473 Line
= CleanString(Content
[Index
], AllowCppStyleComment
=True)
476 if Index
+ 1 < len(Content
):
477 NextLine
= CleanString(Content
[Index
+ 1])
480 if Line
.find(DataType
.TAB_COMMENT_EDK_START
) > -1:
481 IsFindBlockComment
= True
483 if Line
.find(DataType
.TAB_COMMENT_EDK_END
) > -1:
484 IsFindBlockComment
= False
486 if IsFindBlockComment
:
489 self
._LineIndex
= Index
490 self
._CurrentLine
= Line
493 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
494 self
._SectionHeaderParser
()
495 # Check invalid sections
496 if self
._Version
< 0x00010005:
497 if self
._SectionType
in [MODEL_META_DATA_BUILD_OPTION
,
498 MODEL_EFI_LIBRARY_CLASS
,
499 MODEL_META_DATA_PACKAGE
,
500 MODEL_PCD_FIXED_AT_BUILD
,
501 MODEL_PCD_PATCHABLE_IN_MODULE
,
502 MODEL_PCD_FEATURE_FLAG
,
503 MODEL_PCD_DYNAMIC_EX
,
508 MODEL_META_DATA_USER_EXTENSION
]:
509 EdkLogger
.error('Parser', FORMAT_INVALID
,
510 "Section [%s] is not allowed in inf file without version" % (self
._SectionName
),
511 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
512 elif self
._SectionType
in [MODEL_EFI_INCLUDE
,
513 MODEL_EFI_LIBRARY_INSTANCE
,
514 MODEL_META_DATA_NMAKE
]:
515 EdkLogger
.error('Parser', FORMAT_INVALID
,
516 "Section [%s] is not allowed in inf file with version 0x%08x" % (self
._SectionName
, self
._Version
),
517 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
519 # merge two lines specified by '\' in section NMAKE
520 elif self
._SectionType
== MODEL_META_DATA_NMAKE
:
523 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
526 if NextLine
[0] == TAB_SECTION_START
and NextLine
[-1] == TAB_SECTION_END
:
527 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
530 NmakeLine
= NmakeLine
+ ' ' + Line
[0:-1]
533 self
._CurrentLine
= NmakeLine
+ Line
537 self
._ValueList
= ['','','']
538 # parse current line, result will be put in self._ValueList
539 self
._SectionParser
[self
._SectionType
](self
)
540 if self
._ValueList
== None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
544 # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
545 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
547 self
._ValueList
[0] = self
._ValueList
[0].replace('/', '\\')
548 for Arch
, Platform
in self
._Scope
:
549 self
._Store
(self
._SectionType
,
564 if IsFindBlockComment
:
565 EdkLogger
.error("Parser", FORMAT_INVALID
, "Open block comments (starting with /*) are expected to end with */",
569 ## Data parser for the format in which there's path
571 # Only path can have macro used. So we need to replace them before use.
573 def _IncludeParser(self
):
574 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
575 self
._ValueList
[0:len(TokenList
)] = TokenList
576 Macros
= self
._Macros
578 for Index
in range(0, len(self
._ValueList
)):
579 Value
= self
._ValueList
[Index
]
583 if Value
.upper().find('$(EFI_SOURCE)\Edk'.upper()) > -1 or Value
.upper().find('$(EFI_SOURCE)/Edk'.upper()) > -1:
584 Value
= '$(EDK_SOURCE)' + Value
[17:]
585 if Value
.find('$(EFI_SOURCE)') > -1 or Value
.find('$(EDK_SOURCE)') > -1:
587 elif Value
.startswith('.'):
589 elif Value
.startswith('$('):
592 Value
= '$(EFI_SOURCE)/' + Value
594 self
._ValueList
[Index
] = ReplaceMacro(Value
, Macros
)
596 ## Parse [Sources] section
598 # Only path can have macro used. So we need to replace them before use.
601 def _SourceFileParser(self
):
602 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
603 self
._ValueList
[0:len(TokenList
)] = TokenList
604 Macros
= self
._Macros
605 # For Acpi tables, remove macro like ' TABLE_NAME=Sata1'
606 if 'COMPONENT_TYPE' in Macros
:
607 if self
._Defines
['COMPONENT_TYPE'].upper() == 'ACPITABLE':
608 self
._ValueList
[0] = GetSplitValueList(self
._ValueList
[0], ' ', 1)[0]
609 if self
._Defines
['BASE_NAME'] == 'Microcode':
611 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
613 ## Parse [Binaries] section
615 # Only path can have macro used. So we need to replace them before use.
618 def _BinaryFileParser(self
):
619 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 2)
620 if len(TokenList
) < 2:
621 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type or path specified",
622 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
623 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
625 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type specified",
626 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
627 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
629 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file path specified",
630 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
631 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
632 self
._ValueList
[0:len(TokenList
)] = TokenList
633 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
635 ## [nmake] section parser (Edk.x style only)
636 def _NmakeParser(self
):
637 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
638 self
._ValueList
[0:len(TokenList
)] = TokenList
640 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
641 # remove self-reference in macro setting
642 #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
644 ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
646 def _PcdParser(self
):
647 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
648 ValueList
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
649 if len(ValueList
) != 2:
650 EdkLogger
.error('Parser', FORMAT_INVALID
, "Illegal token space GUID and PCD name format",
651 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
652 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
653 self
._ValueList
[0:1] = ValueList
654 if len(TokenList
) > 1:
655 self
._ValueList
[2] = TokenList
[1]
656 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
657 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
658 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
659 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
661 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
662 if self
._ValueList
[2] != '':
663 InfPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
664 if InfPcdValueList
[0] in ['True', 'true', 'TRUE']:
665 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '1', 1);
666 elif InfPcdValueList
[0] in ['False', 'false', 'FALSE']:
667 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '0', 1);
669 ## [depex] section parser
671 def _DepexParser(self
):
672 self
._ValueList
[0:1] = [self
._CurrentLine
]
675 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
676 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
677 MODEL_META_DATA_BUILD_OPTION
: MetaFileParser
._BuildOptionParser
,
678 MODEL_EFI_INCLUDE
: _IncludeParser
, # for Edk.x modules
679 MODEL_EFI_LIBRARY_INSTANCE
: MetaFileParser
._CommonParser
, # for Edk.x modules
680 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
681 MODEL_META_DATA_PACKAGE
: MetaFileParser
._PathParser
,
682 MODEL_META_DATA_NMAKE
: _NmakeParser
, # for Edk.x modules
683 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
684 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
685 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
686 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
687 MODEL_PCD_DYNAMIC
: _PcdParser
,
688 MODEL_EFI_SOURCE_FILE
: _SourceFileParser
,
689 MODEL_EFI_GUID
: MetaFileParser
._CommonParser
,
690 MODEL_EFI_PROTOCOL
: MetaFileParser
._CommonParser
,
691 MODEL_EFI_PPI
: MetaFileParser
._CommonParser
,
692 MODEL_EFI_DEPEX
: _DepexParser
,
693 MODEL_EFI_BINARY_FILE
: _BinaryFileParser
,
694 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
697 ## DSC file parser class
699 # @param FilePath The path of platform description file
700 # @param FileType The raw data of DSC file
701 # @param Table Database used to retrieve module/package information
702 # @param Macros Macros used for replacement in file
703 # @param Owner Owner ID (for sub-section parsing)
704 # @param From ID from which the data comes (for !INCLUDE directive)
706 class DscParser(MetaFileParser
):
707 # DSC file supported data types (one type per section)
709 TAB_SKUIDS
.upper() : MODEL_EFI_SKU_ID
,
710 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
711 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
712 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
713 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
714 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
715 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
716 TAB_PCDS_DYNAMIC_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_DEFAULT
,
717 TAB_PCDS_DYNAMIC_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_HII
,
718 TAB_PCDS_DYNAMIC_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_VPD
,
719 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT
,
720 TAB_PCDS_DYNAMIC_EX_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_HII
,
721 TAB_PCDS_DYNAMIC_EX_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_VPD
,
722 TAB_COMPONENTS
.upper() : MODEL_META_DATA_COMPONENT
,
723 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
.upper() : MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
,
724 TAB_DSC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
725 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
726 TAB_DSC_DEFINES_EDKGLOBAL
: MODEL_META_DATA_GLOBAL_DEFINE
,
727 TAB_INCLUDE
.upper() : MODEL_META_DATA_INCLUDE
,
728 TAB_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
729 TAB_IF_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
730 TAB_IF_N_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
,
731 TAB_ELSE_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
,
732 TAB_ELSE
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
,
733 TAB_END_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
,
736 # Valid names in define section
743 "PCD_INFO_GENERATION",
744 "SUPPORTED_ARCHITECTURES",
753 "FIX_LOAD_TOP_MEMORY_ADDRESS"
756 SymbolPattern
= ValueExpression
.SymbolPattern
758 ## Constructor of DscParser
760 # Initialize object of DscParser
762 # @param FilePath The path of platform description file
763 # @param FileType The raw data of DSC file
764 # @param Table Database used to retrieve module/package information
765 # @param Macros Macros used for replacement in file
766 # @param Owner Owner ID (for sub-section parsing)
767 # @param From ID from which the data comes (for !INCLUDE directive)
769 def __init__(self
, FilePath
, FileType
, Table
, Owner
=-1, From
=-1):
770 # prevent re-initialization
771 if hasattr(self
, "_Table"):
773 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
, Owner
, From
)
774 self
._Version
= 0x00010005 # Only EDK2 dsc file is supported
775 # to store conditional directive evaluation result
776 self
._DirectiveStack
= []
777 self
._DirectiveEvalStack
= []
780 # Final valid replacable symbols
783 # Map the ID between the original table and new table to track
786 self
._IdMapping
= {-1:-1}
788 self
.TblFile
= EccGlobalData
.gDb
.TblFile
795 Content
= open(str(self
.MetaFile
.Path
), 'r').readlines()
797 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
799 # Insert a record for file
801 Filename
= NormPath(self
.MetaFile
.Path
)
802 FileID
= self
.TblFile
.GetFileId(Filename
)
806 self
.FileID
= self
.TblFile
.InsertFile(Filename
, MODEL_FILE_DSC
)
809 for Index
in range(0, len(Content
)):
810 Line
= CleanString(Content
[Index
])
815 self
._CurrentLine
= Line
816 self
._LineIndex
= Index
817 if self
._InSubsection
and self
._Owner
[-1] == -1:
818 self
._Owner
.append(self
._LastItem
)
821 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
822 self
._SectionType
= MODEL_META_DATA_SECTION_HEADER
824 elif Line
[0] == '}' and self
._InSubsection
:
825 self
._InSubsection
= False
826 self
._SubsectionType
= MODEL_UNKNOWN
827 self
._SubsectionName
= ''
831 elif Line
[0] == TAB_OPTION_START
and Line
[-1] == TAB_OPTION_END
:
832 self
._SubsectionType
= MODEL_META_DATA_SUBSECTION_HEADER
835 self
._DirectiveParser
()
838 if self
._InSubsection
:
839 SectionType
= self
._SubsectionType
841 SectionType
= self
._SectionType
842 self
._ItemType
= SectionType
844 self
._ValueList
= ['', '', '']
845 self
._SectionParser
[SectionType
](self
)
846 if self
._ValueList
== None:
849 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
850 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
852 for Arch
, ModuleType
in self
._Scope
:
853 self
._LastItem
= self
._Store
(
870 if self
._DirectiveStack
:
871 Type
, Line
, Text
= self
._DirectiveStack
[-1]
872 EdkLogger
.error('Parser', FORMAT_INVALID
, "No matching '!endif' found",
873 ExtraData
=Text
, File
=self
.MetaFile
, Line
=Line
)
876 ## <subsection_header> parser
877 def _SubsectionHeaderParser(self
):
878 self
._SubsectionName
= self
._CurrentLine
[1:-1].upper()
879 if self
._SubsectionName
in self
.DataType
:
880 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
882 self
._SubsectionType
= MODEL_UNKNOWN
883 EdkLogger
.warn("Parser", "Unrecognized sub-section", File
=self
.MetaFile
,
884 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
885 self
._ValueList
[0] = self
._SubsectionName
887 ## Directive statement parser
888 def _DirectiveParser(self
):
889 self
._ValueList
= ['','','']
890 TokenList
= GetSplitValueList(self
._CurrentLine
, ' ', 1)
891 self
._ValueList
[0:len(TokenList
)] = TokenList
894 DirectiveName
= self
._ValueList
[0].upper()
895 if DirectiveName
not in self
.DataType
:
896 EdkLogger
.error("Parser", FORMAT_INVALID
, "Unknown directive [%s]" % DirectiveName
,
897 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
898 if DirectiveName
in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self
._ValueList
[1] == '':
899 EdkLogger
.error("Parser", FORMAT_INVALID
, "Missing expression",
900 File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
901 ExtraData
=self
._CurrentLine
)
903 ItemType
= self
.DataType
[DirectiveName
]
904 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
905 # Remove all directives between !if and !endif, including themselves
906 while self
._DirectiveStack
:
907 # Remove any !else or !elseif
908 DirectiveInfo
= self
._DirectiveStack
.pop()
909 if DirectiveInfo
[0] in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
910 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
911 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
914 EdkLogger
.error("Parser", FORMAT_INVALID
, "Redundant '!endif'",
915 File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
916 ExtraData
=self
._CurrentLine
)
917 elif ItemType
!= MODEL_META_DATA_INCLUDE
:
918 # Break if there's a !else is followed by a !elseif
919 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
and \
920 self
._DirectiveStack
and \
921 self
._DirectiveStack
[-1][0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
922 EdkLogger
.error("Parser", FORMAT_INVALID
, "'!elseif' after '!else'",
923 File
=self
.MetaFile
, Line
=self
._LineIndex
+1,
924 ExtraData
=self
._CurrentLine
)
925 self
._DirectiveStack
.append((ItemType
, self
._LineIndex
+1, self
._CurrentLine
))
927 EdkLogger
.error('Parser', FORMAT_INVALID
,
928 "No '!include' allowed in included file",
929 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
,
930 Line
=self
._LineIndex
+1)
933 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
934 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
936 self
._LastItem
= self
._Store
(
953 ## [defines] section parser
955 def _DefineParser(self
):
956 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
957 self
._ValueList
[1:len(TokenList
)] = TokenList
960 if not self
._ValueList
[1]:
961 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
962 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
963 if not self
._ValueList
[2]:
964 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
965 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
966 if not self
._ValueList
[1] in self
.DefineKeywords
:
967 EdkLogger
.error('Parser', FORMAT_INVALID
,
968 "Unknown keyword found: %s. "
969 "If this is a macro you must "
970 "add it as a DEFINE in the DSC" % self
._ValueList
[1],
971 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
972 self
._Defines
[self
._ValueList
[1]] = self
._ValueList
[2]
973 self
._ItemType
= self
.DataType
[TAB_DSC_DEFINES
.upper()]
976 def _SkuIdParser(self
):
977 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
978 if len(TokenList
) != 2:
979 EdkLogger
.error('Parser', FORMAT_INVALID
, "Correct format is '<Integer>|<UiName>'",
980 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
981 self
._ValueList
[0:len(TokenList
)] = TokenList
983 ## Parse Edk style of library modules
984 def _LibraryInstanceParser(self
):
985 self
._ValueList
[0] = self
._CurrentLine
987 ## PCD sections parser
990 # [PcdsPatchableInModule]
993 # [PcdsDynamicExDefault]
997 # [PcdsDynamicDefault]
1002 def _PcdParser(self
):
1003 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1004 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1005 if len(TokenList
) == 2:
1006 self
._ValueList
[2] = TokenList
[1]
1007 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1008 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1009 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1010 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1011 if self
._ValueList
[2] == '':
1012 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD value given",
1013 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1014 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1015 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
1016 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
1017 if DscPcdValueList
[0] in ['True', 'true', 'TRUE']:
1018 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '1', 1);
1019 elif DscPcdValueList
[0] in ['False', 'false', 'FALSE']:
1020 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '0', 1);
1022 ## [components] section parser
1024 def _ComponentParser(self
):
1025 if self
._CurrentLine
[-1] == '{':
1026 self
._ValueList
[0] = self
._CurrentLine
[0:-1].strip()
1027 self
._InSubsection
= True
1029 self
._ValueList
[0] = self
._CurrentLine
1031 ## [LibraryClasses] section
1033 def _LibraryClassParser(self
):
1034 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1035 if len(TokenList
) < 2:
1036 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class or instance specified",
1037 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1038 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1039 if TokenList
[0] == '':
1040 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class specified",
1041 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1042 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1043 if TokenList
[1] == '':
1044 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library instance specified",
1045 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1046 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1048 self
._ValueList
[0:len(TokenList
)] = TokenList
1050 def _CompponentSourceOverridePathParser(self
):
1051 self
._ValueList
[0] = self
._CurrentLine
1053 ## [BuildOptions] section parser
1055 def _BuildOptionParser(self
):
1056 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1057 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
1058 if len(TokenList2
) == 2:
1059 self
._ValueList
[0] = TokenList2
[0] # toolchain family
1060 self
._ValueList
[1] = TokenList2
[1] # keys
1062 self
._ValueList
[1] = TokenList
[0]
1063 if len(TokenList
) == 2: # value
1064 self
._ValueList
[2] = TokenList
[1]
1066 if self
._ValueList
[1].count('_') != 4:
1070 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
1071 ExtraData
=self
._CurrentLine
,
1073 Line
=self
._LineIndex
+1
1076 ## Override parent's method since we'll do all macro replacements in parser
1077 def _GetMacros(self
):
1078 Macros
= dict( [('ARCH','IA32'), ('FAMILY','MSFT'),('TOOL_CHAIN_TAG','VS2008x86'),('TARGET','DEBUG')])
1079 Macros
.update(self
._FileLocalMacros
)
1080 Macros
.update(self
._GetApplicableSectionMacro
())
1081 Macros
.update(GlobalData
.gEdkGlobal
)
1082 Macros
.update(GlobalData
.gPlatformDefines
)
1083 Macros
.update(GlobalData
.gCommandLineDefines
)
1084 # PCD cannot be referenced in macro definition
1085 if self
._ItemType
not in [MODEL_META_DATA_DEFINE
, MODEL_META_DATA_GLOBAL_DEFINE
]:
1086 Macros
.update(self
._Symbols
)
1089 def _PostProcess(self
):
1091 MODEL_META_DATA_SECTION_HEADER
: self
.__ProcessSectionHeader
,
1092 MODEL_META_DATA_SUBSECTION_HEADER
: self
.__ProcessSubsectionHeader
,
1093 MODEL_META_DATA_HEADER
: self
.__ProcessDefine
,
1094 MODEL_META_DATA_DEFINE
: self
.__ProcessDefine
,
1095 MODEL_META_DATA_GLOBAL_DEFINE
: self
.__ProcessDefine
,
1096 MODEL_META_DATA_INCLUDE
: self
.__ProcessDirective
,
1097 MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
: self
.__ProcessDirective
,
1098 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
: self
.__ProcessDirective
,
1099 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
: self
.__ProcessDirective
,
1100 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
: self
.__ProcessDirective
,
1101 MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
: self
.__ProcessDirective
,
1102 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
: self
.__ProcessDirective
,
1103 MODEL_EFI_SKU_ID
: self
.__ProcessSkuId
,
1104 MODEL_EFI_LIBRARY_INSTANCE
: self
.__ProcessLibraryInstance
,
1105 MODEL_EFI_LIBRARY_CLASS
: self
.__ProcessLibraryClass
,
1106 MODEL_PCD_FIXED_AT_BUILD
: self
.__ProcessPcd
,
1107 MODEL_PCD_PATCHABLE_IN_MODULE
: self
.__ProcessPcd
,
1108 MODEL_PCD_FEATURE_FLAG
: self
.__ProcessPcd
,
1109 MODEL_PCD_DYNAMIC_DEFAULT
: self
.__ProcessPcd
,
1110 MODEL_PCD_DYNAMIC_HII
: self
.__ProcessPcd
,
1111 MODEL_PCD_DYNAMIC_VPD
: self
.__ProcessPcd
,
1112 MODEL_PCD_DYNAMIC_EX_DEFAULT
: self
.__ProcessPcd
,
1113 MODEL_PCD_DYNAMIC_EX_HII
: self
.__ProcessPcd
,
1114 MODEL_PCD_DYNAMIC_EX_VPD
: self
.__ProcessPcd
,
1115 MODEL_META_DATA_COMPONENT
: self
.__ProcessComponent
,
1116 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: self
.__ProcessSourceOverridePath
,
1117 MODEL_META_DATA_BUILD_OPTION
: self
.__ProcessBuildOption
,
1118 MODEL_UNKNOWN
: self
._Skip
,
1119 MODEL_META_DATA_USER_EXTENSION
: self
._Skip
,
1122 self
._RawTable
= self
._Table
1123 self
._Table
= MetaFileStorage(self
._RawTable
.Cur
, self
.MetaFile
, MODEL_FILE_DSC
, True)
1124 self
._DirectiveStack
= []
1125 self
._DirectiveEvalStack
= []
1126 self
._FileWithError
= self
.MetaFile
1127 self
._FileLocalMacros
= {}
1128 self
._SectionsMacroDict
= {}
1129 GlobalData
.gPlatformDefines
= {}
1131 # Get all macro and PCD which has straitforward value
1132 self
.__RetrievePcdValue
()
1133 self
._Content
= self
._RawTable
.GetAll()
1134 self
._ContentIndex
= 0
1135 while self
._ContentIndex
< len(self
._Content
) :
1136 Id
, self
._ItemType
, V1
, V2
, V3
, S1
, S2
, Owner
, BelongsToFile
, self
._From
, \
1137 LineStart
, ColStart
, LineEnd
, ColEnd
, Enabled
= self
._Content
[self
._ContentIndex
]
1140 self
._FileWithError
= self
.MetaFile
1142 self
._ContentIndex
+= 1
1144 self
._Scope
= [[S1
, S2
]]
1145 self
._LineIndex
= LineStart
- 1
1146 self
._ValueList
= [V1
, V2
, V3
]
1149 Processer
[self
._ItemType
]()
1150 except EvaluationException
, Excpt
:
1152 # Only catch expression evaluation error here. We need to report
1153 # the precise number of line on which the error occurred
1155 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
1156 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1157 Line
=self
._LineIndex
+1)
1158 except MacroException
, Excpt
:
1159 EdkLogger
.error('Parser', FORMAT_INVALID
, str(Excpt
),
1160 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1161 Line
=self
._LineIndex
+1)
1163 if self
._ValueList
== None:
1166 NewOwner
= self
._IdMapping
.get(Owner
, -1)
1167 self
._Enabled
= int((not self
._DirectiveEvalStack
) or (False not in self
._DirectiveEvalStack
))
1168 self
._LastItem
= self
._Store
(
1184 self
._IdMapping
[Id
] = self
._LastItem
1186 RecordList
= self
._Table
.GetAll()
1188 self
._RawTable
.Drop()
1190 for Record
in RecordList
:
1191 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])
1192 GlobalData
.gPlatformDefines
.update(self
._FileLocalMacros
)
1193 self
._PostProcessed
= True
1194 self
._Content
= None
1196 def __ProcessSectionHeader(self
):
1197 self
._SectionName
= self
._ValueList
[0]
1198 if self
._SectionName
in self
.DataType
:
1199 self
._SectionType
= self
.DataType
[self
._SectionName
]
1201 self
._SectionType
= MODEL_UNKNOWN
1203 def __ProcessSubsectionHeader(self
):
1204 self
._SubsectionName
= self
._ValueList
[0]
1205 if self
._SubsectionName
in self
.DataType
:
1206 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
1208 self
._SubsectionType
= MODEL_UNKNOWN
1210 def __RetrievePcdValue(self
):
1211 Records
= self
._RawTable
.Query(MODEL_PCD_FEATURE_FLAG
, BelongsToItem
=-1.0)
1212 for TokenSpaceGuid
,PcdName
,Value
,Dummy2
,Dummy3
,ID
,Line
in Records
:
1213 Value
, DatumType
, MaxDatumSize
= AnalyzePcdData(Value
)
1214 # Only use PCD whose value is straitforward (no macro and PCD)
1215 if self
.SymbolPattern
.findall(Value
):
1217 Name
= TokenSpaceGuid
+ '.' + PcdName
1218 # Don't use PCD with different values.
1219 if Name
in self
._Symbols
and self
._Symbols
[Name
] != Value
:
1220 self
._Symbols
.pop(Name
)
1222 self
._Symbols
[Name
] = Value
1224 Records
= self
._RawTable
.Query(MODEL_PCD_FIXED_AT_BUILD
, BelongsToItem
=-1.0)
1225 for TokenSpaceGuid
,PcdName
,Value
,Dummy2
,Dummy3
,ID
,Line
in Records
:
1226 Value
, DatumType
, MaxDatumSize
= AnalyzePcdData(Value
)
1227 # Only use PCD whose value is straitforward (no macro and PCD)
1228 if self
.SymbolPattern
.findall(Value
):
1230 Name
= TokenSpaceGuid
+'.'+PcdName
1231 # Don't use PCD with different values.
1232 if Name
in self
._Symbols
and self
._Symbols
[Name
] != Value
:
1233 self
._Symbols
.pop(Name
)
1235 self
._Symbols
[Name
] = Value
1237 def __ProcessDefine(self
):
1238 if not self
._Enabled
:
1241 Type
, Name
, Value
= self
._ValueList
1242 Value
= ReplaceMacro(Value
, self
._Macros
, False)
1243 if self
._ItemType
== MODEL_META_DATA_DEFINE
:
1244 if self
._SectionType
== MODEL_META_DATA_HEADER
:
1245 self
._FileLocalMacros
[Name
] = Value
1247 SectionDictKey
= self
._SectionType
, self
._Scope
[0][0], self
._Scope
[0][1]
1248 if SectionDictKey
not in self
._SectionsMacroDict
:
1249 self
._SectionsMacroDict
[SectionDictKey
] = {}
1250 SectionLocalMacros
= self
._SectionsMacroDict
[SectionDictKey
]
1251 SectionLocalMacros
[Name
] = Value
1252 elif self
._ItemType
== MODEL_META_DATA_GLOBAL_DEFINE
:
1253 GlobalData
.gEdkGlobal
[Name
] = Value
1256 # Keyword in [Defines] section can be used as Macros
1258 if (self
._ItemType
== MODEL_META_DATA_HEADER
) and (self
._SectionType
== MODEL_META_DATA_HEADER
):
1259 self
._FileLocalMacros
[Name
] = Value
1261 self
._ValueList
= [Type
, Name
, Value
]
1263 def __ProcessDirective(self
):
1265 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1266 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
]:
1267 Macros
= self
._Macros
1268 Macros
.update(GlobalData
.gGlobalDefines
)
1270 Result
= ValueExpression(self
._ValueList
[1], Macros
)()
1271 except SymbolNotFound
, Exc
:
1272 EdkLogger
.debug(EdkLogger
.DEBUG_5
, str(Exc
), self
._ValueList
[1])
1274 except WrnExpression
, Excpt
:
1276 # Catch expression evaluation warning here. We need to report
1277 # the precise number of line and return the evaluation result
1279 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
1280 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1281 Line
=self
._LineIndex
+1)
1282 Result
= Excpt
.result
1284 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1285 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1286 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1287 self
._DirectiveStack
.append(self
._ItemType
)
1288 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
:
1289 Result
= bool(Result
)
1291 Macro
= self
._ValueList
[1]
1292 Macro
= Macro
[2:-1] if (Macro
.startswith("$(") and Macro
.endswith(")")) else Macro
1293 Result
= Macro
in self
._Macros
1294 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
:
1296 self
._DirectiveEvalStack
.append(Result
)
1297 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
:
1298 self
._DirectiveStack
.append(self
._ItemType
)
1299 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1300 self
._DirectiveEvalStack
.append(bool(Result
))
1301 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1302 self
._DirectiveStack
[-1] = self
._ItemType
1303 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1304 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1305 # Back to the nearest !if/!ifdef/!ifndef
1306 while self
._DirectiveStack
:
1307 self
._DirectiveEvalStack
.pop()
1308 Directive
= self
._DirectiveStack
.pop()
1309 if Directive
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1310 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1311 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
,
1312 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1314 elif self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1315 # The included file must be relative to workspace or same directory as DSC file
1316 __IncludeMacros
= {}
1318 # Allow using system environment variables in path after !include
1320 __IncludeMacros
['WORKSPACE'] = GlobalData
.gGlobalDefines
['WORKSPACE']
1321 if "ECP_SOURCE" in GlobalData
.gGlobalDefines
.keys():
1322 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gGlobalDefines
['ECP_SOURCE']
1324 # During GenFds phase call DSC parser, will go into this branch.
1326 elif "ECP_SOURCE" in GlobalData
.gCommandLineDefines
.keys():
1327 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gCommandLineDefines
['ECP_SOURCE']
1329 __IncludeMacros
['EFI_SOURCE'] = GlobalData
.gGlobalDefines
['EFI_SOURCE']
1330 __IncludeMacros
['EDK_SOURCE'] = GlobalData
.gGlobalDefines
['EDK_SOURCE']
1332 # Allow using MACROs comes from [Defines] section to keep compatible.
1334 __IncludeMacros
.update(self
._Macros
)
1336 IncludedFile
= NormPath(ReplaceMacro(self
._ValueList
[1], __IncludeMacros
, RaiseError
=True))
1338 # First search the include file under the same directory as DSC file
1340 IncludedFile1
= PathClass(IncludedFile
, self
.MetaFile
.Dir
)
1341 ErrorCode
, ErrorInfo1
= IncludedFile1
.Validate()
1344 # Also search file under the WORKSPACE directory
1346 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
1347 ErrorCode
, ErrorInfo2
= IncludedFile1
.Validate()
1349 EdkLogger
.error('parser', ErrorCode
, File
=self
._FileWithError
,
1350 Line
=self
._LineIndex
+1, ExtraData
=ErrorInfo1
+ "\n"+ ErrorInfo2
)
1352 self
._FileWithError
= IncludedFile1
1354 IncludedFileTable
= MetaFileStorage(self
._Table
.Cur
, IncludedFile1
, MODEL_FILE_DSC
, True)
1355 Owner
= self
._Content
[self
._ContentIndex
-1][0]
1356 Parser
= DscParser(IncludedFile1
, self
._FileType
, IncludedFileTable
,
1357 Owner
=Owner
, From
=Owner
)
1359 # set the parser status with current status
1360 Parser
._SectionName
= self
._SectionName
1361 Parser
._SectionType
= self
._SectionType
1362 Parser
._Scope
= self
._Scope
1363 Parser
._Enabled
= self
._Enabled
1364 # Parse the included file
1367 # update current status with sub-parser's status
1368 self
._SectionName
= Parser
._SectionName
1369 self
._SectionType
= Parser
._SectionType
1370 self
._Scope
= Parser
._Scope
1371 self
._Enabled
= Parser
._Enabled
1373 # Insert all records in the table for the included file into dsc file table
1374 Records
= IncludedFileTable
.GetAll()
1376 self
._Content
[self
._ContentIndex
:self
._ContentIndex
] = Records
1377 self
._Content
.pop(self
._ContentIndex
-1)
1378 self
._ValueList
= None
1379 self
._ContentIndex
-= 1
1381 def __ProcessSkuId(self
):
1382 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=True)
1383 for Value
in self
._ValueList
]
1385 def __ProcessLibraryInstance(self
):
1386 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
1388 def __ProcessLibraryClass(self
):
1389 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
, RaiseError
=True)
1391 def __ProcessPcd(self
):
1392 ValueList
= GetSplitValueList(self
._ValueList
[2])
1394 # PCD value can be an expression
1396 if len(ValueList
) > 1 and ValueList
[1] == 'VOID*':
1397 PcdValue
= ValueList
[0]
1399 ValueList
[0] = ValueExpression(PcdValue
, self
._Macros
)(True)
1400 except WrnExpression
, Value
:
1401 ValueList
[0] = Value
.result
1403 PcdValue
= ValueList
[-1]
1405 ValueList
[-1] = ValueExpression(PcdValue
, self
._Macros
)(True)
1406 except WrnExpression
, Value
:
1407 ValueList
[-1] = Value
.result
1409 if ValueList
[-1] == 'True':
1411 if ValueList
[-1] == 'False':
1414 self
._ValueList
[2] = '|'.join(ValueList
)
1416 def __ProcessComponent(self
):
1417 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1419 def __ProcessSourceOverridePath(self
):
1420 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1422 def __ProcessBuildOption(self
):
1423 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=False)
1424 for Value
in self
._ValueList
]
1427 MODEL_META_DATA_HEADER
: _DefineParser
,
1428 MODEL_EFI_SKU_ID
: _SkuIdParser
,
1429 MODEL_EFI_LIBRARY_INSTANCE
: _LibraryInstanceParser
,
1430 MODEL_EFI_LIBRARY_CLASS
: _LibraryClassParser
,
1431 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1432 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1433 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1434 MODEL_PCD_DYNAMIC_DEFAULT
: _PcdParser
,
1435 MODEL_PCD_DYNAMIC_HII
: _PcdParser
,
1436 MODEL_PCD_DYNAMIC_VPD
: _PcdParser
,
1437 MODEL_PCD_DYNAMIC_EX_DEFAULT
: _PcdParser
,
1438 MODEL_PCD_DYNAMIC_EX_HII
: _PcdParser
,
1439 MODEL_PCD_DYNAMIC_EX_VPD
: _PcdParser
,
1440 MODEL_META_DATA_COMPONENT
: _ComponentParser
,
1441 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: _CompponentSourceOverridePathParser
,
1442 MODEL_META_DATA_BUILD_OPTION
: _BuildOptionParser
,
1443 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1444 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
1445 MODEL_META_DATA_SECTION_HEADER
: MetaFileParser
._SectionHeaderParser
,
1446 MODEL_META_DATA_SUBSECTION_HEADER
: _SubsectionHeaderParser
,
1449 _Macros
= property(_GetMacros
)
1451 ## DEC file parser class
1453 # @param FilePath The path of platform description file
1454 # @param FileType The raw data of DSC file
1455 # @param Table Database used to retrieve module/package information
1456 # @param Macros Macros used for replacement in file
1458 class DecParser(MetaFileParser
):
1459 # DEC file supported data types (one type per section)
1461 TAB_DEC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
1462 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
1463 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
1464 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
1465 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
1466 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
1467 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
1468 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
1469 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
1470 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
1471 TAB_PCDS_DYNAMIC_NULL
.upper() : MODEL_PCD_DYNAMIC
,
1472 TAB_PCDS_DYNAMIC_EX_NULL
.upper() : MODEL_PCD_DYNAMIC_EX
,
1475 ## Constructor of DecParser
1477 # Initialize object of DecParser
1479 # @param FilePath The path of platform description file
1480 # @param FileType The raw data of DSC file
1481 # @param Table Database used to retrieve module/package information
1482 # @param Macros Macros used for replacement in file
1484 def __init__(self
, FilePath
, FileType
, Table
):
1485 # prevent re-initialization
1486 if hasattr(self
, "_Table"):
1488 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Table
)
1490 self
._Version
= 0x00010005 # Only EDK2 dec file is supported
1491 self
.TblFile
= EccGlobalData
.gDb
.TblFile
1498 Content
= open(str(self
.MetaFile
), 'r').readlines()
1500 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
1503 # Insert a record for file
1505 Filename
= NormPath(self
.MetaFile
)
1506 FileID
= self
.TblFile
.GetFileId(Filename
)
1508 self
.FileID
= FileID
1510 self
.FileID
= self
.TblFile
.InsertFile(Filename
, MODEL_FILE_DEC
)
1512 for Index
in range(0, len(Content
)):
1513 Line
, Comment
= CleanString2(Content
[Index
])
1514 self
._CurrentLine
= Line
1515 self
._LineIndex
= Index
1517 # save comment for later use
1519 self
._Comments
.append((Comment
, self
._LineIndex
+1))
1525 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
1526 self
._SectionHeaderParser
()
1529 elif len(self
._SectionType
) == 0:
1534 self
._ValueList
= ['','','']
1535 self
._SectionParser
[self
._SectionType
[0]](self
)
1536 if self
._ValueList
== None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
1542 # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,
1543 # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1
1545 for Arch
, ModuleType
, Type
in self
._Scope
:
1546 self
._LastItem
= self
._Store
(
1561 for Comment
, LineNo
in self
._Comments
:
1563 MODEL_META_DATA_COMMENT
,
1580 def _GetApplicableSectionMacro(self
):
1582 for S1
, S2
, SectionType
in self
._Scope
:
1583 for Scope1
, Scope2
in [("COMMON", "COMMON"), ("COMMON", S2
), (S1
, "COMMON"), (S1
, S2
)]:
1584 if (SectionType
, Scope1
, Scope2
) in self
._SectionsMacroDict
:
1585 Macros
.update(self
._SectionsMacroDict
[(SectionType
, Scope1
, Scope2
)])
1588 ## Section header parser
1590 # The section header is always in following format:
1592 # [section_name.arch<.platform|module_type>]
1594 def _SectionHeaderParser(self
):
1596 self
._SectionName
= ''
1597 self
._SectionType
= []
1599 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
1602 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
)
1604 # different types of PCD are permissible in one section
1605 self
._SectionName
= ItemList
[0].upper()
1606 if self
._SectionName
in self
.DataType
:
1607 if self
.DataType
[self
._SectionName
] not in self
._SectionType
:
1608 self
._SectionType
.append(self
.DataType
[self
._SectionName
])
1610 EdkLogger
.warn("Parser", "Unrecognized section", File
=self
.MetaFile
,
1611 Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
1614 if MODEL_PCD_FEATURE_FLAG
in self
._SectionType
and len(self
._SectionType
) > 1:
1618 "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL
,
1620 Line
=self
._LineIndex
+1,
1621 ExtraData
=self
._CurrentLine
1624 if len(ItemList
) > 1:
1625 S1
= ItemList
[1].upper()
1629 # S2 may be Platform or ModuleType
1630 if len(ItemList
) > 2:
1631 S2
= ItemList
[2].upper()
1634 if [S1
, S2
, self
.DataType
[self
._SectionName
]] not in self
._Scope
:
1635 self
._Scope
.append([S1
, S2
, self
.DataType
[self
._SectionName
]])
1637 # 'COMMON' must not be used with specific ARCHs at the same section
1638 if 'COMMON' in ArchList
and len(ArchList
) > 1:
1639 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
1640 File
=self
.MetaFile
, Line
=self
._LineIndex
+1, ExtraData
=self
._CurrentLine
)
1642 ## [guids], [ppis] and [protocols] section parser
1644 def _GuidParser(self
):
1645 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1646 if len(TokenList
) < 2:
1647 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name or value specified",
1648 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1649 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1650 if TokenList
[0] == '':
1651 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name specified",
1652 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1653 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1654 if TokenList
[1] == '':
1655 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID value specified",
1656 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1657 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1658 if TokenList
[1][0] != '{' or TokenList
[1][-1] != '}' or GuidStructureStringToGuidString(TokenList
[1]) == '':
1659 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid GUID value format",
1660 ExtraData
=self
._CurrentLine
+ \
1661 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
1662 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1663 self
._ValueList
[0] = TokenList
[0]
1664 #Parse the Guid value format
1665 GuidValueList
= TokenList
[1].strip(' {}').split(',')
1668 if len(GuidValueList
) == 11:
1669 for GuidValue
in GuidValueList
:
1670 GuidValue
= GuidValue
.strip()
1671 if GuidValue
.startswith('0x') or GuidValue
.startswith('0X'):
1672 HexList
.append('0x' + str(GuidValue
[2:]))
1676 if GuidValue
.startswith('{'):
1677 HexList
.append('0x' + str(GuidValue
[3:]))
1679 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])
1681 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid GUID value format",
1682 ExtraData
=self
._CurrentLine
+ \
1683 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
1684 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1685 self
._ValueList
[0] = ''
1687 ## PCD sections parser
1689 # [PcdsFixedAtBuild]
1690 # [PcdsPatchableInModule]
1696 def _PcdParser(self
):
1697 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1698 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1699 # check PCD information
1700 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1701 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1702 ExtraData
=self
._CurrentLine
+ \
1703 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1704 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1705 # check PCD datum information
1706 if len(TokenList
) < 2 or TokenList
[1] == '':
1707 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD Datum information given",
1708 ExtraData
=self
._CurrentLine
+ \
1709 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1710 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1713 ValueRe
= re
.compile(r
'^\s*L?\".*\|.*\"')
1714 PtrValue
= ValueRe
.findall(TokenList
[1])
1716 # Has VOID* type string, may contain "|" character in the string.
1717 if len(PtrValue
) != 0:
1718 ptrValueList
= re
.sub(ValueRe
, '', TokenList
[1])
1719 ValueList
= GetSplitValueList(ptrValueList
)
1720 ValueList
[0] = PtrValue
[0]
1722 ValueList
= GetSplitValueList(TokenList
[1])
1725 # check if there's enough datum information given
1726 if len(ValueList
) != 3:
1727 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid PCD Datum information given",
1728 ExtraData
=self
._CurrentLine
+ \
1729 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1730 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1731 # check default value
1732 if ValueList
[0] == '':
1733 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DefaultValue in PCD Datum information",
1734 ExtraData
=self
._CurrentLine
+ \
1735 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1736 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1738 if ValueList
[1] == '':
1739 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DatumType in PCD Datum information",
1740 ExtraData
=self
._CurrentLine
+ \
1741 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1742 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1743 # check token of the PCD
1744 if ValueList
[2] == '':
1745 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing Token in PCD Datum information",
1746 ExtraData
=self
._CurrentLine
+ \
1747 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1748 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1749 # check format of default value against the datum type
1750 IsValid
, Cause
= CheckPcdDatum(ValueList
[1], ValueList
[0])
1752 EdkLogger
.error('Parser', FORMAT_INVALID
, Cause
, ExtraData
=self
._CurrentLine
,
1753 File
=self
.MetaFile
, Line
=self
._LineIndex
+1)
1755 if ValueList
[0] in ['True', 'true', 'TRUE']:
1757 elif ValueList
[0] in ['False', 'false', 'FALSE']:
1760 self
._ValueList
[2] = ValueList
[0].strip() + '|' + ValueList
[1].strip() + '|' + ValueList
[2].strip()
1763 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
1764 MODEL_EFI_INCLUDE
: MetaFileParser
._PathParser
,
1765 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
1766 MODEL_EFI_GUID
: _GuidParser
,
1767 MODEL_EFI_PPI
: _GuidParser
,
1768 MODEL_EFI_PROTOCOL
: _GuidParser
,
1769 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1770 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1771 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1772 MODEL_PCD_DYNAMIC
: _PcdParser
,
1773 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
1774 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1775 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._Skip
,
1781 # This class defined basic Fdf object which is used by inheriting
1783 # @param object: Inherited from object class
1785 class FdfObject(object):
1791 # This class defined the structure used in Fdf object
1793 # @param FdfObject: Inherited from FdfObject class
1794 # @param Filename: Input value for Ffilename of Fdf file, default is None
1795 # @param WorkspaceDir: Input value for current workspace directory, default is None
1797 class Fdf(FdfObject
):
1798 def __init__(self
, Filename
= None, IsToDatabase
= False, WorkspaceDir
= None, Database
= None):
1799 self
.WorkspaceDir
= WorkspaceDir
1800 self
.IsToDatabase
= IsToDatabase
1802 self
.Cur
= Database
.Cur
1803 self
.TblFile
= Database
.TblFile
1804 self
.TblFdf
= Database
.TblFdf
1809 # Load Fdf file if filename is not None
1811 if Filename
!= None:
1812 self
.LoadFdfFile(Filename
)
1815 # Insert a FDF file record into database
1817 def InsertFile(self
, Filename
):
1819 Filename
= NormPath(Filename
)
1820 if Filename
not in self
.FileList
:
1821 FileID
= self
.TblFile
.InsertFile(Filename
, MODEL_FILE_FDF
)
1822 self
.FileList
[Filename
] = FileID
1824 return self
.FileList
[Filename
]
1829 # Load the file if it exists
1831 # @param Filename: Input value for filename of Fdf file
1833 def LoadFdfFile(self
, Filename
):
1838 Filename
= NormPath(Filename
)
1839 Fdf
= FdfParser(Filename
)
1843 # Insert inf file and pcd information
1845 if self
.IsToDatabase
:
1846 (Model
, Value1
, Value2
, Value3
, Scope1
, Scope2
, BelongsToItem
, BelongsToFile
, StartLine
, StartColumn
, EndLine
, EndColumn
, Enabled
) = \
1847 (0, '', '', '', 'COMMON', 'COMMON', -1, -1, -1, -1, -1, -1, 0)
1848 for Index
in range(0, len(Fdf
.Profile
.PcdDict
)):
1850 for Key
in Fdf
.Profile
.PcdDict
.keys():
1854 FileName
= Fdf
.Profile
.PcdFileLineDict
[Key
][0]
1855 StartLine
= Fdf
.Profile
.PcdFileLineDict
[Key
][1]
1856 BelongsToFile
= self
.InsertFile(FileName
)
1857 self
.TblFdf
.Insert(Model
, Value1
, Value2
, Value3
, Scope1
, Scope2
, BelongsToItem
, BelongsToFile
, StartLine
, StartColumn
, EndLine
, EndColumn
, Enabled
)
1858 for Index
in range(0, len(Fdf
.Profile
.InfList
)):
1859 Model
= MODEL_META_DATA_COMPONENT
1860 Value1
= Fdf
.Profile
.InfList
[Index
]
1862 FileName
= Fdf
.Profile
.InfFileLineList
[Index
][0]
1863 StartLine
= Fdf
.Profile
.InfFileLineList
[Index
][1]
1864 BelongsToFile
= self
.InsertFile(FileName
)
1865 self
.TblFdf
.Insert(Model
, Value1
, Value2
, Value3
, Scope1
, Scope2
, BelongsToItem
, BelongsToFile
, StartLine
, StartColumn
, EndLine
, EndColumn
, Enabled
)
1869 # This acts like the main() function for the script, unless it is 'import'ed into another
1872 if __name__
== '__main__':