2 # This file is used to parse meta files
4 # Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
5 # (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
6 # This program and the accompanying materials
7 # are licensed and made available under the terms and conditions of the BSD License
8 # which accompanies this distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 import Common
.LongFilePathOs
as os
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
.String
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
35 from MetaFileTable
import MetaFileStorage
36 from MetaFileCommentParser
import CheckInfComment
38 ## A decorator used to parse macro definition
39 def ParseMacro(Parser
):
40 def MacroParser(self
):
41 Match
= gMacroDefPattern
.match(self
._CurrentLine
)
43 # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method
47 TokenList
= GetSplitValueList(self
._CurrentLine
[Match
.end(1):], TAB_EQUAL_SPLIT
, 1)
50 EdkLogger
.error('Parser', FORMAT_INVALID
, "No macro name given",
51 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
52 if len(TokenList
) < 2:
56 Name
, Value
= TokenList
57 # Global macros can be only defined via environment variable
58 if Name
in GlobalData
.gGlobalDefines
:
59 EdkLogger
.error('Parser', FORMAT_INVALID
, "%s can only be defined via environment variable" % Name
,
60 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
61 # Only upper case letters, digit and '_' are allowed
62 if not gMacroNamePattern
.match(Name
):
63 EdkLogger
.error('Parser', FORMAT_INVALID
, "The macro name must be in the pattern [A-Z][A-Z0-9_]*",
64 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
66 Value
= ReplaceMacro(Value
, self
._Macros
)
67 if Type
in self
.DataType
:
68 self
._ItemType
= self
.DataType
[Type
]
70 self
._ItemType
= MODEL_META_DATA_DEFINE
71 # DEFINE defined macros
72 if Type
== TAB_DSC_DEFINES_DEFINE
:
74 # First judge whether this DEFINE is in conditional directive statements or not.
76 if type(self
) == DscParser
and self
._InDirective
> -1:
79 if type(self
) == DecParser
:
80 if MODEL_META_DATA_HEADER
in self
._SectionType
:
81 self
._FileLocalMacros
[Name
] = Value
83 self
._ConstructSectionMacroDict
(Name
, Value
)
84 elif self
._SectionType
== MODEL_META_DATA_HEADER
:
85 self
._FileLocalMacros
[Name
] = Value
87 self
._ConstructSectionMacroDict
(Name
, Value
)
89 # EDK_GLOBAL defined macros
90 elif type(self
) != DscParser
:
91 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL can only be used in .dsc file",
92 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
93 elif self
._SectionType
!= MODEL_META_DATA_HEADER
:
94 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL can only be used under [Defines] section",
95 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
96 elif (Name
in self
._FileLocalMacros
) and (self
._FileLocalMacros
[Name
] != Value
):
97 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL defined a macro with the same name and different value as one defined by 'DEFINE'",
98 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
100 self
._ValueList
= [Type
, Name
, Value
]
104 ## Base class of parser
106 # This class is used for derivation purpose. The specific parser for one kind
107 # type file must derive this class and implement some public interfaces.
109 # @param FilePath The path of platform description file
110 # @param FileType The raw data of DSC file
111 # @param Table Database used to retrieve module/package information
112 # @param Macros Macros used for replacement in file
113 # @param Owner Owner ID (for sub-section parsing)
114 # @param From ID from which the data comes (for !INCLUDE directive)
116 class MetaFileParser(object):
117 # data type (file content) for specific file type
120 # Parser objects used to implement singleton
125 # One file, one parser object. This factory method makes sure that there's
126 # only one object constructed for one meta file.
128 # @param Class class object of real AutoGen class
129 # (InfParser, DecParser or DscParser)
130 # @param FilePath The path of meta file
131 # @param *args The specific class related parameters
132 # @param **kwargs The specific class related dict parameters
134 def __new__(Class
, FilePath
, *args
, **kwargs
):
135 if FilePath
in Class
.MetaFiles
:
136 return Class
.MetaFiles
[FilePath
]
138 ParserObject
= super(MetaFileParser
, Class
).__new
__(Class
)
139 Class
.MetaFiles
[FilePath
] = ParserObject
142 ## Constructor of MetaFileParser
144 # Initialize object of MetaFileParser
146 # @param FilePath The path of platform description file
147 # @param FileType The raw data of DSC file
148 # @param Arch Default Arch value for filtering sections
149 # @param Table Database used to retrieve module/package information
150 # @param Owner Owner ID (for sub-section parsing)
151 # @param From ID from which the data comes (for !INCLUDE directive)
153 def __init__(self
, FilePath
, FileType
, Arch
, Table
, Owner
= -1, From
= -1):
155 self
._RawTable
= Table
157 self
._FileType
= FileType
158 self
.MetaFile
= FilePath
159 self
._FileDir
= self
.MetaFile
.Dir
161 self
._FileLocalMacros
= {}
162 self
._SectionsMacroDict
= {}
164 # for recursive parsing
165 self
._Owner
= [Owner
]
168 # parsr status for parsing
169 self
._ValueList
= ['', '', '', '', '']
172 self
._CurrentLine
= ''
173 self
._SectionType
= MODEL_UNKNOWN
174 self
._SectionName
= ''
175 self
._InSubsection
= False
176 self
._SubsectionType
= MODEL_UNKNOWN
177 self
._SubsectionName
= ''
178 self
._ItemType
= MODEL_UNKNOWN
181 self
._Finished
= False
182 self
._PostProcessed
= False
183 # Different version of meta-file has different way to parse.
185 self
._GuidDict
= {} # for Parser PCD value {GUID(gTokeSpaceGuidName)}
187 ## Store the parsed data in table
188 def _Store(self
, *Args
):
189 return self
._Table
.Insert(*Args
)
191 ## Virtual method for starting parse
193 raise NotImplementedError
195 ## Notify a post-process is needed
196 def DoPostProcess(self
):
197 self
._PostProcessed
= False
199 ## Set parsing complete flag in both class and table
201 self
._Finished
= True
202 ## Do not set end flag when processing included files
204 self
._Table
.SetEndFlag()
206 def _PostProcess(self
):
207 self
._PostProcessed
= True
209 ## Get the parse complete flag
210 def _GetFinished(self
):
211 return self
._Finished
213 ## Set the complete flag
214 def _SetFinished(self
, Value
):
215 self
._Finished
= Value
217 ## Remove records that do not match given Filter Arch
218 def _FilterRecordList(self
, RecordList
, FilterArch
):
220 for Record
in RecordList
:
222 if Arch
== 'COMMON' or Arch
== FilterArch
:
223 NewRecordList
.append(Record
)
226 ## Use [] style to query data in table, just for readability
228 # DataInfo = [data_type, scope1(arch), scope2(platform/moduletype)]
230 def __getitem__(self
, DataInfo
):
231 if type(DataInfo
) != type(()):
232 DataInfo
= (DataInfo
,)
234 # Parse the file first, if necessary
235 if not self
._Finished
:
236 if self
._RawTable
.IsIntegrity():
237 self
._Finished
= True
239 self
._Table
= self
._RawTable
240 self
._PostProcessed
= False
243 # No specific ARCH or Platform given, use raw data
244 if self
._RawTable
and (len(DataInfo
) == 1 or DataInfo
[1] == None):
245 return self
._FilterRecordList
(self
._RawTable
.Query(*DataInfo
), self
._Arch
)
247 # Do post-process if necessary
248 if not self
._PostProcessed
:
251 return self
._FilterRecordList
(self
._Table
.Query(*DataInfo
), DataInfo
[1])
253 ## Data parser for the common format in different type of file
255 # The common format in the meatfile is like
260 def _CommonParser(self
):
261 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
262 self
._ValueList
[0:len(TokenList
)] = TokenList
264 ## Data parser for the format in which there's path
266 # Only path can have macro used. So we need to replace them before use.
269 def _PathParser(self
):
270 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
271 self
._ValueList
[0:len(TokenList
)] = TokenList
272 # Don't do macro replacement for dsc file at this point
273 if type(self
) != DscParser
:
274 Macros
= self
._Macros
275 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
277 ## Skip unsupported data
279 EdkLogger
.warn("Parser", "Unrecognized content", File
=self
.MetaFile
,
280 Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
);
281 self
._ValueList
[0:1] = [self
._CurrentLine
]
283 ## Skip unsupported data for UserExtension Section
284 def _SkipUserExtension(self
):
285 self
._ValueList
[0:1] = [self
._CurrentLine
]
287 ## Section header parser
289 # The section header is always in following format:
291 # [section_name.arch<.platform|module_type>]
293 def _SectionHeaderParser(self
):
295 self
._SectionName
= ''
297 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
300 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
,3)
301 # different section should not mix in one section
302 if self
._SectionName
!= '' and self
._SectionName
!= ItemList
[0].upper():
303 EdkLogger
.error('Parser', FORMAT_INVALID
, "Different section names in the same section",
304 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
305 self
._SectionName
= ItemList
[0].upper()
306 if self
._SectionName
in self
.DataType
:
307 self
._SectionType
= self
.DataType
[self
._SectionName
]
308 # Check if the section name is valid
309 if self
._SectionName
not in SECTIONS_HAVE_ITEM_AFTER_ARCH
and len(ItemList
) > 3:
310 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
311 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
312 elif self
._Version
>= 0x00010005:
313 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
314 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
316 self
._SectionType
= MODEL_UNKNOWN
319 if len(ItemList
) > 1:
320 S1
= ItemList
[1].upper()
325 # S2 may be Platform or ModuleType
326 if len(ItemList
) > 2:
327 if self
._SectionName
.upper() in SECTIONS_HAVE_ITEM_PCD
:
330 S2
= ItemList
[2].upper()
333 if len(ItemList
) > 3:
337 self
._Scope
.append([S1
, S2
, S3
])
339 # 'COMMON' must not be used with specific ARCHs at the same section
340 if 'COMMON' in ArchList
and len(ArchList
) > 1:
341 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
342 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
343 # If the section information is needed later, it should be stored in database
344 self
._ValueList
[0] = self
._SectionName
346 ## [defines] section parser
348 def _DefineParser(self
):
349 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
350 self
._ValueList
[1:len(TokenList
)] = TokenList
351 if not self
._ValueList
[1]:
352 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
353 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
354 if not self
._ValueList
[2]:
355 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
356 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
358 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
359 Name
, Value
= self
._ValueList
[1], self
._ValueList
[2]
360 MacroUsed
= GlobalData
.gMacroRefPattern
.findall(Value
)
361 if len(MacroUsed
) != 0:
362 for Macro
in MacroUsed
:
363 if Macro
in GlobalData
.gGlobalDefines
:
364 EdkLogger
.error("Parser", FORMAT_INVALID
, "Global macro %s is not permitted." % (Macro
), ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
366 EdkLogger
.error("Parser", FORMAT_INVALID
, "%s not defined" % (Macro
), ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
367 # Sometimes, we need to make differences between EDK and EDK2 modules
368 if Name
== 'INF_VERSION':
369 if re
.match(r
'0[xX][\da-f-A-F]{5,8}', Value
):
370 self
._Version
= int(Value
, 0)
371 elif re
.match(r
'\d+\.\d+', Value
):
372 ValueList
= Value
.split('.')
373 Major
= '%04o' % int(ValueList
[0], 0)
374 Minor
= '%04o' % int(ValueList
[1], 0)
375 self
._Version
= int('0x' + Major
+ Minor
, 0)
377 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid version number",
378 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
380 if type(self
) == InfParser
and self
._Version
< 0x00010005:
381 # EDK module allows using defines as macros
382 self
._FileLocalMacros
[Name
] = Value
383 self
._Defines
[Name
] = Value
385 ## [BuildOptions] section parser
387 def _BuildOptionParser(self
):
388 self
._CurrentLine
= CleanString(self
._CurrentLine
, BuildOption
=True)
389 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
390 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
391 if len(TokenList2
) == 2:
392 self
._ValueList
[0] = TokenList2
[0] # toolchain family
393 self
._ValueList
[1] = TokenList2
[1] # keys
395 self
._ValueList
[1] = TokenList
[0]
396 if len(TokenList
) == 2 and type(self
) != DscParser
: # value
397 self
._ValueList
[2] = ReplaceMacro(TokenList
[1], self
._Macros
)
399 if self
._ValueList
[1].count('_') != 4:
403 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
404 ExtraData
=self
._CurrentLine
,
406 Line
=self
._LineIndex
+ 1
408 def GetValidExpression(self
, TokenSpaceGuid
, PcdCName
):
409 return self
._Table
.GetValidExpression(TokenSpaceGuid
, PcdCName
)
410 def _GetMacros(self
):
412 Macros
.update(self
._FileLocalMacros
)
413 Macros
.update(self
._GetApplicableSectionMacro
())
416 ## Construct section Macro dict
417 def _ConstructSectionMacroDict(self
, Name
, Value
):
418 ScopeKey
= [(Scope
[0], Scope
[1],Scope
[2]) for Scope
in self
._Scope
]
419 ScopeKey
= tuple(ScopeKey
)
420 SectionDictKey
= self
._SectionType
, ScopeKey
422 # DecParser SectionType is a list, will contain more than one item only in Pcd Section
423 # As Pcd section macro usage is not alllowed, so here it is safe
425 if type(self
) == DecParser
:
426 SectionDictKey
= self
._SectionType
[0], ScopeKey
427 if SectionDictKey
not in self
._SectionsMacroDict
:
428 self
._SectionsMacroDict
[SectionDictKey
] = {}
429 SectionLocalMacros
= self
._SectionsMacroDict
[SectionDictKey
]
430 SectionLocalMacros
[Name
] = Value
432 ## Get section Macros that are applicable to current line, which may come from other sections
433 ## that share the same name while scope is wider
434 def _GetApplicableSectionMacro(self
):
441 ActiveSectionType
= self
._SectionType
442 if type(self
) == DecParser
:
443 ActiveSectionType
= self
._SectionType
[0]
445 for (SectionType
, Scope
) in self
._SectionsMacroDict
:
446 if SectionType
!= ActiveSectionType
:
449 for ActiveScope
in self
._Scope
:
450 Scope0
, Scope1
,Scope2
= ActiveScope
[0], ActiveScope
[1],ActiveScope
[2]
451 if(Scope0
, Scope1
,Scope2
) not in Scope
:
454 SpeSpeMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
456 for ActiveScope
in self
._Scope
:
457 Scope0
, Scope1
,Scope2
= ActiveScope
[0], ActiveScope
[1],ActiveScope
[2]
458 if(Scope0
, Scope1
,Scope2
) not in Scope
and (Scope0
, "COMMON","COMMON") not in Scope
and ("COMMON", Scope1
,"COMMON") not in Scope
:
461 ComSpeMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
463 if ("COMMON", "COMMON","COMMON") in Scope
:
464 ComComMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
466 Macros
.update(ComComMacroDict
)
467 Macros
.update(ComSpeMacroDict
)
468 Macros
.update(SpeSpeMacroDict
)
473 Finished
= property(_GetFinished
, _SetFinished
)
474 _Macros
= property(_GetMacros
)
477 ## INF file parser class
479 # @param FilePath The path of platform description file
480 # @param FileType The raw data of DSC file
481 # @param Table Database used to retrieve module/package information
482 # @param Macros Macros used for replacement in file
484 class InfParser(MetaFileParser
):
485 # INF file supported data types (one type per section)
487 TAB_UNKNOWN
.upper() : MODEL_UNKNOWN
,
488 TAB_INF_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
489 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
490 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
491 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
492 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
493 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
494 TAB_PACKAGES
.upper() : MODEL_META_DATA_PACKAGE
,
495 TAB_NMAKE
.upper() : MODEL_META_DATA_NMAKE
,
496 TAB_INF_FIXED_PCD
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
497 TAB_INF_PATCH_PCD
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
498 TAB_INF_FEATURE_PCD
.upper() : MODEL_PCD_FEATURE_FLAG
,
499 TAB_INF_PCD_EX
.upper() : MODEL_PCD_DYNAMIC_EX
,
500 TAB_INF_PCD
.upper() : MODEL_PCD_DYNAMIC
,
501 TAB_SOURCES
.upper() : MODEL_EFI_SOURCE_FILE
,
502 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
503 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
504 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
505 TAB_DEPEX
.upper() : MODEL_EFI_DEPEX
,
506 TAB_BINARIES
.upper() : MODEL_EFI_BINARY_FILE
,
507 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
510 ## Constructor of InfParser
512 # Initialize object of InfParser
514 # @param FilePath The path of module description file
515 # @param FileType The raw data of DSC file
516 # @param Arch Default Arch value for filtering sections
517 # @param Table Database used to retrieve module/package information
519 def __init__(self
, FilePath
, FileType
, Arch
, Table
):
520 # prevent re-initialization
521 if hasattr(self
, "_Table"):
523 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
)
531 Content
= open(str(self
.MetaFile
), 'r').readlines()
533 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
535 # parse the file line by line
536 IsFindBlockComment
= False
537 GetHeaderComment
= False
542 for Index
in range(0, len(Content
)):
543 # skip empty, commented, block commented lines
544 Line
, Comment
= CleanString2(Content
[Index
], AllowCppStyleComment
=True)
546 if Index
+ 1 < len(Content
):
547 NextLine
, NextComment
= CleanString2(Content
[Index
+ 1])
550 Comments
.append((Comment
, Index
+ 1))
551 elif GetHeaderComment
:
552 SectionComments
.extend(Comments
)
555 if Line
.find(DataType
.TAB_COMMENT_EDK_START
) > -1:
556 IsFindBlockComment
= True
558 if Line
.find(DataType
.TAB_COMMENT_EDK_END
) > -1:
559 IsFindBlockComment
= False
561 if IsFindBlockComment
:
564 self
._LineIndex
= Index
565 self
._CurrentLine
= Line
568 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
569 if not GetHeaderComment
:
570 for Cmt
, LNo
in Comments
:
571 self
._Store
(MODEL_META_DATA_HEADER_COMMENT
, Cmt
, '', '', 'COMMON',
572 'COMMON', self
._Owner
[-1], LNo
, -1, LNo
, -1, 0)
573 GetHeaderComment
= True
575 TailComments
.extend(SectionComments
+ Comments
)
577 self
._SectionHeaderParser
()
578 # Check invalid sections
579 if self
._Version
< 0x00010005:
580 if self
._SectionType
in [MODEL_META_DATA_BUILD_OPTION
,
581 MODEL_EFI_LIBRARY_CLASS
,
582 MODEL_META_DATA_PACKAGE
,
583 MODEL_PCD_FIXED_AT_BUILD
,
584 MODEL_PCD_PATCHABLE_IN_MODULE
,
585 MODEL_PCD_FEATURE_FLAG
,
586 MODEL_PCD_DYNAMIC_EX
,
591 MODEL_META_DATA_USER_EXTENSION
]:
592 EdkLogger
.error('Parser', FORMAT_INVALID
,
593 "Section [%s] is not allowed in inf file without version" % (self
._SectionName
),
594 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
595 elif self
._SectionType
in [MODEL_EFI_INCLUDE
,
596 MODEL_EFI_LIBRARY_INSTANCE
,
597 MODEL_META_DATA_NMAKE
]:
598 EdkLogger
.error('Parser', FORMAT_INVALID
,
599 "Section [%s] is not allowed in inf file with version 0x%08x" % (self
._SectionName
, self
._Version
),
600 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
602 # merge two lines specified by '\' in section NMAKE
603 elif self
._SectionType
== MODEL_META_DATA_NMAKE
:
606 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
609 if NextLine
[0] == TAB_SECTION_START
and NextLine
[-1] == TAB_SECTION_END
:
610 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
613 NmakeLine
= NmakeLine
+ ' ' + Line
[0:-1]
616 self
._CurrentLine
= NmakeLine
+ Line
620 self
._ValueList
= ['', '', '']
621 # parse current line, result will be put in self._ValueList
622 self
._SectionParser
[self
._SectionType
](self
)
623 if self
._ValueList
== None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
628 Comments
.append((Comment
, Index
+ 1))
629 if GlobalData
.gOptions
and GlobalData
.gOptions
.CheckUsage
:
630 CheckInfComment(self
._SectionType
, Comments
, str(self
.MetaFile
), Index
+ 1, self
._ValueList
)
632 # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
633 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
635 for Arch
, Platform
,_
in self
._Scope
:
636 LastItem
= self
._Store
(self
._SectionType
,
649 for Comment
, LineNo
in Comments
:
650 self
._Store
(MODEL_META_DATA_COMMENT
, Comment
, '', '', Arch
, Platform
,
651 LastItem
, LineNo
, -1, LineNo
, -1, 0)
654 TailComments
.extend(SectionComments
+ Comments
)
655 if IsFindBlockComment
:
656 EdkLogger
.error("Parser", FORMAT_INVALID
, "Open block comments (starting with /*) are expected to end with */",
659 # If there are tail comments in INF file, save to database whatever the comments are
660 for Comment
in TailComments
:
661 self
._Store
(MODEL_META_DATA_TAIL_COMMENT
, Comment
[0], '', '', 'COMMON',
662 'COMMON', self
._Owner
[-1], -1, -1, -1, -1, 0)
665 ## Data parser for the format in which there's path
667 # Only path can have macro used. So we need to replace them before use.
669 def _IncludeParser(self
):
670 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
671 self
._ValueList
[0:len(TokenList
)] = TokenList
672 Macros
= self
._Macros
674 for Index
in range(0, len(self
._ValueList
)):
675 Value
= self
._ValueList
[Index
]
679 if Value
.upper().find('$(EFI_SOURCE)\Edk'.upper()) > -1 or Value
.upper().find('$(EFI_SOURCE)/Edk'.upper()) > -1:
680 Value
= '$(EDK_SOURCE)' + Value
[17:]
681 if Value
.find('$(EFI_SOURCE)') > -1 or Value
.find('$(EDK_SOURCE)') > -1:
683 elif Value
.startswith('.'):
685 elif Value
.startswith('$('):
688 Value
= '$(EFI_SOURCE)/' + Value
690 self
._ValueList
[Index
] = ReplaceMacro(Value
, Macros
)
692 ## Parse [Sources] section
694 # Only path can have macro used. So we need to replace them before use.
697 def _SourceFileParser(self
):
698 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
699 self
._ValueList
[0:len(TokenList
)] = TokenList
700 Macros
= self
._Macros
701 # For Acpi tables, remove macro like ' TABLE_NAME=Sata1'
702 if 'COMPONENT_TYPE' in Macros
:
703 if self
._Defines
['COMPONENT_TYPE'].upper() == 'ACPITABLE':
704 self
._ValueList
[0] = GetSplitValueList(self
._ValueList
[0], ' ', 1)[0]
705 if self
._Defines
['BASE_NAME'] == 'Microcode':
707 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
709 ## Parse [Binaries] section
711 # Only path can have macro used. So we need to replace them before use.
714 def _BinaryFileParser(self
):
715 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 2)
716 if len(TokenList
) < 2:
717 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type or path specified",
718 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
719 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
721 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type specified",
722 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
723 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
725 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file path specified",
726 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
727 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
728 self
._ValueList
[0:len(TokenList
)] = TokenList
729 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
731 ## [nmake] section parser (Edk.x style only)
732 def _NmakeParser(self
):
733 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
734 self
._ValueList
[0:len(TokenList
)] = TokenList
736 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
737 # remove self-reference in macro setting
738 #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
740 ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
742 def _PcdParser(self
):
743 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
744 ValueList
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
745 if len(ValueList
) != 2:
746 EdkLogger
.error('Parser', FORMAT_INVALID
, "Illegal token space GUID and PCD name format",
747 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
748 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
749 self
._ValueList
[0:1] = ValueList
750 if len(TokenList
) > 1:
751 self
._ValueList
[2] = TokenList
[1]
752 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
753 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
754 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
755 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
757 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
758 if self
._ValueList
[2] != '':
759 InfPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
760 if InfPcdValueList
[0] in ['True', 'true', 'TRUE']:
761 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '1', 1);
762 elif InfPcdValueList
[0] in ['False', 'false', 'FALSE']:
763 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '0', 1);
764 if (self
._ValueList
[0], self
._ValueList
[1]) not in self
.PcdsDict
:
765 self
.PcdsDict
[self
._ValueList
[0], self
._ValueList
[1]] = self
._SectionType
766 elif self
.PcdsDict
[self
._ValueList
[0], self
._ValueList
[1]] != self
._SectionType
:
767 EdkLogger
.error('Parser', FORMAT_INVALID
, "It is not permissible to list a specified PCD in different PCD type sections.",
768 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
769 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
771 ## [depex] section parser
773 def _DepexParser(self
):
774 self
._ValueList
[0:1] = [self
._CurrentLine
]
777 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
778 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
779 MODEL_META_DATA_BUILD_OPTION
: MetaFileParser
._BuildOptionParser
,
780 MODEL_EFI_INCLUDE
: _IncludeParser
, # for Edk.x modules
781 MODEL_EFI_LIBRARY_INSTANCE
: MetaFileParser
._CommonParser
, # for Edk.x modules
782 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
783 MODEL_META_DATA_PACKAGE
: MetaFileParser
._PathParser
,
784 MODEL_META_DATA_NMAKE
: _NmakeParser
, # for Edk.x modules
785 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
786 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
787 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
788 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
789 MODEL_PCD_DYNAMIC
: _PcdParser
,
790 MODEL_EFI_SOURCE_FILE
: _SourceFileParser
,
791 MODEL_EFI_GUID
: MetaFileParser
._CommonParser
,
792 MODEL_EFI_PROTOCOL
: MetaFileParser
._CommonParser
,
793 MODEL_EFI_PPI
: MetaFileParser
._CommonParser
,
794 MODEL_EFI_DEPEX
: _DepexParser
,
795 MODEL_EFI_BINARY_FILE
: _BinaryFileParser
,
796 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
799 ## DSC file parser class
801 # @param FilePath The path of platform description file
802 # @param FileType The raw data of DSC file
803 # @param Table Database used to retrieve module/package information
804 # @param Macros Macros used for replacement in file
805 # @param Owner Owner ID (for sub-section parsing)
806 # @param From ID from which the data comes (for !INCLUDE directive)
808 class DscParser(MetaFileParser
):
809 # DSC file supported data types (one type per section)
811 TAB_SKUIDS
.upper() : MODEL_EFI_SKU_ID
,
812 TAB_DEFAULT_STORES
.upper() : MODEL_EFI_DEFAULT_STORES
,
813 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
814 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
815 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
816 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
817 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
818 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
819 TAB_PCDS_DYNAMIC_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_DEFAULT
,
820 TAB_PCDS_DYNAMIC_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_HII
,
821 TAB_PCDS_DYNAMIC_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_VPD
,
822 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT
,
823 TAB_PCDS_DYNAMIC_EX_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_HII
,
824 TAB_PCDS_DYNAMIC_EX_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_VPD
,
825 TAB_COMPONENTS
.upper() : MODEL_META_DATA_COMPONENT
,
826 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
.upper() : MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
,
827 TAB_DSC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
828 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
829 TAB_DSC_DEFINES_EDKGLOBAL
: MODEL_META_DATA_GLOBAL_DEFINE
,
830 TAB_INCLUDE
.upper() : MODEL_META_DATA_INCLUDE
,
831 TAB_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
832 TAB_IF_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
833 TAB_IF_N_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
,
834 TAB_ELSE_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
,
835 TAB_ELSE
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
,
836 TAB_END_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
,
837 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
,
840 # Valid names in define section
847 "PCD_INFO_GENERATION",
848 "PCD_VAR_CHECK_GENERATION",
849 "SUPPORTED_ARCHITECTURES",
858 "FIX_LOAD_TOP_MEMORY_ADDRESS",
863 SubSectionDefineKeywords
= [
867 SymbolPattern
= ValueExpression
.SymbolPattern
869 IncludedFiles
= set()
871 ## Constructor of DscParser
873 # Initialize object of DscParser
875 # @param FilePath The path of platform description file
876 # @param FileType The raw data of DSC file
877 # @param Arch Default Arch value for filtering sections
878 # @param Table Database used to retrieve module/package information
879 # @param Owner Owner ID (for sub-section parsing)
880 # @param From ID from which the data comes (for !INCLUDE directive)
882 def __init__(self
, FilePath
, FileType
, Arch
, Table
, Owner
= -1, From
= -1):
883 # prevent re-initialization
884 if hasattr(self
, "_Table"):
886 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
, Owner
, From
)
887 self
._Version
= 0x00010005 # Only EDK2 dsc file is supported
888 # to store conditional directive evaluation result
889 self
._DirectiveStack
= []
890 self
._DirectiveEvalStack
= []
894 # Specify whether current line is in uncertain condition
896 self
._InDirective
= -1
898 # Final valid replacable symbols
901 # Map the ID between the original table and new table to track
904 self
._IdMapping
= {-1:-1}
910 Content
= open(str(self
.MetaFile
), 'r').readlines()
912 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
915 for Index
in range(0, len(Content
)):
916 Line
= CleanString(Content
[Index
])
921 self
._CurrentLine
= Line
922 self
._LineIndex
= Index
923 if self
._InSubsection
and self
._Owner
[-1] == -1:
924 self
._Owner
.append(self
._LastItem
)
927 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
928 self
._SectionType
= MODEL_META_DATA_SECTION_HEADER
930 elif Line
[0] == '}' and self
._InSubsection
:
931 self
._InSubsection
= False
932 self
._SubsectionType
= MODEL_UNKNOWN
933 self
._SubsectionName
= ''
938 elif Line
[0] == TAB_OPTION_START
and Line
[-1] == TAB_OPTION_END
:
939 self
._SubsectionType
= MODEL_META_DATA_SUBSECTION_HEADER
942 self
._DirectiveParser
()
944 if Line
[0] == TAB_OPTION_START
and not self
._InSubsection
:
945 EdkLogger
.error("Parser", FILE_READ_FAILURE
, "Missing the '{' before %s in Line %s" % (Line
, Index
+1),ExtraData
=self
.MetaFile
)
947 if self
._InSubsection
:
948 SectionType
= self
._SubsectionType
950 SectionType
= self
._SectionType
951 self
._ItemType
= SectionType
953 self
._ValueList
= ['', '', '']
954 self
._SectionParser
[SectionType
](self
)
955 if self
._ValueList
== None:
958 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
959 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
961 for Arch
, ModuleType
, DefaultStore
in self
._Scope
:
962 Owner
= self
._Owner
[-1]
963 if self
._SubsectionType
!= MODEL_UNKNOWN
:
964 Owner
= OwnerId
[Arch
]
965 self
._LastItem
= self
._Store
(
981 if self
._SubsectionType
== MODEL_UNKNOWN
and self
._InSubsection
:
982 OwnerId
[Arch
] = self
._LastItem
984 if self
._DirectiveStack
:
985 Type
, Line
, Text
= self
._DirectiveStack
[-1]
986 EdkLogger
.error('Parser', FORMAT_INVALID
, "No matching '!endif' found",
987 ExtraData
=Text
, File
=self
.MetaFile
, Line
=Line
)
990 ## <subsection_header> parser
991 def _SubsectionHeaderParser(self
):
992 self
._SubsectionName
= self
._CurrentLine
[1:-1].upper()
993 if self
._SubsectionName
in self
.DataType
:
994 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
996 self
._SubsectionType
= MODEL_UNKNOWN
997 EdkLogger
.warn("Parser", "Unrecognized sub-section", File
=self
.MetaFile
,
998 Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
999 self
._ValueList
[0] = self
._SubsectionName
1001 ## Directive statement parser
1002 def _DirectiveParser(self
):
1003 self
._ValueList
= ['', '', '']
1004 TokenList
= GetSplitValueList(self
._CurrentLine
, ' ', 1)
1005 self
._ValueList
[0:len(TokenList
)] = TokenList
1008 DirectiveName
= self
._ValueList
[0].upper()
1009 if DirectiveName
not in self
.DataType
:
1010 EdkLogger
.error("Parser", FORMAT_INVALID
, "Unknown directive [%s]" % DirectiveName
,
1011 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1013 if DirectiveName
in ['!IF', '!IFDEF', '!IFNDEF']:
1014 self
._InDirective
+= 1
1016 if DirectiveName
in ['!ENDIF']:
1017 self
._InDirective
-= 1
1019 if DirectiveName
in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self
._ValueList
[1] == '':
1020 EdkLogger
.error("Parser", FORMAT_INVALID
, "Missing expression",
1021 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1022 ExtraData
=self
._CurrentLine
)
1024 ItemType
= self
.DataType
[DirectiveName
]
1025 Scope
= [['COMMON', 'COMMON','COMMON']]
1026 if ItemType
== MODEL_META_DATA_INCLUDE
:
1028 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1029 # Remove all directives between !if and !endif, including themselves
1030 while self
._DirectiveStack
:
1031 # Remove any !else or !elseif
1032 DirectiveInfo
= self
._DirectiveStack
.pop()
1033 if DirectiveInfo
[0] in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1034 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1035 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1038 EdkLogger
.error("Parser", FORMAT_INVALID
, "Redundant '!endif'",
1039 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1040 ExtraData
=self
._CurrentLine
)
1041 elif ItemType
!= MODEL_META_DATA_INCLUDE
:
1042 # Break if there's a !else is followed by a !elseif
1043 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
and \
1044 self
._DirectiveStack
and \
1045 self
._DirectiveStack
[-1][0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1046 EdkLogger
.error("Parser", FORMAT_INVALID
, "'!elseif' after '!else'",
1047 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1048 ExtraData
=self
._CurrentLine
)
1049 self
._DirectiveStack
.append((ItemType
, self
._LineIndex
+ 1, self
._CurrentLine
))
1052 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
1053 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
1055 for Arch
, ModuleType
, DefaultStore
in Scope
:
1056 self
._LastItem
= self
._Store
(
1066 self
._LineIndex
+ 1,
1068 self
._LineIndex
+ 1,
1073 ## [defines] section parser
1075 def _DefineParser(self
):
1076 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1077 self
._ValueList
[1:len(TokenList
)] = TokenList
1080 if not self
._ValueList
[1]:
1081 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
1082 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1083 if not self
._ValueList
[2]:
1084 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
1085 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1086 if (not self
._ValueList
[1] in self
.DefineKeywords
and
1087 (self
._InSubsection
and self
._ValueList
[1] not in self
.SubSectionDefineKeywords
)):
1088 EdkLogger
.error('Parser', FORMAT_INVALID
,
1089 "Unknown keyword found: %s. "
1090 "If this is a macro you must "
1091 "add it as a DEFINE in the DSC" % self
._ValueList
[1],
1092 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1093 if not self
._InSubsection
:
1094 self
._Defines
[self
._ValueList
[1]] = self
._ValueList
[2]
1095 self
._ItemType
= self
.DataType
[TAB_DSC_DEFINES
.upper()]
1098 def _SkuIdParser(self
):
1099 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1100 if len(TokenList
) not in (2,3):
1101 EdkLogger
.error('Parser', FORMAT_INVALID
, "Correct format is '<Number>|<UiName>[|<UiName>]'",
1102 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1103 self
._ValueList
[0:len(TokenList
)] = TokenList
1105 def _DefaultStoresParser(self
):
1106 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1107 if len(TokenList
) != 2:
1108 EdkLogger
.error('Parser', FORMAT_INVALID
, "Correct format is '<Number>|<UiName>'",
1109 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1110 self
._ValueList
[0:len(TokenList
)] = TokenList
1112 ## Parse Edk style of library modules
1114 def _LibraryInstanceParser(self
):
1115 self
._ValueList
[0] = self
._CurrentLine
1117 ## PCD sections parser
1119 # [PcdsFixedAtBuild]
1120 # [PcdsPatchableInModule]
1123 # [PcdsDynamicExDefault]
1124 # [PcdsDynamicExVpd]
1125 # [PcdsDynamicExHii]
1127 # [PcdsDynamicDefault]
1132 def _PcdParser(self
):
1133 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1134 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1135 PcdNameTockens
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1136 if len(PcdNameTockens
) == 2:
1137 self
._ValueList
[0], self
._ValueList
[1] = PcdNameTockens
[0], PcdNameTockens
[1]
1138 elif len(PcdNameTockens
) == 3:
1139 self
._ValueList
[0], self
._ValueList
[1] = ".".join((PcdNameTockens
[0], PcdNameTockens
[1])), PcdNameTockens
[2]
1140 elif len(PcdNameTockens
) > 3:
1141 self
._ValueList
[0], self
._ValueList
[1] = ".".join((PcdNameTockens
[0], PcdNameTockens
[1])), ".".join(PcdNameTockens
[2:])
1142 if len(TokenList
) == 2:
1143 self
._ValueList
[2] = TokenList
[1]
1144 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1145 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1146 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1147 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1148 if self
._ValueList
[2] == '':
1150 # The PCD values are optional for FIXEDATBUILD, PATCHABLEINMODULE, Dynamic/DynamicEx default
1152 if self
._SectionType
in (MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
):
1154 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD value given",
1155 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1156 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1158 # Validate the datum type of Dynamic Defaul PCD and DynamicEx Default PCD
1159 ValueList
= GetSplitValueList(self
._ValueList
[2])
1160 if len(ValueList
) > 1 and ValueList
[1] in [TAB_UINT8
, TAB_UINT16
, TAB_UINT32
, TAB_UINT64
] \
1161 and self
._ItemType
in [MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
]:
1162 EdkLogger
.error('Parser', FORMAT_INVALID
, "The datum type '%s' of PCD is wrong" % ValueList
[1],
1163 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1165 # Validate the VariableName of DynamicHii and DynamicExHii for PCD Entry must not be an empty string
1166 if self
._ItemType
in [MODEL_PCD_DYNAMIC_HII
, MODEL_PCD_DYNAMIC_EX_HII
]:
1167 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
1168 if len(DscPcdValueList
[0].replace('L','').replace('"','').strip()) == 0:
1169 EdkLogger
.error('Parser', FORMAT_INVALID
, "The VariableName field in the HII format PCD entry must not be an empty string",
1170 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1172 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
1173 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
1174 if DscPcdValueList
[0] in ['True', 'true', 'TRUE']:
1175 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '1', 1);
1176 elif DscPcdValueList
[0] in ['False', 'false', 'FALSE']:
1177 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '0', 1);
1180 ## [components] section parser
1182 def _ComponentParser(self
):
1183 if self
._CurrentLine
[-1] == '{':
1184 self
._ValueList
[0] = self
._CurrentLine
[0:-1].strip()
1185 self
._InSubsection
= True
1187 self
._ValueList
[0] = self
._CurrentLine
1189 ## [LibraryClasses] section
1191 def _LibraryClassParser(self
):
1192 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1193 if len(TokenList
) < 2:
1194 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class or instance specified",
1195 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1196 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1197 if TokenList
[0] == '':
1198 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class specified",
1199 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1200 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1201 if TokenList
[1] == '':
1202 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library instance specified",
1203 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1204 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1206 self
._ValueList
[0:len(TokenList
)] = TokenList
1208 def _CompponentSourceOverridePathParser(self
):
1209 self
._ValueList
[0] = self
._CurrentLine
1211 ## [BuildOptions] section parser
1213 def _BuildOptionParser(self
):
1214 self
._CurrentLine
= CleanString(self
._CurrentLine
, BuildOption
=True)
1215 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1216 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
1217 if len(TokenList2
) == 2:
1218 self
._ValueList
[0] = TokenList2
[0] # toolchain family
1219 self
._ValueList
[1] = TokenList2
[1] # keys
1221 self
._ValueList
[1] = TokenList
[0]
1222 if len(TokenList
) == 2: # value
1223 self
._ValueList
[2] = TokenList
[1]
1225 if self
._ValueList
[1].count('_') != 4:
1229 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
1230 ExtraData
=self
._CurrentLine
,
1232 Line
=self
._LineIndex
+ 1
1235 ## Override parent's method since we'll do all macro replacements in parser
1236 def _GetMacros(self
):
1238 Macros
.update(self
._FileLocalMacros
)
1239 Macros
.update(self
._GetApplicableSectionMacro
())
1240 Macros
.update(GlobalData
.gEdkGlobal
)
1241 Macros
.update(GlobalData
.gPlatformDefines
)
1242 Macros
.update(GlobalData
.gCommandLineDefines
)
1243 # PCD cannot be referenced in macro definition
1244 if self
._ItemType
not in [MODEL_META_DATA_DEFINE
, MODEL_META_DATA_GLOBAL_DEFINE
]:
1245 Macros
.update(self
._Symbols
)
1248 def _PostProcess(self
):
1250 MODEL_META_DATA_SECTION_HEADER
: self
.__ProcessSectionHeader
,
1251 MODEL_META_DATA_SUBSECTION_HEADER
: self
.__ProcessSubsectionHeader
,
1252 MODEL_META_DATA_HEADER
: self
.__ProcessDefine
,
1253 MODEL_META_DATA_DEFINE
: self
.__ProcessDefine
,
1254 MODEL_META_DATA_GLOBAL_DEFINE
: self
.__ProcessDefine
,
1255 MODEL_META_DATA_INCLUDE
: self
.__ProcessDirective
,
1256 MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
: self
.__ProcessDirective
,
1257 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
: self
.__ProcessDirective
,
1258 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
: self
.__ProcessDirective
,
1259 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
: self
.__ProcessDirective
,
1260 MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
: self
.__ProcessDirective
,
1261 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
: self
.__ProcessDirective
,
1262 MODEL_EFI_SKU_ID
: self
.__ProcessSkuId
,
1263 MODEL_EFI_DEFAULT_STORES
: self
.__ProcessDefaultStores
,
1264 MODEL_EFI_LIBRARY_INSTANCE
: self
.__ProcessLibraryInstance
,
1265 MODEL_EFI_LIBRARY_CLASS
: self
.__ProcessLibraryClass
,
1266 MODEL_PCD_FIXED_AT_BUILD
: self
.__ProcessPcd
,
1267 MODEL_PCD_PATCHABLE_IN_MODULE
: self
.__ProcessPcd
,
1268 MODEL_PCD_FEATURE_FLAG
: self
.__ProcessPcd
,
1269 MODEL_PCD_DYNAMIC_DEFAULT
: self
.__ProcessPcd
,
1270 MODEL_PCD_DYNAMIC_HII
: self
.__ProcessPcd
,
1271 MODEL_PCD_DYNAMIC_VPD
: self
.__ProcessPcd
,
1272 MODEL_PCD_DYNAMIC_EX_DEFAULT
: self
.__ProcessPcd
,
1273 MODEL_PCD_DYNAMIC_EX_HII
: self
.__ProcessPcd
,
1274 MODEL_PCD_DYNAMIC_EX_VPD
: self
.__ProcessPcd
,
1275 MODEL_META_DATA_COMPONENT
: self
.__ProcessComponent
,
1276 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: self
.__ProcessSourceOverridePath
,
1277 MODEL_META_DATA_BUILD_OPTION
: self
.__ProcessBuildOption
,
1278 MODEL_UNKNOWN
: self
._Skip
,
1279 MODEL_META_DATA_USER_EXTENSION
: self
._SkipUserExtension
,
1282 self
._Table
= MetaFileStorage(self
._RawTable
.Cur
, self
.MetaFile
, MODEL_FILE_DSC
, True)
1283 self
._Table
.Create()
1284 self
._DirectiveStack
= []
1285 self
._DirectiveEvalStack
= []
1286 self
._FileWithError
= self
.MetaFile
1287 self
._FileLocalMacros
= {}
1288 self
._SectionsMacroDict
= {}
1289 GlobalData
.gPlatformDefines
= {}
1291 # Get all macro and PCD which has straitforward value
1292 self
.__RetrievePcdValue
()
1293 self
._Content
= self
._RawTable
.GetAll()
1294 self
._ContentIndex
= 0
1295 self
._InSubsection
= False
1296 while self
._ContentIndex
< len(self
._Content
) :
1297 Id
, self
._ItemType
, V1
, V2
, V3
, S1
, S2
, S3
,Owner
, self
._From
, \
1298 LineStart
, ColStart
, LineEnd
, ColEnd
, Enabled
= self
._Content
[self
._ContentIndex
]
1301 self
._FileWithError
= self
.MetaFile
1303 self
._ContentIndex
+= 1
1305 self
._Scope
= [[S1
, S2
, S3
]]
1307 # For !include directive, handle it specially,
1308 # merge arch and module type in case of duplicate items
1310 while self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1311 if self
._ContentIndex
>= len(self
._Content
):
1313 Record
= self
._Content
[self
._ContentIndex
]
1314 if LineStart
== Record
[10] and LineEnd
== Record
[12]:
1315 if [Record
[5], Record
[6],Record
[7]] not in self
._Scope
:
1316 self
._Scope
.append([Record
[5], Record
[6],Record
[7]])
1317 self
._ContentIndex
+= 1
1321 self
._LineIndex
= LineStart
- 1
1322 self
._ValueList
= [V1
, V2
, V3
]
1324 if Owner
> 0 and Owner
in self
._IdMapping
:
1325 self
._InSubsection
= True
1327 self
._InSubsection
= False
1329 Processer
[self
._ItemType
]()
1330 except EvaluationException
, Excpt
:
1332 # Only catch expression evaluation error here. We need to report
1333 # the precise number of line on which the error occurred
1335 if hasattr(Excpt
, 'Pcd'):
1336 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
1337 Info
= GlobalData
.gPlatformOtherPcds
[Excpt
.Pcd
]
1338 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
1339 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
1340 " of the DSC file, and it is currently defined in this section:"
1341 " %s, line #: %d." % (Excpt
.Pcd
, Info
[0], Info
[1]),
1342 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1343 Line
=self
._LineIndex
+ 1)
1345 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
1346 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1347 Line
=self
._LineIndex
+ 1)
1349 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
1350 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1351 Line
=self
._LineIndex
+ 1)
1352 except MacroException
, Excpt
:
1353 EdkLogger
.error('Parser', FORMAT_INVALID
, str(Excpt
),
1354 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1355 Line
=self
._LineIndex
+ 1)
1357 if self
._ValueList
== None:
1360 NewOwner
= self
._IdMapping
.get(Owner
, -1)
1361 self
._Enabled
= int((not self
._DirectiveEvalStack
) or (False not in self
._DirectiveEvalStack
))
1362 self
._LastItem
= self
._Store
(
1372 self
._LineIndex
+ 1,
1374 self
._LineIndex
+ 1,
1378 self
._IdMapping
[Id
] = self
._LastItem
1380 GlobalData
.gPlatformDefines
.update(self
._FileLocalMacros
)
1381 self
._PostProcessed
= True
1382 self
._Content
= None
1384 def __ProcessSectionHeader(self
):
1385 self
._SectionName
= self
._ValueList
[0]
1386 if self
._SectionName
in self
.DataType
:
1387 self
._SectionType
= self
.DataType
[self
._SectionName
]
1389 self
._SectionType
= MODEL_UNKNOWN
1391 def __ProcessSubsectionHeader(self
):
1392 self
._SubsectionName
= self
._ValueList
[0]
1393 if self
._SubsectionName
in self
.DataType
:
1394 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
1396 self
._SubsectionType
= MODEL_UNKNOWN
1398 def __RetrievePcdValue(self
):
1399 Content
= open(str(self
.MetaFile
), 'r').readlines()
1400 GlobalData
.gPlatformOtherPcds
['DSCFILE'] = str(self
.MetaFile
)
1401 for PcdType
in (MODEL_PCD_PATCHABLE_IN_MODULE
, MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_HII
,
1402 MODEL_PCD_DYNAMIC_VPD
, MODEL_PCD_DYNAMIC_EX_DEFAULT
, MODEL_PCD_DYNAMIC_EX_HII
,
1403 MODEL_PCD_DYNAMIC_EX_VPD
):
1404 Records
= self
._RawTable
.Query(PcdType
, BelongsToItem
= -1.0)
1405 for TokenSpaceGuid
, PcdName
, Value
, Dummy2
, Dummy3
, Dummy4
,ID
, Line
in Records
:
1406 Name
= TokenSpaceGuid
+ '.' + PcdName
1407 if Name
not in GlobalData
.gPlatformOtherPcds
:
1409 while not Content
[Line
- 1].lstrip().startswith(TAB_SECTION_START
):
1411 GlobalData
.gPlatformOtherPcds
[Name
] = (CleanString(Content
[Line
- 1]), PcdLine
, PcdType
)
1413 def __ProcessDefine(self
):
1414 if not self
._Enabled
:
1417 Type
, Name
, Value
= self
._ValueList
1418 Value
= ReplaceMacro(Value
, self
._Macros
, False)
1420 # If it is <Defines>, return
1422 if self
._InSubsection
:
1423 self
._ValueList
= [Type
, Name
, Value
]
1426 if self
._ItemType
== MODEL_META_DATA_DEFINE
:
1427 if self
._SectionType
== MODEL_META_DATA_HEADER
:
1428 self
._FileLocalMacros
[Name
] = Value
1430 self
._ConstructSectionMacroDict
(Name
, Value
)
1431 elif self
._ItemType
== MODEL_META_DATA_GLOBAL_DEFINE
:
1432 GlobalData
.gEdkGlobal
[Name
] = Value
1435 # Keyword in [Defines] section can be used as Macros
1437 if (self
._ItemType
== MODEL_META_DATA_HEADER
) and (self
._SectionType
== MODEL_META_DATA_HEADER
):
1438 self
._FileLocalMacros
[Name
] = Value
1440 self
._ValueList
= [Type
, Name
, Value
]
1442 def __ProcessDirective(self
):
1444 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1445 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
]:
1446 Macros
= self
._Macros
1447 Macros
.update(GlobalData
.gGlobalDefines
)
1449 Result
= ValueExpression(self
._ValueList
[1], Macros
)()
1450 except SymbolNotFound
, Exc
:
1451 EdkLogger
.debug(EdkLogger
.DEBUG_5
, str(Exc
), self
._ValueList
[1])
1453 except WrnExpression
, Excpt
:
1455 # Catch expression evaluation warning here. We need to report
1456 # the precise number of line and return the evaluation result
1458 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
1459 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1460 Line
=self
._LineIndex
+ 1)
1461 Result
= Excpt
.result
1463 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1464 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1465 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1466 self
._DirectiveStack
.append(self
._ItemType
)
1467 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
:
1468 Result
= bool(Result
)
1470 Macro
= self
._ValueList
[1]
1471 Macro
= Macro
[2:-1] if (Macro
.startswith("$(") and Macro
.endswith(")")) else Macro
1472 Result
= Macro
in self
._Macros
1473 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
:
1475 self
._DirectiveEvalStack
.append(Result
)
1476 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
:
1477 self
._DirectiveStack
.append(self
._ItemType
)
1478 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1479 self
._DirectiveEvalStack
.append(bool(Result
))
1480 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1481 self
._DirectiveStack
.append(self
._ItemType
)
1482 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1483 self
._DirectiveEvalStack
.append(True)
1484 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1485 # Back to the nearest !if/!ifdef/!ifndef
1486 while self
._DirectiveStack
:
1487 self
._DirectiveEvalStack
.pop()
1488 Directive
= self
._DirectiveStack
.pop()
1489 if Directive
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1490 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1491 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1493 elif self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1494 # The included file must be relative to workspace or same directory as DSC file
1495 __IncludeMacros
= {}
1497 # Allow using system environment variables in path after !include
1499 __IncludeMacros
['WORKSPACE'] = GlobalData
.gGlobalDefines
['WORKSPACE']
1500 if "ECP_SOURCE" in GlobalData
.gGlobalDefines
.keys():
1501 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gGlobalDefines
['ECP_SOURCE']
1503 # During GenFds phase call DSC parser, will go into this branch.
1505 elif "ECP_SOURCE" in GlobalData
.gCommandLineDefines
.keys():
1506 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gCommandLineDefines
['ECP_SOURCE']
1508 __IncludeMacros
['EFI_SOURCE'] = GlobalData
.gGlobalDefines
['EFI_SOURCE']
1509 __IncludeMacros
['EDK_SOURCE'] = GlobalData
.gGlobalDefines
['EDK_SOURCE']
1511 # Allow using MACROs comes from [Defines] section to keep compatible.
1513 __IncludeMacros
.update(self
._Macros
)
1515 IncludedFile
= NormPath(ReplaceMacro(self
._ValueList
[1], __IncludeMacros
, RaiseError
=True))
1517 # First search the include file under the same directory as DSC file
1519 IncludedFile1
= PathClass(IncludedFile
, self
.MetaFile
.Dir
)
1520 ErrorCode
, ErrorInfo1
= IncludedFile1
.Validate()
1523 # Also search file under the WORKSPACE directory
1525 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
1526 ErrorCode
, ErrorInfo2
= IncludedFile1
.Validate()
1528 EdkLogger
.error('parser', ErrorCode
, File
=self
._FileWithError
,
1529 Line
=self
._LineIndex
+ 1, ExtraData
=ErrorInfo1
+ "\n" + ErrorInfo2
)
1531 self
._FileWithError
= IncludedFile1
1533 IncludedFileTable
= MetaFileStorage(self
._Table
.Cur
, IncludedFile1
, MODEL_FILE_DSC
, False)
1534 Owner
= self
._Content
[self
._ContentIndex
- 1][0]
1535 Parser
= DscParser(IncludedFile1
, self
._FileType
, self
._Arch
, IncludedFileTable
,
1536 Owner
=Owner
, From
=Owner
)
1538 self
.IncludedFiles
.add (IncludedFile1
)
1540 # Does not allow lower level included file to include upper level included file
1541 if Parser
._From
!= Owner
and int(Owner
) > int (Parser
._From
):
1542 EdkLogger
.error('parser', FILE_ALREADY_EXIST
, File
=self
._FileWithError
,
1543 Line
=self
._LineIndex
+ 1, ExtraData
="{0} is already included at a higher level.".format(IncludedFile1
))
1546 # set the parser status with current status
1547 Parser
._SectionName
= self
._SectionName
1548 Parser
._SectionType
= self
._SectionType
1549 Parser
._Scope
= self
._Scope
1550 Parser
._Enabled
= self
._Enabled
1551 # Parse the included file
1554 # update current status with sub-parser's status
1555 self
._SectionName
= Parser
._SectionName
1556 self
._SectionType
= Parser
._SectionType
1557 self
._Scope
= Parser
._Scope
1558 self
._Enabled
= Parser
._Enabled
1560 # Insert all records in the table for the included file into dsc file table
1561 Records
= IncludedFileTable
.GetAll()
1563 self
._Content
[self
._ContentIndex
:self
._ContentIndex
] = Records
1564 self
._Content
.pop(self
._ContentIndex
- 1)
1565 self
._ValueList
= None
1566 self
._ContentIndex
-= 1
1568 def __ProcessSkuId(self
):
1569 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=True)
1570 for Value
in self
._ValueList
]
1571 def __ProcessDefaultStores(self
):
1572 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=True)
1573 for Value
in self
._ValueList
]
1575 def __ProcessLibraryInstance(self
):
1576 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
1578 def __ProcessLibraryClass(self
):
1579 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
, RaiseError
=True)
1581 def __ProcessPcd(self
):
1582 if self
._ItemType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
1583 self
._ValueList
[2] = ReplaceMacro(self
._ValueList
[2], self
._Macros
, RaiseError
=True)
1586 ValList
, Valid
, Index
= AnalyzeDscPcd(self
._ValueList
[2], self
._ItemType
)
1588 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
._FileWithError
, Line
=self
._LineIndex
+ 1,
1589 ExtraData
="%s.%s|%s" % (self
._ValueList
[0], self
._ValueList
[1], self
._ValueList
[2]))
1590 PcdValue
= ValList
[Index
]
1591 if PcdValue
and "." not in self
._ValueList
[0]:
1593 ValList
[Index
] = ValueExpression(PcdValue
, self
._Macros
)(True)
1594 except WrnExpression
, Value
:
1595 ValList
[Index
] = Value
.result
1599 if ValList
[Index
] == 'True':
1600 ValList
[Index
] = '1'
1601 if ValList
[Index
] == 'False':
1602 ValList
[Index
] = '0'
1604 if (not self
._DirectiveEvalStack
) or (False not in self
._DirectiveEvalStack
):
1605 GlobalData
.gPlatformPcds
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = PcdValue
1606 self
._Symbols
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = PcdValue
1608 self
._ValueList
[2] = '|'.join(ValList
)
1612 def __ProcessComponent(self
):
1613 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1615 def __ProcessSourceOverridePath(self
):
1616 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1618 def __ProcessBuildOption(self
):
1619 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=False)
1620 for Value
in self
._ValueList
]
1623 MODEL_META_DATA_HEADER
: _DefineParser
,
1624 MODEL_EFI_SKU_ID
: _SkuIdParser
,
1625 MODEL_EFI_DEFAULT_STORES
: _DefaultStoresParser
,
1626 MODEL_EFI_LIBRARY_INSTANCE
: _LibraryInstanceParser
,
1627 MODEL_EFI_LIBRARY_CLASS
: _LibraryClassParser
,
1628 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1629 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1630 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1631 MODEL_PCD_DYNAMIC_DEFAULT
: _PcdParser
,
1632 MODEL_PCD_DYNAMIC_HII
: _PcdParser
,
1633 MODEL_PCD_DYNAMIC_VPD
: _PcdParser
,
1634 MODEL_PCD_DYNAMIC_EX_DEFAULT
: _PcdParser
,
1635 MODEL_PCD_DYNAMIC_EX_HII
: _PcdParser
,
1636 MODEL_PCD_DYNAMIC_EX_VPD
: _PcdParser
,
1637 MODEL_META_DATA_COMPONENT
: _ComponentParser
,
1638 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: _CompponentSourceOverridePathParser
,
1639 MODEL_META_DATA_BUILD_OPTION
: _BuildOptionParser
,
1640 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1641 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
1642 MODEL_META_DATA_SECTION_HEADER
: MetaFileParser
._SectionHeaderParser
,
1643 MODEL_META_DATA_SUBSECTION_HEADER
: _SubsectionHeaderParser
,
1646 _Macros
= property(_GetMacros
)
1648 ## DEC file parser class
1650 # @param FilePath The path of platform description file
1651 # @param FileType The raw data of DSC file
1652 # @param Table Database used to retrieve module/package information
1653 # @param Macros Macros used for replacement in file
1655 class DecParser(MetaFileParser
):
1656 # DEC file supported data types (one type per section)
1658 TAB_DEC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
1659 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
1660 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
1661 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
1662 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
1663 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
1664 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
1665 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
1666 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
1667 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
1668 TAB_PCDS_DYNAMIC_NULL
.upper() : MODEL_PCD_DYNAMIC
,
1669 TAB_PCDS_DYNAMIC_EX_NULL
.upper() : MODEL_PCD_DYNAMIC_EX
,
1670 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
,
1673 ## Constructor of DecParser
1675 # Initialize object of DecParser
1677 # @param FilePath The path of platform description file
1678 # @param FileType The raw data of DSC file
1679 # @param Arch Default Arch value for filtering sections
1680 # @param Table Database used to retrieve module/package information
1682 def __init__(self
, FilePath
, FileType
, Arch
, Table
):
1683 # prevent re-initialization
1684 if hasattr(self
, "_Table"):
1686 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
, -1)
1688 self
._Version
= 0x00010005 # Only EDK2 dec file is supported
1689 self
._AllPCDs
= [] # Only for check duplicate PCD
1690 self
._AllPcdDict
= {}
1692 self
._CurrentStructurePcdName
= ""
1693 self
._include
_flag
= False
1694 self
._package
_flag
= False
1700 Content
= open(str(self
.MetaFile
), 'r').readlines()
1702 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
1704 self
._DefinesCount
= 0
1705 for Index
in range(0, len(Content
)):
1706 Line
, Comment
= CleanString2(Content
[Index
])
1707 self
._CurrentLine
= Line
1708 self
._LineIndex
= Index
1710 # save comment for later use
1712 self
._Comments
.append((Comment
, self
._LineIndex
+ 1))
1718 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
1719 self
._SectionHeaderParser
()
1720 if self
._SectionName
== TAB_DEC_DEFINES
.upper():
1721 self
._DefinesCount
+= 1
1724 if self
._SectionType
== MODEL_UNKNOWN
:
1725 EdkLogger
.error("Parser", FORMAT_INVALID
,
1727 "Not able to determine \"%s\" in which section."%self
._CurrentLine
,
1728 self
.MetaFile
, self
._LineIndex
+ 1)
1729 elif len(self
._SectionType
) == 0:
1734 self
._ValueList
= ['', '', '']
1735 self
._SectionParser
[self
._SectionType
[0]](self
)
1736 if self
._ValueList
== None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
1742 # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,
1743 # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1
1745 for Arch
, ModuleType
, Type
in self
._Scope
:
1746 self
._LastItem
= self
._Store
(
1754 self
._LineIndex
+ 1,
1756 self
._LineIndex
+ 1,
1760 for Comment
, LineNo
in self
._Comments
:
1762 MODEL_META_DATA_COMMENT
,
1776 if self
._DefinesCount
> 1:
1777 EdkLogger
.error('Parser', FORMAT_INVALID
, 'Multiple [Defines] section is exist.', self
.MetaFile
)
1778 if self
._DefinesCount
== 0:
1779 EdkLogger
.error('Parser', FORMAT_INVALID
, 'No [Defines] section exist.',self
.MetaFile
)
1783 ## Section header parser
1785 # The section header is always in following format:
1787 # [section_name.arch<.platform|module_type>]
1789 def _SectionHeaderParser(self
):
1791 self
._SectionName
= ''
1792 self
._SectionType
= []
1795 Line
= re
.sub(',[\s]*', TAB_COMMA_SPLIT
, self
._CurrentLine
)
1796 for Item
in Line
[1:-1].split(TAB_COMMA_SPLIT
):
1798 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
,
1799 "section name can NOT be empty or incorrectly use separator comma",
1800 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1801 ItemList
= Item
.split(TAB_SPLIT
)
1803 # different types of PCD are permissible in one section
1804 self
._SectionName
= ItemList
[0].upper()
1805 if self
._SectionName
== TAB_DEC_DEFINES
.upper() and (len(ItemList
) > 1 or len(Line
.split(TAB_COMMA_SPLIT
)) > 1):
1806 EdkLogger
.error("Parser", FORMAT_INVALID
, "Defines section format is invalid",
1807 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1808 if self
._SectionName
in self
.DataType
:
1809 if self
.DataType
[self
._SectionName
] not in self
._SectionType
:
1810 self
._SectionType
.append(self
.DataType
[self
._SectionName
])
1812 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
1813 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1815 if MODEL_PCD_FEATURE_FLAG
in self
._SectionType
and len(self
._SectionType
) > 1:
1819 "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL
,
1821 Line
=self
._LineIndex
+ 1,
1822 ExtraData
=self
._CurrentLine
1825 if len(ItemList
) > 1:
1826 S1
= ItemList
[1].upper()
1830 # S2 may be Platform or ModuleType
1831 if len(ItemList
) > 2:
1832 S2
= ItemList
[2].upper()
1833 # only Includes, GUIDs, PPIs, Protocols section have Private tag
1834 if self
._SectionName
in [TAB_INCLUDES
.upper(), TAB_GUIDS
.upper(), TAB_PROTOCOLS
.upper(), TAB_PPIS
.upper()]:
1836 EdkLogger
.error("Parser", FORMAT_INVALID
, 'Please use keyword "Private" as section tag modifier.',
1837 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1841 if [S1
, S2
, self
.DataType
[self
._SectionName
]] not in self
._Scope
:
1842 self
._Scope
.append([S1
, S2
, self
.DataType
[self
._SectionName
]])
1844 # 'COMMON' must not be used with specific ARCHs at the same section
1845 if 'COMMON' in ArchList
and len(ArchList
) > 1:
1846 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
1847 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1849 # It is not permissible to mix section tags without the Private attribute with section tags with the Private attribute
1850 if 'COMMON' in PrivateList
and len(PrivateList
) > 1:
1851 EdkLogger
.error('Parser', FORMAT_INVALID
, "Can't mix section tags without the Private attribute with section tags with the Private attribute",
1852 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1854 ## [guids], [ppis] and [protocols] section parser
1856 def _GuidParser(self
):
1857 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1858 if len(TokenList
) < 2:
1859 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name or value specified",
1860 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1861 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1862 if TokenList
[0] == '':
1863 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name specified",
1864 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1865 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1866 if TokenList
[1] == '':
1867 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID value specified",
1868 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1869 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1870 if TokenList
[1][0] != '{' or TokenList
[1][-1] != '}' or GuidStructureStringToGuidString(TokenList
[1]) == '':
1871 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid GUID value format",
1872 ExtraData
=self
._CurrentLine
+ \
1873 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
1874 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1875 self
._ValueList
[0] = TokenList
[0]
1876 self
._ValueList
[1] = TokenList
[1]
1877 if self
._ValueList
[0] not in self
._GuidDict
:
1878 self
._GuidDict
[self
._ValueList
[0]] = self
._ValueList
[1]
1880 ## PCD sections parser
1882 # [PcdsFixedAtBuild]
1883 # [PcdsPatchableInModule]
1889 def _PcdParser(self
):
1890 if self
._CurrentStructurePcdName
:
1891 self
._ValueList
[0] = self
._CurrentStructurePcdName
1893 if "|" not in self
._CurrentLine
:
1894 if "<HeaderFiles>" == self
._CurrentLine
:
1895 self
._include
_flag
= True
1896 self
._package
_flag
= False
1897 self
._ValueList
= None
1899 if "<Packages>" == self
._CurrentLine
:
1900 self
._package
_flag
= True
1901 self
._ValueList
= None
1902 self
._include
_flag
= False
1905 if self
._include
_flag
:
1906 self
._ValueList
[1] = "<HeaderFiles>_" + md5
.new(self
._CurrentLine
).hexdigest()
1907 self
._ValueList
[2] = self
._CurrentLine
1908 if self
._package
_flag
and "}" != self
._CurrentLine
:
1909 self
._ValueList
[1] = "<Packages>_" + md5
.new(self
._CurrentLine
).hexdigest()
1910 self
._ValueList
[2] = self
._CurrentLine
1911 if self
._CurrentLine
== "}":
1912 self
._package
_flag
= False
1913 self
._include
_flag
= False
1914 self
._ValueList
= None
1917 PcdTockens
= self
._CurrentLine
.split(TAB_VALUE_SPLIT
)
1918 PcdNames
= PcdTockens
[0].split(TAB_SPLIT
)
1919 if len(PcdNames
) == 2:
1920 self
._CurrentStructurePcdName
= ""
1922 if self
._CurrentStructurePcdName
!= TAB_SPLIT
.join(PcdNames
[:2]):
1923 EdkLogger
.error('Parser', FORMAT_INVALID
, "Pcd Name does not match: %s and %s " % (self
._CurrentStructurePcdName
, TAB_SPLIT
.join(PcdNames
[:2])),
1924 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1925 self
._ValueList
[1] = TAB_SPLIT
.join(PcdNames
[2:])
1926 self
._ValueList
[2] = PcdTockens
[1]
1927 if not self
._CurrentStructurePcdName
:
1928 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1929 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1930 ValueRe
= re
.compile(r
'^[a-zA-Z_][a-zA-Z0-9_]*')
1931 # check PCD information
1932 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1933 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1934 ExtraData
=self
._CurrentLine
+ \
1935 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1936 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1937 # check format of token space GUID CName
1938 if not ValueRe
.match(self
._ValueList
[0]):
1939 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_]*'",
1940 ExtraData
=self
._CurrentLine
+ \
1941 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1942 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1943 # check format of PCD CName
1944 if not ValueRe
.match(self
._ValueList
[1]):
1945 EdkLogger
.error('Parser', FORMAT_INVALID
, "The format of the PCD CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",
1946 ExtraData
=self
._CurrentLine
+ \
1947 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1948 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1949 # check PCD datum information
1950 if len(TokenList
) < 2 or TokenList
[1] == '':
1951 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD Datum information given",
1952 ExtraData
=self
._CurrentLine
+ \
1953 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1954 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1957 ValueRe
= re
.compile(r
'^\s*L?\".*\|.*\"')
1958 PtrValue
= ValueRe
.findall(TokenList
[1])
1960 # Has VOID* type string, may contain "|" character in the string.
1961 if len(PtrValue
) != 0:
1962 ptrValueList
= re
.sub(ValueRe
, '', TokenList
[1])
1963 ValueList
= AnalyzePcdExpression(ptrValueList
)
1964 ValueList
[0] = PtrValue
[0]
1966 ValueList
= AnalyzePcdExpression(TokenList
[1])
1969 # check if there's enough datum information given
1970 if len(ValueList
) != 3:
1971 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid PCD Datum information given",
1972 ExtraData
=self
._CurrentLine
+ \
1973 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1974 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1975 # check default value
1976 if ValueList
[0] == '':
1977 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DefaultValue in PCD Datum information",
1978 ExtraData
=self
._CurrentLine
+ \
1979 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1980 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1982 if ValueList
[1] == '':
1983 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DatumType in PCD Datum information",
1984 ExtraData
=self
._CurrentLine
+ \
1985 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1986 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1987 # check token of the PCD
1988 if ValueList
[2] == '':
1989 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing Token in PCD Datum information",
1990 ExtraData
=self
._CurrentLine
+ \
1991 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1992 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1994 PcdValue
= ValueList
[0]
1997 ValueList
[0] = ValueExpressionEx(ValueList
[0], ValueList
[1], self
._GuidDict
)(True)
1998 except BadExpression
, Value
:
1999 EdkLogger
.error('Parser', FORMAT_INVALID
, Value
, ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2000 # check format of default value against the datum type
2001 IsValid
, Cause
= CheckPcdDatum(ValueList
[1], ValueList
[0])
2003 EdkLogger
.error('Parser', FORMAT_INVALID
, Cause
, ExtraData
=self
._CurrentLine
,
2004 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2006 if Cause
== "StructurePcd":
2007 self
._CurrentStructurePcdName
= TAB_SPLIT
.join(self
._ValueList
[0:2])
2008 self
._ValueList
[0] = self
._CurrentStructurePcdName
2009 self
._ValueList
[1] = ValueList
[1].strip()
2011 if ValueList
[0] in ['True', 'true', 'TRUE']:
2013 elif ValueList
[0] in ['False', 'false', 'FALSE']:
2016 # check for duplicate PCD definition
2017 if (self
._Scope
[0], self
._ValueList
[0], self
._ValueList
[1]) in self
._AllPCDs
:
2018 EdkLogger
.error('Parser', FORMAT_INVALID
,
2019 "The same PCD name and GUID have been already defined",
2020 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2022 self
._AllPCDs
.append((self
._Scope
[0], self
._ValueList
[0], self
._ValueList
[1]))
2023 self
._AllPcdDict
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = ValueList
[0]
2025 self
._ValueList
[2] = ValueList
[0].strip() + '|' + ValueList
[1].strip() + '|' + ValueList
[2].strip()
2028 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
2029 MODEL_EFI_INCLUDE
: MetaFileParser
._PathParser
,
2030 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
2031 MODEL_EFI_GUID
: _GuidParser
,
2032 MODEL_EFI_PPI
: _GuidParser
,
2033 MODEL_EFI_PROTOCOL
: _GuidParser
,
2034 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
2035 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
2036 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
2037 MODEL_PCD_DYNAMIC
: _PcdParser
,
2038 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
2039 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
2040 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
2045 # This acts like the main() function for the script, unless it is 'import'ed into another
2048 if __name__
== '__main__':