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
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 type(self
) == DscParser
and self
._InDirective
> -1:
83 if type(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 type(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(MetaFileParser
, Class
).__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
214 def _GetFinished(self
):
215 return self
._Finished
217 ## Set the complete flag
218 def _SetFinished(self
, Value
):
219 self
._Finished
= Value
221 ## Remove records that do not match given Filter Arch
222 def _FilterRecordList(self
, RecordList
, FilterArch
):
224 for Record
in RecordList
:
226 if Arch
== TAB_ARCH_COMMON
or Arch
== FilterArch
:
227 NewRecordList
.append(Record
)
230 ## Use [] style to query data in table, just for readability
232 # DataInfo = [data_type, scope1(arch), scope2(platform/moduletype)]
234 def __getitem__(self
, DataInfo
):
235 if type(DataInfo
) != type(()):
236 DataInfo
= (DataInfo
,)
238 # Parse the file first, if necessary
239 if not self
._Finished
:
240 if self
._RawTable
.IsIntegrity():
241 self
._Finished
= True
243 self
._Table
= self
._RawTable
244 self
._PostProcessed
= False
247 # No specific ARCH or Platform given, use raw data
248 if self
._RawTable
and (len(DataInfo
) == 1 or DataInfo
[1] is None):
249 return self
._FilterRecordList
(self
._RawTable
.Query(*DataInfo
), self
._Arch
)
251 # Do post-process if necessary
252 if not self
._PostProcessed
:
255 return self
._FilterRecordList
(self
._Table
.Query(*DataInfo
), DataInfo
[1])
257 ## Data parser for the common format in different type of file
259 # The common format in the meatfile is like
264 def _CommonParser(self
):
265 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
266 self
._ValueList
[0:len(TokenList
)] = TokenList
268 ## Data parser for the format in which there's path
270 # Only path can have macro used. So we need to replace them before use.
273 def _PathParser(self
):
274 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
275 self
._ValueList
[0:len(TokenList
)] = TokenList
276 # Don't do macro replacement for dsc file at this point
277 if type(self
) != DscParser
:
278 Macros
= self
._Macros
279 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
281 ## Skip unsupported data
283 EdkLogger
.warn("Parser", "Unrecognized content", File
=self
.MetaFile
,
284 Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
);
285 self
._ValueList
[0:1] = [self
._CurrentLine
]
287 ## Skip unsupported data for UserExtension Section
288 def _SkipUserExtension(self
):
289 self
._ValueList
[0:1] = [self
._CurrentLine
]
291 ## Section header parser
293 # The section header is always in following format:
295 # [section_name.arch<.platform|module_type>]
297 def _SectionHeaderParser(self
):
299 self
._SectionName
= ''
301 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
304 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
,3)
305 # different section should not mix in one section
306 if self
._SectionName
!= '' and self
._SectionName
!= ItemList
[0].upper():
307 EdkLogger
.error('Parser', FORMAT_INVALID
, "Different section names in the same section",
308 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
309 self
._SectionName
= ItemList
[0].upper()
310 if self
._SectionName
in self
.DataType
:
311 self
._SectionType
= self
.DataType
[self
._SectionName
]
312 # Check if the section name is valid
313 if self
._SectionName
not in SECTIONS_HAVE_ITEM_AFTER_ARCH_SET
and len(ItemList
) > 3:
314 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
315 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
316 elif self
._Version
>= 0x00010005:
317 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
318 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
320 self
._SectionType
= MODEL_UNKNOWN
323 if len(ItemList
) > 1:
324 S1
= ItemList
[1].upper()
329 # S2 may be Platform or ModuleType
330 if len(ItemList
) > 2:
331 if self
._SectionName
.upper() in SECTIONS_HAVE_ITEM_PCD_SET
:
334 S2
= ItemList
[2].upper()
337 if len(ItemList
) > 3:
341 self
._Scope
.append([S1
, S2
, S3
])
343 # 'COMMON' must not be used with specific ARCHs at the same section
344 if TAB_ARCH_COMMON
in ArchList
and len(ArchList
) > 1:
345 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
346 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
347 # If the section information is needed later, it should be stored in database
348 self
._ValueList
[0] = self
._SectionName
350 ## [defines] section parser
352 def _DefineParser(self
):
353 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
354 self
._ValueList
[1:len(TokenList
)] = TokenList
355 if not self
._ValueList
[1]:
356 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
357 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
358 if not self
._ValueList
[2]:
359 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
360 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
362 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
363 Name
, Value
= self
._ValueList
[1], self
._ValueList
[2]
364 MacroUsed
= GlobalData
.gMacroRefPattern
.findall(Value
)
365 if len(MacroUsed
) != 0:
366 for Macro
in MacroUsed
:
367 if Macro
in GlobalData
.gGlobalDefines
:
368 EdkLogger
.error("Parser", FORMAT_INVALID
, "Global macro %s is not permitted." % (Macro
), ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
370 EdkLogger
.error("Parser", FORMAT_INVALID
, "%s not defined" % (Macro
), ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
371 # Sometimes, we need to make differences between EDK and EDK2 modules
372 if Name
== 'INF_VERSION':
373 if hexVersionPattern
.match(Value
):
374 self
._Version
= int(Value
, 0)
375 elif decVersionPattern
.match(Value
):
376 ValueList
= Value
.split('.')
377 Major
= '%04o' % int(ValueList
[0], 0)
378 Minor
= '%04o' % int(ValueList
[1], 0)
379 self
._Version
= int('0x' + Major
+ Minor
, 0)
381 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid version number",
382 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
384 if type(self
) == InfParser
and self
._Version
< 0x00010005:
385 # EDK module allows using defines as macros
386 self
._FileLocalMacros
[Name
] = Value
387 self
._Defines
[Name
] = Value
389 ## [BuildOptions] section parser
391 def _BuildOptionParser(self
):
392 self
._CurrentLine
= CleanString(self
._CurrentLine
, BuildOption
=True)
393 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
394 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
395 if len(TokenList2
) == 2:
396 self
._ValueList
[0] = TokenList2
[0] # toolchain family
397 self
._ValueList
[1] = TokenList2
[1] # keys
399 self
._ValueList
[1] = TokenList
[0]
400 if len(TokenList
) == 2 and type(self
) != DscParser
: # value
401 self
._ValueList
[2] = ReplaceMacro(TokenList
[1], self
._Macros
)
403 if self
._ValueList
[1].count('_') != 4:
407 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
408 ExtraData
=self
._CurrentLine
,
410 Line
=self
._LineIndex
+ 1
412 def GetValidExpression(self
, TokenSpaceGuid
, PcdCName
):
413 return self
._Table
.GetValidExpression(TokenSpaceGuid
, PcdCName
)
414 def _GetMacros(self
):
416 Macros
.update(self
._FileLocalMacros
)
417 Macros
.update(self
._GetApplicableSectionMacro
())
420 ## Construct section Macro dict
421 def _ConstructSectionMacroDict(self
, Name
, Value
):
422 ScopeKey
= [(Scope
[0], Scope
[1],Scope
[2]) for Scope
in self
._Scope
]
423 ScopeKey
= tuple(ScopeKey
)
425 # DecParser SectionType is a list, will contain more than one item only in Pcd Section
426 # As Pcd section macro usage is not alllowed, so here it is safe
428 if type(self
) == DecParser
:
429 SectionDictKey
= self
._SectionType
[0], ScopeKey
431 SectionDictKey
= self
._SectionType
, ScopeKey
433 self
._SectionsMacroDict
[SectionDictKey
][Name
] = Value
435 ## Get section Macros that are applicable to current line, which may come from other sections
436 ## that share the same name while scope is wider
437 def _GetApplicableSectionMacro(self
):
444 ActiveSectionType
= self
._SectionType
445 if type(self
) == DecParser
:
446 ActiveSectionType
= self
._SectionType
[0]
448 for (SectionType
, Scope
) in self
._SectionsMacroDict
:
449 if SectionType
!= ActiveSectionType
:
452 for ActiveScope
in self
._Scope
:
453 Scope0
, Scope1
,Scope2
= ActiveScope
[0], ActiveScope
[1],ActiveScope
[2]
454 if(Scope0
, Scope1
,Scope2
) not in Scope
:
457 SpeSpeMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
459 for ActiveScope
in self
._Scope
:
460 Scope0
, Scope1
,Scope2
= ActiveScope
[0], ActiveScope
[1],ActiveScope
[2]
461 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
:
464 ComSpeMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
466 if (TAB_COMMON
, TAB_COMMON
, TAB_COMMON
) in Scope
:
467 ComComMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
469 Macros
.update(ComComMacroDict
)
470 Macros
.update(ComSpeMacroDict
)
471 Macros
.update(SpeSpeMacroDict
)
476 Finished
= property(_GetFinished
, _SetFinished
)
477 _Macros
= property(_GetMacros
)
480 ## INF file parser class
482 # @param FilePath The path of platform description file
483 # @param FileType The raw data of DSC file
484 # @param Table Database used to retrieve module/package information
485 # @param Macros Macros used for replacement in file
487 class InfParser(MetaFileParser
):
488 # INF file supported data types (one type per section)
490 TAB_UNKNOWN
.upper() : MODEL_UNKNOWN
,
491 TAB_INF_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
492 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
493 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
494 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
495 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
496 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
497 TAB_PACKAGES
.upper() : MODEL_META_DATA_PACKAGE
,
498 TAB_NMAKE
.upper() : MODEL_META_DATA_NMAKE
,
499 TAB_INF_FIXED_PCD
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
500 TAB_INF_PATCH_PCD
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
501 TAB_INF_FEATURE_PCD
.upper() : MODEL_PCD_FEATURE_FLAG
,
502 TAB_INF_PCD_EX
.upper() : MODEL_PCD_DYNAMIC_EX
,
503 TAB_INF_PCD
.upper() : MODEL_PCD_DYNAMIC
,
504 TAB_SOURCES
.upper() : MODEL_EFI_SOURCE_FILE
,
505 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
506 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
507 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
508 TAB_DEPEX
.upper() : MODEL_EFI_DEPEX
,
509 TAB_BINARIES
.upper() : MODEL_EFI_BINARY_FILE
,
510 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
513 ## Constructor of InfParser
515 # Initialize object of InfParser
517 # @param FilePath The path of module description file
518 # @param FileType The raw data of DSC file
519 # @param Arch Default Arch value for filtering sections
520 # @param Table Database used to retrieve module/package information
522 def __init__(self
, FilePath
, FileType
, Arch
, Table
):
523 # prevent re-initialization
524 if hasattr(self
, "_Table"):
526 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
)
534 Content
= open(str(self
.MetaFile
), 'r').readlines()
536 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
538 # parse the file line by line
539 IsFindBlockComment
= False
540 GetHeaderComment
= False
545 for Index
in range(0, len(Content
)):
546 # skip empty, commented, block commented lines
547 Line
, Comment
= CleanString2(Content
[Index
], AllowCppStyleComment
=True)
549 if Index
+ 1 < len(Content
):
550 NextLine
, NextComment
= CleanString2(Content
[Index
+ 1])
553 Comments
.append((Comment
, Index
+ 1))
554 elif GetHeaderComment
:
555 SectionComments
.extend(Comments
)
558 if Line
.find(DataType
.TAB_COMMENT_EDK_START
) > -1:
559 IsFindBlockComment
= True
561 if Line
.find(DataType
.TAB_COMMENT_EDK_END
) > -1:
562 IsFindBlockComment
= False
564 if IsFindBlockComment
:
567 self
._LineIndex
= Index
568 self
._CurrentLine
= Line
571 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
572 if not GetHeaderComment
:
573 for Cmt
, LNo
in Comments
:
574 self
._Store
(MODEL_META_DATA_HEADER_COMMENT
, Cmt
, '', '', TAB_COMMON
,
575 TAB_COMMON
, self
._Owner
[-1], LNo
, -1, LNo
, -1, 0)
576 GetHeaderComment
= True
578 TailComments
.extend(SectionComments
+ Comments
)
580 self
._SectionHeaderParser
()
581 # Check invalid sections
582 if self
._Version
< 0x00010005:
583 if self
._SectionType
in [MODEL_META_DATA_BUILD_OPTION
,
584 MODEL_EFI_LIBRARY_CLASS
,
585 MODEL_META_DATA_PACKAGE
,
586 MODEL_PCD_FIXED_AT_BUILD
,
587 MODEL_PCD_PATCHABLE_IN_MODULE
,
588 MODEL_PCD_FEATURE_FLAG
,
589 MODEL_PCD_DYNAMIC_EX
,
594 MODEL_META_DATA_USER_EXTENSION
]:
595 EdkLogger
.error('Parser', FORMAT_INVALID
,
596 "Section [%s] is not allowed in inf file without version" % (self
._SectionName
),
597 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
598 elif self
._SectionType
in [MODEL_EFI_INCLUDE
,
599 MODEL_EFI_LIBRARY_INSTANCE
,
600 MODEL_META_DATA_NMAKE
]:
601 EdkLogger
.error('Parser', FORMAT_INVALID
,
602 "Section [%s] is not allowed in inf file with version 0x%08x" % (self
._SectionName
, self
._Version
),
603 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
605 # merge two lines specified by '\' in section NMAKE
606 elif self
._SectionType
== MODEL_META_DATA_NMAKE
:
609 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
612 if NextLine
[0] == TAB_SECTION_START
and NextLine
[-1] == TAB_SECTION_END
:
613 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
616 NmakeLine
= NmakeLine
+ ' ' + Line
[0:-1]
619 self
._CurrentLine
= NmakeLine
+ Line
623 self
._ValueList
= ['', '', '']
624 # parse current line, result will be put in self._ValueList
625 self
._SectionParser
[self
._SectionType
](self
)
626 if self
._ValueList
is None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
631 Comments
.append((Comment
, Index
+ 1))
632 if GlobalData
.gOptions
and GlobalData
.gOptions
.CheckUsage
:
633 CheckInfComment(self
._SectionType
, Comments
, str(self
.MetaFile
), Index
+ 1, self
._ValueList
)
635 # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
636 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
638 for Arch
, Platform
,_
in self
._Scope
:
639 LastItem
= self
._Store
(self
._SectionType
,
652 for Comment
, LineNo
in Comments
:
653 self
._Store
(MODEL_META_DATA_COMMENT
, Comment
, '', '', Arch
, Platform
,
654 LastItem
, LineNo
, -1, LineNo
, -1, 0)
657 TailComments
.extend(SectionComments
+ Comments
)
658 if IsFindBlockComment
:
659 EdkLogger
.error("Parser", FORMAT_INVALID
, "Open block comments (starting with /*) are expected to end with */",
662 # If there are tail comments in INF file, save to database whatever the comments are
663 for Comment
in TailComments
:
664 self
._Store
(MODEL_META_DATA_TAIL_COMMENT
, Comment
[0], '', '', TAB_COMMON
,
665 TAB_COMMON
, self
._Owner
[-1], -1, -1, -1, -1, 0)
668 ## Data parser for the format in which there's path
670 # Only path can have macro used. So we need to replace them before use.
672 def _IncludeParser(self
):
673 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
674 self
._ValueList
[0:len(TokenList
)] = TokenList
675 Macros
= self
._Macros
677 for Index
in range(0, len(self
._ValueList
)):
678 Value
= self
._ValueList
[Index
]
682 if Value
.upper().find('$(EFI_SOURCE)\Edk'.upper()) > -1 or Value
.upper().find('$(EFI_SOURCE)/Edk'.upper()) > -1:
683 Value
= '$(EDK_SOURCE)' + Value
[17:]
684 if Value
.find('$(EFI_SOURCE)') > -1 or Value
.find('$(EDK_SOURCE)') > -1:
686 elif Value
.startswith('.'):
688 elif Value
.startswith('$('):
691 Value
= '$(EFI_SOURCE)/' + Value
693 self
._ValueList
[Index
] = ReplaceMacro(Value
, Macros
)
695 ## Parse [Sources] section
697 # Only path can have macro used. So we need to replace them before use.
700 def _SourceFileParser(self
):
701 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
702 self
._ValueList
[0:len(TokenList
)] = TokenList
703 Macros
= self
._Macros
704 # For Acpi tables, remove macro like ' TABLE_NAME=Sata1'
705 if 'COMPONENT_TYPE' in Macros
:
706 if self
._Defines
['COMPONENT_TYPE'].upper() == 'ACPITABLE':
707 self
._ValueList
[0] = GetSplitValueList(self
._ValueList
[0], ' ', 1)[0]
708 if self
._Defines
['BASE_NAME'] == 'Microcode':
710 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
712 ## Parse [Binaries] section
714 # Only path can have macro used. So we need to replace them before use.
717 def _BinaryFileParser(self
):
718 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 2)
719 if len(TokenList
) < 2:
720 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type or path specified",
721 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
722 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
724 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type specified",
725 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
726 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
728 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file path specified",
729 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
730 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
731 self
._ValueList
[0:len(TokenList
)] = TokenList
732 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
734 ## [nmake] section parser (Edk.x style only)
735 def _NmakeParser(self
):
736 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
737 self
._ValueList
[0:len(TokenList
)] = TokenList
739 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
740 # remove self-reference in macro setting
741 #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
743 ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
745 def _PcdParser(self
):
746 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
747 ValueList
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
748 if len(ValueList
) != 2:
749 EdkLogger
.error('Parser', FORMAT_INVALID
, "Illegal token space GUID and PCD name format",
750 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
751 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
752 self
._ValueList
[0:1] = ValueList
753 if len(TokenList
) > 1:
754 self
._ValueList
[2] = TokenList
[1]
755 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
756 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
757 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
758 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
760 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
761 if self
._ValueList
[2] != '':
762 InfPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
763 if InfPcdValueList
[0] in ['True', 'true', 'TRUE']:
764 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '1', 1);
765 elif InfPcdValueList
[0] in ['False', 'false', 'FALSE']:
766 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '0', 1);
767 if (self
._ValueList
[0], self
._ValueList
[1]) not in self
.PcdsDict
:
768 self
.PcdsDict
[self
._ValueList
[0], self
._ValueList
[1]] = self
._SectionType
769 elif self
.PcdsDict
[self
._ValueList
[0], self
._ValueList
[1]] != self
._SectionType
:
770 EdkLogger
.error('Parser', FORMAT_INVALID
, "It is not permissible to list a specified PCD in different PCD type sections.",
771 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
772 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
774 ## [depex] section parser
776 def _DepexParser(self
):
777 self
._ValueList
[0:1] = [self
._CurrentLine
]
780 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
781 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
782 MODEL_META_DATA_BUILD_OPTION
: MetaFileParser
._BuildOptionParser
,
783 MODEL_EFI_INCLUDE
: _IncludeParser
, # for Edk.x modules
784 MODEL_EFI_LIBRARY_INSTANCE
: MetaFileParser
._CommonParser
, # for Edk.x modules
785 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
786 MODEL_META_DATA_PACKAGE
: MetaFileParser
._PathParser
,
787 MODEL_META_DATA_NMAKE
: _NmakeParser
, # for Edk.x modules
788 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
789 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
790 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
791 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
792 MODEL_PCD_DYNAMIC
: _PcdParser
,
793 MODEL_EFI_SOURCE_FILE
: _SourceFileParser
,
794 MODEL_EFI_GUID
: MetaFileParser
._CommonParser
,
795 MODEL_EFI_PROTOCOL
: MetaFileParser
._CommonParser
,
796 MODEL_EFI_PPI
: MetaFileParser
._CommonParser
,
797 MODEL_EFI_DEPEX
: _DepexParser
,
798 MODEL_EFI_BINARY_FILE
: _BinaryFileParser
,
799 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
802 ## DSC file parser class
804 # @param FilePath The path of platform description file
805 # @param FileType The raw data of DSC file
806 # @param Table Database used to retrieve module/package information
807 # @param Macros Macros used for replacement in file
808 # @param Owner Owner ID (for sub-section parsing)
809 # @param From ID from which the data comes (for !INCLUDE directive)
811 class DscParser(MetaFileParser
):
812 # DSC file supported data types (one type per section)
814 TAB_SKUIDS
.upper() : MODEL_EFI_SKU_ID
,
815 TAB_DEFAULT_STORES
.upper() : MODEL_EFI_DEFAULT_STORES
,
816 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
817 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
818 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
819 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
820 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
821 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
822 TAB_PCDS_DYNAMIC_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_DEFAULT
,
823 TAB_PCDS_DYNAMIC_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_HII
,
824 TAB_PCDS_DYNAMIC_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_VPD
,
825 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT
,
826 TAB_PCDS_DYNAMIC_EX_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_HII
,
827 TAB_PCDS_DYNAMIC_EX_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_VPD
,
828 TAB_COMPONENTS
.upper() : MODEL_META_DATA_COMPONENT
,
829 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
.upper() : MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
,
830 TAB_DSC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
831 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
832 TAB_DSC_DEFINES_EDKGLOBAL
: MODEL_META_DATA_GLOBAL_DEFINE
,
833 TAB_INCLUDE
.upper() : MODEL_META_DATA_INCLUDE
,
834 TAB_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
835 TAB_IF_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
836 TAB_IF_N_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
,
837 TAB_ELSE_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
,
838 TAB_ELSE
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
,
839 TAB_END_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
,
840 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
,
843 # Valid names in define section
850 "PCD_INFO_GENERATION",
851 "PCD_VAR_CHECK_GENERATION",
852 "SUPPORTED_ARCHITECTURES",
861 "FIX_LOAD_TOP_MEMORY_ADDRESS",
866 SubSectionDefineKeywords
= [
870 SymbolPattern
= ValueExpression
.SymbolPattern
872 IncludedFiles
= set()
874 ## Constructor of DscParser
876 # Initialize object of DscParser
878 # @param FilePath The path of platform description file
879 # @param FileType The raw data of DSC file
880 # @param Arch Default Arch value for filtering sections
881 # @param Table Database used to retrieve module/package information
882 # @param Owner Owner ID (for sub-section parsing)
883 # @param From ID from which the data comes (for !INCLUDE directive)
885 def __init__(self
, FilePath
, FileType
, Arch
, Table
, Owner
= -1, From
= -1):
886 # prevent re-initialization
887 if hasattr(self
, "_Table"):
889 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
, Owner
, From
)
890 self
._Version
= 0x00010005 # Only EDK2 dsc file is supported
891 # to store conditional directive evaluation result
892 self
._DirectiveStack
= []
893 self
._DirectiveEvalStack
= []
897 # Specify whether current line is in uncertain condition
899 self
._InDirective
= -1
901 # Final valid replacable symbols
904 # Map the ID between the original table and new table to track
907 self
._IdMapping
= {-1:-1}
913 Content
= open(str(self
.MetaFile
), 'r').readlines()
915 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
918 for Index
in range(0, len(Content
)):
919 Line
= CleanString(Content
[Index
])
924 self
._CurrentLine
= Line
925 self
._LineIndex
= Index
926 if self
._InSubsection
and self
._Owner
[-1] == -1:
927 self
._Owner
.append(self
._LastItem
)
930 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
931 self
._SectionType
= MODEL_META_DATA_SECTION_HEADER
933 elif Line
[0] == '}' and self
._InSubsection
:
934 self
._InSubsection
= False
935 self
._SubsectionType
= MODEL_UNKNOWN
936 self
._SubsectionName
= ''
941 elif Line
[0] == TAB_OPTION_START
and Line
[-1] == TAB_OPTION_END
:
942 self
._SubsectionType
= MODEL_META_DATA_SUBSECTION_HEADER
945 self
._DirectiveParser
()
947 if Line
[0] == TAB_OPTION_START
and not self
._InSubsection
:
948 EdkLogger
.error("Parser", FILE_READ_FAILURE
, "Missing the '{' before %s in Line %s" % (Line
, Index
+1),ExtraData
=self
.MetaFile
)
950 if self
._InSubsection
:
951 SectionType
= self
._SubsectionType
953 SectionType
= self
._SectionType
954 self
._ItemType
= SectionType
956 self
._ValueList
= ['', '', '']
957 self
._SectionParser
[SectionType
](self
)
958 if self
._ValueList
is None:
961 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
962 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
964 for Arch
, ModuleType
, DefaultStore
in self
._Scope
:
965 Owner
= self
._Owner
[-1]
966 if self
._SubsectionType
!= MODEL_UNKNOWN
:
967 Owner
= OwnerId
[Arch
]
968 self
._LastItem
= self
._Store
(
984 if self
._SubsectionType
== MODEL_UNKNOWN
and self
._InSubsection
:
985 OwnerId
[Arch
] = self
._LastItem
987 if self
._DirectiveStack
:
988 Type
, Line
, Text
= self
._DirectiveStack
[-1]
989 EdkLogger
.error('Parser', FORMAT_INVALID
, "No matching '!endif' found",
990 ExtraData
=Text
, File
=self
.MetaFile
, Line
=Line
)
993 ## <subsection_header> parser
994 def _SubsectionHeaderParser(self
):
995 self
._SubsectionName
= self
._CurrentLine
[1:-1].upper()
996 if self
._SubsectionName
in self
.DataType
:
997 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
999 self
._SubsectionType
= MODEL_UNKNOWN
1000 EdkLogger
.warn("Parser", "Unrecognized sub-section", File
=self
.MetaFile
,
1001 Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1002 self
._ValueList
[0] = self
._SubsectionName
1004 ## Directive statement parser
1005 def _DirectiveParser(self
):
1006 self
._ValueList
= ['', '', '']
1007 TokenList
= GetSplitValueList(self
._CurrentLine
, ' ', 1)
1008 self
._ValueList
[0:len(TokenList
)] = TokenList
1011 DirectiveName
= self
._ValueList
[0].upper()
1012 if DirectiveName
not in self
.DataType
:
1013 EdkLogger
.error("Parser", FORMAT_INVALID
, "Unknown directive [%s]" % DirectiveName
,
1014 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1016 if DirectiveName
in ['!IF', '!IFDEF', '!IFNDEF']:
1017 self
._InDirective
+= 1
1019 if DirectiveName
in ['!ENDIF']:
1020 self
._InDirective
-= 1
1022 if DirectiveName
in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self
._ValueList
[1] == '':
1023 EdkLogger
.error("Parser", FORMAT_INVALID
, "Missing expression",
1024 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1025 ExtraData
=self
._CurrentLine
)
1027 ItemType
= self
.DataType
[DirectiveName
]
1028 Scope
= [[TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]]
1029 if ItemType
== MODEL_META_DATA_INCLUDE
:
1031 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1032 # Remove all directives between !if and !endif, including themselves
1033 while self
._DirectiveStack
:
1034 # Remove any !else or !elseif
1035 DirectiveInfo
= self
._DirectiveStack
.pop()
1036 if DirectiveInfo
[0] in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1037 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1038 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1041 EdkLogger
.error("Parser", FORMAT_INVALID
, "Redundant '!endif'",
1042 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1043 ExtraData
=self
._CurrentLine
)
1044 elif ItemType
!= MODEL_META_DATA_INCLUDE
:
1045 # Break if there's a !else is followed by a !elseif
1046 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
and \
1047 self
._DirectiveStack
and \
1048 self
._DirectiveStack
[-1][0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1049 EdkLogger
.error("Parser", FORMAT_INVALID
, "'!elseif' after '!else'",
1050 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1051 ExtraData
=self
._CurrentLine
)
1052 self
._DirectiveStack
.append((ItemType
, self
._LineIndex
+ 1, self
._CurrentLine
))
1055 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
1056 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
1058 for Arch
, ModuleType
, DefaultStore
in Scope
:
1059 self
._LastItem
= self
._Store
(
1069 self
._LineIndex
+ 1,
1071 self
._LineIndex
+ 1,
1076 ## [defines] section parser
1078 def _DefineParser(self
):
1079 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1080 self
._ValueList
[1:len(TokenList
)] = TokenList
1083 if not self
._ValueList
[1]:
1084 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
1085 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1086 if not self
._ValueList
[2]:
1087 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
1088 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1089 if (not self
._ValueList
[1] in self
.DefineKeywords
and
1090 (self
._InSubsection
and self
._ValueList
[1] not in self
.SubSectionDefineKeywords
)):
1091 EdkLogger
.error('Parser', FORMAT_INVALID
,
1092 "Unknown keyword found: %s. "
1093 "If this is a macro you must "
1094 "add it as a DEFINE in the DSC" % self
._ValueList
[1],
1095 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1096 if not self
._InSubsection
:
1097 self
._Defines
[self
._ValueList
[1]] = self
._ValueList
[2]
1098 self
._ItemType
= self
.DataType
[TAB_DSC_DEFINES
.upper()]
1101 def _SkuIdParser(self
):
1102 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1103 if len(TokenList
) not in (2,3):
1104 EdkLogger
.error('Parser', FORMAT_INVALID
, "Correct format is '<Number>|<UiName>[|<UiName>]'",
1105 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1106 self
._ValueList
[0:len(TokenList
)] = TokenList
1108 def _DefaultStoresParser(self
):
1109 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1110 if len(TokenList
) != 2:
1111 EdkLogger
.error('Parser', FORMAT_INVALID
, "Correct format is '<Number>|<UiName>'",
1112 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1113 self
._ValueList
[0:len(TokenList
)] = TokenList
1115 ## Parse Edk style of library modules
1117 def _LibraryInstanceParser(self
):
1118 self
._ValueList
[0] = self
._CurrentLine
1120 ## PCD sections parser
1122 # [PcdsFixedAtBuild]
1123 # [PcdsPatchableInModule]
1126 # [PcdsDynamicExDefault]
1127 # [PcdsDynamicExVpd]
1128 # [PcdsDynamicExHii]
1130 # [PcdsDynamicDefault]
1135 def _PcdParser(self
):
1136 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1137 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1138 PcdNameTockens
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1139 if len(PcdNameTockens
) == 2:
1140 self
._ValueList
[0], self
._ValueList
[1] = PcdNameTockens
[0], PcdNameTockens
[1]
1141 elif len(PcdNameTockens
) == 3:
1142 self
._ValueList
[0], self
._ValueList
[1] = ".".join((PcdNameTockens
[0], PcdNameTockens
[1])), PcdNameTockens
[2]
1143 elif len(PcdNameTockens
) > 3:
1144 self
._ValueList
[0], self
._ValueList
[1] = ".".join((PcdNameTockens
[0], PcdNameTockens
[1])), ".".join(PcdNameTockens
[2:])
1145 if len(TokenList
) == 2:
1146 self
._ValueList
[2] = TokenList
[1]
1147 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1148 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1149 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1150 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1151 if self
._ValueList
[2] == '':
1153 # The PCD values are optional for FIXEDATBUILD, PATCHABLEINMODULE, Dynamic/DynamicEx default
1155 if self
._SectionType
in (MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
):
1157 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD value given",
1158 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1159 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1161 # Validate the datum type of Dynamic Defaul PCD and DynamicEx Default PCD
1162 ValueList
= GetSplitValueList(self
._ValueList
[2])
1163 if len(ValueList
) > 1 and ValueList
[1] in [TAB_UINT8
, TAB_UINT16
, TAB_UINT32
, TAB_UINT64
] \
1164 and self
._ItemType
in [MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
]:
1165 EdkLogger
.error('Parser', FORMAT_INVALID
, "The datum type '%s' of PCD is wrong" % ValueList
[1],
1166 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1168 # Validate the VariableName of DynamicHii and DynamicExHii for PCD Entry must not be an empty string
1169 if self
._ItemType
in [MODEL_PCD_DYNAMIC_HII
, MODEL_PCD_DYNAMIC_EX_HII
]:
1170 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
1171 if len(DscPcdValueList
[0].replace('L','').replace('"','').strip()) == 0:
1172 EdkLogger
.error('Parser', FORMAT_INVALID
, "The VariableName field in the HII format PCD entry must not be an empty string",
1173 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1175 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
1176 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
1177 if DscPcdValueList
[0] in ['True', 'true', 'TRUE']:
1178 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '1', 1);
1179 elif DscPcdValueList
[0] in ['False', 'false', 'FALSE']:
1180 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '0', 1);
1183 ## [components] section parser
1185 def _ComponentParser(self
):
1186 if self
._CurrentLine
[-1] == '{':
1187 self
._ValueList
[0] = self
._CurrentLine
[0:-1].strip()
1188 self
._InSubsection
= True
1190 self
._ValueList
[0] = self
._CurrentLine
1192 ## [LibraryClasses] section
1194 def _LibraryClassParser(self
):
1195 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1196 if len(TokenList
) < 2:
1197 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class or instance specified",
1198 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1199 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1200 if TokenList
[0] == '':
1201 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class specified",
1202 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1203 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1204 if TokenList
[1] == '':
1205 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library instance specified",
1206 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1207 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1209 self
._ValueList
[0:len(TokenList
)] = TokenList
1211 def _CompponentSourceOverridePathParser(self
):
1212 self
._ValueList
[0] = self
._CurrentLine
1214 ## [BuildOptions] section parser
1216 def _BuildOptionParser(self
):
1217 self
._CurrentLine
= CleanString(self
._CurrentLine
, BuildOption
=True)
1218 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1219 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
1220 if len(TokenList2
) == 2:
1221 self
._ValueList
[0] = TokenList2
[0] # toolchain family
1222 self
._ValueList
[1] = TokenList2
[1] # keys
1224 self
._ValueList
[1] = TokenList
[0]
1225 if len(TokenList
) == 2: # value
1226 self
._ValueList
[2] = TokenList
[1]
1228 if self
._ValueList
[1].count('_') != 4:
1232 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
1233 ExtraData
=self
._CurrentLine
,
1235 Line
=self
._LineIndex
+ 1
1238 ## Override parent's method since we'll do all macro replacements in parser
1239 def _GetMacros(self
):
1241 Macros
.update(self
._FileLocalMacros
)
1242 Macros
.update(self
._GetApplicableSectionMacro
())
1243 Macros
.update(GlobalData
.gEdkGlobal
)
1244 Macros
.update(GlobalData
.gPlatformDefines
)
1245 Macros
.update(GlobalData
.gCommandLineDefines
)
1246 # PCD cannot be referenced in macro definition
1247 if self
._ItemType
not in [MODEL_META_DATA_DEFINE
, MODEL_META_DATA_GLOBAL_DEFINE
]:
1248 Macros
.update(self
._Symbols
)
1249 if GlobalData
.BuildOptionPcd
:
1250 for Item
in GlobalData
.BuildOptionPcd
:
1251 if type(Item
) is tuple:
1253 PcdName
, TmpValue
= Item
.split("=")
1254 TmpValue
= BuildOptionValue(TmpValue
, self
._GuidDict
)
1255 Macros
[PcdName
.strip()] = TmpValue
1258 def _PostProcess(self
):
1260 MODEL_META_DATA_SECTION_HEADER
: self
.__ProcessSectionHeader
,
1261 MODEL_META_DATA_SUBSECTION_HEADER
: self
.__ProcessSubsectionHeader
,
1262 MODEL_META_DATA_HEADER
: self
.__ProcessDefine
,
1263 MODEL_META_DATA_DEFINE
: self
.__ProcessDefine
,
1264 MODEL_META_DATA_GLOBAL_DEFINE
: self
.__ProcessDefine
,
1265 MODEL_META_DATA_INCLUDE
: self
.__ProcessDirective
,
1266 MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
: self
.__ProcessDirective
,
1267 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
: self
.__ProcessDirective
,
1268 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
: self
.__ProcessDirective
,
1269 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
: self
.__ProcessDirective
,
1270 MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
: self
.__ProcessDirective
,
1271 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
: self
.__ProcessDirective
,
1272 MODEL_EFI_SKU_ID
: self
.__ProcessSkuId
,
1273 MODEL_EFI_DEFAULT_STORES
: self
.__ProcessDefaultStores
,
1274 MODEL_EFI_LIBRARY_INSTANCE
: self
.__ProcessLibraryInstance
,
1275 MODEL_EFI_LIBRARY_CLASS
: self
.__ProcessLibraryClass
,
1276 MODEL_PCD_FIXED_AT_BUILD
: self
.__ProcessPcd
,
1277 MODEL_PCD_PATCHABLE_IN_MODULE
: self
.__ProcessPcd
,
1278 MODEL_PCD_FEATURE_FLAG
: self
.__ProcessPcd
,
1279 MODEL_PCD_DYNAMIC_DEFAULT
: self
.__ProcessPcd
,
1280 MODEL_PCD_DYNAMIC_HII
: self
.__ProcessPcd
,
1281 MODEL_PCD_DYNAMIC_VPD
: self
.__ProcessPcd
,
1282 MODEL_PCD_DYNAMIC_EX_DEFAULT
: self
.__ProcessPcd
,
1283 MODEL_PCD_DYNAMIC_EX_HII
: self
.__ProcessPcd
,
1284 MODEL_PCD_DYNAMIC_EX_VPD
: self
.__ProcessPcd
,
1285 MODEL_META_DATA_COMPONENT
: self
.__ProcessComponent
,
1286 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: self
.__ProcessSourceOverridePath
,
1287 MODEL_META_DATA_BUILD_OPTION
: self
.__ProcessBuildOption
,
1288 MODEL_UNKNOWN
: self
._Skip
,
1289 MODEL_META_DATA_USER_EXTENSION
: self
._SkipUserExtension
,
1292 self
._Table
= MetaFileStorage(self
._RawTable
.Cur
, self
.MetaFile
, MODEL_FILE_DSC
, True)
1293 self
._Table
.Create()
1294 self
._DirectiveStack
= []
1295 self
._DirectiveEvalStack
= []
1296 self
._FileWithError
= self
.MetaFile
1297 self
._FileLocalMacros
= {}
1298 self
._SectionsMacroDict
.clear()
1299 GlobalData
.gPlatformDefines
= {}
1301 # Get all macro and PCD which has straitforward value
1302 self
.__RetrievePcdValue
()
1303 self
._Content
= self
._RawTable
.GetAll()
1304 self
._ContentIndex
= 0
1305 self
._InSubsection
= False
1306 while self
._ContentIndex
< len(self
._Content
) :
1307 Id
, self
._ItemType
, V1
, V2
, V3
, S1
, S2
, S3
,Owner
, self
._From
, \
1308 LineStart
, ColStart
, LineEnd
, ColEnd
, Enabled
= self
._Content
[self
._ContentIndex
]
1311 self
._FileWithError
= self
.MetaFile
1313 self
._ContentIndex
+= 1
1315 self
._Scope
= [[S1
, S2
, S3
]]
1317 # For !include directive, handle it specially,
1318 # merge arch and module type in case of duplicate items
1320 while self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1321 if self
._ContentIndex
>= len(self
._Content
):
1323 Record
= self
._Content
[self
._ContentIndex
]
1324 if LineStart
== Record
[10] and LineEnd
== Record
[12]:
1325 if [Record
[5], Record
[6],Record
[7]] not in self
._Scope
:
1326 self
._Scope
.append([Record
[5], Record
[6],Record
[7]])
1327 self
._ContentIndex
+= 1
1331 self
._LineIndex
= LineStart
- 1
1332 self
._ValueList
= [V1
, V2
, V3
]
1334 if Owner
> 0 and Owner
in self
._IdMapping
:
1335 self
._InSubsection
= True
1337 self
._InSubsection
= False
1339 Processer
[self
._ItemType
]()
1340 except EvaluationException
, Excpt
:
1342 # Only catch expression evaluation error here. We need to report
1343 # the precise number of line on which the error occurred
1345 if hasattr(Excpt
, 'Pcd'):
1346 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
1347 Info
= GlobalData
.gPlatformOtherPcds
[Excpt
.Pcd
]
1348 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
1349 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
1350 " of the DSC file, and it is currently defined in this section:"
1351 " %s, line #: %d." % (Excpt
.Pcd
, Info
[0], Info
[1]),
1352 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1353 Line
=self
._LineIndex
+ 1)
1355 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
1356 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1357 Line
=self
._LineIndex
+ 1)
1359 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
1360 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1361 Line
=self
._LineIndex
+ 1)
1362 except MacroException
, Excpt
:
1363 EdkLogger
.error('Parser', FORMAT_INVALID
, str(Excpt
),
1364 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1365 Line
=self
._LineIndex
+ 1)
1367 if self
._ValueList
is None:
1370 NewOwner
= self
._IdMapping
.get(Owner
, -1)
1371 self
._Enabled
= int((not self
._DirectiveEvalStack
) or (False not in self
._DirectiveEvalStack
))
1372 self
._LastItem
= self
._Store
(
1382 self
._LineIndex
+ 1,
1384 self
._LineIndex
+ 1,
1388 self
._IdMapping
[Id
] = self
._LastItem
1390 GlobalData
.gPlatformDefines
.update(self
._FileLocalMacros
)
1391 self
._PostProcessed
= True
1392 self
._Content
= None
1394 def __ProcessSectionHeader(self
):
1395 self
._SectionName
= self
._ValueList
[0]
1396 if self
._SectionName
in self
.DataType
:
1397 self
._SectionType
= self
.DataType
[self
._SectionName
]
1399 self
._SectionType
= MODEL_UNKNOWN
1401 def __ProcessSubsectionHeader(self
):
1402 self
._SubsectionName
= self
._ValueList
[0]
1403 if self
._SubsectionName
in self
.DataType
:
1404 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
1406 self
._SubsectionType
= MODEL_UNKNOWN
1408 def __RetrievePcdValue(self
):
1409 Content
= open(str(self
.MetaFile
), 'r').readlines()
1410 GlobalData
.gPlatformOtherPcds
['DSCFILE'] = str(self
.MetaFile
)
1411 for PcdType
in (MODEL_PCD_PATCHABLE_IN_MODULE
, MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_HII
,
1412 MODEL_PCD_DYNAMIC_VPD
, MODEL_PCD_DYNAMIC_EX_DEFAULT
, MODEL_PCD_DYNAMIC_EX_HII
,
1413 MODEL_PCD_DYNAMIC_EX_VPD
):
1414 Records
= self
._RawTable
.Query(PcdType
, BelongsToItem
= -1.0)
1415 for TokenSpaceGuid
, PcdName
, Value
, Dummy2
, Dummy3
, Dummy4
,ID
, Line
in Records
:
1416 Name
= TokenSpaceGuid
+ '.' + PcdName
1417 if Name
not in GlobalData
.gPlatformOtherPcds
:
1419 while not Content
[Line
- 1].lstrip().startswith(TAB_SECTION_START
):
1421 GlobalData
.gPlatformOtherPcds
[Name
] = (CleanString(Content
[Line
- 1]), PcdLine
, PcdType
)
1423 def __ProcessDefine(self
):
1424 if not self
._Enabled
:
1427 Type
, Name
, Value
= self
._ValueList
1428 Value
= ReplaceMacro(Value
, self
._Macros
, False)
1430 # If it is <Defines>, return
1432 if self
._InSubsection
:
1433 self
._ValueList
= [Type
, Name
, Value
]
1436 if self
._ItemType
== MODEL_META_DATA_DEFINE
:
1437 if self
._SectionType
== MODEL_META_DATA_HEADER
:
1438 self
._FileLocalMacros
[Name
] = Value
1440 self
._ConstructSectionMacroDict
(Name
, Value
)
1441 elif self
._ItemType
== MODEL_META_DATA_GLOBAL_DEFINE
:
1442 GlobalData
.gEdkGlobal
[Name
] = Value
1445 # Keyword in [Defines] section can be used as Macros
1447 if (self
._ItemType
== MODEL_META_DATA_HEADER
) and (self
._SectionType
== MODEL_META_DATA_HEADER
):
1448 self
._FileLocalMacros
[Name
] = Value
1450 self
._ValueList
= [Type
, Name
, Value
]
1452 def __ProcessDirective(self
):
1454 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1455 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
]:
1456 Macros
= self
._Macros
1457 Macros
.update(GlobalData
.gGlobalDefines
)
1459 Result
= ValueExpression(self
._ValueList
[1], Macros
)()
1460 except SymbolNotFound
, Exc
:
1461 EdkLogger
.debug(EdkLogger
.DEBUG_5
, str(Exc
), self
._ValueList
[1])
1463 except WrnExpression
, Excpt
:
1465 # Catch expression evaluation warning here. We need to report
1466 # the precise number of line and return the evaluation result
1468 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
1469 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1470 Line
=self
._LineIndex
+ 1)
1471 Result
= Excpt
.result
1473 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1474 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1475 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1476 self
._DirectiveStack
.append(self
._ItemType
)
1477 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
:
1478 Result
= bool(Result
)
1480 Macro
= self
._ValueList
[1]
1481 Macro
= Macro
[2:-1] if (Macro
.startswith("$(") and Macro
.endswith(")")) else Macro
1482 Result
= Macro
in self
._Macros
1483 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
:
1485 self
._DirectiveEvalStack
.append(Result
)
1486 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
:
1487 self
._DirectiveStack
.append(self
._ItemType
)
1488 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1489 self
._DirectiveEvalStack
.append(bool(Result
))
1490 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1491 self
._DirectiveStack
.append(self
._ItemType
)
1492 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1493 self
._DirectiveEvalStack
.append(True)
1494 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1495 # Back to the nearest !if/!ifdef/!ifndef
1496 while self
._DirectiveStack
:
1497 self
._DirectiveEvalStack
.pop()
1498 Directive
= self
._DirectiveStack
.pop()
1499 if Directive
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1500 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1501 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1503 elif self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1504 # The included file must be relative to workspace or same directory as DSC file
1505 __IncludeMacros
= {}
1507 # Allow using system environment variables in path after !include
1509 __IncludeMacros
['WORKSPACE'] = GlobalData
.gGlobalDefines
['WORKSPACE']
1510 if "ECP_SOURCE" in GlobalData
.gGlobalDefines
:
1511 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gGlobalDefines
['ECP_SOURCE']
1513 # During GenFds phase call DSC parser, will go into this branch.
1515 elif "ECP_SOURCE" in GlobalData
.gCommandLineDefines
:
1516 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gCommandLineDefines
['ECP_SOURCE']
1518 __IncludeMacros
['EFI_SOURCE'] = GlobalData
.gGlobalDefines
['EFI_SOURCE']
1519 __IncludeMacros
['EDK_SOURCE'] = GlobalData
.gGlobalDefines
['EDK_SOURCE']
1521 # Allow using MACROs comes from [Defines] section to keep compatible.
1523 __IncludeMacros
.update(self
._Macros
)
1525 IncludedFile
= NormPath(ReplaceMacro(self
._ValueList
[1], __IncludeMacros
, RaiseError
=True))
1527 # First search the include file under the same directory as DSC file
1529 IncludedFile1
= PathClass(IncludedFile
, self
.MetaFile
.Dir
)
1530 ErrorCode
, ErrorInfo1
= IncludedFile1
.Validate()
1533 # Also search file under the WORKSPACE directory
1535 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
1536 ErrorCode
, ErrorInfo2
= IncludedFile1
.Validate()
1538 EdkLogger
.error('parser', ErrorCode
, File
=self
._FileWithError
,
1539 Line
=self
._LineIndex
+ 1, ExtraData
=ErrorInfo1
+ "\n" + ErrorInfo2
)
1541 self
._FileWithError
= IncludedFile1
1543 IncludedFileTable
= MetaFileStorage(self
._Table
.Cur
, IncludedFile1
, MODEL_FILE_DSC
, False)
1544 FromItem
= self
._Content
[self
._ContentIndex
- 1][0]
1545 if self
._InSubsection
:
1546 Owner
= self
._Content
[self
._ContentIndex
- 1][8]
1548 Owner
= self
._Content
[self
._ContentIndex
- 1][0]
1549 Parser
= DscParser(IncludedFile1
, self
._FileType
, self
._Arch
, IncludedFileTable
,
1550 Owner
=Owner
, From
=FromItem
)
1552 self
.IncludedFiles
.add (IncludedFile1
)
1554 # todo: rework the nested include checking logic
1555 # Current nested include checking rely on dsc file order inside build.db.
1556 # It is not reliable and will lead to build fail in some case.
1558 # When project A and B include a common dsc file C.
1559 # Build project A. It give dsc file A = ID 1 in build.db, and C ID = 2.
1560 # Build project B. It give dsc file B ID = 3, and C ID still = 2.
1561 # Then, we build project B fail, unless we clean build.db.
1562 # In oldder BaseTools, the project B ID will still be 1,
1563 # that's why it work before.
1565 # Does not allow lower level included file to include upper level included file
1566 #if Parser._From != Owner and int(Owner) > int (Parser._From):
1567 # EdkLogger.error('parser', FILE_ALREADY_EXIST, File=self._FileWithError,
1568 # Line=self._LineIndex + 1, ExtraData="{0} is already included at a higher level.".format(IncludedFile1))
1571 # set the parser status with current status
1572 Parser
._SectionName
= self
._SectionName
1573 if self
._InSubsection
:
1574 Parser
._SectionType
= self
._SubsectionType
1576 Parser
._SectionType
= self
._SectionType
1577 Parser
._Scope
= self
._Scope
1578 Parser
._Enabled
= self
._Enabled
1579 # Parse the included file
1582 # update current status with sub-parser's status
1583 self
._SectionName
= Parser
._SectionName
1584 if not self
._InSubsection
:
1585 self
._SectionType
= Parser
._SectionType
1586 self
._SubsectionType
= Parser
._SubsectionType
1587 self
._InSubsection
= Parser
._InSubsection
1589 self
._Scope
= Parser
._Scope
1590 self
._Enabled
= Parser
._Enabled
1592 # Insert all records in the table for the included file into dsc file table
1593 Records
= IncludedFileTable
.GetAll()
1595 self
._Content
[self
._ContentIndex
:self
._ContentIndex
] = Records
1596 self
._Content
.pop(self
._ContentIndex
- 1)
1597 self
._ValueList
= None
1598 self
._ContentIndex
-= 1
1600 def __ProcessSkuId(self
):
1601 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=True)
1602 for Value
in self
._ValueList
]
1603 def __ProcessDefaultStores(self
):
1604 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=True)
1605 for Value
in self
._ValueList
]
1607 def __ProcessLibraryInstance(self
):
1608 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
1610 def __ProcessLibraryClass(self
):
1611 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
, RaiseError
=True)
1613 def __ProcessPcd(self
):
1614 if self
._ItemType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
1615 self
._ValueList
[2] = ReplaceMacro(self
._ValueList
[2], self
._Macros
, RaiseError
=True)
1618 ValList
, Valid
, Index
= AnalyzeDscPcd(self
._ValueList
[2], self
._ItemType
)
1620 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
._FileWithError
, Line
=self
._LineIndex
+ 1,
1621 ExtraData
="%s.%s|%s" % (self
._ValueList
[0], self
._ValueList
[1], self
._ValueList
[2]))
1622 PcdValue
= ValList
[Index
]
1623 if PcdValue
and "." not in self
._ValueList
[0]:
1625 ValList
[Index
] = ValueExpression(PcdValue
, self
._Macros
)(True)
1626 except WrnExpression
, Value
:
1627 ValList
[Index
] = Value
.result
1631 if ValList
[Index
] == 'True':
1632 ValList
[Index
] = '1'
1633 if ValList
[Index
] == 'False':
1634 ValList
[Index
] = '0'
1636 if (not self
._DirectiveEvalStack
) or (False not in self
._DirectiveEvalStack
):
1637 GlobalData
.gPlatformPcds
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = PcdValue
1638 self
._Symbols
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = PcdValue
1640 self
._ValueList
[2] = '|'.join(ValList
)
1644 def __ProcessComponent(self
):
1645 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1647 def __ProcessSourceOverridePath(self
):
1648 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1650 def __ProcessBuildOption(self
):
1651 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=False)
1652 for Value
in self
._ValueList
]
1655 MODEL_META_DATA_HEADER
: _DefineParser
,
1656 MODEL_EFI_SKU_ID
: _SkuIdParser
,
1657 MODEL_EFI_DEFAULT_STORES
: _DefaultStoresParser
,
1658 MODEL_EFI_LIBRARY_INSTANCE
: _LibraryInstanceParser
,
1659 MODEL_EFI_LIBRARY_CLASS
: _LibraryClassParser
,
1660 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1661 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1662 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1663 MODEL_PCD_DYNAMIC_DEFAULT
: _PcdParser
,
1664 MODEL_PCD_DYNAMIC_HII
: _PcdParser
,
1665 MODEL_PCD_DYNAMIC_VPD
: _PcdParser
,
1666 MODEL_PCD_DYNAMIC_EX_DEFAULT
: _PcdParser
,
1667 MODEL_PCD_DYNAMIC_EX_HII
: _PcdParser
,
1668 MODEL_PCD_DYNAMIC_EX_VPD
: _PcdParser
,
1669 MODEL_META_DATA_COMPONENT
: _ComponentParser
,
1670 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: _CompponentSourceOverridePathParser
,
1671 MODEL_META_DATA_BUILD_OPTION
: _BuildOptionParser
,
1672 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1673 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
1674 MODEL_META_DATA_SECTION_HEADER
: MetaFileParser
._SectionHeaderParser
,
1675 MODEL_META_DATA_SUBSECTION_HEADER
: _SubsectionHeaderParser
,
1678 _Macros
= property(_GetMacros
)
1680 ## DEC file parser class
1682 # @param FilePath The path of platform description file
1683 # @param FileType The raw data of DSC file
1684 # @param Table Database used to retrieve module/package information
1685 # @param Macros Macros used for replacement in file
1687 class DecParser(MetaFileParser
):
1688 # DEC file supported data types (one type per section)
1690 TAB_DEC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
1691 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
1692 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
1693 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
1694 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
1695 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
1696 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
1697 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
1698 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
1699 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
1700 TAB_PCDS_DYNAMIC_NULL
.upper() : MODEL_PCD_DYNAMIC
,
1701 TAB_PCDS_DYNAMIC_EX_NULL
.upper() : MODEL_PCD_DYNAMIC_EX
,
1702 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
,
1705 ## Constructor of DecParser
1707 # Initialize object of DecParser
1709 # @param FilePath The path of platform description file
1710 # @param FileType The raw data of DSC file
1711 # @param Arch Default Arch value for filtering sections
1712 # @param Table Database used to retrieve module/package information
1714 def __init__(self
, FilePath
, FileType
, Arch
, Table
):
1715 # prevent re-initialization
1716 if hasattr(self
, "_Table"):
1718 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
, -1)
1720 self
._Version
= 0x00010005 # Only EDK2 dec file is supported
1721 self
._AllPCDs
= [] # Only for check duplicate PCD
1722 self
._AllPcdDict
= {}
1724 self
._CurrentStructurePcdName
= ""
1725 self
._include
_flag
= False
1726 self
._package
_flag
= False
1732 Content
= open(str(self
.MetaFile
), 'r').readlines()
1734 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
1736 self
._DefinesCount
= 0
1737 for Index
in range(0, len(Content
)):
1738 Line
, Comment
= CleanString2(Content
[Index
])
1739 self
._CurrentLine
= Line
1740 self
._LineIndex
= Index
1742 # save comment for later use
1744 self
._Comments
.append((Comment
, self
._LineIndex
+ 1))
1750 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
1751 self
._SectionHeaderParser
()
1752 if self
._SectionName
== TAB_DEC_DEFINES
.upper():
1753 self
._DefinesCount
+= 1
1756 if self
._SectionType
== MODEL_UNKNOWN
:
1757 EdkLogger
.error("Parser", FORMAT_INVALID
,
1759 "Not able to determine \"%s\" in which section."%self
._CurrentLine
,
1760 self
.MetaFile
, self
._LineIndex
+ 1)
1761 elif len(self
._SectionType
) == 0:
1766 self
._ValueList
= ['', '', '']
1767 self
._SectionParser
[self
._SectionType
[0]](self
)
1768 if self
._ValueList
is None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
1774 # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,
1775 # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1
1777 for Arch
, ModuleType
, Type
in self
._Scope
:
1778 self
._LastItem
= self
._Store
(
1786 self
._LineIndex
+ 1,
1788 self
._LineIndex
+ 1,
1792 for Comment
, LineNo
in self
._Comments
:
1794 MODEL_META_DATA_COMMENT
,
1808 if self
._DefinesCount
> 1:
1809 EdkLogger
.error('Parser', FORMAT_INVALID
, 'Multiple [Defines] section is exist.', self
.MetaFile
)
1810 if self
._DefinesCount
== 0:
1811 EdkLogger
.error('Parser', FORMAT_INVALID
, 'No [Defines] section exist.',self
.MetaFile
)
1815 ## Section header parser
1817 # The section header is always in following format:
1819 # [section_name.arch<.platform|module_type>]
1821 def _SectionHeaderParser(self
):
1823 self
._SectionName
= ''
1824 self
._SectionType
= []
1827 Line
= re
.sub(',[\s]*', TAB_COMMA_SPLIT
, self
._CurrentLine
)
1828 for Item
in Line
[1:-1].split(TAB_COMMA_SPLIT
):
1830 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
,
1831 "section name can NOT be empty or incorrectly use separator comma",
1832 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1833 ItemList
= Item
.split(TAB_SPLIT
)
1835 # different types of PCD are permissible in one section
1836 self
._SectionName
= ItemList
[0].upper()
1837 if self
._SectionName
== TAB_DEC_DEFINES
.upper() and (len(ItemList
) > 1 or len(Line
.split(TAB_COMMA_SPLIT
)) > 1):
1838 EdkLogger
.error("Parser", FORMAT_INVALID
, "Defines section format is invalid",
1839 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1840 if self
._SectionName
in self
.DataType
:
1841 if self
.DataType
[self
._SectionName
] not in self
._SectionType
:
1842 self
._SectionType
.append(self
.DataType
[self
._SectionName
])
1844 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
1845 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1847 if MODEL_PCD_FEATURE_FLAG
in self
._SectionType
and len(self
._SectionType
) > 1:
1851 "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL
,
1853 Line
=self
._LineIndex
+ 1,
1854 ExtraData
=self
._CurrentLine
1857 if len(ItemList
) > 1:
1858 S1
= ItemList
[1].upper()
1860 S1
= TAB_ARCH_COMMON
1862 # S2 may be Platform or ModuleType
1863 if len(ItemList
) > 2:
1864 S2
= ItemList
[2].upper()
1865 # only Includes, GUIDs, PPIs, Protocols section have Private tag
1866 if self
._SectionName
in [TAB_INCLUDES
.upper(), TAB_GUIDS
.upper(), TAB_PROTOCOLS
.upper(), TAB_PPIS
.upper()]:
1868 EdkLogger
.error("Parser", FORMAT_INVALID
, 'Please use keyword "Private" as section tag modifier.',
1869 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1873 if [S1
, S2
, self
.DataType
[self
._SectionName
]] not in self
._Scope
:
1874 self
._Scope
.append([S1
, S2
, self
.DataType
[self
._SectionName
]])
1876 # 'COMMON' must not be used with specific ARCHs at the same section
1877 if TAB_ARCH_COMMON
in ArchList
and len(ArchList
) > 1:
1878 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
1879 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1881 # It is not permissible to mix section tags without the Private attribute with section tags with the Private attribute
1882 if TAB_COMMON
in PrivateList
and len(PrivateList
) > 1:
1883 EdkLogger
.error('Parser', FORMAT_INVALID
, "Can't mix section tags without the Private attribute with section tags with the Private attribute",
1884 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1886 ## [guids], [ppis] and [protocols] section parser
1888 def _GuidParser(self
):
1889 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1890 if len(TokenList
) < 2:
1891 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name or value specified",
1892 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1893 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1894 if TokenList
[0] == '':
1895 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name specified",
1896 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1897 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1898 if TokenList
[1] == '':
1899 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID value specified",
1900 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1901 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1902 if TokenList
[1][0] != '{' or TokenList
[1][-1] != '}' or GuidStructureStringToGuidString(TokenList
[1]) == '':
1903 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid GUID value format",
1904 ExtraData
=self
._CurrentLine
+ \
1905 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
1906 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1907 self
._ValueList
[0] = TokenList
[0]
1908 self
._ValueList
[1] = TokenList
[1]
1909 if self
._ValueList
[0] not in self
._GuidDict
:
1910 self
._GuidDict
[self
._ValueList
[0]] = self
._ValueList
[1]
1912 ## PCD sections parser
1914 # [PcdsFixedAtBuild]
1915 # [PcdsPatchableInModule]
1921 def _PcdParser(self
):
1922 if self
._CurrentStructurePcdName
:
1923 self
._ValueList
[0] = self
._CurrentStructurePcdName
1925 if "|" not in self
._CurrentLine
:
1926 if "<HeaderFiles>" == self
._CurrentLine
:
1927 self
._include
_flag
= True
1928 self
._package
_flag
= False
1929 self
._ValueList
= None
1931 if "<Packages>" == self
._CurrentLine
:
1932 self
._package
_flag
= True
1933 self
._ValueList
= None
1934 self
._include
_flag
= False
1937 if self
._include
_flag
:
1938 self
._ValueList
[1] = "<HeaderFiles>_" + md5
.new(self
._CurrentLine
).hexdigest()
1939 self
._ValueList
[2] = self
._CurrentLine
1940 if self
._package
_flag
and "}" != self
._CurrentLine
:
1941 self
._ValueList
[1] = "<Packages>_" + md5
.new(self
._CurrentLine
).hexdigest()
1942 self
._ValueList
[2] = self
._CurrentLine
1943 if self
._CurrentLine
== "}":
1944 self
._package
_flag
= False
1945 self
._include
_flag
= False
1946 self
._ValueList
= None
1949 PcdTockens
= self
._CurrentLine
.split(TAB_VALUE_SPLIT
)
1950 PcdNames
= PcdTockens
[0].split(TAB_SPLIT
)
1951 if len(PcdNames
) == 2:
1952 self
._CurrentStructurePcdName
= ""
1954 if self
._CurrentStructurePcdName
!= TAB_SPLIT
.join(PcdNames
[:2]):
1955 EdkLogger
.error('Parser', FORMAT_INVALID
, "Pcd Name does not match: %s and %s " % (self
._CurrentStructurePcdName
, TAB_SPLIT
.join(PcdNames
[:2])),
1956 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1957 self
._ValueList
[1] = TAB_SPLIT
.join(PcdNames
[2:])
1958 self
._ValueList
[2] = PcdTockens
[1]
1959 if not self
._CurrentStructurePcdName
:
1960 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1961 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1962 ValueRe
= re
.compile(r
'^[a-zA-Z_][a-zA-Z0-9_]*')
1963 # check PCD information
1964 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1965 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1966 ExtraData
=self
._CurrentLine
+ \
1967 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1968 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1969 # check format of token space GUID CName
1970 if not ValueRe
.match(self
._ValueList
[0]):
1971 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_]*'",
1972 ExtraData
=self
._CurrentLine
+ \
1973 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1974 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1975 # check format of PCD CName
1976 if not ValueRe
.match(self
._ValueList
[1]):
1977 EdkLogger
.error('Parser', FORMAT_INVALID
, "The format of the PCD CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",
1978 ExtraData
=self
._CurrentLine
+ \
1979 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1980 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1981 # check PCD datum information
1982 if len(TokenList
) < 2 or TokenList
[1] == '':
1983 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD Datum information given",
1984 ExtraData
=self
._CurrentLine
+ \
1985 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1986 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1989 ValueRe
= re
.compile(r
'^\s*L?\".*\|.*\"')
1990 PtrValue
= ValueRe
.findall(TokenList
[1])
1992 # Has VOID* type string, may contain "|" character in the string.
1993 if len(PtrValue
) != 0:
1994 ptrValueList
= re
.sub(ValueRe
, '', TokenList
[1])
1995 ValueList
= AnalyzePcdExpression(ptrValueList
)
1996 ValueList
[0] = PtrValue
[0]
1998 ValueList
= AnalyzePcdExpression(TokenList
[1])
2001 # check if there's enough datum information given
2002 if len(ValueList
) != 3:
2003 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid PCD Datum information given",
2004 ExtraData
=self
._CurrentLine
+ \
2005 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2006 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2007 # check default value
2008 if ValueList
[0] == '':
2009 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DefaultValue in PCD Datum information",
2010 ExtraData
=self
._CurrentLine
+ \
2011 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2012 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2014 if ValueList
[1] == '':
2015 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DatumType in PCD Datum information",
2016 ExtraData
=self
._CurrentLine
+ \
2017 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2018 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2019 # check token of the PCD
2020 if ValueList
[2] == '':
2021 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing Token in PCD Datum information",
2022 ExtraData
=self
._CurrentLine
+ \
2023 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2024 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2026 PcdValue
= ValueList
[0]
2029 self
._GuidDict
.update(self
._AllPcdDict
)
2030 ValueList
[0] = ValueExpressionEx(ValueList
[0], ValueList
[1], self
._GuidDict
)(True)
2031 except BadExpression
, Value
:
2032 EdkLogger
.error('Parser', FORMAT_INVALID
, Value
, ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2033 # check format of default value against the datum type
2034 IsValid
, Cause
= CheckPcdDatum(ValueList
[1], ValueList
[0])
2036 EdkLogger
.error('Parser', FORMAT_INVALID
, Cause
, ExtraData
=self
._CurrentLine
,
2037 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2039 if Cause
== "StructurePcd":
2040 self
._CurrentStructurePcdName
= TAB_SPLIT
.join(self
._ValueList
[0:2])
2041 self
._ValueList
[0] = self
._CurrentStructurePcdName
2042 self
._ValueList
[1] = ValueList
[1].strip()
2044 if ValueList
[0] in ['True', 'true', 'TRUE']:
2046 elif ValueList
[0] in ['False', 'false', 'FALSE']:
2049 # check for duplicate PCD definition
2050 if (self
._Scope
[0], self
._ValueList
[0], self
._ValueList
[1]) in self
._AllPCDs
:
2051 EdkLogger
.error('Parser', FORMAT_INVALID
,
2052 "The same PCD name and GUID have been already defined",
2053 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2055 self
._AllPCDs
.append((self
._Scope
[0], self
._ValueList
[0], self
._ValueList
[1]))
2056 self
._AllPcdDict
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = ValueList
[0]
2058 self
._ValueList
[2] = ValueList
[0].strip() + '|' + ValueList
[1].strip() + '|' + ValueList
[2].strip()
2061 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
2062 MODEL_EFI_INCLUDE
: MetaFileParser
._PathParser
,
2063 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
2064 MODEL_EFI_GUID
: _GuidParser
,
2065 MODEL_EFI_PPI
: _GuidParser
,
2066 MODEL_EFI_PROTOCOL
: _GuidParser
,
2067 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
2068 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
2069 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
2070 MODEL_PCD_DYNAMIC
: _PcdParser
,
2071 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
2072 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
2073 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
2078 # This acts like the main() function for the script, unless it is 'import'ed into another
2081 if __name__
== '__main__':