2 # This file is used to parse meta files
4 # Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.<BR>
5 # (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
6 # This program and the accompanying materials
7 # are licensed and made available under the terms and conditions of the BSD License
8 # which accompanies this distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 import Common
.LongFilePathOs
as os
23 import Common
.EdkLogger
as EdkLogger
24 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
, AnalyzeDscPcd
, AnalyzePcdExpression
30 from Common
.Expression
import *
31 from CommonDataClass
.Exceptions
import *
32 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
34 from MetaFileTable
import MetaFileStorage
35 from MetaFileCommentParser
import CheckInfComment
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 if Type
in self
.DataType
:
67 self
._ItemType
= self
.DataType
[Type
]
69 self
._ItemType
= MODEL_META_DATA_DEFINE
70 # DEFINE defined macros
71 if Type
== TAB_DSC_DEFINES_DEFINE
:
73 # First judge whether this DEFINE is in conditional directive statements or not.
75 if type(self
) == DscParser
and self
._InDirective
> -1:
78 if type(self
) == DecParser
:
79 if MODEL_META_DATA_HEADER
in self
._SectionType
:
80 self
._FileLocalMacros
[Name
] = Value
82 self
._ConstructSectionMacroDict
(Name
, Value
)
83 elif self
._SectionType
== MODEL_META_DATA_HEADER
:
84 self
._FileLocalMacros
[Name
] = Value
86 self
._ConstructSectionMacroDict
(Name
, Value
)
88 # EDK_GLOBAL defined macros
89 elif type(self
) != DscParser
:
90 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL can only be used in .dsc file",
91 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
92 elif self
._SectionType
!= MODEL_META_DATA_HEADER
:
93 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL can only be used under [Defines] section",
94 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
95 elif (Name
in self
._FileLocalMacros
) and (self
._FileLocalMacros
[Name
] != Value
):
96 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL defined a macro with the same name and different value as one defined by 'DEFINE'",
97 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
99 self
._ValueList
= [Type
, Name
, Value
]
103 ## Base class of parser
105 # This class is used for derivation purpose. The specific parser for one kind
106 # type file must derive this class and implement some public interfaces.
108 # @param FilePath The path of platform description file
109 # @param FileType The raw data of DSC file
110 # @param Table Database used to retrieve module/package information
111 # @param Macros Macros used for replacement in file
112 # @param Owner Owner ID (for sub-section parsing)
113 # @param From ID from which the data comes (for !INCLUDE directive)
115 class MetaFileParser(object):
116 # data type (file content) for specific file type
119 # Parser objects used to implement singleton
124 # One file, one parser object. This factory method makes sure that there's
125 # only one object constructed for one meta file.
127 # @param Class class object of real AutoGen class
128 # (InfParser, DecParser or DscParser)
129 # @param FilePath The path of meta file
130 # @param *args The specific class related parameters
131 # @param **kwargs The specific class related dict parameters
133 def __new__(Class
, FilePath
, *args
, **kwargs
):
134 if FilePath
in Class
.MetaFiles
:
135 return Class
.MetaFiles
[FilePath
]
137 ParserObject
= super(MetaFileParser
, Class
).__new
__(Class
)
138 Class
.MetaFiles
[FilePath
] = ParserObject
141 ## Constructor of MetaFileParser
143 # Initialize object of MetaFileParser
145 # @param FilePath The path of platform description file
146 # @param FileType The raw data of DSC file
147 # @param Arch Default Arch value for filtering sections
148 # @param Table Database used to retrieve module/package information
149 # @param Owner Owner ID (for sub-section parsing)
150 # @param From ID from which the data comes (for !INCLUDE directive)
152 def __init__(self
, FilePath
, FileType
, Arch
, Table
, Owner
= -1, From
= -1):
154 self
._RawTable
= Table
156 self
._FileType
= FileType
157 self
.MetaFile
= FilePath
158 self
._FileDir
= self
.MetaFile
.Dir
160 self
._FileLocalMacros
= {}
161 self
._SectionsMacroDict
= {}
163 # for recursive parsing
164 self
._Owner
= [Owner
]
167 # parsr status for parsing
168 self
._ValueList
= ['', '', '', '', '']
171 self
._CurrentLine
= ''
172 self
._SectionType
= MODEL_UNKNOWN
173 self
._SectionName
= ''
174 self
._InSubsection
= False
175 self
._SubsectionType
= MODEL_UNKNOWN
176 self
._SubsectionName
= ''
177 self
._ItemType
= MODEL_UNKNOWN
180 self
._Finished
= False
181 self
._PostProcessed
= False
182 # Different version of meta-file has different way to parse.
185 ## Store the parsed data in table
186 def _Store(self
, *Args
):
187 return self
._Table
.Insert(*Args
)
189 ## Virtual method for starting parse
191 raise NotImplementedError
193 ## Notify a post-process is needed
194 def DoPostProcess(self
):
195 self
._PostProcessed
= False
197 ## Set parsing complete flag in both class and table
199 self
._Finished
= True
200 ## Do not set end flag when processing included files
202 self
._Table
.SetEndFlag()
204 def _PostProcess(self
):
205 self
._PostProcessed
= True
207 ## Get the parse complete flag
208 def _GetFinished(self
):
209 return self
._Finished
211 ## Set the complete flag
212 def _SetFinished(self
, Value
):
213 self
._Finished
= Value
215 ## Remove records that do not match given Filter Arch
216 def _FilterRecordList(self
, RecordList
, FilterArch
):
218 for Record
in RecordList
:
220 if Arch
== 'COMMON' or Arch
== FilterArch
:
221 NewRecordList
.append(Record
)
224 ## Use [] style to query data in table, just for readability
226 # DataInfo = [data_type, scope1(arch), scope2(platform/moduletype)]
228 def __getitem__(self
, DataInfo
):
229 if type(DataInfo
) != type(()):
230 DataInfo
= (DataInfo
,)
232 # Parse the file first, if necessary
233 if not self
._Finished
:
234 if self
._RawTable
.IsIntegrity():
235 self
._Finished
= True
237 self
._Table
= self
._RawTable
238 self
._PostProcessed
= False
241 # No specific ARCH or Platform given, use raw data
242 if self
._RawTable
and (len(DataInfo
) == 1 or DataInfo
[1] == None):
243 return self
._FilterRecordList
(self
._RawTable
.Query(*DataInfo
), self
._Arch
)
245 # Do post-process if necessary
246 if not self
._PostProcessed
:
249 return self
._FilterRecordList
(self
._Table
.Query(*DataInfo
), DataInfo
[1])
251 ## Data parser for the common format in different type of file
253 # The common format in the meatfile is like
258 def _CommonParser(self
):
259 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
260 self
._ValueList
[0:len(TokenList
)] = TokenList
262 ## Data parser for the format in which there's path
264 # Only path can have macro used. So we need to replace them before use.
267 def _PathParser(self
):
268 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
269 self
._ValueList
[0:len(TokenList
)] = TokenList
270 # Don't do macro replacement for dsc file at this point
271 if type(self
) != DscParser
:
272 Macros
= self
._Macros
273 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
275 ## Skip unsupported data
277 EdkLogger
.warn("Parser", "Unrecognized content", File
=self
.MetaFile
,
278 Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
);
279 self
._ValueList
[0:1] = [self
._CurrentLine
]
281 ## Skip unsupported data for UserExtension Section
282 def _SkipUserExtension(self
):
283 self
._ValueList
[0:1] = [self
._CurrentLine
]
285 ## Section header parser
287 # The section header is always in following format:
289 # [section_name.arch<.platform|module_type>]
291 def _SectionHeaderParser(self
):
293 self
._SectionName
= ''
295 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
298 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
,2)
299 # different section should not mix in one section
300 if self
._SectionName
!= '' and self
._SectionName
!= ItemList
[0].upper():
301 EdkLogger
.error('Parser', FORMAT_INVALID
, "Different section names in the same section",
302 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
303 self
._SectionName
= ItemList
[0].upper()
304 if self
._SectionName
in self
.DataType
:
305 self
._SectionType
= self
.DataType
[self
._SectionName
]
306 # Check if the section name is valid
307 if self
._SectionName
not in SECTIONS_HAVE_ITEM_AFTER_ARCH
and len(ItemList
) > 3:
308 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
309 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
310 elif self
._Version
>= 0x00010005:
311 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
312 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
314 self
._SectionType
= MODEL_UNKNOWN
317 if len(ItemList
) > 1:
318 S1
= ItemList
[1].upper()
323 # S2 may be Platform or ModuleType
324 if len(ItemList
) > 2:
325 if self
._SectionName
.upper() in SECTIONS_HAVE_ITEM_PCD
:
328 S2
= ItemList
[2].upper()
331 self
._Scope
.append([S1
, S2
])
333 # 'COMMON' must not be used with specific ARCHs at the same section
334 if 'COMMON' in ArchList
and len(ArchList
) > 1:
335 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
336 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
337 # If the section information is needed later, it should be stored in database
338 self
._ValueList
[0] = self
._SectionName
340 ## [defines] section parser
342 def _DefineParser(self
):
343 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
344 self
._ValueList
[1:len(TokenList
)] = TokenList
345 if not self
._ValueList
[1]:
346 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
347 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
348 if not self
._ValueList
[2]:
349 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
350 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
352 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
353 Name
, Value
= self
._ValueList
[1], self
._ValueList
[2]
354 MacroUsed
= GlobalData
.gMacroRefPattern
.findall(Value
)
355 if len(MacroUsed
) != 0:
356 for Macro
in MacroUsed
:
357 if Macro
in GlobalData
.gGlobalDefines
:
358 EdkLogger
.error("Parser", FORMAT_INVALID
, "Global macro %s is not permitted." % (Macro
), ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
360 EdkLogger
.error("Parser", FORMAT_INVALID
, "%s not defined" % (Macro
), ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
361 # Sometimes, we need to make differences between EDK and EDK2 modules
362 if Name
== 'INF_VERSION':
363 if re
.match(r
'0[xX][\da-f-A-F]{5,8}', Value
):
364 self
._Version
= int(Value
, 0)
365 elif re
.match(r
'\d+\.\d+', Value
):
366 ValueList
= Value
.split('.')
367 Major
= '%04o' % int(ValueList
[0], 0)
368 Minor
= '%04o' % int(ValueList
[1], 0)
369 self
._Version
= int('0x' + Major
+ Minor
, 0)
371 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid version number",
372 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
374 if type(self
) == InfParser
and self
._Version
< 0x00010005:
375 # EDK module allows using defines as macros
376 self
._FileLocalMacros
[Name
] = Value
377 self
._Defines
[Name
] = Value
379 ## [BuildOptions] section parser
381 def _BuildOptionParser(self
):
382 self
._CurrentLine
= CleanString(self
._CurrentLine
, BuildOption
=True)
383 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
384 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
385 if len(TokenList2
) == 2:
386 self
._ValueList
[0] = TokenList2
[0] # toolchain family
387 self
._ValueList
[1] = TokenList2
[1] # keys
389 self
._ValueList
[1] = TokenList
[0]
390 if len(TokenList
) == 2 and type(self
) != DscParser
: # value
391 self
._ValueList
[2] = ReplaceMacro(TokenList
[1], self
._Macros
)
393 if self
._ValueList
[1].count('_') != 4:
397 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
398 ExtraData
=self
._CurrentLine
,
400 Line
=self
._LineIndex
+ 1
402 def GetValidExpression(self
, TokenSpaceGuid
, PcdCName
):
403 return self
._Table
.GetValidExpression(TokenSpaceGuid
, PcdCName
)
404 def _GetMacros(self
):
406 Macros
.update(self
._FileLocalMacros
)
407 Macros
.update(self
._GetApplicableSectionMacro
())
410 ## Construct section Macro dict
411 def _ConstructSectionMacroDict(self
, Name
, Value
):
412 ScopeKey
= [(Scope
[0], Scope
[1]) for Scope
in self
._Scope
]
413 ScopeKey
= tuple(ScopeKey
)
414 SectionDictKey
= self
._SectionType
, ScopeKey
416 # DecParser SectionType is a list, will contain more than one item only in Pcd Section
417 # As Pcd section macro usage is not alllowed, so here it is safe
419 if type(self
) == DecParser
:
420 SectionDictKey
= self
._SectionType
[0], ScopeKey
421 if SectionDictKey
not in self
._SectionsMacroDict
:
422 self
._SectionsMacroDict
[SectionDictKey
] = {}
423 SectionLocalMacros
= self
._SectionsMacroDict
[SectionDictKey
]
424 SectionLocalMacros
[Name
] = Value
426 ## Get section Macros that are applicable to current line, which may come from other sections
427 ## that share the same name while scope is wider
428 def _GetApplicableSectionMacro(self
):
435 ActiveSectionType
= self
._SectionType
436 if type(self
) == DecParser
:
437 ActiveSectionType
= self
._SectionType
[0]
439 for (SectionType
, Scope
) in self
._SectionsMacroDict
:
440 if SectionType
!= ActiveSectionType
:
443 for ActiveScope
in self
._Scope
:
444 Scope0
, Scope1
= ActiveScope
[0], ActiveScope
[1]
445 if(Scope0
, Scope1
) not in Scope
:
448 SpeSpeMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
450 for ActiveScope
in self
._Scope
:
451 Scope0
, Scope1
= ActiveScope
[0], ActiveScope
[1]
452 if(Scope0
, Scope1
) not in Scope
and (Scope0
, "COMMON") not in Scope
and ("COMMON", Scope1
) not in Scope
:
455 ComSpeMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
457 if ("COMMON", "COMMON") in Scope
:
458 ComComMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
460 Macros
.update(ComComMacroDict
)
461 Macros
.update(ComSpeMacroDict
)
462 Macros
.update(SpeSpeMacroDict
)
467 Finished
= property(_GetFinished
, _SetFinished
)
468 _Macros
= property(_GetMacros
)
471 ## INF file parser class
473 # @param FilePath The path of platform description file
474 # @param FileType The raw data of DSC file
475 # @param Table Database used to retrieve module/package information
476 # @param Macros Macros used for replacement in file
478 class InfParser(MetaFileParser
):
479 # INF file supported data types (one type per section)
481 TAB_UNKNOWN
.upper() : MODEL_UNKNOWN
,
482 TAB_INF_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
483 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
484 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
485 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
486 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
487 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
488 TAB_PACKAGES
.upper() : MODEL_META_DATA_PACKAGE
,
489 TAB_NMAKE
.upper() : MODEL_META_DATA_NMAKE
,
490 TAB_INF_FIXED_PCD
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
491 TAB_INF_PATCH_PCD
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
492 TAB_INF_FEATURE_PCD
.upper() : MODEL_PCD_FEATURE_FLAG
,
493 TAB_INF_PCD_EX
.upper() : MODEL_PCD_DYNAMIC_EX
,
494 TAB_INF_PCD
.upper() : MODEL_PCD_DYNAMIC
,
495 TAB_SOURCES
.upper() : MODEL_EFI_SOURCE_FILE
,
496 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
497 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
498 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
499 TAB_DEPEX
.upper() : MODEL_EFI_DEPEX
,
500 TAB_BINARIES
.upper() : MODEL_EFI_BINARY_FILE
,
501 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
504 ## Constructor of InfParser
506 # Initialize object of InfParser
508 # @param FilePath The path of module description file
509 # @param FileType The raw data of DSC file
510 # @param Arch Default Arch value for filtering sections
511 # @param Table Database used to retrieve module/package information
513 def __init__(self
, FilePath
, FileType
, Arch
, Table
):
514 # prevent re-initialization
515 if hasattr(self
, "_Table"):
517 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
)
525 Content
= open(str(self
.MetaFile
), 'r').readlines()
527 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
529 # parse the file line by line
530 IsFindBlockComment
= False
531 GetHeaderComment
= False
536 for Index
in range(0, len(Content
)):
537 # skip empty, commented, block commented lines
538 Line
, Comment
= CleanString2(Content
[Index
], AllowCppStyleComment
=True)
540 if Index
+ 1 < len(Content
):
541 NextLine
, NextComment
= CleanString2(Content
[Index
+ 1])
544 Comments
.append((Comment
, Index
+ 1))
545 elif GetHeaderComment
:
546 SectionComments
.extend(Comments
)
549 if Line
.find(DataType
.TAB_COMMENT_EDK_START
) > -1:
550 IsFindBlockComment
= True
552 if Line
.find(DataType
.TAB_COMMENT_EDK_END
) > -1:
553 IsFindBlockComment
= False
555 if IsFindBlockComment
:
558 self
._LineIndex
= Index
559 self
._CurrentLine
= Line
562 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
563 if not GetHeaderComment
:
564 for Cmt
, LNo
in Comments
:
565 self
._Store
(MODEL_META_DATA_HEADER_COMMENT
, Cmt
, '', '', 'COMMON',
566 'COMMON', self
._Owner
[-1], LNo
, -1, LNo
, -1, 0)
567 GetHeaderComment
= True
569 TailComments
.extend(SectionComments
+ Comments
)
571 self
._SectionHeaderParser
()
572 # Check invalid sections
573 if self
._Version
< 0x00010005:
574 if self
._SectionType
in [MODEL_META_DATA_BUILD_OPTION
,
575 MODEL_EFI_LIBRARY_CLASS
,
576 MODEL_META_DATA_PACKAGE
,
577 MODEL_PCD_FIXED_AT_BUILD
,
578 MODEL_PCD_PATCHABLE_IN_MODULE
,
579 MODEL_PCD_FEATURE_FLAG
,
580 MODEL_PCD_DYNAMIC_EX
,
585 MODEL_META_DATA_USER_EXTENSION
]:
586 EdkLogger
.error('Parser', FORMAT_INVALID
,
587 "Section [%s] is not allowed in inf file without version" % (self
._SectionName
),
588 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
589 elif self
._SectionType
in [MODEL_EFI_INCLUDE
,
590 MODEL_EFI_LIBRARY_INSTANCE
,
591 MODEL_META_DATA_NMAKE
]:
592 EdkLogger
.error('Parser', FORMAT_INVALID
,
593 "Section [%s] is not allowed in inf file with version 0x%08x" % (self
._SectionName
, self
._Version
),
594 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
596 # merge two lines specified by '\' in section NMAKE
597 elif self
._SectionType
== MODEL_META_DATA_NMAKE
:
600 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
603 if NextLine
[0] == TAB_SECTION_START
and NextLine
[-1] == TAB_SECTION_END
:
604 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
607 NmakeLine
= NmakeLine
+ ' ' + Line
[0:-1]
610 self
._CurrentLine
= NmakeLine
+ Line
614 self
._ValueList
= ['', '', '']
615 # parse current line, result will be put in self._ValueList
616 self
._SectionParser
[self
._SectionType
](self
)
617 if self
._ValueList
== None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
622 Comments
.append((Comment
, Index
+ 1))
623 if GlobalData
.gOptions
and GlobalData
.gOptions
.CheckUsage
:
624 CheckInfComment(self
._SectionType
, Comments
, str(self
.MetaFile
), Index
+ 1, self
._ValueList
)
626 # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
627 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
629 for Arch
, Platform
in self
._Scope
:
630 LastItem
= self
._Store
(self
._SectionType
,
643 for Comment
, LineNo
in Comments
:
644 self
._Store
(MODEL_META_DATA_COMMENT
, Comment
, '', '', Arch
, Platform
,
645 LastItem
, LineNo
, -1, LineNo
, -1, 0)
648 TailComments
.extend(SectionComments
+ Comments
)
649 if IsFindBlockComment
:
650 EdkLogger
.error("Parser", FORMAT_INVALID
, "Open block comments (starting with /*) are expected to end with */",
653 # If there are tail comments in INF file, save to database whatever the comments are
654 for Comment
in TailComments
:
655 self
._Store
(MODEL_META_DATA_TAIL_COMMENT
, Comment
[0], '', '', 'COMMON',
656 'COMMON', self
._Owner
[-1], -1, -1, -1, -1, 0)
659 ## Data parser for the format in which there's path
661 # Only path can have macro used. So we need to replace them before use.
663 def _IncludeParser(self
):
664 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
665 self
._ValueList
[0:len(TokenList
)] = TokenList
666 Macros
= self
._Macros
668 for Index
in range(0, len(self
._ValueList
)):
669 Value
= self
._ValueList
[Index
]
673 if Value
.upper().find('$(EFI_SOURCE)\Edk'.upper()) > -1 or Value
.upper().find('$(EFI_SOURCE)/Edk'.upper()) > -1:
674 Value
= '$(EDK_SOURCE)' + Value
[17:]
675 if Value
.find('$(EFI_SOURCE)') > -1 or Value
.find('$(EDK_SOURCE)') > -1:
677 elif Value
.startswith('.'):
679 elif Value
.startswith('$('):
682 Value
= '$(EFI_SOURCE)/' + Value
684 self
._ValueList
[Index
] = ReplaceMacro(Value
, Macros
)
686 ## Parse [Sources] section
688 # Only path can have macro used. So we need to replace them before use.
691 def _SourceFileParser(self
):
692 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
693 self
._ValueList
[0:len(TokenList
)] = TokenList
694 Macros
= self
._Macros
695 # For Acpi tables, remove macro like ' TABLE_NAME=Sata1'
696 if 'COMPONENT_TYPE' in Macros
:
697 if self
._Defines
['COMPONENT_TYPE'].upper() == 'ACPITABLE':
698 self
._ValueList
[0] = GetSplitValueList(self
._ValueList
[0], ' ', 1)[0]
699 if self
._Defines
['BASE_NAME'] == 'Microcode':
701 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
703 ## Parse [Binaries] section
705 # Only path can have macro used. So we need to replace them before use.
708 def _BinaryFileParser(self
):
709 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 2)
710 if len(TokenList
) < 2:
711 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type or path specified",
712 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
713 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
715 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type specified",
716 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
717 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
719 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file path specified",
720 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
721 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
722 self
._ValueList
[0:len(TokenList
)] = TokenList
723 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
725 ## [nmake] section parser (Edk.x style only)
726 def _NmakeParser(self
):
727 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
728 self
._ValueList
[0:len(TokenList
)] = TokenList
730 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
731 # remove self-reference in macro setting
732 #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
734 ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
736 def _PcdParser(self
):
737 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
738 ValueList
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
739 if len(ValueList
) != 2:
740 EdkLogger
.error('Parser', FORMAT_INVALID
, "Illegal token space GUID and PCD name format",
741 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
742 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
743 self
._ValueList
[0:1] = ValueList
744 if len(TokenList
) > 1:
745 self
._ValueList
[2] = TokenList
[1]
746 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
747 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
748 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
749 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
751 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
752 if self
._ValueList
[2] != '':
753 InfPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
754 if InfPcdValueList
[0] in ['True', 'true', 'TRUE']:
755 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '1', 1);
756 elif InfPcdValueList
[0] in ['False', 'false', 'FALSE']:
757 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '0', 1);
758 if (self
._ValueList
[0], self
._ValueList
[1]) not in self
.PcdsDict
:
759 self
.PcdsDict
[self
._ValueList
[0], self
._ValueList
[1]] = self
._SectionType
760 elif self
.PcdsDict
[self
._ValueList
[0], self
._ValueList
[1]] != self
._SectionType
:
761 EdkLogger
.error('Parser', FORMAT_INVALID
, "It is not permissible to list a specified PCD in different PCD type sections.",
762 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
763 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
765 ## [depex] section parser
767 def _DepexParser(self
):
768 self
._ValueList
[0:1] = [self
._CurrentLine
]
771 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
772 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
773 MODEL_META_DATA_BUILD_OPTION
: MetaFileParser
._BuildOptionParser
,
774 MODEL_EFI_INCLUDE
: _IncludeParser
, # for Edk.x modules
775 MODEL_EFI_LIBRARY_INSTANCE
: MetaFileParser
._CommonParser
, # for Edk.x modules
776 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
777 MODEL_META_DATA_PACKAGE
: MetaFileParser
._PathParser
,
778 MODEL_META_DATA_NMAKE
: _NmakeParser
, # for Edk.x modules
779 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
780 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
781 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
782 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
783 MODEL_PCD_DYNAMIC
: _PcdParser
,
784 MODEL_EFI_SOURCE_FILE
: _SourceFileParser
,
785 MODEL_EFI_GUID
: MetaFileParser
._CommonParser
,
786 MODEL_EFI_PROTOCOL
: MetaFileParser
._CommonParser
,
787 MODEL_EFI_PPI
: MetaFileParser
._CommonParser
,
788 MODEL_EFI_DEPEX
: _DepexParser
,
789 MODEL_EFI_BINARY_FILE
: _BinaryFileParser
,
790 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
793 ## DSC file parser class
795 # @param FilePath The path of platform description file
796 # @param FileType The raw data of DSC file
797 # @param Table Database used to retrieve module/package information
798 # @param Macros Macros used for replacement in file
799 # @param Owner Owner ID (for sub-section parsing)
800 # @param From ID from which the data comes (for !INCLUDE directive)
802 class DscParser(MetaFileParser
):
803 # DSC file supported data types (one type per section)
805 TAB_SKUIDS
.upper() : MODEL_EFI_SKU_ID
,
806 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
807 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
808 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
809 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
810 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
811 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
812 TAB_PCDS_DYNAMIC_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_DEFAULT
,
813 TAB_PCDS_DYNAMIC_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_HII
,
814 TAB_PCDS_DYNAMIC_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_VPD
,
815 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT
,
816 TAB_PCDS_DYNAMIC_EX_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_HII
,
817 TAB_PCDS_DYNAMIC_EX_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_VPD
,
818 TAB_COMPONENTS
.upper() : MODEL_META_DATA_COMPONENT
,
819 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
.upper() : MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
,
820 TAB_DSC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
821 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
822 TAB_DSC_DEFINES_EDKGLOBAL
: MODEL_META_DATA_GLOBAL_DEFINE
,
823 TAB_INCLUDE
.upper() : MODEL_META_DATA_INCLUDE
,
824 TAB_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
825 TAB_IF_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
826 TAB_IF_N_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
,
827 TAB_ELSE_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
,
828 TAB_ELSE
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
,
829 TAB_END_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
,
830 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
,
833 # Valid names in define section
840 "PCD_INFO_GENERATION",
841 "PCD_VAR_CHECK_GENERATION",
842 "SUPPORTED_ARCHITECTURES",
851 "FIX_LOAD_TOP_MEMORY_ADDRESS",
856 SubSectionDefineKeywords
= [
860 SymbolPattern
= ValueExpression
.SymbolPattern
862 IncludedFiles
= set()
864 ## Constructor of DscParser
866 # Initialize object of DscParser
868 # @param FilePath The path of platform description file
869 # @param FileType The raw data of DSC file
870 # @param Arch Default Arch value for filtering sections
871 # @param Table Database used to retrieve module/package information
872 # @param Owner Owner ID (for sub-section parsing)
873 # @param From ID from which the data comes (for !INCLUDE directive)
875 def __init__(self
, FilePath
, FileType
, Arch
, Table
, Owner
= -1, From
= -1):
876 # prevent re-initialization
877 if hasattr(self
, "_Table"):
879 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
, Owner
, From
)
880 self
._Version
= 0x00010005 # Only EDK2 dsc file is supported
881 # to store conditional directive evaluation result
882 self
._DirectiveStack
= []
883 self
._DirectiveEvalStack
= []
887 # Specify whether current line is in uncertain condition
889 self
._InDirective
= -1
891 # Final valid replacable symbols
894 # Map the ID between the original table and new table to track
897 self
._IdMapping
= {-1:-1}
903 Content
= open(str(self
.MetaFile
), 'r').readlines()
905 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
908 for Index
in range(0, len(Content
)):
909 Line
= CleanString(Content
[Index
])
914 self
._CurrentLine
= Line
915 self
._LineIndex
= Index
916 if self
._InSubsection
and self
._Owner
[-1] == -1:
917 self
._Owner
.append(self
._LastItem
)
920 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
921 self
._SectionType
= MODEL_META_DATA_SECTION_HEADER
923 elif Line
[0] == '}' and self
._InSubsection
:
924 self
._InSubsection
= False
925 self
._SubsectionType
= MODEL_UNKNOWN
926 self
._SubsectionName
= ''
931 elif Line
[0] == TAB_OPTION_START
and Line
[-1] == TAB_OPTION_END
:
932 self
._SubsectionType
= MODEL_META_DATA_SUBSECTION_HEADER
935 self
._DirectiveParser
()
937 if Line
[0] == TAB_OPTION_START
and not self
._InSubsection
:
938 EdkLogger
.error("Parser", FILE_READ_FAILURE
, "Missing the '{' before %s in Line %s" % (Line
, Index
+1),ExtraData
=self
.MetaFile
)
940 if self
._InSubsection
:
941 SectionType
= self
._SubsectionType
943 SectionType
= self
._SectionType
944 self
._ItemType
= SectionType
946 self
._ValueList
= ['', '', '']
947 self
._SectionParser
[SectionType
](self
)
948 if self
._ValueList
== None:
951 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
952 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
954 for Arch
, ModuleType
in self
._Scope
:
955 Owner
= self
._Owner
[-1]
956 if self
._SubsectionType
!= MODEL_UNKNOWN
:
957 Owner
= OwnerId
[Arch
]
958 self
._LastItem
= self
._Store
(
973 if self
._SubsectionType
== MODEL_UNKNOWN
and self
._InSubsection
:
974 OwnerId
[Arch
] = self
._LastItem
976 if self
._DirectiveStack
:
977 Type
, Line
, Text
= self
._DirectiveStack
[-1]
978 EdkLogger
.error('Parser', FORMAT_INVALID
, "No matching '!endif' found",
979 ExtraData
=Text
, File
=self
.MetaFile
, Line
=Line
)
982 ## <subsection_header> parser
983 def _SubsectionHeaderParser(self
):
984 self
._SubsectionName
= self
._CurrentLine
[1:-1].upper()
985 if self
._SubsectionName
in self
.DataType
:
986 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
988 self
._SubsectionType
= MODEL_UNKNOWN
989 EdkLogger
.warn("Parser", "Unrecognized sub-section", File
=self
.MetaFile
,
990 Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
991 self
._ValueList
[0] = self
._SubsectionName
993 ## Directive statement parser
994 def _DirectiveParser(self
):
995 self
._ValueList
= ['', '', '']
996 TokenList
= GetSplitValueList(self
._CurrentLine
, ' ', 1)
997 self
._ValueList
[0:len(TokenList
)] = TokenList
1000 DirectiveName
= self
._ValueList
[0].upper()
1001 if DirectiveName
not in self
.DataType
:
1002 EdkLogger
.error("Parser", FORMAT_INVALID
, "Unknown directive [%s]" % DirectiveName
,
1003 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1005 if DirectiveName
in ['!IF', '!IFDEF', '!IFNDEF']:
1006 self
._InDirective
+= 1
1008 if DirectiveName
in ['!ENDIF']:
1009 self
._InDirective
-= 1
1011 if DirectiveName
in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self
._ValueList
[1] == '':
1012 EdkLogger
.error("Parser", FORMAT_INVALID
, "Missing expression",
1013 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1014 ExtraData
=self
._CurrentLine
)
1016 ItemType
= self
.DataType
[DirectiveName
]
1017 Scope
= [['COMMON', 'COMMON']]
1018 if ItemType
== MODEL_META_DATA_INCLUDE
:
1020 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1021 # Remove all directives between !if and !endif, including themselves
1022 while self
._DirectiveStack
:
1023 # Remove any !else or !elseif
1024 DirectiveInfo
= self
._DirectiveStack
.pop()
1025 if DirectiveInfo
[0] in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1026 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1027 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1030 EdkLogger
.error("Parser", FORMAT_INVALID
, "Redundant '!endif'",
1031 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1032 ExtraData
=self
._CurrentLine
)
1033 elif ItemType
!= MODEL_META_DATA_INCLUDE
:
1034 # Break if there's a !else is followed by a !elseif
1035 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
and \
1036 self
._DirectiveStack
and \
1037 self
._DirectiveStack
[-1][0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1038 EdkLogger
.error("Parser", FORMAT_INVALID
, "'!elseif' after '!else'",
1039 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1040 ExtraData
=self
._CurrentLine
)
1041 self
._DirectiveStack
.append((ItemType
, self
._LineIndex
+ 1, self
._CurrentLine
))
1044 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
1045 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
1047 for Arch
, ModuleType
in Scope
:
1048 self
._LastItem
= self
._Store
(
1057 self
._LineIndex
+ 1,
1059 self
._LineIndex
+ 1,
1064 ## [defines] section parser
1066 def _DefineParser(self
):
1067 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1068 self
._ValueList
[1:len(TokenList
)] = TokenList
1071 if not self
._ValueList
[1]:
1072 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
1073 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1074 if not self
._ValueList
[2]:
1075 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
1076 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1077 if (not self
._ValueList
[1] in self
.DefineKeywords
and
1078 (self
._InSubsection
and self
._ValueList
[1] not in self
.SubSectionDefineKeywords
)):
1079 EdkLogger
.error('Parser', FORMAT_INVALID
,
1080 "Unknown keyword found: %s. "
1081 "If this is a macro you must "
1082 "add it as a DEFINE in the DSC" % self
._ValueList
[1],
1083 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1084 if not self
._InSubsection
:
1085 self
._Defines
[self
._ValueList
[1]] = self
._ValueList
[2]
1086 self
._ItemType
= self
.DataType
[TAB_DSC_DEFINES
.upper()]
1089 def _SkuIdParser(self
):
1090 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1091 if len(TokenList
) != 2:
1092 EdkLogger
.error('Parser', FORMAT_INVALID
, "Correct format is '<Integer>|<UiName>'",
1093 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1094 self
._ValueList
[0:len(TokenList
)] = TokenList
1096 ## Parse Edk style of library modules
1098 def _LibraryInstanceParser(self
):
1099 self
._ValueList
[0] = self
._CurrentLine
1101 ## PCD sections parser
1103 # [PcdsFixedAtBuild]
1104 # [PcdsPatchableInModule]
1107 # [PcdsDynamicExDefault]
1108 # [PcdsDynamicExVpd]
1109 # [PcdsDynamicExHii]
1111 # [PcdsDynamicDefault]
1116 def _PcdParser(self
):
1117 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1118 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1119 if len(TokenList
) == 2:
1120 self
._ValueList
[2] = TokenList
[1]
1121 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1122 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1123 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1124 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1125 if self
._ValueList
[2] == '':
1127 # The PCD values are optional for FIXEDATBUILD and PATCHABLEINMODULE
1129 if self
._SectionType
in (MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
):
1131 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD value given",
1132 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1133 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1135 # Validate the datum type of Dynamic Defaul PCD and DynamicEx Default PCD
1136 ValueList
= GetSplitValueList(self
._ValueList
[2])
1137 if len(ValueList
) > 1 and ValueList
[1] != TAB_VOID \
1138 and self
._ItemType
in [MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
]:
1139 EdkLogger
.error('Parser', FORMAT_INVALID
, "The datum type '%s' of PCD is wrong" % ValueList
[1],
1140 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1142 # Validate the VariableName of DynamicHii and DynamicExHii for PCD Entry must not be an empty string
1143 if self
._ItemType
in [MODEL_PCD_DYNAMIC_HII
, MODEL_PCD_DYNAMIC_EX_HII
]:
1144 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
1145 if len(DscPcdValueList
[0].replace('L','').replace('"','').strip()) == 0:
1146 EdkLogger
.error('Parser', FORMAT_INVALID
, "The VariableName field in the HII format PCD entry must not be an empty string",
1147 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1149 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
1150 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
1151 if DscPcdValueList
[0] in ['True', 'true', 'TRUE']:
1152 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '1', 1);
1153 elif DscPcdValueList
[0] in ['False', 'false', 'FALSE']:
1154 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '0', 1);
1157 ## [components] section parser
1159 def _ComponentParser(self
):
1160 if self
._CurrentLine
[-1] == '{':
1161 self
._ValueList
[0] = self
._CurrentLine
[0:-1].strip()
1162 self
._InSubsection
= True
1164 self
._ValueList
[0] = self
._CurrentLine
1166 ## [LibraryClasses] section
1168 def _LibraryClassParser(self
):
1169 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1170 if len(TokenList
) < 2:
1171 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class or instance specified",
1172 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1173 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1174 if TokenList
[0] == '':
1175 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class specified",
1176 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1177 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1178 if TokenList
[1] == '':
1179 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library instance specified",
1180 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1181 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1183 self
._ValueList
[0:len(TokenList
)] = TokenList
1185 def _CompponentSourceOverridePathParser(self
):
1186 self
._ValueList
[0] = self
._CurrentLine
1188 ## [BuildOptions] section parser
1190 def _BuildOptionParser(self
):
1191 self
._CurrentLine
= CleanString(self
._CurrentLine
, BuildOption
=True)
1192 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1193 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
1194 if len(TokenList2
) == 2:
1195 self
._ValueList
[0] = TokenList2
[0] # toolchain family
1196 self
._ValueList
[1] = TokenList2
[1] # keys
1198 self
._ValueList
[1] = TokenList
[0]
1199 if len(TokenList
) == 2: # value
1200 self
._ValueList
[2] = TokenList
[1]
1202 if self
._ValueList
[1].count('_') != 4:
1206 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
1207 ExtraData
=self
._CurrentLine
,
1209 Line
=self
._LineIndex
+ 1
1212 ## Override parent's method since we'll do all macro replacements in parser
1213 def _GetMacros(self
):
1215 Macros
.update(self
._FileLocalMacros
)
1216 Macros
.update(self
._GetApplicableSectionMacro
())
1217 Macros
.update(GlobalData
.gEdkGlobal
)
1218 Macros
.update(GlobalData
.gPlatformDefines
)
1219 Macros
.update(GlobalData
.gCommandLineDefines
)
1220 # PCD cannot be referenced in macro definition
1221 if self
._ItemType
not in [MODEL_META_DATA_DEFINE
, MODEL_META_DATA_GLOBAL_DEFINE
]:
1222 Macros
.update(self
._Symbols
)
1225 def _PostProcess(self
):
1227 MODEL_META_DATA_SECTION_HEADER
: self
.__ProcessSectionHeader
,
1228 MODEL_META_DATA_SUBSECTION_HEADER
: self
.__ProcessSubsectionHeader
,
1229 MODEL_META_DATA_HEADER
: self
.__ProcessDefine
,
1230 MODEL_META_DATA_DEFINE
: self
.__ProcessDefine
,
1231 MODEL_META_DATA_GLOBAL_DEFINE
: self
.__ProcessDefine
,
1232 MODEL_META_DATA_INCLUDE
: self
.__ProcessDirective
,
1233 MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
: self
.__ProcessDirective
,
1234 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
: self
.__ProcessDirective
,
1235 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
: self
.__ProcessDirective
,
1236 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
: self
.__ProcessDirective
,
1237 MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
: self
.__ProcessDirective
,
1238 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
: self
.__ProcessDirective
,
1239 MODEL_EFI_SKU_ID
: self
.__ProcessSkuId
,
1240 MODEL_EFI_LIBRARY_INSTANCE
: self
.__ProcessLibraryInstance
,
1241 MODEL_EFI_LIBRARY_CLASS
: self
.__ProcessLibraryClass
,
1242 MODEL_PCD_FIXED_AT_BUILD
: self
.__ProcessPcd
,
1243 MODEL_PCD_PATCHABLE_IN_MODULE
: self
.__ProcessPcd
,
1244 MODEL_PCD_FEATURE_FLAG
: self
.__ProcessPcd
,
1245 MODEL_PCD_DYNAMIC_DEFAULT
: self
.__ProcessPcd
,
1246 MODEL_PCD_DYNAMIC_HII
: self
.__ProcessPcd
,
1247 MODEL_PCD_DYNAMIC_VPD
: self
.__ProcessPcd
,
1248 MODEL_PCD_DYNAMIC_EX_DEFAULT
: self
.__ProcessPcd
,
1249 MODEL_PCD_DYNAMIC_EX_HII
: self
.__ProcessPcd
,
1250 MODEL_PCD_DYNAMIC_EX_VPD
: self
.__ProcessPcd
,
1251 MODEL_META_DATA_COMPONENT
: self
.__ProcessComponent
,
1252 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: self
.__ProcessSourceOverridePath
,
1253 MODEL_META_DATA_BUILD_OPTION
: self
.__ProcessBuildOption
,
1254 MODEL_UNKNOWN
: self
._Skip
,
1255 MODEL_META_DATA_USER_EXTENSION
: self
._SkipUserExtension
,
1258 self
._Table
= MetaFileStorage(self
._RawTable
.Cur
, self
.MetaFile
, MODEL_FILE_DSC
, True)
1259 self
._Table
.Create()
1260 self
._DirectiveStack
= []
1261 self
._DirectiveEvalStack
= []
1262 self
._FileWithError
= self
.MetaFile
1263 self
._FileLocalMacros
= {}
1264 self
._SectionsMacroDict
= {}
1265 GlobalData
.gPlatformDefines
= {}
1267 # Get all macro and PCD which has straitforward value
1268 self
.__RetrievePcdValue
()
1269 self
._Content
= self
._RawTable
.GetAll()
1270 self
._ContentIndex
= 0
1271 self
._InSubsection
= False
1272 while self
._ContentIndex
< len(self
._Content
) :
1273 Id
, self
._ItemType
, V1
, V2
, V3
, S1
, S2
, Owner
, self
._From
, \
1274 LineStart
, ColStart
, LineEnd
, ColEnd
, Enabled
= self
._Content
[self
._ContentIndex
]
1277 self
._FileWithError
= self
.MetaFile
1279 self
._ContentIndex
+= 1
1281 self
._Scope
= [[S1
, S2
]]
1283 # For !include directive, handle it specially,
1284 # merge arch and module type in case of duplicate items
1286 while self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1287 if self
._ContentIndex
>= len(self
._Content
):
1289 Record
= self
._Content
[self
._ContentIndex
]
1290 if LineStart
== Record
[9] and LineEnd
== Record
[11]:
1291 if [Record
[5], Record
[6]] not in self
._Scope
:
1292 self
._Scope
.append([Record
[5], Record
[6]])
1293 self
._ContentIndex
+= 1
1297 self
._LineIndex
= LineStart
- 1
1298 self
._ValueList
= [V1
, V2
, V3
]
1300 if Owner
> 0 and Owner
in self
._IdMapping
:
1301 self
._InSubsection
= True
1303 self
._InSubsection
= False
1305 Processer
[self
._ItemType
]()
1306 except EvaluationException
, Excpt
:
1308 # Only catch expression evaluation error here. We need to report
1309 # the precise number of line on which the error occurred
1311 if hasattr(Excpt
, 'Pcd'):
1312 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
1313 Info
= GlobalData
.gPlatformOtherPcds
[Excpt
.Pcd
]
1314 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
1315 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
1316 " of the DSC file, and it is currently defined in this section:"
1317 " %s, line #: %d." % (Excpt
.Pcd
, Info
[0], Info
[1]),
1318 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1319 Line
=self
._LineIndex
+ 1)
1321 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
1322 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1323 Line
=self
._LineIndex
+ 1)
1325 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
1326 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1327 Line
=self
._LineIndex
+ 1)
1328 except MacroException
, Excpt
:
1329 EdkLogger
.error('Parser', FORMAT_INVALID
, str(Excpt
),
1330 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1331 Line
=self
._LineIndex
+ 1)
1333 if self
._ValueList
== None:
1336 NewOwner
= self
._IdMapping
.get(Owner
, -1)
1337 self
._Enabled
= int((not self
._DirectiveEvalStack
) or (False not in self
._DirectiveEvalStack
))
1338 self
._LastItem
= self
._Store
(
1347 self
._LineIndex
+ 1,
1349 self
._LineIndex
+ 1,
1353 self
._IdMapping
[Id
] = self
._LastItem
1355 GlobalData
.gPlatformDefines
.update(self
._FileLocalMacros
)
1356 self
._PostProcessed
= True
1357 self
._Content
= None
1359 def __ProcessSectionHeader(self
):
1360 self
._SectionName
= self
._ValueList
[0]
1361 if self
._SectionName
in self
.DataType
:
1362 self
._SectionType
= self
.DataType
[self
._SectionName
]
1364 self
._SectionType
= MODEL_UNKNOWN
1366 def __ProcessSubsectionHeader(self
):
1367 self
._SubsectionName
= self
._ValueList
[0]
1368 if self
._SubsectionName
in self
.DataType
:
1369 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
1371 self
._SubsectionType
= MODEL_UNKNOWN
1373 def __RetrievePcdValue(self
):
1374 Content
= open(str(self
.MetaFile
), 'r').readlines()
1375 GlobalData
.gPlatformOtherPcds
['DSCFILE'] = str(self
.MetaFile
)
1376 for PcdType
in (MODEL_PCD_PATCHABLE_IN_MODULE
, MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_HII
,
1377 MODEL_PCD_DYNAMIC_VPD
, MODEL_PCD_DYNAMIC_EX_DEFAULT
, MODEL_PCD_DYNAMIC_EX_HII
,
1378 MODEL_PCD_DYNAMIC_EX_VPD
):
1379 Records
= self
._RawTable
.Query(PcdType
, BelongsToItem
= -1.0)
1380 for TokenSpaceGuid
, PcdName
, Value
, Dummy2
, Dummy3
, ID
, Line
in Records
:
1381 Name
= TokenSpaceGuid
+ '.' + PcdName
1382 if Name
not in GlobalData
.gPlatformOtherPcds
:
1384 while not Content
[Line
- 1].lstrip().startswith(TAB_SECTION_START
):
1386 GlobalData
.gPlatformOtherPcds
[Name
] = (CleanString(Content
[Line
- 1]), PcdLine
, PcdType
)
1388 def __ProcessDefine(self
):
1389 if not self
._Enabled
:
1392 Type
, Name
, Value
= self
._ValueList
1393 Value
= ReplaceMacro(Value
, self
._Macros
, False)
1395 # If it is <Defines>, return
1397 if self
._InSubsection
:
1398 self
._ValueList
= [Type
, Name
, Value
]
1401 if self
._ItemType
== MODEL_META_DATA_DEFINE
:
1402 if self
._SectionType
== MODEL_META_DATA_HEADER
:
1403 self
._FileLocalMacros
[Name
] = Value
1405 self
._ConstructSectionMacroDict
(Name
, Value
)
1406 elif self
._ItemType
== MODEL_META_DATA_GLOBAL_DEFINE
:
1407 GlobalData
.gEdkGlobal
[Name
] = Value
1410 # Keyword in [Defines] section can be used as Macros
1412 if (self
._ItemType
== MODEL_META_DATA_HEADER
) and (self
._SectionType
== MODEL_META_DATA_HEADER
):
1413 self
._FileLocalMacros
[Name
] = Value
1415 self
._ValueList
= [Type
, Name
, Value
]
1417 def __ProcessDirective(self
):
1419 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1420 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
]:
1421 Macros
= self
._Macros
1422 Macros
.update(GlobalData
.gGlobalDefines
)
1424 Result
= ValueExpression(self
._ValueList
[1], Macros
)()
1425 except SymbolNotFound
, Exc
:
1426 EdkLogger
.debug(EdkLogger
.DEBUG_5
, str(Exc
), self
._ValueList
[1])
1428 except WrnExpression
, Excpt
:
1430 # Catch expression evaluation warning here. We need to report
1431 # the precise number of line and return the evaluation result
1433 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
1434 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1435 Line
=self
._LineIndex
+ 1)
1436 Result
= Excpt
.result
1438 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1439 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1440 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1441 self
._DirectiveStack
.append(self
._ItemType
)
1442 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
:
1443 Result
= bool(Result
)
1445 Macro
= self
._ValueList
[1]
1446 Macro
= Macro
[2:-1] if (Macro
.startswith("$(") and Macro
.endswith(")")) else Macro
1447 Result
= Macro
in self
._Macros
1448 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
:
1450 self
._DirectiveEvalStack
.append(Result
)
1451 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
:
1452 self
._DirectiveStack
.append(self
._ItemType
)
1453 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1454 self
._DirectiveEvalStack
.append(bool(Result
))
1455 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1456 self
._DirectiveStack
.append(self
._ItemType
)
1457 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1458 self
._DirectiveEvalStack
.append(True)
1459 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1460 # Back to the nearest !if/!ifdef/!ifndef
1461 while self
._DirectiveStack
:
1462 self
._DirectiveEvalStack
.pop()
1463 Directive
= self
._DirectiveStack
.pop()
1464 if Directive
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1465 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1466 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1468 elif self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1469 # The included file must be relative to workspace or same directory as DSC file
1470 __IncludeMacros
= {}
1472 # Allow using system environment variables in path after !include
1474 __IncludeMacros
['WORKSPACE'] = GlobalData
.gGlobalDefines
['WORKSPACE']
1475 if "ECP_SOURCE" in GlobalData
.gGlobalDefines
.keys():
1476 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gGlobalDefines
['ECP_SOURCE']
1478 # During GenFds phase call DSC parser, will go into this branch.
1480 elif "ECP_SOURCE" in GlobalData
.gCommandLineDefines
.keys():
1481 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gCommandLineDefines
['ECP_SOURCE']
1483 __IncludeMacros
['EFI_SOURCE'] = GlobalData
.gGlobalDefines
['EFI_SOURCE']
1484 __IncludeMacros
['EDK_SOURCE'] = GlobalData
.gGlobalDefines
['EDK_SOURCE']
1486 # Allow using MACROs comes from [Defines] section to keep compatible.
1488 __IncludeMacros
.update(self
._Macros
)
1490 IncludedFile
= NormPath(ReplaceMacro(self
._ValueList
[1], __IncludeMacros
, RaiseError
=True))
1492 # First search the include file under the same directory as DSC file
1494 IncludedFile1
= PathClass(IncludedFile
, self
.MetaFile
.Dir
)
1495 ErrorCode
, ErrorInfo1
= IncludedFile1
.Validate()
1498 # Also search file under the WORKSPACE directory
1500 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
1501 ErrorCode
, ErrorInfo2
= IncludedFile1
.Validate()
1503 EdkLogger
.error('parser', ErrorCode
, File
=self
._FileWithError
,
1504 Line
=self
._LineIndex
+ 1, ExtraData
=ErrorInfo1
+ "\n" + ErrorInfo2
)
1506 self
._FileWithError
= IncludedFile1
1508 IncludedFileTable
= MetaFileStorage(self
._Table
.Cur
, IncludedFile1
, MODEL_FILE_DSC
, False)
1509 Owner
= self
._Content
[self
._ContentIndex
- 1][0]
1510 Parser
= DscParser(IncludedFile1
, self
._FileType
, self
._Arch
, IncludedFileTable
,
1511 Owner
=Owner
, From
=Owner
)
1513 self
.IncludedFiles
.add (IncludedFile1
)
1515 # Does not allow lower level included file to include upper level included file
1516 if Parser
._From
!= Owner
and int(Owner
) > int (Parser
._From
):
1517 EdkLogger
.error('parser', FILE_ALREADY_EXIST
, File
=self
._FileWithError
,
1518 Line
=self
._LineIndex
+ 1, ExtraData
="{0} is already included at a higher level.".format(IncludedFile1
))
1521 # set the parser status with current status
1522 Parser
._SectionName
= self
._SectionName
1523 Parser
._SectionType
= self
._SectionType
1524 Parser
._Scope
= self
._Scope
1525 Parser
._Enabled
= self
._Enabled
1526 # Parse the included file
1529 # update current status with sub-parser's status
1530 self
._SectionName
= Parser
._SectionName
1531 self
._SectionType
= Parser
._SectionType
1532 self
._Scope
= Parser
._Scope
1533 self
._Enabled
= Parser
._Enabled
1535 # Insert all records in the table for the included file into dsc file table
1536 Records
= IncludedFileTable
.GetAll()
1538 self
._Content
[self
._ContentIndex
:self
._ContentIndex
] = Records
1539 self
._Content
.pop(self
._ContentIndex
- 1)
1540 self
._ValueList
= None
1541 self
._ContentIndex
-= 1
1543 def __ProcessSkuId(self
):
1544 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=True)
1545 for Value
in self
._ValueList
]
1547 def __ProcessLibraryInstance(self
):
1548 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
1550 def __ProcessLibraryClass(self
):
1551 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
, RaiseError
=True)
1553 def __ProcessPcd(self
):
1554 if self
._ItemType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
1555 self
._ValueList
[2] = ReplaceMacro(self
._ValueList
[2], self
._Macros
, RaiseError
=True)
1558 ValList
, Valid
, Index
= AnalyzeDscPcd(self
._ValueList
[2], self
._ItemType
)
1560 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
._FileWithError
, Line
=self
._LineIndex
+ 1,
1561 ExtraData
="%s.%s|%s" % (self
._ValueList
[0], self
._ValueList
[1], self
._ValueList
[2]))
1562 PcdValue
= ValList
[Index
]
1565 ValList
[Index
] = ValueExpression(PcdValue
, self
._Macros
)(True)
1566 except WrnExpression
, Value
:
1567 ValList
[Index
] = Value
.result
1569 if ValList
[Index
] == 'True':
1570 ValList
[Index
] = '1'
1571 if ValList
[Index
] == 'False':
1572 ValList
[Index
] = '0'
1574 if (not self
._DirectiveEvalStack
) or (False not in self
._DirectiveEvalStack
):
1575 GlobalData
.gPlatformPcds
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = PcdValue
1576 self
._Symbols
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = PcdValue
1577 self
._ValueList
[2] = '|'.join(ValList
)
1579 def __ProcessComponent(self
):
1580 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1582 def __ProcessSourceOverridePath(self
):
1583 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1585 def __ProcessBuildOption(self
):
1586 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=False)
1587 for Value
in self
._ValueList
]
1590 MODEL_META_DATA_HEADER
: _DefineParser
,
1591 MODEL_EFI_SKU_ID
: _SkuIdParser
,
1592 MODEL_EFI_LIBRARY_INSTANCE
: _LibraryInstanceParser
,
1593 MODEL_EFI_LIBRARY_CLASS
: _LibraryClassParser
,
1594 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1595 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1596 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1597 MODEL_PCD_DYNAMIC_DEFAULT
: _PcdParser
,
1598 MODEL_PCD_DYNAMIC_HII
: _PcdParser
,
1599 MODEL_PCD_DYNAMIC_VPD
: _PcdParser
,
1600 MODEL_PCD_DYNAMIC_EX_DEFAULT
: _PcdParser
,
1601 MODEL_PCD_DYNAMIC_EX_HII
: _PcdParser
,
1602 MODEL_PCD_DYNAMIC_EX_VPD
: _PcdParser
,
1603 MODEL_META_DATA_COMPONENT
: _ComponentParser
,
1604 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: _CompponentSourceOverridePathParser
,
1605 MODEL_META_DATA_BUILD_OPTION
: _BuildOptionParser
,
1606 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1607 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
1608 MODEL_META_DATA_SECTION_HEADER
: MetaFileParser
._SectionHeaderParser
,
1609 MODEL_META_DATA_SUBSECTION_HEADER
: _SubsectionHeaderParser
,
1612 _Macros
= property(_GetMacros
)
1614 ## DEC file parser class
1616 # @param FilePath The path of platform description file
1617 # @param FileType The raw data of DSC file
1618 # @param Table Database used to retrieve module/package information
1619 # @param Macros Macros used for replacement in file
1621 class DecParser(MetaFileParser
):
1622 # DEC file supported data types (one type per section)
1624 TAB_DEC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
1625 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
1626 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
1627 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
1628 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
1629 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
1630 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
1631 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
1632 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
1633 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
1634 TAB_PCDS_DYNAMIC_NULL
.upper() : MODEL_PCD_DYNAMIC
,
1635 TAB_PCDS_DYNAMIC_EX_NULL
.upper() : MODEL_PCD_DYNAMIC_EX
,
1636 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
,
1639 ## Constructor of DecParser
1641 # Initialize object of DecParser
1643 # @param FilePath The path of platform description file
1644 # @param FileType The raw data of DSC file
1645 # @param Arch Default Arch value for filtering sections
1646 # @param Table Database used to retrieve module/package information
1648 def __init__(self
, FilePath
, FileType
, Arch
, Table
):
1649 # prevent re-initialization
1650 if hasattr(self
, "_Table"):
1652 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
, -1)
1654 self
._Version
= 0x00010005 # Only EDK2 dec file is supported
1655 self
._AllPCDs
= [] # Only for check duplicate PCD
1656 self
._AllPcdDict
= {}
1662 Content
= open(str(self
.MetaFile
), 'r').readlines()
1664 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
1666 self
._DefinesCount
= 0
1667 for Index
in range(0, len(Content
)):
1668 Line
, Comment
= CleanString2(Content
[Index
])
1669 self
._CurrentLine
= Line
1670 self
._LineIndex
= Index
1672 # save comment for later use
1674 self
._Comments
.append((Comment
, self
._LineIndex
+ 1))
1680 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
1681 self
._SectionHeaderParser
()
1682 if self
._SectionName
== TAB_DEC_DEFINES
.upper():
1683 self
._DefinesCount
+= 1
1686 if self
._SectionType
== MODEL_UNKNOWN
:
1687 EdkLogger
.error("Parser", FORMAT_INVALID
,
1689 "Not able to determine \"%s\" in which section."%self
._CurrentLine
,
1690 self
.MetaFile
, self
._LineIndex
+ 1)
1691 elif len(self
._SectionType
) == 0:
1696 self
._ValueList
= ['', '', '']
1697 self
._SectionParser
[self
._SectionType
[0]](self
)
1698 if self
._ValueList
== None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
1704 # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,
1705 # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1
1707 for Arch
, ModuleType
, Type
in self
._Scope
:
1708 self
._LastItem
= self
._Store
(
1716 self
._LineIndex
+ 1,
1718 self
._LineIndex
+ 1,
1722 for Comment
, LineNo
in self
._Comments
:
1724 MODEL_META_DATA_COMMENT
,
1738 if self
._DefinesCount
> 1:
1739 EdkLogger
.error('Parser', FORMAT_INVALID
, 'Multiple [Defines] section is exist.', self
.MetaFile
)
1740 if self
._DefinesCount
== 0:
1741 EdkLogger
.error('Parser', FORMAT_INVALID
, 'No [Defines] section exist.',self
.MetaFile
)
1745 ## Section header parser
1747 # The section header is always in following format:
1749 # [section_name.arch<.platform|module_type>]
1751 def _SectionHeaderParser(self
):
1753 self
._SectionName
= ''
1754 self
._SectionType
= []
1757 Line
= self
._CurrentLine
.replace("%s%s" % (TAB_COMMA_SPLIT
, TAB_SPACE_SPLIT
), TAB_COMMA_SPLIT
)
1758 for Item
in Line
[1:-1].split(TAB_COMMA_SPLIT
):
1760 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
,
1761 "section name can NOT be empty or incorrectly use separator comma",
1762 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1763 ItemList
= Item
.split(TAB_SPLIT
)
1765 # different types of PCD are permissible in one section
1766 self
._SectionName
= ItemList
[0].upper()
1767 if self
._SectionName
== TAB_DEC_DEFINES
.upper() and (len(ItemList
) > 1 or len(Line
.split(TAB_COMMA_SPLIT
)) > 1):
1768 EdkLogger
.error("Parser", FORMAT_INVALID
, "Defines section format is invalid",
1769 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1770 if self
._SectionName
in self
.DataType
:
1771 if self
.DataType
[self
._SectionName
] not in self
._SectionType
:
1772 self
._SectionType
.append(self
.DataType
[self
._SectionName
])
1774 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
1775 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1777 if MODEL_PCD_FEATURE_FLAG
in self
._SectionType
and len(self
._SectionType
) > 1:
1781 "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL
,
1783 Line
=self
._LineIndex
+ 1,
1784 ExtraData
=self
._CurrentLine
1787 if len(ItemList
) > 1:
1788 S1
= ItemList
[1].upper()
1792 # S2 may be Platform or ModuleType
1793 if len(ItemList
) > 2:
1794 S2
= ItemList
[2].upper()
1795 # only Includes, GUIDs, PPIs, Protocols section have Private tag
1796 if self
._SectionName
in [TAB_INCLUDES
.upper(), TAB_GUIDS
.upper(), TAB_PROTOCOLS
.upper(), TAB_PPIS
.upper()]:
1798 EdkLogger
.error("Parser", FORMAT_INVALID
, 'Please use keyword "Private" as section tag modifier.',
1799 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1803 if [S1
, S2
, self
.DataType
[self
._SectionName
]] not in self
._Scope
:
1804 self
._Scope
.append([S1
, S2
, self
.DataType
[self
._SectionName
]])
1806 # 'COMMON' must not be used with specific ARCHs at the same section
1807 if 'COMMON' in ArchList
and len(ArchList
) > 1:
1808 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
1809 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1811 # It is not permissible to mix section tags without the Private attribute with section tags with the Private attribute
1812 if 'COMMON' in PrivateList
and len(PrivateList
) > 1:
1813 EdkLogger
.error('Parser', FORMAT_INVALID
, "Can't mix section tags without the Private attribute with section tags with the Private attribute",
1814 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1816 ## [guids], [ppis] and [protocols] section parser
1818 def _GuidParser(self
):
1819 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1820 if len(TokenList
) < 2:
1821 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name or value specified",
1822 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1823 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1824 if TokenList
[0] == '':
1825 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name specified",
1826 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1827 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1828 if TokenList
[1] == '':
1829 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID value specified",
1830 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1831 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1832 if TokenList
[1][0] != '{' or TokenList
[1][-1] != '}' or GuidStructureStringToGuidString(TokenList
[1]) == '':
1833 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid GUID value format",
1834 ExtraData
=self
._CurrentLine
+ \
1835 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
1836 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1837 self
._ValueList
[0] = TokenList
[0]
1838 self
._ValueList
[1] = TokenList
[1]
1840 ## PCD sections parser
1842 # [PcdsFixedAtBuild]
1843 # [PcdsPatchableInModule]
1849 def _PcdParser(self
):
1850 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1851 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1852 ValueRe
= re
.compile(r
'^[a-zA-Z_][a-zA-Z0-9_]*')
1853 # check PCD information
1854 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1855 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1856 ExtraData
=self
._CurrentLine
+ \
1857 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1858 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1859 # check format of token space GUID CName
1860 if not ValueRe
.match(self
._ValueList
[0]):
1861 EdkLogger
.error('Parser', FORMAT_INVALID
, "The format of the token space GUID CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",
1862 ExtraData
=self
._CurrentLine
+ \
1863 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1864 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1865 # check format of PCD CName
1866 if not ValueRe
.match(self
._ValueList
[1]):
1867 EdkLogger
.error('Parser', FORMAT_INVALID
, "The format of the PCD CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",
1868 ExtraData
=self
._CurrentLine
+ \
1869 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1870 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1871 # check PCD datum information
1872 if len(TokenList
) < 2 or TokenList
[1] == '':
1873 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD Datum information given",
1874 ExtraData
=self
._CurrentLine
+ \
1875 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1876 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1879 ValueRe
= re
.compile(r
'^\s*L?\".*\|.*\"')
1880 PtrValue
= ValueRe
.findall(TokenList
[1])
1882 # Has VOID* type string, may contain "|" character in the string.
1883 if len(PtrValue
) != 0:
1884 ptrValueList
= re
.sub(ValueRe
, '', TokenList
[1])
1885 ValueList
= AnalyzePcdExpression(ptrValueList
)
1886 ValueList
[0] = PtrValue
[0]
1888 ValueList
= AnalyzePcdExpression(TokenList
[1])
1891 # check if there's enough datum information given
1892 if len(ValueList
) != 3:
1893 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid PCD Datum information given",
1894 ExtraData
=self
._CurrentLine
+ \
1895 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1896 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1897 # check default value
1898 if ValueList
[0] == '':
1899 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DefaultValue in PCD Datum information",
1900 ExtraData
=self
._CurrentLine
+ \
1901 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1902 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1904 if ValueList
[1] == '':
1905 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DatumType in PCD Datum information",
1906 ExtraData
=self
._CurrentLine
+ \
1907 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1908 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1909 # check token of the PCD
1910 if ValueList
[2] == '':
1911 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing Token in PCD Datum information",
1912 ExtraData
=self
._CurrentLine
+ \
1913 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1914 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1916 PcdValue
= ValueList
[0]
1919 ValueList
[0] = ValueExpression(PcdValue
, self
._AllPcdDict
)(True)
1920 except WrnExpression
, Value
:
1921 ValueList
[0] = Value
.result
1923 if ValueList
[0] == 'True':
1925 if ValueList
[0] == 'False':
1928 # check format of default value against the datum type
1929 IsValid
, Cause
= CheckPcdDatum(ValueList
[1], ValueList
[0])
1931 EdkLogger
.error('Parser', FORMAT_INVALID
, Cause
, ExtraData
=self
._CurrentLine
,
1932 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1934 if ValueList
[0] in ['True', 'true', 'TRUE']:
1936 elif ValueList
[0] in ['False', 'false', 'FALSE']:
1939 # check for duplicate PCD definition
1940 if (self
._Scope
[0], self
._ValueList
[0], self
._ValueList
[1]) in self
._AllPCDs
:
1941 EdkLogger
.error('Parser', FORMAT_INVALID
,
1942 "The same PCD name and GUID have been already defined",
1943 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1945 self
._AllPCDs
.append((self
._Scope
[0], self
._ValueList
[0], self
._ValueList
[1]))
1946 self
._AllPcdDict
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = ValueList
[0]
1948 self
._ValueList
[2] = ValueList
[0].strip() + '|' + ValueList
[1].strip() + '|' + ValueList
[2].strip()
1951 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
1952 MODEL_EFI_INCLUDE
: MetaFileParser
._PathParser
,
1953 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
1954 MODEL_EFI_GUID
: _GuidParser
,
1955 MODEL_EFI_PPI
: _GuidParser
,
1956 MODEL_EFI_PROTOCOL
: _GuidParser
,
1957 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1958 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1959 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1960 MODEL_PCD_DYNAMIC
: _PcdParser
,
1961 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
1962 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1963 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
1968 # This acts like the main() function for the script, unless it is 'import'ed into another
1971 if __name__
== '__main__':