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 # 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
22 from hashlib
import md5
24 import Common
.EdkLogger
as EdkLogger
25 import Common
.GlobalData
as GlobalData
27 from CommonDataClass
.DataClass
import *
28 from Common
.DataType
import *
29 from Common
.StringUtils
import *
30 from Common
.Misc
import GuidStructureStringToGuidString
, CheckPcdDatum
, PathClass
, AnalyzePcdData
, AnalyzeDscPcd
, AnalyzePcdExpression
, ParseFieldValue
31 from Common
.Expression
import *
32 from CommonDataClass
.Exceptions
import *
33 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
34 from collections
import defaultdict
35 from .MetaFileTable
import MetaFileStorage
36 from .MetaFileCommentParser
import CheckInfComment
38 ## RegEx for finding file versions
39 hexVersionPattern
= re
.compile(r
'0[xX][\da-f-A-F]{5,8}')
40 decVersionPattern
= re
.compile(r
'\d+\.\d+')
42 ## A decorator used to parse macro definition
43 def ParseMacro(Parser
):
44 def MacroParser(self
):
45 Match
= gMacroDefPattern
.match(self
._CurrentLine
)
47 # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method
51 TokenList
= GetSplitValueList(self
._CurrentLine
[Match
.end(1):], TAB_EQUAL_SPLIT
, 1)
54 EdkLogger
.error('Parser', FORMAT_INVALID
, "No macro name given",
55 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
56 if len(TokenList
) < 2:
60 Name
, Value
= TokenList
61 # Global macros can be only defined via environment variable
62 if Name
in GlobalData
.gGlobalDefines
:
63 EdkLogger
.error('Parser', FORMAT_INVALID
, "%s can only be defined via environment variable" % Name
,
64 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
65 # Only upper case letters, digit and '_' are allowed
66 if not gMacroNamePattern
.match(Name
):
67 EdkLogger
.error('Parser', FORMAT_INVALID
, "The macro name must be in the pattern [A-Z][A-Z0-9_]*",
68 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
70 Value
= ReplaceMacro(Value
, self
._Macros
)
71 if Type
in self
.DataType
:
72 self
._ItemType
= self
.DataType
[Type
]
74 self
._ItemType
= MODEL_META_DATA_DEFINE
75 # DEFINE defined macros
76 if Type
== TAB_DSC_DEFINES_DEFINE
:
78 # First judge whether this DEFINE is in conditional directive statements or not.
80 if isinstance(self
, DscParser
) and self
._InDirective
> -1:
83 if isinstance(self
, DecParser
):
84 if MODEL_META_DATA_HEADER
in self
._SectionType
:
85 self
._FileLocalMacros
[Name
] = Value
87 self
._ConstructSectionMacroDict
(Name
, Value
)
88 elif self
._SectionType
== MODEL_META_DATA_HEADER
:
89 self
._FileLocalMacros
[Name
] = Value
91 self
._ConstructSectionMacroDict
(Name
, Value
)
93 # EDK_GLOBAL defined macros
94 elif not isinstance(self
, DscParser
):
95 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL can only be used in .dsc file",
96 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
97 elif self
._SectionType
!= MODEL_META_DATA_HEADER
:
98 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL can only be used under [Defines] section",
99 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
100 elif (Name
in self
._FileLocalMacros
) and (self
._FileLocalMacros
[Name
] != Value
):
101 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL defined a macro with the same name and different value as one defined by 'DEFINE'",
102 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
104 self
._ValueList
= [Type
, Name
, Value
]
108 ## Base class of parser
110 # This class is used for derivation purpose. The specific parser for one kind
111 # type file must derive this class and implement some public interfaces.
113 # @param FilePath The path of platform description file
114 # @param FileType The raw data of DSC file
115 # @param Table Database used to retrieve module/package information
116 # @param Macros Macros used for replacement in file
117 # @param Owner Owner ID (for sub-section parsing)
118 # @param From ID from which the data comes (for !INCLUDE directive)
120 class MetaFileParser(object):
121 # data type (file content) for specific file type
124 # Parser objects used to implement singleton
129 # One file, one parser object. This factory method makes sure that there's
130 # only one object constructed for one meta file.
132 # @param Class class object of real AutoGen class
133 # (InfParser, DecParser or DscParser)
134 # @param FilePath The path of meta file
135 # @param *args The specific class related parameters
136 # @param **kwargs The specific class related dict parameters
138 def __new__(Class
, FilePath
, *args
, **kwargs
):
139 if FilePath
in Class
.MetaFiles
:
140 return Class
.MetaFiles
[FilePath
]
142 ParserObject
= super().__new
__(Class
)
143 Class
.MetaFiles
[FilePath
] = ParserObject
146 ## Constructor of MetaFileParser
148 # Initialize object of MetaFileParser
150 # @param FilePath The path of platform description file
151 # @param FileType The raw data of DSC file
152 # @param Arch Default Arch value for filtering sections
153 # @param Table Database used to retrieve module/package information
154 # @param Owner Owner ID (for sub-section parsing)
155 # @param From ID from which the data comes (for !INCLUDE directive)
157 def __init__(self
, FilePath
, FileType
, Arch
, Table
, Owner
= -1, From
= -1):
159 self
._RawTable
= Table
161 self
._FileType
= FileType
162 self
.MetaFile
= FilePath
163 self
._FileDir
= self
.MetaFile
.Dir
165 self
._FileLocalMacros
= {}
166 self
._SectionsMacroDict
= defaultdict(dict)
168 # for recursive parsing
169 self
._Owner
= [Owner
]
172 # parsr status for parsing
173 self
._ValueList
= ['', '', '', '', '']
176 self
._CurrentLine
= ''
177 self
._SectionType
= MODEL_UNKNOWN
178 self
._SectionName
= ''
179 self
._InSubsection
= False
180 self
._SubsectionType
= MODEL_UNKNOWN
181 self
._SubsectionName
= ''
182 self
._ItemType
= MODEL_UNKNOWN
185 self
._Finished
= False
186 self
._PostProcessed
= False
187 # Different version of meta-file has different way to parse.
189 self
._GuidDict
= {} # for Parser PCD value {GUID(gTokeSpaceGuidName)}
191 ## Store the parsed data in table
192 def _Store(self
, *Args
):
193 return self
._Table
.Insert(*Args
)
195 ## Virtual method for starting parse
197 raise NotImplementedError
199 ## Notify a post-process is needed
200 def DoPostProcess(self
):
201 self
._PostProcessed
= False
203 ## Set parsing complete flag in both class and table
205 self
._Finished
= True
206 ## Do not set end flag when processing included files
208 self
._Table
.SetEndFlag()
210 def _PostProcess(self
):
211 self
._PostProcessed
= True
213 ## Get the parse complete flag
216 return self
._Finished
218 ## Set the complete flag
220 def Finished(self
, Value
):
221 self
._Finished
= Value
223 ## Remove records that do not match given Filter Arch
224 def _FilterRecordList(self
, RecordList
, FilterArch
):
226 for Record
in RecordList
:
228 if Arch
== TAB_ARCH_COMMON
or Arch
== FilterArch
:
229 NewRecordList
.append(Record
)
232 ## Use [] style to query data in table, just for readability
234 # DataInfo = [data_type, scope1(arch), scope2(platform/moduletype)]
236 def __getitem__(self
, DataInfo
):
237 if not isinstance(DataInfo
, type(())):
238 DataInfo
= (DataInfo
,)
240 # Parse the file first, if necessary
241 if not self
._Finished
:
242 if self
._RawTable
.IsIntegrity():
243 self
._Finished
= True
245 self
._Table
= self
._RawTable
246 self
._PostProcessed
= False
249 # No specific ARCH or Platform given, use raw data
250 if self
._RawTable
and (len(DataInfo
) == 1 or DataInfo
[1] is None):
251 return self
._FilterRecordList
(self
._RawTable
.Query(*DataInfo
), self
._Arch
)
253 # Do post-process if necessary
254 if not self
._PostProcessed
:
257 return self
._FilterRecordList
(self
._Table
.Query(*DataInfo
), DataInfo
[1])
259 ## Data parser for the common format in different type of file
261 # The common format in the meatfile is like
266 def _CommonParser(self
):
267 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
268 self
._ValueList
[0:len(TokenList
)] = TokenList
270 ## Data parser for the format in which there's path
272 # Only path can have macro used. So we need to replace them before use.
275 def _PathParser(self
):
276 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
277 self
._ValueList
[0:len(TokenList
)] = TokenList
278 # Don't do macro replacement for dsc file at this point
279 if not isinstance(self
, DscParser
):
280 Macros
= self
._Macros
281 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
283 ## Skip unsupported data
285 EdkLogger
.warn("Parser", "Unrecognized content", File
=self
.MetaFile
,
286 Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
);
287 self
._ValueList
[0:1] = [self
._CurrentLine
]
289 ## Skip unsupported data for UserExtension Section
290 def _SkipUserExtension(self
):
291 self
._ValueList
[0:1] = [self
._CurrentLine
]
293 ## Section header parser
295 # The section header is always in following format:
297 # [section_name.arch<.platform|module_type>]
299 def _SectionHeaderParser(self
):
301 self
._SectionName
= ''
303 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
306 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
, 3)
307 # different section should not mix in one section
308 if self
._SectionName
!= '' and self
._SectionName
!= ItemList
[0].upper():
309 EdkLogger
.error('Parser', FORMAT_INVALID
, "Different section names in the same section",
310 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
311 self
._SectionName
= ItemList
[0].upper()
312 if self
._SectionName
in self
.DataType
:
313 self
._SectionType
= self
.DataType
[self
._SectionName
]
314 # Check if the section name is valid
315 if self
._SectionName
not in SECTIONS_HAVE_ITEM_AFTER_ARCH_SET
and len(ItemList
) > 3:
316 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
317 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
318 elif self
._Version
>= 0x00010005:
319 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
320 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
322 self
._SectionType
= MODEL_UNKNOWN
325 if len(ItemList
) > 1:
326 S1
= ItemList
[1].upper()
331 # S2 may be Platform or ModuleType
332 if len(ItemList
) > 2:
333 if self
._SectionName
.upper() in SECTIONS_HAVE_ITEM_PCD_SET
:
336 S2
= ItemList
[2].upper()
339 if len(ItemList
) > 3:
343 self
._Scope
.append([S1
, S2
, S3
])
345 # 'COMMON' must not be used with specific ARCHs at the same section
346 if TAB_ARCH_COMMON
in ArchList
and len(ArchList
) > 1:
347 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
348 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
349 # If the section information is needed later, it should be stored in database
350 self
._ValueList
[0] = self
._SectionName
352 ## [defines] section parser
354 def _DefineParser(self
):
355 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
356 self
._ValueList
[1:len(TokenList
)] = TokenList
357 if not self
._ValueList
[1]:
358 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
359 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
360 if not self
._ValueList
[2]:
361 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
362 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
364 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
365 Name
, Value
= self
._ValueList
[1], self
._ValueList
[2]
366 MacroUsed
= GlobalData
.gMacroRefPattern
.findall(Value
)
367 if len(MacroUsed
) != 0:
368 for Macro
in MacroUsed
:
369 if Macro
in GlobalData
.gGlobalDefines
:
370 EdkLogger
.error("Parser", FORMAT_INVALID
, "Global macro %s is not permitted." % (Macro
), ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
372 EdkLogger
.error("Parser", FORMAT_INVALID
, "%s not defined" % (Macro
), ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
373 # Sometimes, we need to make differences between EDK and EDK2 modules
374 if Name
== 'INF_VERSION':
375 if hexVersionPattern
.match(Value
):
376 self
._Version
= int(Value
, 0)
377 elif decVersionPattern
.match(Value
):
378 ValueList
= Value
.split('.')
379 Major
= int(ValueList
[0], 0)
380 Minor
= int(ValueList
[1], 0)
381 if Major
> 0xffff or Minor
> 0xffff:
382 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid version number",
383 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
384 self
._Version
= int('0x{0:04x}{1:04x}'.format(Major
, Minor
), 0)
386 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid version number",
387 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
389 if isinstance(self
, InfParser
) and self
._Version
< 0x00010005:
390 # EDK module allows using defines as macros
391 self
._FileLocalMacros
[Name
] = Value
392 self
._Defines
[Name
] = Value
394 ## [BuildOptions] section parser
396 def _BuildOptionParser(self
):
397 self
._CurrentLine
= CleanString(self
._CurrentLine
, BuildOption
=True)
398 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
399 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
400 if len(TokenList2
) == 2:
401 self
._ValueList
[0] = TokenList2
[0] # toolchain family
402 self
._ValueList
[1] = TokenList2
[1] # keys
404 self
._ValueList
[1] = TokenList
[0]
405 if len(TokenList
) == 2 and not isinstance(self
, DscParser
): # value
406 self
._ValueList
[2] = ReplaceMacro(TokenList
[1], self
._Macros
)
408 if self
._ValueList
[1].count('_') != 4:
412 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
413 ExtraData
=self
._CurrentLine
,
415 Line
=self
._LineIndex
+ 1
417 def GetValidExpression(self
, TokenSpaceGuid
, PcdCName
):
418 return self
._Table
.GetValidExpression(TokenSpaceGuid
, PcdCName
)
423 Macros
.update(self
._FileLocalMacros
)
424 Macros
.update(self
._GetApplicableSectionMacro
())
427 ## Construct section Macro dict
428 def _ConstructSectionMacroDict(self
, Name
, Value
):
429 ScopeKey
= [(Scope
[0], Scope
[1], Scope
[2]) for Scope
in self
._Scope
]
430 ScopeKey
= tuple(ScopeKey
)
432 # DecParser SectionType is a list, will contain more than one item only in Pcd Section
433 # As Pcd section macro usage is not alllowed, so here it is safe
435 if isinstance(self
, DecParser
):
436 SectionDictKey
= self
._SectionType
[0], ScopeKey
438 SectionDictKey
= self
._SectionType
, ScopeKey
440 self
._SectionsMacroDict
[SectionDictKey
][Name
] = Value
442 ## Get section Macros that are applicable to current line, which may come from other sections
443 ## that share the same name while scope is wider
444 def _GetApplicableSectionMacro(self
):
451 ActiveSectionType
= self
._SectionType
452 if isinstance(self
, DecParser
):
453 ActiveSectionType
= self
._SectionType
[0]
455 for (SectionType
, Scope
) in self
._SectionsMacroDict
:
456 if SectionType
!= ActiveSectionType
:
459 for ActiveScope
in self
._Scope
:
460 Scope0
, Scope1
, Scope2
= ActiveScope
[0], ActiveScope
[1], ActiveScope
[2]
461 if(Scope0
, Scope1
, Scope2
) not in Scope
:
464 SpeSpeMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
466 for ActiveScope
in self
._Scope
:
467 Scope0
, Scope1
, Scope2
= ActiveScope
[0], ActiveScope
[1], ActiveScope
[2]
468 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
:
471 ComSpeMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
473 if (TAB_COMMON
, TAB_COMMON
, TAB_COMMON
) in Scope
:
474 ComComMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
476 Macros
.update(ComComMacroDict
)
477 Macros
.update(ComSpeMacroDict
)
478 Macros
.update(SpeSpeMacroDict
)
484 ## INF file parser class
486 # @param FilePath The path of platform description file
487 # @param FileType The raw data of DSC file
488 # @param Table Database used to retrieve module/package information
489 # @param Macros Macros used for replacement in file
491 class InfParser(MetaFileParser
):
492 # INF file supported data types (one type per section)
494 TAB_UNKNOWN
.upper() : MODEL_UNKNOWN
,
495 TAB_INF_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
496 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
497 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
498 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
499 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
500 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
501 TAB_PACKAGES
.upper() : MODEL_META_DATA_PACKAGE
,
502 TAB_NMAKE
.upper() : MODEL_META_DATA_NMAKE
,
503 TAB_INF_FIXED_PCD
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
504 TAB_INF_PATCH_PCD
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
505 TAB_INF_FEATURE_PCD
.upper() : MODEL_PCD_FEATURE_FLAG
,
506 TAB_INF_PCD_EX
.upper() : MODEL_PCD_DYNAMIC_EX
,
507 TAB_INF_PCD
.upper() : MODEL_PCD_DYNAMIC
,
508 TAB_SOURCES
.upper() : MODEL_EFI_SOURCE_FILE
,
509 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
510 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
511 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
512 TAB_DEPEX
.upper() : MODEL_EFI_DEPEX
,
513 TAB_BINARIES
.upper() : MODEL_EFI_BINARY_FILE
,
514 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
517 ## Constructor of InfParser
519 # Initialize object of InfParser
521 # @param FilePath The path of module description file
522 # @param FileType The raw data of DSC file
523 # @param Arch Default Arch value for filtering sections
524 # @param Table Database used to retrieve module/package information
526 def __init__(self
, FilePath
, FileType
, Arch
, Table
):
527 # prevent re-initialization
528 if hasattr(self
, "_Table"):
530 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
)
538 Content
= open(str(self
.MetaFile
), 'r').readlines()
540 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
542 # parse the file line by line
543 IsFindBlockComment
= False
544 GetHeaderComment
= False
549 for Index
in range(0, len(Content
)):
550 # skip empty, commented, block commented lines
551 Line
, Comment
= CleanString2(Content
[Index
], AllowCppStyleComment
=True)
553 if Index
+ 1 < len(Content
):
554 NextLine
, NextComment
= CleanString2(Content
[Index
+ 1])
557 Comments
.append((Comment
, Index
+ 1))
558 elif GetHeaderComment
:
559 SectionComments
.extend(Comments
)
562 if Line
.find(DataType
.TAB_COMMENT_EDK_START
) > -1:
563 IsFindBlockComment
= True
565 if Line
.find(DataType
.TAB_COMMENT_EDK_END
) > -1:
566 IsFindBlockComment
= False
568 if IsFindBlockComment
:
571 self
._LineIndex
= Index
572 self
._CurrentLine
= Line
575 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
576 if not GetHeaderComment
:
577 for Cmt
, LNo
in Comments
:
578 self
._Store
(MODEL_META_DATA_HEADER_COMMENT
, Cmt
, '', '', TAB_COMMON
,
579 TAB_COMMON
, self
._Owner
[-1], LNo
, -1, LNo
, -1, 0)
580 GetHeaderComment
= True
582 TailComments
.extend(SectionComments
+ Comments
)
584 self
._SectionHeaderParser
()
585 # Check invalid sections
586 if self
._Version
< 0x00010005:
587 if self
._SectionType
in [MODEL_META_DATA_BUILD_OPTION
,
588 MODEL_EFI_LIBRARY_CLASS
,
589 MODEL_META_DATA_PACKAGE
,
590 MODEL_PCD_FIXED_AT_BUILD
,
591 MODEL_PCD_PATCHABLE_IN_MODULE
,
592 MODEL_PCD_FEATURE_FLAG
,
593 MODEL_PCD_DYNAMIC_EX
,
598 MODEL_META_DATA_USER_EXTENSION
]:
599 EdkLogger
.error('Parser', FORMAT_INVALID
,
600 "Section [%s] is not allowed in inf file without version" % (self
._SectionName
),
601 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
602 elif self
._SectionType
in [MODEL_EFI_INCLUDE
,
603 MODEL_EFI_LIBRARY_INSTANCE
,
604 MODEL_META_DATA_NMAKE
]:
605 EdkLogger
.error('Parser', FORMAT_INVALID
,
606 "Section [%s] is not allowed in inf file with version 0x%08x" % (self
._SectionName
, self
._Version
),
607 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
609 # merge two lines specified by '\' in section NMAKE
610 elif self
._SectionType
== MODEL_META_DATA_NMAKE
:
613 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
616 if NextLine
[0] == TAB_SECTION_START
and NextLine
[-1] == TAB_SECTION_END
:
617 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
620 NmakeLine
= NmakeLine
+ ' ' + Line
[0:-1]
623 self
._CurrentLine
= NmakeLine
+ Line
627 self
._ValueList
= ['', '', '']
628 # parse current line, result will be put in self._ValueList
629 self
._SectionParser
[self
._SectionType
](self
)
630 if self
._ValueList
is None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
635 Comments
.append((Comment
, Index
+ 1))
636 if GlobalData
.gOptions
and GlobalData
.gOptions
.CheckUsage
:
637 CheckInfComment(self
._SectionType
, Comments
, str(self
.MetaFile
), Index
+ 1, self
._ValueList
)
639 # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
640 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
642 for Arch
, Platform
, _
in self
._Scope
:
643 LastItem
= self
._Store
(self
._SectionType
,
656 for Comment
, LineNo
in Comments
:
657 self
._Store
(MODEL_META_DATA_COMMENT
, Comment
, '', '', Arch
, Platform
,
658 LastItem
, LineNo
, -1, LineNo
, -1, 0)
661 TailComments
.extend(SectionComments
+ Comments
)
662 if IsFindBlockComment
:
663 EdkLogger
.error("Parser", FORMAT_INVALID
, "Open block comments (starting with /*) are expected to end with */",
666 # If there are tail comments in INF file, save to database whatever the comments are
667 for Comment
in TailComments
:
668 self
._Store
(MODEL_META_DATA_TAIL_COMMENT
, Comment
[0], '', '', TAB_COMMON
,
669 TAB_COMMON
, self
._Owner
[-1], -1, -1, -1, -1, 0)
672 ## Data parser for the format in which there's path
674 # Only path can have macro used. So we need to replace them before use.
676 def _IncludeParser(self
):
677 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
678 self
._ValueList
[0:len(TokenList
)] = TokenList
679 Macros
= self
._Macros
681 for Index
in range(0, len(self
._ValueList
)):
682 Value
= self
._ValueList
[Index
]
686 if Value
.upper().find('$(EFI_SOURCE)\Edk'.upper()) > -1 or Value
.upper().find('$(EFI_SOURCE)/Edk'.upper()) > -1:
687 Value
= '$(EDK_SOURCE)' + Value
[17:]
688 if Value
.find('$(EFI_SOURCE)') > -1 or Value
.find('$(EDK_SOURCE)') > -1:
690 elif Value
.startswith('.'):
692 elif Value
.startswith('$('):
695 Value
= '$(EFI_SOURCE)/' + Value
697 self
._ValueList
[Index
] = ReplaceMacro(Value
, Macros
)
699 ## Parse [Sources] section
701 # Only path can have macro used. So we need to replace them before use.
704 def _SourceFileParser(self
):
705 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
706 self
._ValueList
[0:len(TokenList
)] = TokenList
707 Macros
= self
._Macros
708 # For Acpi tables, remove macro like ' TABLE_NAME=Sata1'
709 if 'COMPONENT_TYPE' in Macros
:
710 if self
._Defines
['COMPONENT_TYPE'].upper() == 'ACPITABLE':
711 self
._ValueList
[0] = GetSplitValueList(self
._ValueList
[0], ' ', 1)[0]
712 if self
._Defines
['BASE_NAME'] == 'Microcode':
714 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
716 ## Parse [Binaries] section
718 # Only path can have macro used. So we need to replace them before use.
721 def _BinaryFileParser(self
):
722 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 2)
723 if len(TokenList
) < 2:
724 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type or path specified",
725 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
726 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
728 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type specified",
729 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
730 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
732 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file path specified",
733 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
734 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
735 self
._ValueList
[0:len(TokenList
)] = TokenList
736 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
738 ## [nmake] section parser (Edk.x style only)
739 def _NmakeParser(self
):
740 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
741 self
._ValueList
[0:len(TokenList
)] = TokenList
743 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
744 # remove self-reference in macro setting
745 #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
747 ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
749 def _PcdParser(self
):
750 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
751 ValueList
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
752 if len(ValueList
) != 2:
753 EdkLogger
.error('Parser', FORMAT_INVALID
, "Illegal token space GUID and PCD name format",
754 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
755 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
756 self
._ValueList
[0:1] = ValueList
757 if len(TokenList
) > 1:
758 self
._ValueList
[2] = TokenList
[1]
759 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
760 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
761 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
762 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
764 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
765 if self
._ValueList
[2] != '':
766 InfPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
767 if InfPcdValueList
[0] in ['True', 'true', 'TRUE']:
768 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '1', 1);
769 elif InfPcdValueList
[0] in ['False', 'false', 'FALSE']:
770 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '0', 1);
771 if (self
._ValueList
[0], self
._ValueList
[1]) not in self
.PcdsDict
:
772 self
.PcdsDict
[self
._ValueList
[0], self
._ValueList
[1]] = self
._SectionType
773 elif self
.PcdsDict
[self
._ValueList
[0], self
._ValueList
[1]] != self
._SectionType
:
774 EdkLogger
.error('Parser', FORMAT_INVALID
, "It is not permissible to list a specified PCD in different PCD type sections.",
775 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
776 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
778 ## [depex] section parser
780 def _DepexParser(self
):
781 self
._ValueList
[0:1] = [self
._CurrentLine
]
784 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
785 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
786 MODEL_META_DATA_BUILD_OPTION
: MetaFileParser
._BuildOptionParser
,
787 MODEL_EFI_INCLUDE
: _IncludeParser
, # for Edk.x modules
788 MODEL_EFI_LIBRARY_INSTANCE
: MetaFileParser
._CommonParser
, # for Edk.x modules
789 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
790 MODEL_META_DATA_PACKAGE
: MetaFileParser
._PathParser
,
791 MODEL_META_DATA_NMAKE
: _NmakeParser
, # for Edk.x modules
792 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
793 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
794 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
795 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
796 MODEL_PCD_DYNAMIC
: _PcdParser
,
797 MODEL_EFI_SOURCE_FILE
: _SourceFileParser
,
798 MODEL_EFI_GUID
: MetaFileParser
._CommonParser
,
799 MODEL_EFI_PROTOCOL
: MetaFileParser
._CommonParser
,
800 MODEL_EFI_PPI
: MetaFileParser
._CommonParser
,
801 MODEL_EFI_DEPEX
: _DepexParser
,
802 MODEL_EFI_BINARY_FILE
: _BinaryFileParser
,
803 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
806 ## DSC file parser class
808 # @param FilePath The path of platform description file
809 # @param FileType The raw data of DSC file
810 # @param Table Database used to retrieve module/package information
811 # @param Macros Macros used for replacement in file
812 # @param Owner Owner ID (for sub-section parsing)
813 # @param From ID from which the data comes (for !INCLUDE directive)
815 class DscParser(MetaFileParser
):
816 # DSC file supported data types (one type per section)
818 TAB_SKUIDS
.upper() : MODEL_EFI_SKU_ID
,
819 TAB_DEFAULT_STORES
.upper() : MODEL_EFI_DEFAULT_STORES
,
820 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
821 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
822 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
823 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
824 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
825 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
826 TAB_PCDS_DYNAMIC_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_DEFAULT
,
827 TAB_PCDS_DYNAMIC_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_HII
,
828 TAB_PCDS_DYNAMIC_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_VPD
,
829 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT
,
830 TAB_PCDS_DYNAMIC_EX_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_HII
,
831 TAB_PCDS_DYNAMIC_EX_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_VPD
,
832 TAB_COMPONENTS
.upper() : MODEL_META_DATA_COMPONENT
,
833 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
.upper() : MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
,
834 TAB_DSC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
835 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
836 TAB_DSC_DEFINES_EDKGLOBAL
: MODEL_META_DATA_GLOBAL_DEFINE
,
837 TAB_INCLUDE
.upper() : MODEL_META_DATA_INCLUDE
,
838 TAB_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
839 TAB_IF_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
840 TAB_IF_N_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
,
841 TAB_ELSE_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
,
842 TAB_ELSE
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
,
843 TAB_END_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
,
844 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
,
845 TAB_ERROR
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR
,
848 # Valid names in define section
855 "PCD_INFO_GENERATION",
856 "PCD_VAR_CHECK_GENERATION",
857 "SUPPORTED_ARCHITECTURES",
866 "FIX_LOAD_TOP_MEMORY_ADDRESS",
871 SubSectionDefineKeywords
= [
875 SymbolPattern
= ValueExpression
.SymbolPattern
877 IncludedFiles
= set()
879 ## Constructor of DscParser
881 # Initialize object of DscParser
883 # @param FilePath The path of platform description file
884 # @param FileType The raw data of DSC file
885 # @param Arch Default Arch value for filtering sections
886 # @param Table Database used to retrieve module/package information
887 # @param Owner Owner ID (for sub-section parsing)
888 # @param From ID from which the data comes (for !INCLUDE directive)
890 def __init__(self
, FilePath
, FileType
, Arch
, Table
, Owner
= -1, From
= -1):
891 # prevent re-initialization
892 if hasattr(self
, "_Table") and self
._Table
is Table
:
894 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
, Owner
, From
)
895 self
._Version
= 0x00010005 # Only EDK2 dsc file is supported
896 # to store conditional directive evaluation result
897 self
._DirectiveStack
= []
898 self
._DirectiveEvalStack
= []
902 # Specify whether current line is in uncertain condition
904 self
._InDirective
= -1
906 # Final valid replacable symbols
909 # Map the ID between the original table and new table to track
912 self
._IdMapping
= {-1:-1}
918 Content
= open(str(self
.MetaFile
), 'r').readlines()
920 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
923 for Index
in range(0, len(Content
)):
924 Line
= CleanString(Content
[Index
])
929 self
._CurrentLine
= Line
930 self
._LineIndex
= Index
931 if self
._InSubsection
and self
._Owner
[-1] == -1:
932 self
._Owner
.append(self
._LastItem
)
935 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
936 self
._SectionType
= MODEL_META_DATA_SECTION_HEADER
938 elif Line
[0] == '}' and self
._InSubsection
:
939 self
._InSubsection
= False
940 self
._SubsectionType
= MODEL_UNKNOWN
941 self
._SubsectionName
= ''
946 elif Line
[0] == TAB_OPTION_START
and Line
[-1] == TAB_OPTION_END
:
947 self
._SubsectionType
= MODEL_META_DATA_SUBSECTION_HEADER
950 TokenList
= GetSplitValueList(Line
, ' ', 1)
951 if TokenList
[0] == TAB_INCLUDE
:
952 for Arch
, ModuleType
, DefaultStore
in self
._Scope
:
953 if self
._SubsectionType
!= MODEL_UNKNOWN
and Arch
in OwnerId
:
954 self
._Owner
[-1] = OwnerId
[Arch
]
955 self
._DirectiveParser
()
957 self
._DirectiveParser
()
959 if Line
[0] == TAB_OPTION_START
and not self
._InSubsection
:
960 EdkLogger
.error("Parser", FILE_READ_FAILURE
, "Missing the '{' before %s in Line %s" % (Line
, Index
+1), ExtraData
=self
.MetaFile
)
962 if self
._InSubsection
:
963 SectionType
= self
._SubsectionType
965 SectionType
= self
._SectionType
966 self
._ItemType
= SectionType
968 self
._ValueList
= ['', '', '']
969 self
._SectionParser
[SectionType
](self
)
970 if self
._ValueList
is None:
973 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
974 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
976 for Arch
, ModuleType
, DefaultStore
in self
._Scope
:
977 Owner
= self
._Owner
[-1]
978 if self
._SubsectionType
!= MODEL_UNKNOWN
and Arch
in OwnerId
:
979 Owner
= OwnerId
[Arch
]
980 self
._LastItem
= self
._Store
(
996 if self
._SubsectionType
== MODEL_UNKNOWN
and self
._InSubsection
:
997 OwnerId
[Arch
] = self
._LastItem
999 if self
._DirectiveStack
:
1000 Type
, Line
, Text
= self
._DirectiveStack
[-1]
1001 EdkLogger
.error('Parser', FORMAT_INVALID
, "No matching '!endif' found",
1002 ExtraData
=Text
, File
=self
.MetaFile
, Line
=Line
)
1005 ## <subsection_header> parser
1006 def _SubsectionHeaderParser(self
):
1007 self
._SubsectionName
= self
._CurrentLine
[1:-1].upper()
1008 if self
._SubsectionName
in self
.DataType
:
1009 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
1011 self
._SubsectionType
= MODEL_UNKNOWN
1012 EdkLogger
.warn("Parser", "Unrecognized sub-section", File
=self
.MetaFile
,
1013 Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1014 self
._ValueList
[0] = self
._SubsectionName
1016 ## Directive statement parser
1017 def _DirectiveParser(self
):
1018 self
._ValueList
= ['', '', '']
1019 TokenList
= GetSplitValueList(self
._CurrentLine
, ' ', 1)
1020 self
._ValueList
[0:len(TokenList
)] = TokenList
1023 DirectiveName
= self
._ValueList
[0].upper()
1024 if DirectiveName
not in self
.DataType
:
1025 EdkLogger
.error("Parser", FORMAT_INVALID
, "Unknown directive [%s]" % DirectiveName
,
1026 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1028 if DirectiveName
in ['!IF', '!IFDEF', '!IFNDEF']:
1029 self
._InDirective
+= 1
1031 if DirectiveName
in ['!ENDIF']:
1032 self
._InDirective
-= 1
1034 if DirectiveName
in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self
._ValueList
[1] == '':
1035 EdkLogger
.error("Parser", FORMAT_INVALID
, "Missing expression",
1036 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1037 ExtraData
=self
._CurrentLine
)
1039 ItemType
= self
.DataType
[DirectiveName
]
1040 Scope
= [[TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]]
1041 if ItemType
== MODEL_META_DATA_INCLUDE
:
1043 elif ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR
:
1045 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1046 # Remove all directives between !if and !endif, including themselves
1047 while self
._DirectiveStack
:
1048 # Remove any !else or !elseif
1049 DirectiveInfo
= self
._DirectiveStack
.pop()
1050 if DirectiveInfo
[0] in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1051 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1052 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1055 EdkLogger
.error("Parser", FORMAT_INVALID
, "Redundant '!endif'",
1056 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1057 ExtraData
=self
._CurrentLine
)
1058 elif ItemType
not in {MODEL_META_DATA_INCLUDE
, MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR
}:
1059 # Break if there's a !else is followed by a !elseif
1060 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
and \
1061 self
._DirectiveStack
and \
1062 self
._DirectiveStack
[-1][0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1063 EdkLogger
.error("Parser", FORMAT_INVALID
, "'!elseif' after '!else'",
1064 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1065 ExtraData
=self
._CurrentLine
)
1066 self
._DirectiveStack
.append((ItemType
, self
._LineIndex
+ 1, self
._CurrentLine
))
1069 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
1070 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
1072 for Arch
, ModuleType
, DefaultStore
in Scope
:
1073 self
._LastItem
= self
._Store
(
1083 self
._LineIndex
+ 1,
1085 self
._LineIndex
+ 1,
1090 ## [defines] section parser
1092 def _DefineParser(self
):
1093 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1094 self
._ValueList
[1:len(TokenList
)] = TokenList
1097 if not self
._ValueList
[1]:
1098 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
1099 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1100 if not self
._ValueList
[2]:
1101 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
1102 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1103 if (not self
._ValueList
[1] in self
.DefineKeywords
and
1104 (self
._InSubsection
and self
._ValueList
[1] not in self
.SubSectionDefineKeywords
)):
1105 EdkLogger
.error('Parser', FORMAT_INVALID
,
1106 "Unknown keyword found: %s. "
1107 "If this is a macro you must "
1108 "add it as a DEFINE in the DSC" % self
._ValueList
[1],
1109 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1110 if not self
._InSubsection
:
1111 self
._Defines
[self
._ValueList
[1]] = self
._ValueList
[2]
1112 self
._ItemType
= self
.DataType
[TAB_DSC_DEFINES
.upper()]
1115 def _SkuIdParser(self
):
1116 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1117 if len(TokenList
) not in (2, 3):
1118 EdkLogger
.error('Parser', FORMAT_INVALID
, "Correct format is '<Number>|<UiName>[|<UiName>]'",
1119 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1120 self
._ValueList
[0:len(TokenList
)] = TokenList
1122 def _DefaultStoresParser(self
):
1123 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1124 if len(TokenList
) != 2:
1125 EdkLogger
.error('Parser', FORMAT_INVALID
, "Correct format is '<Number>|<UiName>'",
1126 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1127 self
._ValueList
[0:len(TokenList
)] = TokenList
1129 ## Parse Edk style of library modules
1131 def _LibraryInstanceParser(self
):
1132 self
._ValueList
[0] = self
._CurrentLine
1134 ## PCD sections parser
1136 # [PcdsFixedAtBuild]
1137 # [PcdsPatchableInModule]
1140 # [PcdsDynamicExDefault]
1141 # [PcdsDynamicExVpd]
1142 # [PcdsDynamicExHii]
1144 # [PcdsDynamicDefault]
1149 def _PcdParser(self
):
1150 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1151 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1152 PcdNameTockens
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1153 if len(PcdNameTockens
) == 2:
1154 self
._ValueList
[0], self
._ValueList
[1] = PcdNameTockens
[0], PcdNameTockens
[1]
1155 elif len(PcdNameTockens
) == 3:
1156 self
._ValueList
[0], self
._ValueList
[1] = ".".join((PcdNameTockens
[0], PcdNameTockens
[1])), PcdNameTockens
[2]
1157 elif len(PcdNameTockens
) > 3:
1158 self
._ValueList
[0], self
._ValueList
[1] = ".".join((PcdNameTockens
[0], PcdNameTockens
[1])), ".".join(PcdNameTockens
[2:])
1159 if len(TokenList
) == 2:
1160 self
._ValueList
[2] = TokenList
[1]
1161 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1162 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1163 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1164 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1165 if self
._ValueList
[2] == '':
1167 # The PCD values are optional for FIXEDATBUILD, PATCHABLEINMODULE, Dynamic/DynamicEx default
1169 if self
._SectionType
in (MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
):
1171 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD value given",
1172 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1173 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1175 # Validate the datum type of Dynamic Defaul PCD and DynamicEx Default PCD
1176 ValueList
= GetSplitValueList(self
._ValueList
[2])
1177 if len(ValueList
) > 1 and ValueList
[1] in [TAB_UINT8
, TAB_UINT16
, TAB_UINT32
, TAB_UINT64
] \
1178 and self
._ItemType
in [MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
]:
1179 EdkLogger
.error('Parser', FORMAT_INVALID
, "The datum type '%s' of PCD is wrong" % ValueList
[1],
1180 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1182 # Validate the VariableName of DynamicHii and DynamicExHii for PCD Entry must not be an empty string
1183 if self
._ItemType
in [MODEL_PCD_DYNAMIC_HII
, MODEL_PCD_DYNAMIC_EX_HII
]:
1184 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
1185 if len(DscPcdValueList
[0].replace('L', '').replace('"', '').strip()) == 0:
1186 EdkLogger
.error('Parser', FORMAT_INVALID
, "The VariableName field in the HII format PCD entry must not be an empty string",
1187 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1189 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
1190 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
1191 if DscPcdValueList
[0] in ['True', 'true', 'TRUE']:
1192 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '1', 1);
1193 elif DscPcdValueList
[0] in ['False', 'false', 'FALSE']:
1194 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '0', 1);
1197 ## [components] section parser
1199 def _ComponentParser(self
):
1200 if self
._CurrentLine
[-1] == '{':
1201 self
._ValueList
[0] = self
._CurrentLine
[0:-1].strip()
1202 self
._InSubsection
= True
1203 self
._SubsectionType
= MODEL_UNKNOWN
1205 self
._ValueList
[0] = self
._CurrentLine
1207 ## [LibraryClasses] section
1209 def _LibraryClassParser(self
):
1210 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1211 if len(TokenList
) < 2:
1212 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class or instance specified",
1213 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1214 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1215 if TokenList
[0] == '':
1216 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class specified",
1217 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1218 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1219 if TokenList
[1] == '':
1220 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library instance specified",
1221 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1222 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1224 self
._ValueList
[0:len(TokenList
)] = TokenList
1226 def _CompponentSourceOverridePathParser(self
):
1227 self
._ValueList
[0] = self
._CurrentLine
1229 ## [BuildOptions] section parser
1231 def _BuildOptionParser(self
):
1232 self
._CurrentLine
= CleanString(self
._CurrentLine
, BuildOption
=True)
1233 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1234 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
1235 if len(TokenList2
) == 2:
1236 self
._ValueList
[0] = TokenList2
[0] # toolchain family
1237 self
._ValueList
[1] = TokenList2
[1] # keys
1239 self
._ValueList
[1] = TokenList
[0]
1240 if len(TokenList
) == 2: # value
1241 self
._ValueList
[2] = TokenList
[1]
1243 if self
._ValueList
[1].count('_') != 4:
1247 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
1248 ExtraData
=self
._CurrentLine
,
1250 Line
=self
._LineIndex
+ 1
1253 ## Override parent's method since we'll do all macro replacements in parser
1257 Macros
.update(self
._FileLocalMacros
)
1258 Macros
.update(self
._GetApplicableSectionMacro
())
1259 Macros
.update(GlobalData
.gEdkGlobal
)
1260 Macros
.update(GlobalData
.gPlatformDefines
)
1261 Macros
.update(GlobalData
.gCommandLineDefines
)
1262 # PCD cannot be referenced in macro definition
1263 if self
._ItemType
not in [MODEL_META_DATA_DEFINE
, MODEL_META_DATA_GLOBAL_DEFINE
]:
1264 Macros
.update(self
._Symbols
)
1265 if GlobalData
.BuildOptionPcd
:
1266 for Item
in GlobalData
.BuildOptionPcd
:
1267 if isinstance(Item
, tuple):
1269 PcdName
, TmpValue
= Item
.split("=")
1270 TmpValue
= BuildOptionValue(TmpValue
, self
._GuidDict
)
1271 Macros
[PcdName
.strip()] = TmpValue
1274 def _PostProcess(self
):
1276 MODEL_META_DATA_SECTION_HEADER
: self
.__ProcessSectionHeader
,
1277 MODEL_META_DATA_SUBSECTION_HEADER
: self
.__ProcessSubsectionHeader
,
1278 MODEL_META_DATA_HEADER
: self
.__ProcessDefine
,
1279 MODEL_META_DATA_DEFINE
: self
.__ProcessDefine
,
1280 MODEL_META_DATA_GLOBAL_DEFINE
: self
.__ProcessDefine
,
1281 MODEL_META_DATA_INCLUDE
: self
.__ProcessDirective
,
1282 MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
: self
.__ProcessDirective
,
1283 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
: self
.__ProcessDirective
,
1284 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
: self
.__ProcessDirective
,
1285 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
: self
.__ProcessDirective
,
1286 MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
: self
.__ProcessDirective
,
1287 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
: self
.__ProcessDirective
,
1288 MODEL_EFI_SKU_ID
: self
.__ProcessSkuId
,
1289 MODEL_EFI_DEFAULT_STORES
: self
.__ProcessDefaultStores
,
1290 MODEL_EFI_LIBRARY_INSTANCE
: self
.__ProcessLibraryInstance
,
1291 MODEL_EFI_LIBRARY_CLASS
: self
.__ProcessLibraryClass
,
1292 MODEL_PCD_FIXED_AT_BUILD
: self
.__ProcessPcd
,
1293 MODEL_PCD_PATCHABLE_IN_MODULE
: self
.__ProcessPcd
,
1294 MODEL_PCD_FEATURE_FLAG
: self
.__ProcessPcd
,
1295 MODEL_PCD_DYNAMIC_DEFAULT
: self
.__ProcessPcd
,
1296 MODEL_PCD_DYNAMIC_HII
: self
.__ProcessPcd
,
1297 MODEL_PCD_DYNAMIC_VPD
: self
.__ProcessPcd
,
1298 MODEL_PCD_DYNAMIC_EX_DEFAULT
: self
.__ProcessPcd
,
1299 MODEL_PCD_DYNAMIC_EX_HII
: self
.__ProcessPcd
,
1300 MODEL_PCD_DYNAMIC_EX_VPD
: self
.__ProcessPcd
,
1301 MODEL_META_DATA_COMPONENT
: self
.__ProcessComponent
,
1302 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: self
.__ProcessSourceOverridePath
,
1303 MODEL_META_DATA_BUILD_OPTION
: self
.__ProcessBuildOption
,
1304 MODEL_UNKNOWN
: self
._Skip
,
1305 MODEL_META_DATA_USER_EXTENSION
: self
._SkipUserExtension
,
1306 MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR
: self
._ProcessError
,
1309 self
._Table
= MetaFileStorage(self
._RawTable
.Cur
, self
.MetaFile
, MODEL_FILE_DSC
, True)
1310 self
._Table
.Create()
1311 self
._DirectiveStack
= []
1312 self
._DirectiveEvalStack
= []
1313 self
._FileWithError
= self
.MetaFile
1314 self
._FileLocalMacros
= {}
1315 self
._SectionsMacroDict
.clear()
1316 GlobalData
.gPlatformDefines
= {}
1318 # Get all macro and PCD which has straitforward value
1319 self
.__RetrievePcdValue
()
1320 self
._Content
= self
._RawTable
.GetAll()
1321 self
._ContentIndex
= 0
1322 self
._InSubsection
= False
1323 while self
._ContentIndex
< len(self
._Content
) :
1324 Id
, self
._ItemType
, V1
, V2
, V3
, S1
, S2
, S3
, Owner
, self
._From
, \
1325 LineStart
, ColStart
, LineEnd
, ColEnd
, Enabled
= self
._Content
[self
._ContentIndex
]
1328 self
._FileWithError
= self
.MetaFile
1330 self
._ContentIndex
+= 1
1332 self
._Scope
= [[S1
, S2
, S3
]]
1334 # For !include directive, handle it specially,
1335 # merge arch and module type in case of duplicate items
1337 while self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1338 if self
._ContentIndex
>= len(self
._Content
):
1340 Record
= self
._Content
[self
._ContentIndex
]
1341 if LineStart
== Record
[10] and LineEnd
== Record
[12]:
1342 if [Record
[5], Record
[6], Record
[7]] not in self
._Scope
:
1343 self
._Scope
.append([Record
[5], Record
[6], Record
[7]])
1344 self
._ContentIndex
+= 1
1348 self
._LineIndex
= LineStart
- 1
1349 self
._ValueList
= [V1
, V2
, V3
]
1351 if Owner
> 0 and Owner
in self
._IdMapping
:
1352 self
._InSubsection
= True
1354 self
._InSubsection
= False
1356 Processer
[self
._ItemType
]()
1357 except EvaluationException
as Excpt
:
1359 # Only catch expression evaluation error here. We need to report
1360 # the precise number of line on which the error occurred
1362 if hasattr(Excpt
, 'Pcd'):
1363 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
1364 Info
= GlobalData
.gPlatformOtherPcds
[Excpt
.Pcd
]
1365 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
1366 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
1367 " of the DSC file, and it is currently defined in this section:"
1368 " %s, line #: %d." % (Excpt
.Pcd
, Info
[0], Info
[1]),
1369 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1370 Line
=self
._LineIndex
+ 1)
1372 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
1373 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1374 Line
=self
._LineIndex
+ 1)
1376 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
1377 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1378 Line
=self
._LineIndex
+ 1)
1379 except MacroException
as Excpt
:
1380 EdkLogger
.error('Parser', FORMAT_INVALID
, str(Excpt
),
1381 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1382 Line
=self
._LineIndex
+ 1)
1384 if self
._ValueList
is None:
1387 NewOwner
= self
._IdMapping
.get(Owner
, -1)
1388 self
._Enabled
= int((not self
._DirectiveEvalStack
) or (False not in self
._DirectiveEvalStack
))
1389 self
._LastItem
= self
._Store
(
1399 self
._LineIndex
+ 1,
1401 self
._LineIndex
+ 1,
1405 self
._IdMapping
[Id
] = self
._LastItem
1407 GlobalData
.gPlatformDefines
.update(self
._FileLocalMacros
)
1408 self
._PostProcessed
= True
1409 self
._Content
= None
1410 def _ProcessError(self
):
1411 if not self
._Enabled
:
1413 EdkLogger
.error('Parser', ERROR_STATEMENT
, self
._ValueList
[1], File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1415 def __ProcessSectionHeader(self
):
1416 self
._SectionName
= self
._ValueList
[0]
1417 if self
._SectionName
in self
.DataType
:
1418 self
._SectionType
= self
.DataType
[self
._SectionName
]
1420 self
._SectionType
= MODEL_UNKNOWN
1422 def __ProcessSubsectionHeader(self
):
1423 self
._SubsectionName
= self
._ValueList
[0]
1424 if self
._SubsectionName
in self
.DataType
:
1425 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
1427 self
._SubsectionType
= MODEL_UNKNOWN
1429 def __RetrievePcdValue(self
):
1430 Content
= open(str(self
.MetaFile
), 'r').readlines()
1431 GlobalData
.gPlatformOtherPcds
['DSCFILE'] = str(self
.MetaFile
)
1432 for PcdType
in (MODEL_PCD_PATCHABLE_IN_MODULE
, MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_HII
,
1433 MODEL_PCD_DYNAMIC_VPD
, MODEL_PCD_DYNAMIC_EX_DEFAULT
, MODEL_PCD_DYNAMIC_EX_HII
,
1434 MODEL_PCD_DYNAMIC_EX_VPD
):
1435 Records
= self
._RawTable
.Query(PcdType
, BelongsToItem
= -1.0)
1436 for TokenSpaceGuid
, PcdName
, Value
, Dummy2
, Dummy3
, Dummy4
, ID
, Line
in Records
:
1437 Name
= TokenSpaceGuid
+ '.' + PcdName
1438 if Name
not in GlobalData
.gPlatformOtherPcds
:
1440 while not Content
[Line
- 1].lstrip().startswith(TAB_SECTION_START
):
1442 GlobalData
.gPlatformOtherPcds
[Name
] = (CleanString(Content
[Line
- 1]), PcdLine
, PcdType
)
1444 def __ProcessDefine(self
):
1445 if not self
._Enabled
:
1448 Type
, Name
, Value
= self
._ValueList
1449 Value
= ReplaceMacro(Value
, self
._Macros
, False)
1451 # If it is <Defines>, return
1453 if self
._InSubsection
:
1454 self
._ValueList
= [Type
, Name
, Value
]
1457 if self
._ItemType
== MODEL_META_DATA_DEFINE
:
1458 if self
._SectionType
== MODEL_META_DATA_HEADER
:
1459 self
._FileLocalMacros
[Name
] = Value
1461 self
._ConstructSectionMacroDict
(Name
, Value
)
1462 elif self
._ItemType
== MODEL_META_DATA_GLOBAL_DEFINE
:
1463 GlobalData
.gEdkGlobal
[Name
] = Value
1466 # Keyword in [Defines] section can be used as Macros
1468 if (self
._ItemType
== MODEL_META_DATA_HEADER
) and (self
._SectionType
== MODEL_META_DATA_HEADER
):
1469 self
._FileLocalMacros
[Name
] = Value
1471 self
._ValueList
= [Type
, Name
, Value
]
1473 def __ProcessDirective(self
):
1475 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1476 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
]:
1477 Macros
= self
._Macros
1478 Macros
.update(GlobalData
.gGlobalDefines
)
1480 Result
= ValueExpression(self
._ValueList
[1], Macros
)()
1481 except SymbolNotFound
as Exc
:
1482 EdkLogger
.debug(EdkLogger
.DEBUG_5
, str(Exc
), self
._ValueList
[1])
1484 except WrnExpression
as Excpt
:
1486 # Catch expression evaluation warning here. We need to report
1487 # the precise number of line and return the evaluation result
1489 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
1490 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1491 Line
=self
._LineIndex
+ 1)
1492 Result
= Excpt
.result
1494 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1495 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1496 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1497 self
._DirectiveStack
.append(self
._ItemType
)
1498 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
:
1499 Result
= bool(Result
)
1501 Macro
= self
._ValueList
[1]
1502 Macro
= Macro
[2:-1] if (Macro
.startswith("$(") and Macro
.endswith(")")) else Macro
1503 Result
= Macro
in self
._Macros
1504 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
:
1506 self
._DirectiveEvalStack
.append(Result
)
1507 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
:
1508 self
._DirectiveStack
.append(self
._ItemType
)
1509 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1510 self
._DirectiveEvalStack
.append(bool(Result
))
1511 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1512 self
._DirectiveStack
.append(self
._ItemType
)
1513 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1514 self
._DirectiveEvalStack
.append(True)
1515 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1516 # Back to the nearest !if/!ifdef/!ifndef
1517 while self
._DirectiveStack
:
1518 self
._DirectiveEvalStack
.pop()
1519 Directive
= self
._DirectiveStack
.pop()
1520 if Directive
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1521 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1522 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1524 elif self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1525 # The included file must be relative to workspace or same directory as DSC file
1526 __IncludeMacros
= {}
1528 # Allow using system environment variables in path after !include
1530 __IncludeMacros
['WORKSPACE'] = GlobalData
.gGlobalDefines
['WORKSPACE']
1531 if "ECP_SOURCE" in GlobalData
.gGlobalDefines
:
1532 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gGlobalDefines
['ECP_SOURCE']
1534 # During GenFds phase call DSC parser, will go into this branch.
1536 elif "ECP_SOURCE" in GlobalData
.gCommandLineDefines
:
1537 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gCommandLineDefines
['ECP_SOURCE']
1539 __IncludeMacros
['EFI_SOURCE'] = GlobalData
.gGlobalDefines
['EFI_SOURCE']
1540 __IncludeMacros
['EDK_SOURCE'] = GlobalData
.gGlobalDefines
['EDK_SOURCE']
1542 # Allow using MACROs comes from [Defines] section to keep compatible.
1544 __IncludeMacros
.update(self
._Macros
)
1546 IncludedFile
= NormPath(ReplaceMacro(self
._ValueList
[1], __IncludeMacros
, RaiseError
=True))
1548 # First search the include file under the same directory as DSC file
1550 IncludedFile1
= PathClass(IncludedFile
, self
.MetaFile
.Dir
)
1551 ErrorCode
, ErrorInfo1
= IncludedFile1
.Validate()
1554 # Also search file under the WORKSPACE directory
1556 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
1557 ErrorCode
, ErrorInfo2
= IncludedFile1
.Validate()
1559 EdkLogger
.error('parser', ErrorCode
, File
=self
._FileWithError
,
1560 Line
=self
._LineIndex
+ 1, ExtraData
=ErrorInfo1
+ "\n" + ErrorInfo2
)
1562 self
._FileWithError
= IncludedFile1
1564 FromItem
= self
._Content
[self
._ContentIndex
- 1][0]
1565 if self
._InSubsection
:
1566 Owner
= self
._Content
[self
._ContentIndex
- 1][8]
1568 Owner
= self
._Content
[self
._ContentIndex
- 1][0]
1569 IncludedFileTable
= MetaFileStorage(self
._Table
.Cur
, IncludedFile1
, MODEL_FILE_DSC
, False, FromItem
=FromItem
)
1570 Parser
= DscParser(IncludedFile1
, self
._FileType
, self
._Arch
, IncludedFileTable
,
1571 Owner
=Owner
, From
=FromItem
)
1573 self
.IncludedFiles
.add (IncludedFile1
)
1575 # set the parser status with current status
1576 Parser
._SectionName
= self
._SectionName
1577 Parser
._SubsectionType
= self
._SubsectionType
1578 Parser
._InSubsection
= self
._InSubsection
1579 Parser
._SectionType
= self
._SectionType
1580 Parser
._Scope
= self
._Scope
1581 Parser
._Enabled
= self
._Enabled
1582 # Parse the included file
1586 # Insert all records in the table for the included file into dsc file table
1587 Records
= IncludedFileTable
.GetAll()
1589 self
._Content
[self
._ContentIndex
:self
._ContentIndex
] = Records
1590 self
._Content
.pop(self
._ContentIndex
- 1)
1591 self
._ValueList
= None
1592 self
._ContentIndex
-= 1
1594 def __ProcessSkuId(self
):
1595 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=True)
1596 for Value
in self
._ValueList
]
1597 def __ProcessDefaultStores(self
):
1598 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=True)
1599 for Value
in self
._ValueList
]
1601 def __ProcessLibraryInstance(self
):
1602 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
1604 def __ProcessLibraryClass(self
):
1605 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
, RaiseError
=True)
1607 def __ProcessPcd(self
):
1608 if self
._ItemType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
1609 self
._ValueList
[2] = ReplaceMacro(self
._ValueList
[2], self
._Macros
, RaiseError
=True)
1612 ValList
, Valid
, Index
= AnalyzeDscPcd(self
._ValueList
[2], self
._ItemType
)
1614 if self
._ItemType
in (MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
, MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
):
1615 if ValList
[1] != TAB_VOID
and ValList
[2]:
1616 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect. Only VOID* type PCD need the maxsize info.", File
=self
._FileWithError
,
1617 Line
=self
._LineIndex
+ 1, ExtraData
="%s.%s|%s" % (self
._ValueList
[0], self
._ValueList
[1], self
._ValueList
[2]))
1618 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
._FileWithError
, Line
=self
._LineIndex
+ 1,
1619 ExtraData
="%s.%s|%s" % (self
._ValueList
[0], self
._ValueList
[1], self
._ValueList
[2]))
1620 PcdValue
= ValList
[Index
]
1621 if PcdValue
and "." not in self
._ValueList
[0]:
1623 ValList
[Index
] = ValueExpression(PcdValue
, self
._Macros
)(True)
1624 except WrnExpression
as Value
:
1625 ValList
[Index
] = Value
.result
1629 if ValList
[Index
] == 'True':
1630 ValList
[Index
] = '1'
1631 if ValList
[Index
] == 'False':
1632 ValList
[Index
] = '0'
1634 if (not self
._DirectiveEvalStack
) or (False not in self
._DirectiveEvalStack
):
1635 GlobalData
.gPlatformPcds
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = PcdValue
1636 self
._Symbols
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = PcdValue
1638 self
._ValueList
[2] = '|'.join(ValList
)
1642 def __ProcessComponent(self
):
1643 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1645 def __ProcessSourceOverridePath(self
):
1646 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1648 def __ProcessBuildOption(self
):
1649 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=False)
1650 for Value
in self
._ValueList
]
1653 MODEL_META_DATA_HEADER
: _DefineParser
,
1654 MODEL_EFI_SKU_ID
: _SkuIdParser
,
1655 MODEL_EFI_DEFAULT_STORES
: _DefaultStoresParser
,
1656 MODEL_EFI_LIBRARY_INSTANCE
: _LibraryInstanceParser
,
1657 MODEL_EFI_LIBRARY_CLASS
: _LibraryClassParser
,
1658 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1659 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1660 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1661 MODEL_PCD_DYNAMIC_DEFAULT
: _PcdParser
,
1662 MODEL_PCD_DYNAMIC_HII
: _PcdParser
,
1663 MODEL_PCD_DYNAMIC_VPD
: _PcdParser
,
1664 MODEL_PCD_DYNAMIC_EX_DEFAULT
: _PcdParser
,
1665 MODEL_PCD_DYNAMIC_EX_HII
: _PcdParser
,
1666 MODEL_PCD_DYNAMIC_EX_VPD
: _PcdParser
,
1667 MODEL_META_DATA_COMPONENT
: _ComponentParser
,
1668 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: _CompponentSourceOverridePathParser
,
1669 MODEL_META_DATA_BUILD_OPTION
: _BuildOptionParser
,
1670 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1671 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
1672 MODEL_META_DATA_SECTION_HEADER
: MetaFileParser
._SectionHeaderParser
,
1673 MODEL_META_DATA_SUBSECTION_HEADER
: _SubsectionHeaderParser
,
1676 ## DEC file parser class
1678 # @param FilePath The path of platform description file
1679 # @param FileType The raw data of DSC file
1680 # @param Table Database used to retrieve module/package information
1681 # @param Macros Macros used for replacement in file
1683 class DecParser(MetaFileParser
):
1684 # DEC file supported data types (one type per section)
1686 TAB_DEC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
1687 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
1688 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
1689 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
1690 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
1691 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
1692 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
1693 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
1694 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
1695 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
1696 TAB_PCDS_DYNAMIC_NULL
.upper() : MODEL_PCD_DYNAMIC
,
1697 TAB_PCDS_DYNAMIC_EX_NULL
.upper() : MODEL_PCD_DYNAMIC_EX
,
1698 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
,
1701 ## Constructor of DecParser
1703 # Initialize object of DecParser
1705 # @param FilePath The path of platform description file
1706 # @param FileType The raw data of DSC file
1707 # @param Arch Default Arch value for filtering sections
1708 # @param Table Database used to retrieve module/package information
1710 def __init__(self
, FilePath
, FileType
, Arch
, Table
):
1711 # prevent re-initialization
1712 if hasattr(self
, "_Table"):
1714 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
, -1)
1716 self
._Version
= 0x00010005 # Only EDK2 dec file is supported
1717 self
._AllPCDs
= [] # Only for check duplicate PCD
1718 self
._AllPcdDict
= {}
1720 self
._CurrentStructurePcdName
= ""
1721 self
._include
_flag
= False
1722 self
._package
_flag
= False
1728 Content
= open(str(self
.MetaFile
), 'r').readlines()
1730 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
1732 self
._DefinesCount
= 0
1733 for Index
in range(0, len(Content
)):
1734 Line
, Comment
= CleanString2(Content
[Index
])
1735 self
._CurrentLine
= Line
1736 self
._LineIndex
= Index
1738 # save comment for later use
1740 self
._Comments
.append((Comment
, self
._LineIndex
+ 1))
1746 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
1747 self
._SectionHeaderParser
()
1748 if self
._SectionName
== TAB_DEC_DEFINES
.upper():
1749 self
._DefinesCount
+= 1
1752 if self
._SectionType
== MODEL_UNKNOWN
:
1753 EdkLogger
.error("Parser", FORMAT_INVALID
,
1755 "Not able to determine \"%s\" in which section."%self
._CurrentLine
,
1756 self
.MetaFile
, self
._LineIndex
+ 1)
1757 elif len(self
._SectionType
) == 0:
1762 self
._ValueList
= ['', '', '']
1763 self
._SectionParser
[self
._SectionType
[0]](self
)
1764 if self
._ValueList
is None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
1770 # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,
1771 # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1
1773 for Arch
, ModuleType
, Type
in self
._Scope
:
1774 self
._LastItem
= self
._Store
(
1782 self
._LineIndex
+ 1,
1784 self
._LineIndex
+ 1,
1788 for Comment
, LineNo
in self
._Comments
:
1790 MODEL_META_DATA_COMMENT
,
1804 if self
._DefinesCount
> 1:
1805 EdkLogger
.error('Parser', FORMAT_INVALID
, 'Multiple [Defines] section is exist.', self
.MetaFile
)
1806 if self
._DefinesCount
== 0:
1807 EdkLogger
.error('Parser', FORMAT_INVALID
, 'No [Defines] section exist.', self
.MetaFile
)
1811 ## Section header parser
1813 # The section header is always in following format:
1815 # [section_name.arch<.platform|module_type>]
1817 def _SectionHeaderParser(self
):
1819 self
._SectionName
= ''
1820 self
._SectionType
= []
1823 Line
= re
.sub(',[\s]*', TAB_COMMA_SPLIT
, self
._CurrentLine
)
1824 for Item
in Line
[1:-1].split(TAB_COMMA_SPLIT
):
1826 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
,
1827 "section name can NOT be empty or incorrectly use separator comma",
1828 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1829 ItemList
= Item
.split(TAB_SPLIT
)
1831 # different types of PCD are permissible in one section
1832 self
._SectionName
= ItemList
[0].upper()
1833 if self
._SectionName
== TAB_DEC_DEFINES
.upper() and (len(ItemList
) > 1 or len(Line
.split(TAB_COMMA_SPLIT
)) > 1):
1834 EdkLogger
.error("Parser", FORMAT_INVALID
, "Defines section format is invalid",
1835 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1836 if self
._SectionName
in self
.DataType
:
1837 if self
.DataType
[self
._SectionName
] not in self
._SectionType
:
1838 self
._SectionType
.append(self
.DataType
[self
._SectionName
])
1840 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
1841 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1843 if MODEL_PCD_FEATURE_FLAG
in self
._SectionType
and len(self
._SectionType
) > 1:
1847 "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL
,
1849 Line
=self
._LineIndex
+ 1,
1850 ExtraData
=self
._CurrentLine
1853 if len(ItemList
) > 1:
1854 S1
= ItemList
[1].upper()
1856 S1
= TAB_ARCH_COMMON
1858 # S2 may be Platform or ModuleType
1859 if len(ItemList
) > 2:
1860 S2
= ItemList
[2].upper()
1861 # only Includes, GUIDs, PPIs, Protocols section have Private tag
1862 if self
._SectionName
in [TAB_INCLUDES
.upper(), TAB_GUIDS
.upper(), TAB_PROTOCOLS
.upper(), TAB_PPIS
.upper()]:
1864 EdkLogger
.error("Parser", FORMAT_INVALID
, 'Please use keyword "Private" as section tag modifier.',
1865 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1869 if [S1
, S2
, self
.DataType
[self
._SectionName
]] not in self
._Scope
:
1870 self
._Scope
.append([S1
, S2
, self
.DataType
[self
._SectionName
]])
1872 # 'COMMON' must not be used with specific ARCHs at the same section
1873 if TAB_ARCH_COMMON
in ArchList
and len(ArchList
) > 1:
1874 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
1875 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1877 # It is not permissible to mix section tags without the Private attribute with section tags with the Private attribute
1878 if TAB_COMMON
in PrivateList
and len(PrivateList
) > 1:
1879 EdkLogger
.error('Parser', FORMAT_INVALID
, "Can't mix section tags without the Private attribute with section tags with the Private attribute",
1880 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1882 ## [guids], [ppis] and [protocols] section parser
1884 def _GuidParser(self
):
1885 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1886 if len(TokenList
) < 2:
1887 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name or value specified",
1888 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1889 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1890 if TokenList
[0] == '':
1891 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name specified",
1892 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1893 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1894 if TokenList
[1] == '':
1895 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID value specified",
1896 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1897 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1898 if TokenList
[1][0] != '{' or TokenList
[1][-1] != '}' or GuidStructureStringToGuidString(TokenList
[1]) == '':
1899 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid GUID value format",
1900 ExtraData
=self
._CurrentLine
+ \
1901 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
1902 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1903 self
._ValueList
[0] = TokenList
[0]
1904 self
._ValueList
[1] = TokenList
[1]
1905 if self
._ValueList
[0] not in self
._GuidDict
:
1906 self
._GuidDict
[self
._ValueList
[0]] = self
._ValueList
[1]
1908 ## PCD sections parser
1910 # [PcdsFixedAtBuild]
1911 # [PcdsPatchableInModule]
1917 def _PcdParser(self
):
1918 if self
._CurrentStructurePcdName
:
1919 self
._ValueList
[0] = self
._CurrentStructurePcdName
1921 if "|" not in self
._CurrentLine
:
1922 if "<HeaderFiles>" == self
._CurrentLine
:
1923 self
._include
_flag
= True
1924 self
._package
_flag
= False
1925 self
._ValueList
= None
1927 if "<Packages>" == self
._CurrentLine
:
1928 self
._package
_flag
= True
1929 self
._ValueList
= None
1930 self
._include
_flag
= False
1933 if self
._include
_flag
:
1934 self
._ValueList
[1] = "<HeaderFiles>_" + md5(self
._CurrentLine
.encode('utf-8')).hexdigest()
1935 self
._ValueList
[2] = self
._CurrentLine
1936 if self
._package
_flag
and "}" != self
._CurrentLine
:
1937 self
._ValueList
[1] = "<Packages>_" + md5(self
._CurrentLine
.encode('utf-8')).hexdigest()
1938 self
._ValueList
[2] = self
._CurrentLine
1939 if self
._CurrentLine
== "}":
1940 self
._package
_flag
= False
1941 self
._include
_flag
= False
1942 self
._ValueList
= None
1945 PcdTockens
= self
._CurrentLine
.split(TAB_VALUE_SPLIT
)
1946 PcdNames
= PcdTockens
[0].split(TAB_SPLIT
)
1947 if len(PcdNames
) == 2:
1948 self
._CurrentStructurePcdName
= ""
1950 if self
._CurrentStructurePcdName
!= TAB_SPLIT
.join(PcdNames
[:2]):
1951 EdkLogger
.error('Parser', FORMAT_INVALID
, "Pcd Name does not match: %s and %s " % (self
._CurrentStructurePcdName
, TAB_SPLIT
.join(PcdNames
[:2])),
1952 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1953 self
._ValueList
[1] = TAB_SPLIT
.join(PcdNames
[2:])
1954 self
._ValueList
[2] = PcdTockens
[1]
1955 if not self
._CurrentStructurePcdName
:
1956 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1957 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1958 ValueRe
= re
.compile(r
'^[a-zA-Z_][a-zA-Z0-9_]*')
1959 # check PCD information
1960 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1961 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1962 ExtraData
=self
._CurrentLine
+ \
1963 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1964 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1965 # check format of token space GUID CName
1966 if not ValueRe
.match(self
._ValueList
[0]):
1967 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_]*'",
1968 ExtraData
=self
._CurrentLine
+ \
1969 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1970 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1971 # check format of PCD CName
1972 if not ValueRe
.match(self
._ValueList
[1]):
1973 EdkLogger
.error('Parser', FORMAT_INVALID
, "The format of the PCD CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",
1974 ExtraData
=self
._CurrentLine
+ \
1975 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1976 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1977 # check PCD datum information
1978 if len(TokenList
) < 2 or TokenList
[1] == '':
1979 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD Datum information given",
1980 ExtraData
=self
._CurrentLine
+ \
1981 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1982 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1985 ValueRe
= re
.compile(r
'^\s*L?\".*\|.*\"')
1986 PtrValue
= ValueRe
.findall(TokenList
[1])
1988 # Has VOID* type string, may contain "|" character in the string.
1989 if len(PtrValue
) != 0:
1990 ptrValueList
= re
.sub(ValueRe
, '', TokenList
[1])
1991 ValueList
= AnalyzePcdExpression(ptrValueList
)
1992 ValueList
[0] = PtrValue
[0]
1994 ValueList
= AnalyzePcdExpression(TokenList
[1])
1997 # check if there's enough datum information given
1998 if len(ValueList
) != 3:
1999 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid PCD Datum information given",
2000 ExtraData
=self
._CurrentLine
+ \
2001 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2002 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2003 # check default value
2004 if ValueList
[0] == '':
2005 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DefaultValue in PCD Datum information",
2006 ExtraData
=self
._CurrentLine
+ \
2007 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2008 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2010 if ValueList
[1] == '':
2011 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DatumType in PCD Datum information",
2012 ExtraData
=self
._CurrentLine
+ \
2013 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2014 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2015 # check token of the PCD
2016 if ValueList
[2] == '':
2017 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing Token in PCD Datum information",
2018 ExtraData
=self
._CurrentLine
+ \
2019 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2020 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2022 PcdValue
= ValueList
[0]
2025 self
._GuidDict
.update(self
._AllPcdDict
)
2026 ValueList
[0] = ValueExpressionEx(ValueList
[0], ValueList
[1], self
._GuidDict
)(True)
2027 except BadExpression
as Value
:
2028 EdkLogger
.error('Parser', FORMAT_INVALID
, Value
, ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2029 # check format of default value against the datum type
2030 IsValid
, Cause
= CheckPcdDatum(ValueList
[1], ValueList
[0])
2032 EdkLogger
.error('Parser', FORMAT_INVALID
, Cause
, ExtraData
=self
._CurrentLine
,
2033 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2035 if Cause
== "StructurePcd":
2036 self
._CurrentStructurePcdName
= TAB_SPLIT
.join(self
._ValueList
[0:2])
2037 self
._ValueList
[0] = self
._CurrentStructurePcdName
2038 self
._ValueList
[1] = ValueList
[1].strip()
2040 if ValueList
[0] in ['True', 'true', 'TRUE']:
2042 elif ValueList
[0] in ['False', 'false', 'FALSE']:
2045 # check for duplicate PCD definition
2046 if (self
._Scope
[0], self
._ValueList
[0], self
._ValueList
[1]) in self
._AllPCDs
:
2047 EdkLogger
.error('Parser', FORMAT_INVALID
,
2048 "The same PCD name and GUID have been already defined",
2049 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2051 self
._AllPCDs
.append((self
._Scope
[0], self
._ValueList
[0], self
._ValueList
[1]))
2052 self
._AllPcdDict
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = ValueList
[0]
2054 self
._ValueList
[2] = ValueList
[0].strip() + '|' + ValueList
[1].strip() + '|' + ValueList
[2].strip()
2057 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
2058 MODEL_EFI_INCLUDE
: MetaFileParser
._PathParser
,
2059 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
2060 MODEL_EFI_GUID
: _GuidParser
,
2061 MODEL_EFI_PPI
: _GuidParser
,
2062 MODEL_EFI_PROTOCOL
: _GuidParser
,
2063 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
2064 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
2065 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
2066 MODEL_PCD_DYNAMIC
: _PcdParser
,
2067 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
2068 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
2069 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
2074 # This acts like the main() function for the script, unless it is 'import'ed into another
2077 if __name__
== '__main__':