2 # This file is used to parse meta files
4 # Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
5 # (C) Copyright 2015-2018 Hewlett Packard Enterprise Development LP<BR>
6 # SPDX-License-Identifier: BSD-2-Clause-Patent
12 from __future__
import print_function
13 from __future__
import absolute_import
14 import Common
.LongFilePathOs
as os
18 from hashlib
import md5
20 import Common
.EdkLogger
as EdkLogger
21 import Common
.GlobalData
as GlobalData
23 from CommonDataClass
.DataClass
import *
24 from Common
.DataType
import *
25 from Common
.StringUtils
import *
26 from Common
.Misc
import GuidStructureStringToGuidString
, CheckPcdDatum
, PathClass
, AnalyzePcdData
, AnalyzeDscPcd
, AnalyzePcdExpression
, ParseFieldValue
, StructPattern
27 from Common
.Expression
import *
28 from CommonDataClass
.Exceptions
import *
29 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
30 from collections
import defaultdict
31 from .MetaFileTable
import MetaFileStorage
32 from .MetaFileCommentParser
import CheckInfComment
33 from Common
.DataType
import TAB_COMMENT_EDK_START
, TAB_COMMENT_EDK_END
35 ## RegEx for finding file versions
36 hexVersionPattern
= re
.compile(r
'0[xX][\da-f-A-F]{5,8}')
37 decVersionPattern
= re
.compile(r
'\d+\.\d+')
38 CODEPattern
= re
.compile(r
"{CODE\([a-fA-F0-9Xx\{\},\s]*\)}")
40 ## A decorator used to parse macro definition
41 def ParseMacro(Parser
):
42 def MacroParser(self
):
43 Match
= GlobalData
.gMacroDefPattern
.match(self
._CurrentLine
)
45 # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method
49 TokenList
= GetSplitValueList(self
._CurrentLine
[Match
.end(1):], TAB_EQUAL_SPLIT
, 1)
52 EdkLogger
.error('Parser', FORMAT_INVALID
, "No macro name given",
53 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
54 if len(TokenList
) < 2:
58 Name
, Value
= TokenList
59 # Global macros can be only defined via environment variable
60 if Name
in GlobalData
.gGlobalDefines
:
61 EdkLogger
.error('Parser', FORMAT_INVALID
, "%s can only be defined via environment variable" % Name
,
62 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
63 # Only upper case letters, digit and '_' are allowed
64 if not GlobalData
.gMacroNamePattern
.match(Name
):
65 EdkLogger
.error('Parser', FORMAT_INVALID
, "The macro name must be in the pattern [A-Z][A-Z0-9_]*",
66 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
68 Value
= ReplaceMacro(Value
, self
._Macros
)
69 if Type
in self
.DataType
:
70 self
._ItemType
= self
.DataType
[Type
]
72 self
._ItemType
= MODEL_META_DATA_DEFINE
73 # DEFINE defined macros
74 if Type
== TAB_DSC_DEFINES_DEFINE
:
76 # First judge whether this DEFINE is in conditional directive statements or not.
78 if isinstance(self
, DscParser
) and self
._InDirective
> -1:
81 if isinstance(self
, DecParser
):
82 if MODEL_META_DATA_HEADER
in self
._SectionType
:
83 self
._FileLocalMacros
[Name
] = Value
85 self
._ConstructSectionMacroDict
(Name
, Value
)
86 elif self
._SectionType
== MODEL_META_DATA_HEADER
:
87 self
._FileLocalMacros
[Name
] = Value
89 self
._ConstructSectionMacroDict
(Name
, Value
)
91 # EDK_GLOBAL defined macros
92 elif not isinstance(self
, DscParser
):
93 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL can only be used in .dsc file",
94 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
95 elif self
._SectionType
!= MODEL_META_DATA_HEADER
:
96 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL can only be used under [Defines] section",
97 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
98 elif (Name
in self
._FileLocalMacros
) and (self
._FileLocalMacros
[Name
] != Value
):
99 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL defined a macro with the same name and different value as one defined by 'DEFINE'",
100 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
102 self
._ValueList
= [Type
, Name
, Value
]
106 ## Base class of parser
108 # This class is used for derivation purpose. The specific parser for one kind
109 # type file must derive this class and implement some public interfaces.
111 # @param FilePath The path of platform description file
112 # @param FileType The raw data of DSC file
113 # @param Table Database used to retrieve module/package information
114 # @param Macros Macros used for replacement in file
115 # @param Owner Owner ID (for sub-section parsing)
116 # @param From ID from which the data comes (for !INCLUDE directive)
118 class MetaFileParser(object):
119 # data type (file content) for specific file type
122 # Parser objects used to implement singleton
127 # One file, one parser object. This factory method makes sure that there's
128 # only one object constructed for one meta file.
130 # @param Class class object of real AutoGen class
131 # (InfParser, DecParser or DscParser)
132 # @param FilePath The path of meta file
133 # @param *args The specific class related parameters
134 # @param **kwargs The specific class related dict parameters
136 def __new__(Class
, FilePath
, *args
, **kwargs
):
137 if FilePath
in Class
.MetaFiles
:
138 return Class
.MetaFiles
[FilePath
]
140 ParserObject
= super(MetaFileParser
, Class
).__new
__(Class
)
141 Class
.MetaFiles
[FilePath
] = ParserObject
144 ## Constructor of MetaFileParser
146 # Initialize object of MetaFileParser
148 # @param FilePath The path of platform description file
149 # @param FileType The raw data of DSC file
150 # @param Arch Default Arch value for filtering sections
151 # @param Table Database used to retrieve module/package information
152 # @param Owner Owner ID (for sub-section parsing)
153 # @param From ID from which the data comes (for !INCLUDE directive)
155 def __init__(self
, FilePath
, FileType
, Arch
, Table
, Owner
= -1, From
= -1):
157 self
._RawTable
= Table
159 self
._FileType
= FileType
160 self
.MetaFile
= FilePath
161 self
._FileDir
= self
.MetaFile
.Dir
164 self
._FileLocalMacros
= {}
165 self
._SectionsMacroDict
= defaultdict(dict)
167 # for recursive parsing
168 self
._Owner
= [Owner
]
171 # parsr status for parsing
172 self
._ValueList
= ['', '', '', '', '']
175 self
._CurrentLine
= ''
176 self
._SectionType
= MODEL_UNKNOWN
177 self
._SectionName
= ''
178 self
._InSubsection
= False
179 self
._SubsectionType
= MODEL_UNKNOWN
180 self
._SubsectionName
= ''
181 self
._ItemType
= MODEL_UNKNOWN
184 self
._Finished
= False
185 self
._PostProcessed
= False
186 # Different version of meta-file has different way to parse.
188 self
._GuidDict
= {} # for Parser PCD value {GUID(gTokeSpaceGuidName)}
190 self
._PcdCodeValue
= ""
191 self
._PcdDataTypeCODE
= False
192 self
._CurrentPcdName
= ""
194 ## Store the parsed data in table
195 def _Store(self
, *Args
):
196 return self
._Table
.Insert(*Args
)
198 ## Virtual method for starting parse
200 raise NotImplementedError
202 ## Notify a post-process is needed
203 def DoPostProcess(self
):
204 self
._PostProcessed
= False
206 ## Set parsing complete flag in both class and table
208 self
._Finished
= True
209 self
._Table
.SetEndFlag()
211 def _PostProcess(self
):
212 self
._PostProcessed
= True
214 ## Get the parse complete flag
217 return self
._Finished
219 ## Set the complete flag
221 def Finished(self
, Value
):
222 self
._Finished
= Value
224 ## Remove records that do not match given Filter Arch
225 def _FilterRecordList(self
, RecordList
, FilterArch
):
227 for Record
in RecordList
:
229 if Arch
== TAB_ARCH_COMMON
or Arch
== FilterArch
:
230 NewRecordList
.append(Record
)
233 ## Use [] style to query data in table, just for readability
235 # DataInfo = [data_type, scope1(arch), scope2(platform/moduletype)]
237 def __getitem__(self
, DataInfo
):
238 if not isinstance(DataInfo
, type(())):
239 DataInfo
= (DataInfo
,)
241 # Parse the file first, if necessary
244 # No specific ARCH or Platform given, use raw data
245 if self
._RawTable
and (len(DataInfo
) == 1 or DataInfo
[1] is None):
246 return self
._FilterRecordList
(self
._RawTable
.Query(*DataInfo
), self
._Arch
)
248 # Do post-process if necessary
249 if not self
._PostProcessed
:
252 return self
._FilterRecordList
(self
._Table
.Query(*DataInfo
), DataInfo
[1])
254 def StartParse(self
):
255 if not self
._Finished
:
256 if self
._RawTable
.IsIntegrity():
257 self
._Finished
= True
259 self
._Table
= self
._RawTable
260 self
._PostProcessed
= False
262 ## Data parser for the common format in different type of file
264 # The common format in the meatfile is like
269 def _CommonParser(self
):
270 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
271 self
._ValueList
[0:len(TokenList
)] = TokenList
273 ## Data parser for the format in which there's path
275 # Only path can have macro used. So we need to replace them before use.
278 def _PathParser(self
):
279 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
280 self
._ValueList
[0:len(TokenList
)] = TokenList
281 # Don't do macro replacement for dsc file at this point
282 if not isinstance(self
, DscParser
):
283 Macros
= self
._Macros
284 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
286 ## Skip unsupported data
288 EdkLogger
.warn("Parser", "Unrecognized content", File
=self
.MetaFile
,
289 Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
);
290 self
._ValueList
[0:1] = [self
._CurrentLine
]
292 ## Skip unsupported data for UserExtension Section
293 def _SkipUserExtension(self
):
294 self
._ValueList
[0:1] = [self
._CurrentLine
]
296 ## Section header parser
298 # The section header is always in following format:
300 # [section_name.arch<.platform|module_type>]
302 def _SectionHeaderParser(self
):
304 self
._SectionName
= ''
306 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
309 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
, 3)
310 # different section should not mix in one section
311 if self
._SectionName
!= '' and self
._SectionName
!= ItemList
[0].upper():
312 EdkLogger
.error('Parser', FORMAT_INVALID
, "Different section names in the same section",
313 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
314 self
._SectionName
= ItemList
[0].upper()
315 if self
._SectionName
in self
.DataType
:
316 self
._SectionType
= self
.DataType
[self
._SectionName
]
317 # Check if the section name is valid
318 if self
._SectionName
not in SECTIONS_HAVE_ITEM_AFTER_ARCH_SET
and len(ItemList
) > 3:
319 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
320 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
321 elif self
._Version
>= 0x00010005:
322 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
323 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
325 self
._SectionType
= MODEL_UNKNOWN
328 if len(ItemList
) > 1:
329 S1
= ItemList
[1].upper()
332 S1
= ReplaceMacro(S1
, self
._Macros
)
335 # S2 may be Platform or ModuleType
336 if len(ItemList
) > 2:
337 if self
._SectionName
.upper() in SECTIONS_HAVE_ITEM_PCD_SET
:
340 S2
= ItemList
[2].upper()
343 if len(ItemList
) > 3:
347 self
._Scope
.append([S1
, S2
, S3
])
349 # 'COMMON' must not be used with specific ARCHs at the same section
350 if TAB_ARCH_COMMON
in ArchList
and len(ArchList
) > 1:
351 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
352 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
353 # If the section information is needed later, it should be stored in database
354 self
._ValueList
[0] = self
._SectionName
356 ## [packages] section parser
358 def _PackageParser(self
):
359 self
._CurrentLine
= CleanString(self
._CurrentLine
)
360 self
._Packages
.append(self
._CurrentLine
)
361 self
._ValueList
[0] = self
._CurrentLine
363 ## [defines] section parser
365 def _DefineParser(self
):
366 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
367 self
._ValueList
[1:len(TokenList
)] = TokenList
368 if not self
._ValueList
[1]:
369 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
370 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
371 if not self
._ValueList
[2]:
372 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
373 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
375 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
376 Name
, Value
= self
._ValueList
[1], self
._ValueList
[2]
377 MacroUsed
= GlobalData
.gMacroRefPattern
.findall(Value
)
378 if len(MacroUsed
) != 0:
379 for Macro
in MacroUsed
:
380 if Macro
in GlobalData
.gGlobalDefines
:
381 EdkLogger
.error("Parser", FORMAT_INVALID
, "Global macro %s is not permitted." % (Macro
), ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
383 EdkLogger
.error("Parser", FORMAT_INVALID
, "%s not defined" % (Macro
), ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
384 # Sometimes, we need to make differences between EDK and EDK2 modules
385 if Name
== 'INF_VERSION':
386 if hexVersionPattern
.match(Value
):
387 self
._Version
= int(Value
, 0)
388 elif decVersionPattern
.match(Value
):
389 ValueList
= Value
.split('.')
390 Major
= int(ValueList
[0], 0)
391 Minor
= int(ValueList
[1], 0)
392 if Major
> 0xffff or Minor
> 0xffff:
393 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid version number",
394 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
395 self
._Version
= int('0x{0:04x}{1:04x}'.format(Major
, Minor
), 0)
397 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid version number",
398 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
400 if isinstance(self
, InfParser
) and self
._Version
< 0x00010005:
401 # EDK module allows using defines as macros
402 self
._FileLocalMacros
[Name
] = Value
403 self
._Defines
[Name
] = Value
405 ## [BuildOptions] section parser
407 def _BuildOptionParser(self
):
408 self
._CurrentLine
= CleanString(self
._CurrentLine
, BuildOption
=True)
409 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
410 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
411 if len(TokenList2
) == 2:
412 self
._ValueList
[0] = TokenList2
[0] # toolchain family
413 self
._ValueList
[1] = TokenList2
[1] # keys
415 self
._ValueList
[1] = TokenList
[0]
416 if len(TokenList
) == 2 and not isinstance(self
, DscParser
): # value
417 self
._ValueList
[2] = ReplaceMacro(TokenList
[1], self
._Macros
)
419 if self
._ValueList
[1].count('_') != 4:
423 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
424 ExtraData
=self
._CurrentLine
,
426 Line
=self
._LineIndex
+ 1
428 def GetValidExpression(self
, TokenSpaceGuid
, PcdCName
):
429 return self
._Table
.GetValidExpression(TokenSpaceGuid
, PcdCName
)
434 Macros
.update(self
._FileLocalMacros
)
435 Macros
.update(self
._GetApplicableSectionMacro
())
438 ## Construct section Macro dict
439 def _ConstructSectionMacroDict(self
, Name
, Value
):
440 ScopeKey
= [(Scope
[0], Scope
[1], Scope
[2]) for Scope
in self
._Scope
]
441 ScopeKey
= tuple(ScopeKey
)
443 # DecParser SectionType is a list, will contain more than one item only in Pcd Section
444 # As Pcd section macro usage is not allowed, so here it is safe
446 if isinstance(self
, DecParser
):
447 SectionDictKey
= self
._SectionType
[0], ScopeKey
449 SectionDictKey
= self
._SectionType
, ScopeKey
451 self
._SectionsMacroDict
[SectionDictKey
][Name
] = Value
453 ## Get section Macros that are applicable to current line, which may come from other sections
454 ## that share the same name while scope is wider
455 def _GetApplicableSectionMacro(self
):
462 ActiveSectionType
= self
._SectionType
463 if isinstance(self
, DecParser
):
464 ActiveSectionType
= self
._SectionType
[0]
466 for (SectionType
, Scope
) in self
._SectionsMacroDict
:
467 if SectionType
!= ActiveSectionType
:
470 for ActiveScope
in self
._Scope
:
471 Scope0
, Scope1
, Scope2
= ActiveScope
[0], ActiveScope
[1], ActiveScope
[2]
472 if(Scope0
, Scope1
, Scope2
) not in Scope
:
475 SpeSpeMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
477 for ActiveScope
in self
._Scope
:
478 Scope0
, Scope1
, Scope2
= ActiveScope
[0], ActiveScope
[1], ActiveScope
[2]
479 if(Scope0
, Scope1
, Scope2
) not in Scope
and (Scope0
, TAB_COMMON
, TAB_COMMON
) not in Scope
and (TAB_COMMON
, Scope1
, TAB_COMMON
) not in Scope
:
482 ComSpeMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
484 if (TAB_COMMON
, TAB_COMMON
, TAB_COMMON
) in Scope
:
485 ComComMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
487 Macros
.update(ComComMacroDict
)
488 Macros
.update(ComSpeMacroDict
)
489 Macros
.update(SpeSpeMacroDict
)
493 def ProcessMultipleLineCODEValue(self
,Content
):
496 continuelinecount
= 0
498 for Index
in range(0, len(Content
)):
499 Line
= Content
[Index
]
501 CODELine
= CODELine
+ Line
502 continuelinecount
+=1
504 newContent
.append(CODELine
)
505 for _
in range(continuelinecount
):
506 newContent
.append("")
509 continuelinecount
= 0
512 newContent
.append(Line
)
514 if "{CODE(" not in Line
:
515 newContent
.append(Line
)
517 elif CODEPattern
.findall(Line
):
518 newContent
.append(Line
)
528 ## INF file parser class
530 # @param FilePath The path of platform description file
531 # @param FileType The raw data of DSC file
532 # @param Table Database used to retrieve module/package information
533 # @param Macros Macros used for replacement in file
535 class InfParser(MetaFileParser
):
536 # INF file supported data types (one type per section)
538 TAB_UNKNOWN
.upper() : MODEL_UNKNOWN
,
539 TAB_INF_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
540 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
541 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
542 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
543 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
544 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
545 TAB_PACKAGES
.upper() : MODEL_META_DATA_PACKAGE
,
546 TAB_NMAKE
.upper() : MODEL_META_DATA_NMAKE
,
547 TAB_INF_FIXED_PCD
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
548 TAB_INF_PATCH_PCD
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
549 TAB_INF_FEATURE_PCD
.upper() : MODEL_PCD_FEATURE_FLAG
,
550 TAB_INF_PCD_EX
.upper() : MODEL_PCD_DYNAMIC_EX
,
551 TAB_INF_PCD
.upper() : MODEL_PCD_DYNAMIC
,
552 TAB_SOURCES
.upper() : MODEL_EFI_SOURCE_FILE
,
553 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
554 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
555 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
556 TAB_DEPEX
.upper() : MODEL_EFI_DEPEX
,
557 TAB_BINARIES
.upper() : MODEL_EFI_BINARY_FILE
,
558 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
561 ## Constructor of InfParser
563 # Initialize object of InfParser
565 # @param FilePath The path of module description file
566 # @param FileType The raw data of DSC file
567 # @param Arch Default Arch value for filtering sections
568 # @param Table Database used to retrieve module/package information
570 def __init__(self
, FilePath
, FileType
, Arch
, Table
):
571 # prevent re-initialization
572 if hasattr(self
, "_Table"):
574 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
)
582 with
open(str(self
.MetaFile
), 'r') as File
:
583 Content
= File
.readlines()
585 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
587 # parse the file line by line
588 IsFindBlockComment
= False
589 GetHeaderComment
= False
594 for Index
in range(0, len(Content
)):
595 # skip empty, commented, block commented lines
596 Line
, Comment
= CleanString2(Content
[Index
], AllowCppStyleComment
=True)
598 if Index
+ 1 < len(Content
):
599 NextLine
, NextComment
= CleanString2(Content
[Index
+ 1])
602 Comments
.append((Comment
, Index
+ 1))
603 elif GetHeaderComment
:
604 SectionComments
.extend(Comments
)
607 if Line
.find(TAB_COMMENT_EDK_START
) > -1:
608 IsFindBlockComment
= True
610 if Line
.find(TAB_COMMENT_EDK_END
) > -1:
611 IsFindBlockComment
= False
613 if IsFindBlockComment
:
616 self
._LineIndex
= Index
617 self
._CurrentLine
= Line
620 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
621 if not GetHeaderComment
:
622 for Cmt
, LNo
in Comments
:
623 self
._Store
(MODEL_META_DATA_HEADER_COMMENT
, Cmt
, '', '', TAB_COMMON
,
624 TAB_COMMON
, self
._Owner
[-1], LNo
, -1, LNo
, -1, 0)
625 GetHeaderComment
= True
627 TailComments
.extend(SectionComments
+ Comments
)
629 self
._SectionHeaderParser
()
630 # Check invalid sections
631 if self
._Version
< 0x00010005:
632 if self
._SectionType
in [MODEL_META_DATA_BUILD_OPTION
,
633 MODEL_EFI_LIBRARY_CLASS
,
634 MODEL_META_DATA_PACKAGE
,
635 MODEL_PCD_FIXED_AT_BUILD
,
636 MODEL_PCD_PATCHABLE_IN_MODULE
,
637 MODEL_PCD_FEATURE_FLAG
,
638 MODEL_PCD_DYNAMIC_EX
,
643 MODEL_META_DATA_USER_EXTENSION
]:
644 EdkLogger
.error('Parser', FORMAT_INVALID
,
645 "Section [%s] is not allowed in inf file without version" % (self
._SectionName
),
646 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
647 elif self
._SectionType
in [MODEL_EFI_INCLUDE
,
648 MODEL_EFI_LIBRARY_INSTANCE
,
649 MODEL_META_DATA_NMAKE
]:
650 EdkLogger
.error('Parser', FORMAT_INVALID
,
651 "Section [%s] is not allowed in inf file with version 0x%08x" % (self
._SectionName
, self
._Version
),
652 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
654 # merge two lines specified by '\' in section NMAKE
655 elif self
._SectionType
== MODEL_META_DATA_NMAKE
:
658 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
661 if NextLine
[0] == TAB_SECTION_START
and NextLine
[-1] == TAB_SECTION_END
:
662 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
665 NmakeLine
= NmakeLine
+ ' ' + Line
[0:-1]
668 self
._CurrentLine
= NmakeLine
+ Line
672 self
._ValueList
= ['', '', '']
673 # parse current line, result will be put in self._ValueList
674 self
._SectionParser
[self
._SectionType
](self
)
675 if self
._ValueList
is None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
680 Comments
.append((Comment
, Index
+ 1))
681 if GlobalData
.gOptions
and GlobalData
.gOptions
.CheckUsage
:
682 CheckInfComment(self
._SectionType
, Comments
, str(self
.MetaFile
), Index
+ 1, self
._ValueList
)
684 # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
685 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
687 for Arch
, Platform
, _
in self
._Scope
:
688 LastItem
= self
._Store
(self
._SectionType
,
701 for Comment
, LineNo
in Comments
:
702 self
._Store
(MODEL_META_DATA_COMMENT
, Comment
, '', '', Arch
, Platform
,
703 LastItem
, LineNo
, -1, LineNo
, -1, 0)
706 TailComments
.extend(SectionComments
+ Comments
)
707 if IsFindBlockComment
:
708 EdkLogger
.error("Parser", FORMAT_INVALID
, "Open block comments (starting with /*) are expected to end with */",
711 # If there are tail comments in INF file, save to database whatever the comments are
712 for Comment
in TailComments
:
713 self
._Store
(MODEL_META_DATA_TAIL_COMMENT
, Comment
[0], '', '', TAB_COMMON
,
714 TAB_COMMON
, self
._Owner
[-1], -1, -1, -1, -1, 0)
717 ## Data parser for the format in which there's path
719 # Only path can have macro used. So we need to replace them before use.
721 def _IncludeParser(self
):
722 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
723 self
._ValueList
[0:len(TokenList
)] = TokenList
724 Macros
= self
._Macros
726 for Index
in range(0, len(self
._ValueList
)):
727 Value
= self
._ValueList
[Index
]
730 self
._ValueList
[Index
] = ReplaceMacro(Value
, Macros
)
732 ## Parse [Sources] section
734 # Only path can have macro used. So we need to replace them before use.
737 def _SourceFileParser(self
):
738 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
739 # Let TokenList[2] be TagName|ToolCode|FeatureFlag
740 if len(TokenList
) > 3:
741 for extraToken
in range(3, len(TokenList
)):
742 TokenList
[2] = TokenList
[2] + '|' + TokenList
[extraToken
]
743 self
._ValueList
[0:len(TokenList
)] = TokenList
744 Macros
= self
._Macros
745 # For Acpi tables, remove macro like ' TABLE_NAME=Sata1'
746 if 'COMPONENT_TYPE' in Macros
:
747 if self
._Defines
['COMPONENT_TYPE'].upper() == 'ACPITABLE':
748 self
._ValueList
[0] = GetSplitValueList(self
._ValueList
[0], ' ', 1)[0]
749 if self
._Defines
['BASE_NAME'] == 'Microcode':
751 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
753 ## Parse [Binaries] section
755 # Only path can have macro used. So we need to replace them before use.
758 def _BinaryFileParser(self
):
759 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 2)
760 if len(TokenList
) < 2:
761 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type or path specified",
762 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
763 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
765 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type specified",
766 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
767 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
769 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file path specified",
770 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
771 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
772 self
._ValueList
[0:len(TokenList
)] = TokenList
773 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
775 ## [nmake] section parser (Edk.x style only)
776 def _NmakeParser(self
):
777 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
778 self
._ValueList
[0:len(TokenList
)] = TokenList
780 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
781 # remove self-reference in macro setting
782 #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
784 ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
786 def _PcdParser(self
):
787 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
788 ValueList
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
789 if len(ValueList
) != 2:
790 EdkLogger
.error('Parser', FORMAT_INVALID
, "Illegal token space GUID and PCD name format",
791 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
792 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
793 self
._ValueList
[0:1] = ValueList
794 if len(TokenList
) > 1:
795 self
._ValueList
[2] = TokenList
[1]
796 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
797 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
798 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
799 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
801 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
802 if self
._ValueList
[2] != '':
803 InfPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
804 if InfPcdValueList
[0] in ['True', 'true', 'TRUE']:
805 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '1', 1)
806 elif InfPcdValueList
[0] in ['False', 'false', 'FALSE']:
807 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '0', 1)
808 elif isinstance(InfPcdValueList
[0], str) and InfPcdValueList
[0].find('$(') >= 0:
809 Value
= ReplaceExprMacro(InfPcdValueList
[0],self
._Macros
)
811 self
._ValueList
[2] = Value
812 if (self
._ValueList
[0], self
._ValueList
[1]) not in self
.PcdsDict
:
813 self
.PcdsDict
[self
._ValueList
[0], self
._ValueList
[1]] = self
._SectionType
814 elif self
.PcdsDict
[self
._ValueList
[0], self
._ValueList
[1]] != self
._SectionType
:
815 EdkLogger
.error('Parser', FORMAT_INVALID
, "It is not permissible to list a specified PCD in different PCD type sections.",
816 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
817 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
819 ## [depex] section parser
821 def _DepexParser(self
):
822 self
._ValueList
[0:1] = [self
._CurrentLine
]
825 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
826 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
827 MODEL_META_DATA_BUILD_OPTION
: MetaFileParser
._BuildOptionParser
,
828 MODEL_EFI_INCLUDE
: _IncludeParser
, # for Edk.x modules
829 MODEL_EFI_LIBRARY_INSTANCE
: MetaFileParser
._CommonParser
, # for Edk.x modules
830 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
831 MODEL_META_DATA_PACKAGE
: MetaFileParser
._PathParser
,
832 MODEL_META_DATA_NMAKE
: _NmakeParser
, # for Edk.x modules
833 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
834 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
835 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
836 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
837 MODEL_PCD_DYNAMIC
: _PcdParser
,
838 MODEL_EFI_SOURCE_FILE
: _SourceFileParser
,
839 MODEL_EFI_GUID
: MetaFileParser
._CommonParser
,
840 MODEL_EFI_PROTOCOL
: MetaFileParser
._CommonParser
,
841 MODEL_EFI_PPI
: MetaFileParser
._CommonParser
,
842 MODEL_EFI_DEPEX
: _DepexParser
,
843 MODEL_EFI_BINARY_FILE
: _BinaryFileParser
,
844 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
847 ## DSC file parser class
849 # @param FilePath The path of platform description file
850 # @param FileType The raw data of DSC file
851 # @param Table Database used to retrieve module/package information
852 # @param Macros Macros used for replacement in file
853 # @param Owner Owner ID (for sub-section parsing)
854 # @param From ID from which the data comes (for !INCLUDE directive)
856 class DscParser(MetaFileParser
):
857 # DSC file supported data types (one type per section)
859 TAB_SKUIDS
.upper() : MODEL_EFI_SKU_ID
,
860 TAB_DEFAULT_STORES
.upper() : MODEL_EFI_DEFAULT_STORES
,
861 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
862 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
863 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
864 TAB_PACKAGES
.upper() : MODEL_META_DATA_PACKAGE
,
865 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
866 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
867 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
868 TAB_PCDS_DYNAMIC_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_DEFAULT
,
869 TAB_PCDS_DYNAMIC_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_HII
,
870 TAB_PCDS_DYNAMIC_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_VPD
,
871 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT
,
872 TAB_PCDS_DYNAMIC_EX_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_HII
,
873 TAB_PCDS_DYNAMIC_EX_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_VPD
,
874 TAB_COMPONENTS
.upper() : MODEL_META_DATA_COMPONENT
,
875 TAB_DSC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
876 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
877 TAB_DSC_DEFINES_EDKGLOBAL
: MODEL_META_DATA_GLOBAL_DEFINE
,
878 TAB_INCLUDE
.upper() : MODEL_META_DATA_INCLUDE
,
879 TAB_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
880 TAB_IF_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
881 TAB_IF_N_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
,
882 TAB_ELSE_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
,
883 TAB_ELSE
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
,
884 TAB_END_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
,
885 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
,
886 TAB_ERROR
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR
,
889 # Valid names in define section
896 "PCD_INFO_GENERATION",
897 "PCD_VAR_CHECK_GENERATION",
898 "SUPPORTED_ARCHITECTURES",
907 "FIX_LOAD_TOP_MEMORY_ADDRESS",
912 SubSectionDefineKeywords
= [
916 SymbolPattern
= ValueExpression
.SymbolPattern
918 IncludedFiles
= set()
920 ## Constructor of DscParser
922 # Initialize object of DscParser
924 # @param FilePath The path of platform description file
925 # @param FileType The raw data of DSC file
926 # @param Arch Default Arch value for filtering sections
927 # @param Table Database used to retrieve module/package information
928 # @param Owner Owner ID (for sub-section parsing)
929 # @param From ID from which the data comes (for !INCLUDE directive)
931 def __init__(self
, FilePath
, FileType
, Arch
, Table
, Owner
= -1, From
= -1):
932 # prevent re-initialization
933 if hasattr(self
, "_Table") and self
._Table
is Table
:
935 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
, Owner
, From
)
936 self
._Version
= 0x00010005 # Only EDK2 dsc file is supported
937 # to store conditional directive evaluation result
938 self
._DirectiveStack
= []
939 self
._DirectiveEvalStack
= []
943 # Specify whether current line is in uncertain condition
945 self
._InDirective
= -1
947 # Final valid replacable symbols
950 # Map the ID between the original table and new table to track
953 self
._IdMapping
= {-1:-1}
961 with
open(str(self
.MetaFile
), 'r') as File
:
962 Content
= File
.readlines()
964 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
968 Content
= self
.ProcessMultipleLineCODEValue(Content
)
970 for Index
in range(0, len(Content
)):
971 Line
= CleanString(Content
[Index
])
976 self
._CurrentLine
= Line
977 self
._LineIndex
= Index
978 if self
._InSubsection
and self
._Owner
[-1] == -1:
979 self
._Owner
.append(self
._LastItem
)
982 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
983 self
._SectionType
= MODEL_META_DATA_SECTION_HEADER
985 elif Line
[0] == '}' and self
._InSubsection
:
986 self
._InSubsection
= False
987 self
._SubsectionType
= MODEL_UNKNOWN
988 self
._SubsectionName
= ''
993 elif Line
[0] == TAB_OPTION_START
and Line
[-1] == TAB_OPTION_END
:
994 self
._SubsectionType
= MODEL_META_DATA_SUBSECTION_HEADER
997 TokenList
= GetSplitValueList(Line
, ' ', 1)
998 if TokenList
[0] == TAB_INCLUDE
:
999 for Arch
, ModuleType
, DefaultStore
in self
._Scope
:
1000 if self
._SubsectionType
!= MODEL_UNKNOWN
and Arch
in OwnerId
:
1001 self
._Owner
[-1] = OwnerId
[Arch
]
1002 self
._DirectiveParser
()
1004 self
._DirectiveParser
()
1006 if Line
[0] == TAB_OPTION_START
and not self
._InSubsection
:
1007 EdkLogger
.error("Parser", FILE_READ_FAILURE
, "Missing the '{' before %s in Line %s" % (Line
, Index
+1), ExtraData
=self
.MetaFile
)
1009 if self
._InSubsection
:
1010 SectionType
= self
._SubsectionType
1012 SectionType
= self
._SectionType
1013 self
._ItemType
= SectionType
1015 self
._ValueList
= ['', '', '']
1016 # "SET pcd = pcd_expression" syntax is not supported in Dsc file.
1017 if self
._CurrentLine
.upper().strip().startswith("SET "):
1018 EdkLogger
.error('Parser', FORMAT_INVALID
, '''"SET pcd = pcd_expression" syntax is not support in Dsc file''',
1019 ExtraData
=self
._CurrentLine
,
1020 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1021 self
._SectionParser
[SectionType
](self
)
1022 if self
._ValueList
is None:
1025 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
1026 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
1028 for Arch
, ModuleType
, DefaultStore
in self
._Scope
:
1029 Owner
= self
._Owner
[-1]
1030 if self
._SubsectionType
!= MODEL_UNKNOWN
and Arch
in OwnerId
:
1031 Owner
= OwnerId
[Arch
]
1032 self
._LastItem
= self
._Store
(
1042 self
._LineIndex
+ 1,
1044 self
._LineIndex
+ 1,
1048 if self
._SubsectionType
== MODEL_UNKNOWN
and self
._InSubsection
:
1049 OwnerId
[Arch
] = self
._LastItem
1051 if self
._DirectiveStack
:
1052 Type
, Line
, Text
= self
._DirectiveStack
[-1]
1053 EdkLogger
.error('Parser', FORMAT_INVALID
, "No matching '!endif' found",
1054 ExtraData
=Text
, File
=self
.MetaFile
, Line
=Line
)
1057 ## <subsection_header> parser
1058 def _SubsectionHeaderParser(self
):
1059 self
._SubsectionName
= self
._CurrentLine
[1:-1].upper()
1060 if self
._SubsectionName
in self
.DataType
:
1061 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
1063 self
._SubsectionType
= MODEL_UNKNOWN
1064 EdkLogger
.warn("Parser", "Unrecognized sub-section", File
=self
.MetaFile
,
1065 Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1066 self
._ValueList
[0] = self
._SubsectionName
1068 ## Directive statement parser
1069 def _DirectiveParser(self
):
1070 self
._ValueList
= ['', '', '']
1071 TokenList
= GetSplitValueList(self
._CurrentLine
, ' ', 1)
1072 self
._ValueList
[0:len(TokenList
)] = TokenList
1075 DirectiveName
= self
._ValueList
[0].upper()
1076 if DirectiveName
not in self
.DataType
:
1077 EdkLogger
.error("Parser", FORMAT_INVALID
, "Unknown directive [%s]" % DirectiveName
,
1078 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1080 if DirectiveName
in ['!IF', '!IFDEF', '!IFNDEF']:
1081 self
._InDirective
+= 1
1083 if DirectiveName
in ['!ENDIF']:
1084 self
._InDirective
-= 1
1086 if DirectiveName
in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self
._ValueList
[1] == '':
1087 EdkLogger
.error("Parser", FORMAT_INVALID
, "Missing expression",
1088 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1089 ExtraData
=self
._CurrentLine
)
1091 ItemType
= self
.DataType
[DirectiveName
]
1092 Scope
= [[TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]]
1093 if ItemType
== MODEL_META_DATA_INCLUDE
:
1095 elif ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR
:
1097 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1098 # Remove all directives between !if and !endif, including themselves
1099 while self
._DirectiveStack
:
1100 # Remove any !else or !elseif
1101 DirectiveInfo
= self
._DirectiveStack
.pop()
1102 if DirectiveInfo
[0] in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1103 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1104 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1107 EdkLogger
.error("Parser", FORMAT_INVALID
, "Redundant '!endif'",
1108 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1109 ExtraData
=self
._CurrentLine
)
1110 elif ItemType
not in {MODEL_META_DATA_INCLUDE
, MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR
}:
1111 # Break if there's a !else is followed by a !elseif
1112 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
and \
1113 self
._DirectiveStack
and \
1114 self
._DirectiveStack
[-1][0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1115 EdkLogger
.error("Parser", FORMAT_INVALID
, "'!elseif' after '!else'",
1116 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1117 ExtraData
=self
._CurrentLine
)
1118 self
._DirectiveStack
.append((ItemType
, self
._LineIndex
+ 1, self
._CurrentLine
))
1121 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
1122 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
1124 for Arch
, ModuleType
, DefaultStore
in Scope
:
1125 self
._LastItem
= self
._Store
(
1135 self
._LineIndex
+ 1,
1137 self
._LineIndex
+ 1,
1142 ## [defines] section parser
1144 def _DefineParser(self
):
1145 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1146 self
._ValueList
[1:len(TokenList
)] = TokenList
1149 if not self
._ValueList
[1]:
1150 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
1151 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1152 if not self
._ValueList
[2]:
1153 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
1154 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1155 if (not self
._ValueList
[1] in self
.DefineKeywords
and
1156 (self
._InSubsection
and self
._ValueList
[1] not in self
.SubSectionDefineKeywords
)):
1157 EdkLogger
.error('Parser', FORMAT_INVALID
,
1158 "Unknown keyword found: %s. "
1159 "If this is a macro you must "
1160 "add it as a DEFINE in the DSC" % self
._ValueList
[1],
1161 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1162 if not self
._InSubsection
:
1163 self
._Defines
[self
._ValueList
[1]] = self
._ValueList
[2]
1164 self
._ItemType
= self
.DataType
[TAB_DSC_DEFINES
.upper()]
1167 def _SkuIdParser(self
):
1168 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1169 if len(TokenList
) not in (2, 3):
1170 EdkLogger
.error('Parser', FORMAT_INVALID
, "Correct format is '<Number>|<UiName>[|<UiName>]'",
1171 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1172 self
._ValueList
[0:len(TokenList
)] = TokenList
1174 def _DefaultStoresParser(self
):
1175 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1176 if len(TokenList
) != 2:
1177 EdkLogger
.error('Parser', FORMAT_INVALID
, "Correct format is '<Number>|<UiName>'",
1178 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1179 self
._ValueList
[0:len(TokenList
)] = TokenList
1181 ## Parse Edk style of library modules
1183 def _LibraryInstanceParser(self
):
1184 self
._ValueList
[0] = self
._CurrentLine
1187 def _DecodeCODEData(self
):
1189 ## PCD sections parser
1191 # [PcdsFixedAtBuild]
1192 # [PcdsPatchableInModule]
1195 # [PcdsDynamicExDefault]
1196 # [PcdsDynamicExVpd]
1197 # [PcdsDynamicExHii]
1199 # [PcdsDynamicDefault]
1204 def _PcdParser(self
):
1205 if self
._PcdDataTypeCODE
:
1206 self
._PcdCodeValue
= self
._PcdCodeValue
+ "\n " + self
._CurrentLine
1207 if self
._CurrentLine
.endswith(")}"):
1208 self
._CurrentLine
= "|".join((self
._CurrentPcdName
, self
._PcdCodeValue
))
1209 self
._PcdDataTypeCODE
= False
1210 self
._PcdCodeValue
= ""
1212 self
._ValueList
= None
1214 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1215 self
._CurrentPcdName
= TokenList
[0]
1216 if len(TokenList
) == 2 and TokenList
[1].strip().startswith("{CODE"):
1217 self
._PcdDataTypeCODE
= True
1218 self
._PcdCodeValue
= TokenList
[1].strip()
1220 if self
._PcdDataTypeCODE
:
1221 if self
._CurrentLine
.endswith(")}"):
1222 self
._PcdDataTypeCODE
= False
1223 self
._PcdCodeValue
= ""
1225 self
._ValueList
= None
1227 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1228 PcdNameTockens
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1229 if len(PcdNameTockens
) == 2:
1230 self
._ValueList
[0], self
._ValueList
[1] = PcdNameTockens
[0], PcdNameTockens
[1]
1231 elif len(PcdNameTockens
) == 3:
1232 self
._ValueList
[0], self
._ValueList
[1] = ".".join((PcdNameTockens
[0], PcdNameTockens
[1])), PcdNameTockens
[2]
1233 elif len(PcdNameTockens
) > 3:
1234 self
._ValueList
[0], self
._ValueList
[1] = ".".join((PcdNameTockens
[0], PcdNameTockens
[1])), ".".join(PcdNameTockens
[2:])
1235 if len(TokenList
) == 2:
1236 self
._ValueList
[2] = TokenList
[1]
1237 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1238 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1239 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1240 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1241 if self
._ValueList
[2] == '':
1243 # The PCD values are optional for FIXEDATBUILD, PATCHABLEINMODULE, Dynamic/DynamicEx default
1245 if self
._SectionType
in (MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
):
1247 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD value given",
1248 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1249 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1251 # Validate the datum type of Dynamic Defaul PCD and DynamicEx Default PCD
1252 ValueList
= GetSplitValueList(self
._ValueList
[2])
1253 if len(ValueList
) > 1 and ValueList
[1] in [TAB_UINT8
, TAB_UINT16
, TAB_UINT32
, TAB_UINT64
] \
1254 and self
._ItemType
in [MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
]:
1255 EdkLogger
.error('Parser', FORMAT_INVALID
, "The datum type '%s' of PCD is wrong" % ValueList
[1],
1256 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1258 # Validate the VariableName of DynamicHii and DynamicExHii for PCD Entry must not be an empty string
1259 if self
._ItemType
in [MODEL_PCD_DYNAMIC_HII
, MODEL_PCD_DYNAMIC_EX_HII
]:
1260 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
1261 if len(DscPcdValueList
[0].replace('L', '').replace('"', '').strip()) == 0:
1262 EdkLogger
.error('Parser', FORMAT_INVALID
, "The VariableName field in the HII format PCD entry must not be an empty string",
1263 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1265 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
1266 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
1267 if DscPcdValueList
[0] in ['True', 'true', 'TRUE']:
1268 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '1', 1);
1269 elif DscPcdValueList
[0] in ['False', 'false', 'FALSE']:
1270 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '0', 1);
1273 ## [components] section parser
1275 def _ComponentParser(self
):
1276 if self
._CurrentLine
[-1] == '{':
1277 self
._ValueList
[0] = self
._CurrentLine
[0:-1].strip()
1278 self
._InSubsection
= True
1279 self
._SubsectionType
= MODEL_UNKNOWN
1281 self
._ValueList
[0] = self
._CurrentLine
1283 ## [LibraryClasses] section
1285 def _LibraryClassParser(self
):
1286 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1287 if len(TokenList
) < 2:
1288 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class or instance specified",
1289 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1290 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1291 if TokenList
[0] == '':
1292 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class specified",
1293 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1294 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1295 if TokenList
[1] == '':
1296 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library instance specified",
1297 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1298 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1300 self
._ValueList
[0:len(TokenList
)] = TokenList
1303 ## [BuildOptions] section parser
1305 def _BuildOptionParser(self
):
1306 self
._CurrentLine
= CleanString(self
._CurrentLine
, BuildOption
=True)
1307 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1308 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
1309 if len(TokenList2
) == 2:
1310 self
._ValueList
[0] = TokenList2
[0] # toolchain family
1311 self
._ValueList
[1] = TokenList2
[1] # keys
1313 self
._ValueList
[1] = TokenList
[0]
1314 if len(TokenList
) == 2: # value
1315 self
._ValueList
[2] = TokenList
[1]
1317 if self
._ValueList
[1].count('_') != 4:
1321 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
1322 ExtraData
=self
._CurrentLine
,
1324 Line
=self
._LineIndex
+ 1
1327 ## Override parent's method since we'll do all macro replacements in parser
1331 Macros
.update(self
._FileLocalMacros
)
1332 Macros
.update(self
._GetApplicableSectionMacro
())
1333 Macros
.update(GlobalData
.gEdkGlobal
)
1334 Macros
.update(GlobalData
.gPlatformDefines
)
1335 Macros
.update(GlobalData
.gCommandLineDefines
)
1336 # PCD cannot be referenced in macro definition
1337 if self
._ItemType
not in [MODEL_META_DATA_DEFINE
, MODEL_META_DATA_GLOBAL_DEFINE
]:
1338 Macros
.update(self
._Symbols
)
1339 if GlobalData
.BuildOptionPcd
:
1340 for Item
in GlobalData
.BuildOptionPcd
:
1341 if isinstance(Item
, tuple):
1343 PcdName
, TmpValue
= Item
.split("=")
1344 TmpValue
= BuildOptionValue(TmpValue
, self
._GuidDict
)
1345 Macros
[PcdName
.strip()] = TmpValue
1348 def _PostProcess(self
):
1350 MODEL_META_DATA_SECTION_HEADER
: self
.__ProcessSectionHeader
,
1351 MODEL_META_DATA_SUBSECTION_HEADER
: self
.__ProcessSubsectionHeader
,
1352 MODEL_META_DATA_HEADER
: self
.__ProcessDefine
,
1353 MODEL_META_DATA_DEFINE
: self
.__ProcessDefine
,
1354 MODEL_META_DATA_GLOBAL_DEFINE
: self
.__ProcessDefine
,
1355 MODEL_META_DATA_INCLUDE
: self
.__ProcessDirective
,
1356 MODEL_META_DATA_PACKAGE
: self
.__ProcessPackages
,
1357 MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
: self
.__ProcessDirective
,
1358 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
: self
.__ProcessDirective
,
1359 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
: self
.__ProcessDirective
,
1360 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
: self
.__ProcessDirective
,
1361 MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
: self
.__ProcessDirective
,
1362 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
: self
.__ProcessDirective
,
1363 MODEL_EFI_SKU_ID
: self
.__ProcessSkuId
,
1364 MODEL_EFI_DEFAULT_STORES
: self
.__ProcessDefaultStores
,
1365 MODEL_EFI_LIBRARY_INSTANCE
: self
.__ProcessLibraryInstance
,
1366 MODEL_EFI_LIBRARY_CLASS
: self
.__ProcessLibraryClass
,
1367 MODEL_PCD_FIXED_AT_BUILD
: self
.__ProcessPcd
,
1368 MODEL_PCD_PATCHABLE_IN_MODULE
: self
.__ProcessPcd
,
1369 MODEL_PCD_FEATURE_FLAG
: self
.__ProcessPcd
,
1370 MODEL_PCD_DYNAMIC_DEFAULT
: self
.__ProcessPcd
,
1371 MODEL_PCD_DYNAMIC_HII
: self
.__ProcessPcd
,
1372 MODEL_PCD_DYNAMIC_VPD
: self
.__ProcessPcd
,
1373 MODEL_PCD_DYNAMIC_EX_DEFAULT
: self
.__ProcessPcd
,
1374 MODEL_PCD_DYNAMIC_EX_HII
: self
.__ProcessPcd
,
1375 MODEL_PCD_DYNAMIC_EX_VPD
: self
.__ProcessPcd
,
1376 MODEL_META_DATA_COMPONENT
: self
.__ProcessComponent
,
1377 MODEL_META_DATA_BUILD_OPTION
: self
.__ProcessBuildOption
,
1378 MODEL_UNKNOWN
: self
._Skip
,
1379 MODEL_META_DATA_USER_EXTENSION
: self
._SkipUserExtension
,
1380 MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR
: self
._ProcessError
,
1383 self
._Table
= MetaFileStorage(self
._RawTable
.DB
, self
.MetaFile
, MODEL_FILE_DSC
, True)
1384 self
._DirectiveStack
= []
1385 self
._DirectiveEvalStack
= []
1386 self
._FileWithError
= self
.MetaFile
1387 self
._FileLocalMacros
= {}
1388 self
._SectionsMacroDict
.clear()
1389 GlobalData
.gPlatformDefines
= {}
1391 # Get all macro and PCD which has straitforward value
1392 self
.__RetrievePcdValue
()
1393 self
._Content
= self
._RawTable
.GetAll()
1394 self
._ContentIndex
= 0
1395 self
._InSubsection
= False
1396 while self
._ContentIndex
< len(self
._Content
) :
1397 Id
, self
._ItemType
, V1
, V2
, V3
, S1
, S2
, S3
, Owner
, self
._From
, \
1398 LineStart
, ColStart
, LineEnd
, ColEnd
, Enabled
= self
._Content
[self
._ContentIndex
]
1401 self
._FileWithError
= self
.MetaFile
1403 self
._ContentIndex
+= 1
1405 self
._Scope
= [[S1
, S2
, S3
]]
1407 # For !include directive, handle it specially,
1408 # merge arch and module type in case of duplicate items
1410 while self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1411 if self
._ContentIndex
>= len(self
._Content
):
1413 Record
= self
._Content
[self
._ContentIndex
]
1414 if LineStart
== Record
[10] and LineEnd
== Record
[12]:
1415 if [Record
[5], Record
[6], Record
[7]] not in self
._Scope
:
1416 self
._Scope
.append([Record
[5], Record
[6], Record
[7]])
1417 self
._ContentIndex
+= 1
1421 self
._LineIndex
= LineStart
- 1
1422 self
._ValueList
= [V1
, V2
, V3
]
1424 if Owner
> 0 and Owner
in self
._IdMapping
:
1425 self
._InSubsection
= True
1427 self
._InSubsection
= False
1429 Processer
[self
._ItemType
]()
1430 except EvaluationException
as Excpt
:
1432 # Only catch expression evaluation error here. We need to report
1433 # the precise number of line on which the error occurred
1435 if hasattr(Excpt
, 'Pcd'):
1436 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
1437 Info
= GlobalData
.gPlatformOtherPcds
[Excpt
.Pcd
]
1438 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
1439 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
1440 " of the DSC file, and it is currently defined in this section:"
1441 " %s, line #: %d." % (Excpt
.Pcd
, Info
[0], Info
[1]),
1442 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1443 Line
=self
._LineIndex
+ 1)
1445 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
1446 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1447 Line
=self
._LineIndex
+ 1)
1449 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
1450 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1451 Line
=self
._LineIndex
+ 1)
1452 except MacroException
as Excpt
:
1453 EdkLogger
.error('Parser', FORMAT_INVALID
, str(Excpt
),
1454 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1455 Line
=self
._LineIndex
+ 1)
1457 if self
._ValueList
is None:
1460 NewOwner
= self
._IdMapping
.get(Owner
, -1)
1461 self
._Enabled
= int((not self
._DirectiveEvalStack
) or (False not in self
._DirectiveEvalStack
))
1462 self
._LastItem
= self
._Store
(
1472 self
._LineIndex
+ 1,
1474 self
._LineIndex
+ 1,
1478 self
._IdMapping
[Id
] = self
._LastItem
1480 GlobalData
.gPlatformDefines
.update(self
._FileLocalMacros
)
1481 self
._PostProcessed
= True
1482 self
._Content
= None
1483 def _ProcessError(self
):
1484 if not self
._Enabled
:
1486 EdkLogger
.error('Parser', ERROR_STATEMENT
, self
._ValueList
[1], File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1488 def __ProcessSectionHeader(self
):
1489 self
._SectionName
= self
._ValueList
[0]
1490 if self
._SectionName
in self
.DataType
:
1491 self
._SectionType
= self
.DataType
[self
._SectionName
]
1493 self
._SectionType
= MODEL_UNKNOWN
1495 def __ProcessSubsectionHeader(self
):
1496 self
._SubsectionName
= self
._ValueList
[0]
1497 if self
._SubsectionName
in self
.DataType
:
1498 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
1500 self
._SubsectionType
= MODEL_UNKNOWN
1502 def __RetrievePcdValue(self
):
1504 with
open(str(self
.MetaFile
), 'r') as File
:
1505 Content
= File
.readlines()
1507 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
1509 GlobalData
.gPlatformOtherPcds
['DSCFILE'] = str(self
.MetaFile
)
1510 for PcdType
in (MODEL_PCD_PATCHABLE_IN_MODULE
, MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_HII
,
1511 MODEL_PCD_DYNAMIC_VPD
, MODEL_PCD_DYNAMIC_EX_DEFAULT
, MODEL_PCD_DYNAMIC_EX_HII
,
1512 MODEL_PCD_DYNAMIC_EX_VPD
):
1513 Records
= self
._RawTable
.Query(PcdType
, BelongsToItem
= -1.0)
1514 for TokenSpaceGuid
, PcdName
, Value
, Dummy2
, Dummy3
, Dummy4
, ID
, Line
in Records
:
1515 Name
= TokenSpaceGuid
+ '.' + PcdName
1516 if Name
not in GlobalData
.gPlatformOtherPcds
:
1518 while not Content
[Line
- 1].lstrip().startswith(TAB_SECTION_START
):
1520 GlobalData
.gPlatformOtherPcds
[Name
] = (CleanString(Content
[Line
- 1]), PcdLine
, PcdType
)
1522 def __ProcessDefine(self
):
1523 if not self
._Enabled
:
1526 Type
, Name
, Value
= self
._ValueList
1527 Value
= ReplaceMacro(Value
, self
._Macros
, False)
1529 # If it is <Defines>, return
1531 if self
._InSubsection
:
1532 self
._ValueList
= [Type
, Name
, Value
]
1535 if self
._ItemType
== MODEL_META_DATA_DEFINE
:
1536 if self
._SectionType
== MODEL_META_DATA_HEADER
:
1537 self
._FileLocalMacros
[Name
] = Value
1539 self
._ConstructSectionMacroDict
(Name
, Value
)
1540 elif self
._ItemType
== MODEL_META_DATA_GLOBAL_DEFINE
:
1541 GlobalData
.gEdkGlobal
[Name
] = Value
1544 # Keyword in [Defines] section can be used as Macros
1546 if (self
._ItemType
== MODEL_META_DATA_HEADER
) and (self
._SectionType
== MODEL_META_DATA_HEADER
):
1547 self
._FileLocalMacros
[Name
] = Value
1549 self
._ValueList
= [Type
, Name
, Value
]
1551 def __ProcessDirective(self
):
1553 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1554 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
]:
1555 Macros
= self
._Macros
1556 Macros
.update(GlobalData
.gGlobalDefines
)
1558 Result
= ValueExpression(self
._ValueList
[1], Macros
)()
1559 except SymbolNotFound
as Exc
:
1560 EdkLogger
.debug(EdkLogger
.DEBUG_5
, str(Exc
), self
._ValueList
[1])
1562 except WrnExpression
as Excpt
:
1564 # Catch expression evaluation warning here. We need to report
1565 # the precise number of line and return the evaluation result
1567 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
1568 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1569 Line
=self
._LineIndex
+ 1)
1570 Result
= Excpt
.result
1572 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1573 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1574 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1575 self
._DirectiveStack
.append(self
._ItemType
)
1576 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
:
1577 Result
= bool(Result
)
1579 Macro
= self
._ValueList
[1]
1580 Macro
= Macro
[2:-1] if (Macro
.startswith("$(") and Macro
.endswith(")")) else Macro
1581 Result
= Macro
in self
._Macros
1582 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
:
1584 self
._DirectiveEvalStack
.append(Result
)
1585 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
:
1586 self
._DirectiveStack
.append(self
._ItemType
)
1587 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1588 self
._DirectiveEvalStack
.append(bool(Result
))
1589 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1590 self
._DirectiveStack
.append(self
._ItemType
)
1591 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1592 self
._DirectiveEvalStack
.append(True)
1593 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1594 # Back to the nearest !if/!ifdef/!ifndef
1595 while self
._DirectiveStack
:
1596 self
._DirectiveEvalStack
.pop()
1597 Directive
= self
._DirectiveStack
.pop()
1598 if Directive
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1599 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1600 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1602 elif self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1603 # The included file must be relative to workspace or same directory as DSC file
1604 __IncludeMacros
= {}
1606 # Allow using system environment variables in path after !include
1608 __IncludeMacros
['WORKSPACE'] = GlobalData
.gGlobalDefines
['WORKSPACE']
1610 # Allow using MACROs comes from [Defines] section to keep compatible.
1612 __IncludeMacros
.update(self
._Macros
)
1614 IncludedFile
= NormPath(ReplaceMacro(self
._ValueList
[1], __IncludeMacros
, RaiseError
=True))
1616 # First search the include file under the same directory as DSC file
1618 IncludedFile1
= PathClass(IncludedFile
, self
.MetaFile
.Dir
)
1620 ErrorCode
, ErrorInfo1
= IncludedFile1
.Validate()
1623 # Also search file under the WORKSPACE directory
1625 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
1626 ErrorCode
, ErrorInfo2
= IncludedFile1
.Validate()
1628 EdkLogger
.error('parser', ErrorCode
, File
=self
._FileWithError
,
1629 Line
=self
._LineIndex
+ 1, ExtraData
=ErrorInfo1
+ "\n" + ErrorInfo2
)
1631 self
._FileWithError
= IncludedFile1
1633 FromItem
= self
._Content
[self
._ContentIndex
- 1][0]
1634 if self
._InSubsection
:
1635 Owner
= self
._Content
[self
._ContentIndex
- 1][8]
1637 Owner
= self
._Content
[self
._ContentIndex
- 1][0]
1638 IncludedFileTable
= MetaFileStorage(self
._RawTable
.DB
, IncludedFile1
, MODEL_FILE_DSC
, False, FromItem
=FromItem
)
1639 Parser
= DscParser(IncludedFile1
, self
._FileType
, self
._Arch
, IncludedFileTable
,
1640 Owner
=Owner
, From
=FromItem
)
1642 self
.IncludedFiles
.add (IncludedFile1
)
1644 # set the parser status with current status
1645 Parser
._SectionName
= self
._SectionName
1646 Parser
._SubsectionType
= self
._SubsectionType
1647 Parser
._InSubsection
= self
._InSubsection
1648 Parser
._SectionType
= self
._SectionType
1649 Parser
._Scope
= self
._Scope
1650 Parser
._Enabled
= self
._Enabled
1651 # Parse the included file
1653 # Insert all records in the table for the included file into dsc file table
1654 Records
= IncludedFileTable
.GetAll()
1656 self
._Content
[self
._ContentIndex
:self
._ContentIndex
] = Records
1657 self
._Content
.pop(self
._ContentIndex
- 1)
1658 self
._ValueList
= None
1659 self
._ContentIndex
-= 1
1661 def __ProcessPackages(self
):
1662 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1664 def __ProcessSkuId(self
):
1665 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=True)
1666 for Value
in self
._ValueList
]
1667 def __ProcessDefaultStores(self
):
1668 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=True)
1669 for Value
in self
._ValueList
]
1671 def __ProcessLibraryInstance(self
):
1672 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
1674 def __ProcessLibraryClass(self
):
1675 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
, RaiseError
=True)
1677 def __ProcessPcd(self
):
1678 if self
._ItemType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
1679 self
._ValueList
[2] = ReplaceMacro(self
._ValueList
[2], self
._Macros
, RaiseError
=True)
1682 ValList
, Valid
, Index
= AnalyzeDscPcd(self
._ValueList
[2], self
._ItemType
)
1684 if self
._ItemType
in (MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
, MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
):
1685 if ValList
[1] != TAB_VOID
and StructPattern
.match(ValList
[1]) is None and ValList
[2]:
1686 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect. The datum type info should be VOID* or a valid struct name.", File
=self
._FileWithError
,
1687 Line
=self
._LineIndex
+ 1, ExtraData
="%s.%s|%s" % (self
._ValueList
[0], self
._ValueList
[1], self
._ValueList
[2]))
1688 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
._FileWithError
, Line
=self
._LineIndex
+ 1,
1689 ExtraData
="%s.%s|%s" % (self
._ValueList
[0], self
._ValueList
[1], self
._ValueList
[2]))
1690 PcdValue
= ValList
[Index
]
1691 if PcdValue
and "." not in self
._ValueList
[0]:
1693 ValList
[Index
] = ValueExpression(PcdValue
, self
._Macros
)(True)
1694 except WrnExpression
as Value
:
1695 ValList
[Index
] = Value
.result
1699 if ValList
[Index
] == 'True':
1700 ValList
[Index
] = '1'
1701 if ValList
[Index
] == 'False':
1702 ValList
[Index
] = '0'
1704 if (not self
._DirectiveEvalStack
) or (False not in self
._DirectiveEvalStack
):
1705 GlobalData
.gPlatformPcds
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = PcdValue
1706 self
._Symbols
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = PcdValue
1708 self
._ValueList
[2] = '|'.join(ValList
)
1712 def __ProcessComponent(self
):
1713 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1715 def __ProcessBuildOption(self
):
1716 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=False)
1717 for Value
in self
._ValueList
]
1719 def DisableOverrideComponent(self
,module_id
):
1720 for ori_id
in self
._IdMapping
:
1721 if self
._IdMapping
[ori_id
] == module_id
:
1722 self
._RawTable
.DisableComponent(ori_id
)
1725 MODEL_META_DATA_HEADER
: _DefineParser
,
1726 MODEL_EFI_SKU_ID
: _SkuIdParser
,
1727 MODEL_EFI_DEFAULT_STORES
: _DefaultStoresParser
,
1728 MODEL_EFI_LIBRARY_INSTANCE
: _LibraryInstanceParser
,
1729 MODEL_EFI_LIBRARY_CLASS
: _LibraryClassParser
,
1730 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1731 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1732 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1733 MODEL_PCD_DYNAMIC_DEFAULT
: _PcdParser
,
1734 MODEL_PCD_DYNAMIC_HII
: _PcdParser
,
1735 MODEL_PCD_DYNAMIC_VPD
: _PcdParser
,
1736 MODEL_PCD_DYNAMIC_EX_DEFAULT
: _PcdParser
,
1737 MODEL_PCD_DYNAMIC_EX_HII
: _PcdParser
,
1738 MODEL_PCD_DYNAMIC_EX_VPD
: _PcdParser
,
1739 MODEL_META_DATA_COMPONENT
: _ComponentParser
,
1740 MODEL_META_DATA_BUILD_OPTION
: _BuildOptionParser
,
1741 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1742 MODEL_META_DATA_PACKAGE
: MetaFileParser
._PackageParser
,
1743 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
1744 MODEL_META_DATA_SECTION_HEADER
: MetaFileParser
._SectionHeaderParser
,
1745 MODEL_META_DATA_SUBSECTION_HEADER
: _SubsectionHeaderParser
,
1748 ## DEC file parser class
1750 # @param FilePath The path of platform description file
1751 # @param FileType The raw data of DSC file
1752 # @param Table Database used to retrieve module/package information
1753 # @param Macros Macros used for replacement in file
1755 class DecParser(MetaFileParser
):
1756 # DEC file supported data types (one type per section)
1758 TAB_DEC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
1759 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
1760 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
1761 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
1762 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
1763 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
1764 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
1765 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
1766 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
1767 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
1768 TAB_PCDS_DYNAMIC_NULL
.upper() : MODEL_PCD_DYNAMIC
,
1769 TAB_PCDS_DYNAMIC_EX_NULL
.upper() : MODEL_PCD_DYNAMIC_EX
,
1770 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
,
1773 ## Constructor of DecParser
1775 # Initialize object of DecParser
1777 # @param FilePath The path of platform description file
1778 # @param FileType The raw data of DSC file
1779 # @param Arch Default Arch value for filtering sections
1780 # @param Table Database used to retrieve module/package information
1782 def __init__(self
, FilePath
, FileType
, Arch
, Table
):
1783 # prevent re-initialization
1784 if hasattr(self
, "_Table"):
1786 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
, -1)
1788 self
._Version
= 0x00010005 # Only EDK2 dec file is supported
1789 self
._AllPCDs
= [] # Only for check duplicate PCD
1790 self
._AllPcdDict
= {}
1792 self
._CurrentStructurePcdName
= ""
1793 self
._include
_flag
= False
1794 self
._package
_flag
= False
1796 self
._RestofValue
= ""
1802 with
open(str(self
.MetaFile
), 'r') as File
:
1803 Content
= File
.readlines()
1805 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
1807 Content
= self
.ProcessMultipleLineCODEValue(Content
)
1809 self
._DefinesCount
= 0
1810 for Index
in range(0, len(Content
)):
1811 Line
, Comment
= CleanString2(Content
[Index
])
1812 self
._CurrentLine
= Line
1813 self
._LineIndex
= Index
1815 # save comment for later use
1817 self
._Comments
.append((Comment
, self
._LineIndex
+ 1))
1823 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
1824 self
._SectionHeaderParser
()
1825 if self
._SectionName
== TAB_DEC_DEFINES
.upper():
1826 self
._DefinesCount
+= 1
1829 if self
._SectionType
== MODEL_UNKNOWN
:
1830 EdkLogger
.error("Parser", FORMAT_INVALID
,
1832 "Not able to determine \"%s\" in which section."%self
._CurrentLine
,
1833 self
.MetaFile
, self
._LineIndex
+ 1)
1834 elif len(self
._SectionType
) == 0:
1839 self
._ValueList
= ['', '', '']
1840 self
._SectionParser
[self
._SectionType
[0]](self
)
1841 if self
._ValueList
is None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
1847 # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,
1848 # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1
1850 for Arch
, ModuleType
, Type
in self
._Scope
:
1851 self
._LastItem
= self
._Store
(
1859 self
._LineIndex
+ 1,
1861 self
._LineIndex
+ 1,
1865 for Comment
, LineNo
in self
._Comments
:
1867 MODEL_META_DATA_COMMENT
,
1881 if self
._DefinesCount
> 1:
1882 EdkLogger
.error('Parser', FORMAT_INVALID
, 'Multiple [Defines] section is exist.', self
.MetaFile
)
1883 if self
._DefinesCount
== 0:
1884 EdkLogger
.error('Parser', FORMAT_INVALID
, 'No [Defines] section exist.', self
.MetaFile
)
1888 ## Section header parser
1890 # The section header is always in following format:
1892 # [section_name.arch<.platform|module_type>]
1894 def _SectionHeaderParser(self
):
1896 self
._SectionName
= ''
1897 self
._SectionType
= []
1900 Line
= re
.sub(',[\s]*', TAB_COMMA_SPLIT
, self
._CurrentLine
)
1901 for Item
in Line
[1:-1].split(TAB_COMMA_SPLIT
):
1903 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
,
1904 "section name can NOT be empty or incorrectly use separator comma",
1905 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1906 ItemList
= Item
.split(TAB_SPLIT
)
1908 # different types of PCD are permissible in one section
1909 self
._SectionName
= ItemList
[0].upper()
1910 if self
._SectionName
== TAB_DEC_DEFINES
.upper() and (len(ItemList
) > 1 or len(Line
.split(TAB_COMMA_SPLIT
)) > 1):
1911 EdkLogger
.error("Parser", FORMAT_INVALID
, "Defines section format is invalid",
1912 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1913 if self
._SectionName
in self
.DataType
:
1914 if self
.DataType
[self
._SectionName
] not in self
._SectionType
:
1915 self
._SectionType
.append(self
.DataType
[self
._SectionName
])
1917 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
1918 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1920 if MODEL_PCD_FEATURE_FLAG
in self
._SectionType
and len(self
._SectionType
) > 1:
1924 "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL
,
1926 Line
=self
._LineIndex
+ 1,
1927 ExtraData
=self
._CurrentLine
1930 if len(ItemList
) > 1:
1931 S1
= ItemList
[1].upper()
1933 S1
= TAB_ARCH_COMMON
1935 # S2 may be Platform or ModuleType
1936 if len(ItemList
) > 2:
1937 S2
= ItemList
[2].upper()
1938 # only Includes, GUIDs, PPIs, Protocols section have Private tag
1939 if self
._SectionName
in [TAB_INCLUDES
.upper(), TAB_GUIDS
.upper(), TAB_PROTOCOLS
.upper(), TAB_PPIS
.upper()]:
1941 EdkLogger
.error("Parser", FORMAT_INVALID
, 'Please use keyword "Private" as section tag modifier.',
1942 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1946 if [S1
, S2
, self
.DataType
[self
._SectionName
]] not in self
._Scope
:
1947 self
._Scope
.append([S1
, S2
, self
.DataType
[self
._SectionName
]])
1949 # 'COMMON' must not be used with specific ARCHs at the same section
1950 if TAB_ARCH_COMMON
in ArchList
and len(ArchList
) > 1:
1951 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
1952 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1954 # It is not permissible to mix section tags without the Private attribute with section tags with the Private attribute
1955 if TAB_COMMON
in PrivateList
and len(PrivateList
) > 1:
1956 EdkLogger
.error('Parser', FORMAT_INVALID
, "Can't mix section tags without the Private attribute with section tags with the Private attribute",
1957 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1959 ## [guids], [ppis] and [protocols] section parser
1961 def _GuidParser(self
):
1962 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1963 if len(TokenList
) < 2:
1964 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name or value specified",
1965 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1966 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1967 if TokenList
[0] == '':
1968 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name specified",
1969 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1970 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1971 if TokenList
[1] == '':
1972 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID value specified",
1973 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1974 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1975 if TokenList
[1][0] != '{' or TokenList
[1][-1] != '}' or GuidStructureStringToGuidString(TokenList
[1]) == '':
1976 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid GUID value format",
1977 ExtraData
=self
._CurrentLine
+ \
1978 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
1979 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1980 self
._ValueList
[0] = TokenList
[0]
1981 self
._ValueList
[1] = TokenList
[1]
1982 if self
._ValueList
[0] not in self
._GuidDict
:
1983 self
._GuidDict
[self
._ValueList
[0]] = self
._ValueList
[1]
1985 def ParsePcdName(self
,namelist
):
1986 if "[" in namelist
[1]:
1987 pcdname
= namelist
[1][:namelist
[1].index("[")]
1988 arrayindex
= namelist
[1][namelist
[1].index("["):]
1989 namelist
[1] = pcdname
1990 if len(namelist
) == 2:
1991 namelist
.append(arrayindex
)
1993 namelist
[2] = ".".join((arrayindex
,namelist
[2]))
1996 ## PCD sections parser
1998 # [PcdsFixedAtBuild]
1999 # [PcdsPatchableInModule]
2005 def _PcdParser(self
):
2007 if self
._CurrentStructurePcdName
:
2008 self
._ValueList
[0] = self
._CurrentStructurePcdName
2010 if "|" not in self
._CurrentLine
:
2011 if "<HeaderFiles>" == self
._CurrentLine
:
2012 self
._include
_flag
= True
2013 self
._package
_flag
= False
2014 self
._ValueList
= None
2016 if "<Packages>" == self
._CurrentLine
:
2017 self
._package
_flag
= True
2018 self
._ValueList
= None
2019 self
._include
_flag
= False
2022 if self
._include
_flag
:
2023 self
._ValueList
[1] = "<HeaderFiles>_" + md5(self
._CurrentLine
.encode('utf-8')).hexdigest()
2024 self
._ValueList
[2] = self
._CurrentLine
2025 if self
._package
_flag
and "}" != self
._CurrentLine
:
2026 self
._ValueList
[1] = "<Packages>_" + md5(self
._CurrentLine
.encode('utf-8')).hexdigest()
2027 self
._ValueList
[2] = self
._CurrentLine
2028 if self
._CurrentLine
== "}":
2029 self
._package
_flag
= False
2030 self
._include
_flag
= False
2031 self
._ValueList
= None
2034 PcdTockens
= self
._CurrentLine
.split(TAB_VALUE_SPLIT
)
2035 PcdNames
= self
.ParsePcdName(PcdTockens
[0].split(TAB_SPLIT
))
2036 if len(PcdNames
) == 2:
2037 if PcdNames
[1].strip().endswith("]"):
2038 PcdName
= PcdNames
[1][:PcdNames
[1].index('[')]
2039 Index
= PcdNames
[1][PcdNames
[1].index('['):]
2040 self
._ValueList
[0] = TAB_SPLIT
.join((PcdNames
[0],PcdName
))
2041 self
._ValueList
[1] = Index
2042 self
._ValueList
[2] = PcdTockens
[1]
2044 self
._CurrentStructurePcdName
= ""
2046 if self
._CurrentStructurePcdName
!= TAB_SPLIT
.join(PcdNames
[:2]):
2047 EdkLogger
.error('Parser', FORMAT_INVALID
, "Pcd Name does not match: %s and %s " % (self
._CurrentStructurePcdName
, TAB_SPLIT
.join(PcdNames
[:2])),
2048 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2049 self
._ValueList
[1] = TAB_SPLIT
.join(PcdNames
[2:])
2050 self
._ValueList
[2] = PcdTockens
[1]
2051 if not self
._CurrentStructurePcdName
:
2052 if self
._PcdDataTypeCODE
:
2053 if ")}" in self
._CurrentLine
:
2054 ValuePart
,RestofValue
= self
._CurrentLine
.split(")}")
2055 self
._PcdCodeValue
= self
._PcdCodeValue
+ "\n " + ValuePart
2056 self
._CurrentLine
= "|".join((self
._CurrentPcdName
, self
._PcdCodeValue
,RestofValue
))
2057 self
._PcdDataTypeCODE
= False
2058 self
._PcdCodeValue
= ""
2060 self
._PcdCodeValue
= self
._PcdCodeValue
+ "\n " + self
._CurrentLine
2061 self
._ValueList
= None
2063 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
2064 self
._CurrentPcdName
= TokenList
[0]
2065 if len(TokenList
) == 2 and TokenList
[1].strip().startswith("{CODE"):
2066 if ")}" in self
._CurrentLine
:
2067 self
._PcdDataTypeCODE
= False
2068 self
._PcdCodeValue
= ""
2070 self
._PcdDataTypeCODE
= True
2071 self
._PcdCodeValue
= TokenList
[1].strip()
2072 self
._ValueList
= None
2075 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
2076 ValueRe
= re
.compile(r
'^[a-zA-Z_][a-zA-Z0-9_]*')
2077 # check PCD information
2078 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
2079 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
2080 ExtraData
=self
._CurrentLine
+ \
2081 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2082 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2083 # check format of token space GUID CName
2084 if not ValueRe
.match(self
._ValueList
[0]):
2085 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_]*'",
2086 ExtraData
=self
._CurrentLine
+ \
2087 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2088 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2089 # check format of PCD CName
2090 if not ValueRe
.match(self
._ValueList
[1]):
2091 EdkLogger
.error('Parser', FORMAT_INVALID
, "The format of the PCD CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",
2092 ExtraData
=self
._CurrentLine
+ \
2093 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2094 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2095 # check PCD datum information
2096 if len(TokenList
) < 2 or TokenList
[1] == '':
2097 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD Datum information given",
2098 ExtraData
=self
._CurrentLine
+ \
2099 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2100 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2103 ValueRe
= re
.compile(r
'^\s*L?\".*\|.*\"')
2104 PtrValue
= ValueRe
.findall(TokenList
[1])
2106 # Has VOID* type string, may contain "|" character in the string.
2107 if len(PtrValue
) != 0:
2108 ptrValueList
= re
.sub(ValueRe
, '', TokenList
[1])
2109 ValueList
= AnalyzePcdExpression(ptrValueList
)
2110 ValueList
[0] = PtrValue
[0]
2112 ValueList
= AnalyzePcdExpression(TokenList
[1])
2115 # check if there's enough datum information given
2116 if len(ValueList
) != 3:
2117 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid PCD Datum information given",
2118 ExtraData
=self
._CurrentLine
+ \
2119 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2120 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2121 # check default value
2122 if ValueList
[0] == '':
2123 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DefaultValue in PCD Datum information",
2124 ExtraData
=self
._CurrentLine
+ \
2125 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2126 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2128 if ValueList
[1] == '':
2129 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DatumType in PCD Datum information",
2130 ExtraData
=self
._CurrentLine
+ \
2131 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2132 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2133 # check token of the PCD
2134 if ValueList
[2] == '':
2135 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing Token in PCD Datum information",
2136 ExtraData
=self
._CurrentLine
+ \
2137 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2138 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2140 PcdValue
= ValueList
[0]
2143 self
._GuidDict
.update(self
._AllPcdDict
)
2144 ValueList
[0] = ValueExpressionEx(ValueList
[0], ValueList
[1], self
._GuidDict
)(True)
2145 except BadExpression
as Value
:
2146 EdkLogger
.error('Parser', FORMAT_INVALID
, Value
, ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2147 # check format of default value against the datum type
2148 IsValid
, Cause
= CheckPcdDatum(ValueList
[1], ValueList
[0])
2150 EdkLogger
.error('Parser', FORMAT_INVALID
, Cause
, ExtraData
=self
._CurrentLine
,
2151 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2153 if Cause
== "StructurePcd":
2154 self
._CurrentStructurePcdName
= TAB_SPLIT
.join(self
._ValueList
[0:2])
2155 self
._ValueList
[0] = self
._CurrentStructurePcdName
2156 self
._ValueList
[1] = ValueList
[1].strip()
2158 if ValueList
[0] in ['True', 'true', 'TRUE']:
2160 elif ValueList
[0] in ['False', 'false', 'FALSE']:
2163 # check for duplicate PCD definition
2164 if (self
._Scope
[0], self
._ValueList
[0], self
._ValueList
[1]) in self
._AllPCDs
:
2165 EdkLogger
.error('Parser', FORMAT_INVALID
,
2166 "The same PCD name and GUID have been already defined",
2167 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2169 self
._AllPCDs
.append((self
._Scope
[0], self
._ValueList
[0], self
._ValueList
[1]))
2170 self
._AllPcdDict
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = ValueList
[0]
2172 self
._ValueList
[2] = ValueList
[0].strip() + '|' + ValueList
[1].strip() + '|' + ValueList
[2].strip()
2175 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
2176 MODEL_EFI_INCLUDE
: MetaFileParser
._PathParser
,
2177 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
2178 MODEL_EFI_GUID
: _GuidParser
,
2179 MODEL_EFI_PPI
: _GuidParser
,
2180 MODEL_EFI_PROTOCOL
: _GuidParser
,
2181 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
2182 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
2183 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
2184 MODEL_PCD_DYNAMIC
: _PcdParser
,
2185 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
2186 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
2187 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
2192 # This acts like the main() function for the script, unless it is 'import'ed into another
2195 if __name__
== '__main__':