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 ## 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
= {}
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
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
:
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
)
424 SectionDictKey
= self
._SectionType
, ScopeKey
426 # DecParser SectionType is a list, will contain more than one item only in Pcd Section
427 # As Pcd section macro usage is not alllowed, so here it is safe
429 if type(self
) == DecParser
:
430 SectionDictKey
= self
._SectionType
[0], ScopeKey
431 if SectionDictKey
not in self
._SectionsMacroDict
:
432 self
._SectionsMacroDict
[SectionDictKey
] = {}
433 SectionLocalMacros
= self
._SectionsMacroDict
[SectionDictKey
]
434 SectionLocalMacros
[Name
] = Value
436 ## Get section Macros that are applicable to current line, which may come from other sections
437 ## that share the same name while scope is wider
438 def _GetApplicableSectionMacro(self
):
445 ActiveSectionType
= self
._SectionType
446 if type(self
) == DecParser
:
447 ActiveSectionType
= self
._SectionType
[0]
449 for (SectionType
, Scope
) in self
._SectionsMacroDict
:
450 if SectionType
!= ActiveSectionType
:
453 for ActiveScope
in self
._Scope
:
454 Scope0
, Scope1
,Scope2
= ActiveScope
[0], ActiveScope
[1],ActiveScope
[2]
455 if(Scope0
, Scope1
,Scope2
) not in Scope
:
458 SpeSpeMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
460 for ActiveScope
in self
._Scope
:
461 Scope0
, Scope1
,Scope2
= ActiveScope
[0], ActiveScope
[1],ActiveScope
[2]
462 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
:
465 ComSpeMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
467 if (TAB_COMMON
, TAB_COMMON
, TAB_COMMON
) in Scope
:
468 ComComMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
470 Macros
.update(ComComMacroDict
)
471 Macros
.update(ComSpeMacroDict
)
472 Macros
.update(SpeSpeMacroDict
)
477 Finished
= property(_GetFinished
, _SetFinished
)
478 _Macros
= property(_GetMacros
)
481 ## INF file parser class
483 # @param FilePath The path of platform description file
484 # @param FileType The raw data of DSC file
485 # @param Table Database used to retrieve module/package information
486 # @param Macros Macros used for replacement in file
488 class InfParser(MetaFileParser
):
489 # INF file supported data types (one type per section)
491 TAB_UNKNOWN
.upper() : MODEL_UNKNOWN
,
492 TAB_INF_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
493 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
494 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
495 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
496 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
497 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
498 TAB_PACKAGES
.upper() : MODEL_META_DATA_PACKAGE
,
499 TAB_NMAKE
.upper() : MODEL_META_DATA_NMAKE
,
500 TAB_INF_FIXED_PCD
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
501 TAB_INF_PATCH_PCD
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
502 TAB_INF_FEATURE_PCD
.upper() : MODEL_PCD_FEATURE_FLAG
,
503 TAB_INF_PCD_EX
.upper() : MODEL_PCD_DYNAMIC_EX
,
504 TAB_INF_PCD
.upper() : MODEL_PCD_DYNAMIC
,
505 TAB_SOURCES
.upper() : MODEL_EFI_SOURCE_FILE
,
506 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
507 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
508 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
509 TAB_DEPEX
.upper() : MODEL_EFI_DEPEX
,
510 TAB_BINARIES
.upper() : MODEL_EFI_BINARY_FILE
,
511 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
514 ## Constructor of InfParser
516 # Initialize object of InfParser
518 # @param FilePath The path of module description file
519 # @param FileType The raw data of DSC file
520 # @param Arch Default Arch value for filtering sections
521 # @param Table Database used to retrieve module/package information
523 def __init__(self
, FilePath
, FileType
, Arch
, Table
):
524 # prevent re-initialization
525 if hasattr(self
, "_Table"):
527 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
)
535 Content
= open(str(self
.MetaFile
), 'r').readlines()
537 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
539 # parse the file line by line
540 IsFindBlockComment
= False
541 GetHeaderComment
= False
546 for Index
in range(0, len(Content
)):
547 # skip empty, commented, block commented lines
548 Line
, Comment
= CleanString2(Content
[Index
], AllowCppStyleComment
=True)
550 if Index
+ 1 < len(Content
):
551 NextLine
, NextComment
= CleanString2(Content
[Index
+ 1])
554 Comments
.append((Comment
, Index
+ 1))
555 elif GetHeaderComment
:
556 SectionComments
.extend(Comments
)
559 if Line
.find(DataType
.TAB_COMMENT_EDK_START
) > -1:
560 IsFindBlockComment
= True
562 if Line
.find(DataType
.TAB_COMMENT_EDK_END
) > -1:
563 IsFindBlockComment
= False
565 if IsFindBlockComment
:
568 self
._LineIndex
= Index
569 self
._CurrentLine
= Line
572 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
573 if not GetHeaderComment
:
574 for Cmt
, LNo
in Comments
:
575 self
._Store
(MODEL_META_DATA_HEADER_COMMENT
, Cmt
, '', '', TAB_COMMON
,
576 TAB_COMMON
, self
._Owner
[-1], LNo
, -1, LNo
, -1, 0)
577 GetHeaderComment
= True
579 TailComments
.extend(SectionComments
+ Comments
)
581 self
._SectionHeaderParser
()
582 # Check invalid sections
583 if self
._Version
< 0x00010005:
584 if self
._SectionType
in [MODEL_META_DATA_BUILD_OPTION
,
585 MODEL_EFI_LIBRARY_CLASS
,
586 MODEL_META_DATA_PACKAGE
,
587 MODEL_PCD_FIXED_AT_BUILD
,
588 MODEL_PCD_PATCHABLE_IN_MODULE
,
589 MODEL_PCD_FEATURE_FLAG
,
590 MODEL_PCD_DYNAMIC_EX
,
595 MODEL_META_DATA_USER_EXTENSION
]:
596 EdkLogger
.error('Parser', FORMAT_INVALID
,
597 "Section [%s] is not allowed in inf file without version" % (self
._SectionName
),
598 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
599 elif self
._SectionType
in [MODEL_EFI_INCLUDE
,
600 MODEL_EFI_LIBRARY_INSTANCE
,
601 MODEL_META_DATA_NMAKE
]:
602 EdkLogger
.error('Parser', FORMAT_INVALID
,
603 "Section [%s] is not allowed in inf file with version 0x%08x" % (self
._SectionName
, self
._Version
),
604 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
606 # merge two lines specified by '\' in section NMAKE
607 elif self
._SectionType
== MODEL_META_DATA_NMAKE
:
610 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
613 if NextLine
[0] == TAB_SECTION_START
and NextLine
[-1] == TAB_SECTION_END
:
614 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
617 NmakeLine
= NmakeLine
+ ' ' + Line
[0:-1]
620 self
._CurrentLine
= NmakeLine
+ Line
624 self
._ValueList
= ['', '', '']
625 # parse current line, result will be put in self._ValueList
626 self
._SectionParser
[self
._SectionType
](self
)
627 if self
._ValueList
is None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
632 Comments
.append((Comment
, Index
+ 1))
633 if GlobalData
.gOptions
and GlobalData
.gOptions
.CheckUsage
:
634 CheckInfComment(self
._SectionType
, Comments
, str(self
.MetaFile
), Index
+ 1, self
._ValueList
)
636 # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
637 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
639 for Arch
, Platform
,_
in self
._Scope
:
640 LastItem
= self
._Store
(self
._SectionType
,
653 for Comment
, LineNo
in Comments
:
654 self
._Store
(MODEL_META_DATA_COMMENT
, Comment
, '', '', Arch
, Platform
,
655 LastItem
, LineNo
, -1, LineNo
, -1, 0)
658 TailComments
.extend(SectionComments
+ Comments
)
659 if IsFindBlockComment
:
660 EdkLogger
.error("Parser", FORMAT_INVALID
, "Open block comments (starting with /*) are expected to end with */",
663 # If there are tail comments in INF file, save to database whatever the comments are
664 for Comment
in TailComments
:
665 self
._Store
(MODEL_META_DATA_TAIL_COMMENT
, Comment
[0], '', '', TAB_COMMON
,
666 TAB_COMMON
, self
._Owner
[-1], -1, -1, -1, -1, 0)
669 ## Data parser for the format in which there's path
671 # Only path can have macro used. So we need to replace them before use.
673 def _IncludeParser(self
):
674 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
675 self
._ValueList
[0:len(TokenList
)] = TokenList
676 Macros
= self
._Macros
678 for Index
in range(0, len(self
._ValueList
)):
679 Value
= self
._ValueList
[Index
]
683 if Value
.upper().find('$(EFI_SOURCE)\Edk'.upper()) > -1 or Value
.upper().find('$(EFI_SOURCE)/Edk'.upper()) > -1:
684 Value
= '$(EDK_SOURCE)' + Value
[17:]
685 if Value
.find('$(EFI_SOURCE)') > -1 or Value
.find('$(EDK_SOURCE)') > -1:
687 elif Value
.startswith('.'):
689 elif Value
.startswith('$('):
692 Value
= '$(EFI_SOURCE)/' + Value
694 self
._ValueList
[Index
] = ReplaceMacro(Value
, Macros
)
696 ## Parse [Sources] section
698 # Only path can have macro used. So we need to replace them before use.
701 def _SourceFileParser(self
):
702 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
703 self
._ValueList
[0:len(TokenList
)] = TokenList
704 Macros
= self
._Macros
705 # For Acpi tables, remove macro like ' TABLE_NAME=Sata1'
706 if 'COMPONENT_TYPE' in Macros
:
707 if self
._Defines
['COMPONENT_TYPE'].upper() == 'ACPITABLE':
708 self
._ValueList
[0] = GetSplitValueList(self
._ValueList
[0], ' ', 1)[0]
709 if self
._Defines
['BASE_NAME'] == 'Microcode':
711 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
713 ## Parse [Binaries] section
715 # Only path can have macro used. So we need to replace them before use.
718 def _BinaryFileParser(self
):
719 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 2)
720 if len(TokenList
) < 2:
721 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type or path specified",
722 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
723 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
725 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type specified",
726 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
727 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
729 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file path specified",
730 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
731 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
732 self
._ValueList
[0:len(TokenList
)] = TokenList
733 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
735 ## [nmake] section parser (Edk.x style only)
736 def _NmakeParser(self
):
737 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
738 self
._ValueList
[0:len(TokenList
)] = TokenList
740 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
741 # remove self-reference in macro setting
742 #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
744 ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
746 def _PcdParser(self
):
747 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
748 ValueList
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
749 if len(ValueList
) != 2:
750 EdkLogger
.error('Parser', FORMAT_INVALID
, "Illegal token space GUID and PCD name format",
751 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
752 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
753 self
._ValueList
[0:1] = ValueList
754 if len(TokenList
) > 1:
755 self
._ValueList
[2] = TokenList
[1]
756 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
757 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
758 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
759 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
761 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
762 if self
._ValueList
[2] != '':
763 InfPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
764 if InfPcdValueList
[0] in ['True', 'true', 'TRUE']:
765 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '1', 1);
766 elif InfPcdValueList
[0] in ['False', 'false', 'FALSE']:
767 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '0', 1);
768 if (self
._ValueList
[0], self
._ValueList
[1]) not in self
.PcdsDict
:
769 self
.PcdsDict
[self
._ValueList
[0], self
._ValueList
[1]] = self
._SectionType
770 elif self
.PcdsDict
[self
._ValueList
[0], self
._ValueList
[1]] != self
._SectionType
:
771 EdkLogger
.error('Parser', FORMAT_INVALID
, "It is not permissible to list a specified PCD in different PCD type sections.",
772 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
773 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
775 ## [depex] section parser
777 def _DepexParser(self
):
778 self
._ValueList
[0:1] = [self
._CurrentLine
]
781 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
782 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
783 MODEL_META_DATA_BUILD_OPTION
: MetaFileParser
._BuildOptionParser
,
784 MODEL_EFI_INCLUDE
: _IncludeParser
, # for Edk.x modules
785 MODEL_EFI_LIBRARY_INSTANCE
: MetaFileParser
._CommonParser
, # for Edk.x modules
786 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
787 MODEL_META_DATA_PACKAGE
: MetaFileParser
._PathParser
,
788 MODEL_META_DATA_NMAKE
: _NmakeParser
, # for Edk.x modules
789 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
790 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
791 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
792 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
793 MODEL_PCD_DYNAMIC
: _PcdParser
,
794 MODEL_EFI_SOURCE_FILE
: _SourceFileParser
,
795 MODEL_EFI_GUID
: MetaFileParser
._CommonParser
,
796 MODEL_EFI_PROTOCOL
: MetaFileParser
._CommonParser
,
797 MODEL_EFI_PPI
: MetaFileParser
._CommonParser
,
798 MODEL_EFI_DEPEX
: _DepexParser
,
799 MODEL_EFI_BINARY_FILE
: _BinaryFileParser
,
800 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
803 ## DSC file parser class
805 # @param FilePath The path of platform description file
806 # @param FileType The raw data of DSC file
807 # @param Table Database used to retrieve module/package information
808 # @param Macros Macros used for replacement in file
809 # @param Owner Owner ID (for sub-section parsing)
810 # @param From ID from which the data comes (for !INCLUDE directive)
812 class DscParser(MetaFileParser
):
813 # DSC file supported data types (one type per section)
815 TAB_SKUIDS
.upper() : MODEL_EFI_SKU_ID
,
816 TAB_DEFAULT_STORES
.upper() : MODEL_EFI_DEFAULT_STORES
,
817 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
818 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
819 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
820 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
821 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
822 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
823 TAB_PCDS_DYNAMIC_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_DEFAULT
,
824 TAB_PCDS_DYNAMIC_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_HII
,
825 TAB_PCDS_DYNAMIC_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_VPD
,
826 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT
,
827 TAB_PCDS_DYNAMIC_EX_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_HII
,
828 TAB_PCDS_DYNAMIC_EX_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_VPD
,
829 TAB_COMPONENTS
.upper() : MODEL_META_DATA_COMPONENT
,
830 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
.upper() : MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
,
831 TAB_DSC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
832 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
833 TAB_DSC_DEFINES_EDKGLOBAL
: MODEL_META_DATA_GLOBAL_DEFINE
,
834 TAB_INCLUDE
.upper() : MODEL_META_DATA_INCLUDE
,
835 TAB_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
836 TAB_IF_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
837 TAB_IF_N_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
,
838 TAB_ELSE_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
,
839 TAB_ELSE
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
,
840 TAB_END_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
,
841 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
,
844 # Valid names in define section
851 "PCD_INFO_GENERATION",
852 "PCD_VAR_CHECK_GENERATION",
853 "SUPPORTED_ARCHITECTURES",
862 "FIX_LOAD_TOP_MEMORY_ADDRESS",
867 SubSectionDefineKeywords
= [
871 SymbolPattern
= ValueExpression
.SymbolPattern
873 IncludedFiles
= set()
875 ## Constructor of DscParser
877 # Initialize object of DscParser
879 # @param FilePath The path of platform description file
880 # @param FileType The raw data of DSC file
881 # @param Arch Default Arch value for filtering sections
882 # @param Table Database used to retrieve module/package information
883 # @param Owner Owner ID (for sub-section parsing)
884 # @param From ID from which the data comes (for !INCLUDE directive)
886 def __init__(self
, FilePath
, FileType
, Arch
, Table
, Owner
= -1, From
= -1):
887 # prevent re-initialization
888 if hasattr(self
, "_Table"):
890 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
, Owner
, From
)
891 self
._Version
= 0x00010005 # Only EDK2 dsc file is supported
892 # to store conditional directive evaluation result
893 self
._DirectiveStack
= []
894 self
._DirectiveEvalStack
= []
898 # Specify whether current line is in uncertain condition
900 self
._InDirective
= -1
902 # Final valid replacable symbols
905 # Map the ID between the original table and new table to track
908 self
._IdMapping
= {-1:-1}
914 Content
= open(str(self
.MetaFile
), 'r').readlines()
916 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
919 for Index
in range(0, len(Content
)):
920 Line
= CleanString(Content
[Index
])
925 self
._CurrentLine
= Line
926 self
._LineIndex
= Index
927 if self
._InSubsection
and self
._Owner
[-1] == -1:
928 self
._Owner
.append(self
._LastItem
)
931 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
932 self
._SectionType
= MODEL_META_DATA_SECTION_HEADER
934 elif Line
[0] == '}' and self
._InSubsection
:
935 self
._InSubsection
= False
936 self
._SubsectionType
= MODEL_UNKNOWN
937 self
._SubsectionName
= ''
942 elif Line
[0] == TAB_OPTION_START
and Line
[-1] == TAB_OPTION_END
:
943 self
._SubsectionType
= MODEL_META_DATA_SUBSECTION_HEADER
946 self
._DirectiveParser
()
948 if Line
[0] == TAB_OPTION_START
and not self
._InSubsection
:
949 EdkLogger
.error("Parser", FILE_READ_FAILURE
, "Missing the '{' before %s in Line %s" % (Line
, Index
+1),ExtraData
=self
.MetaFile
)
951 if self
._InSubsection
:
952 SectionType
= self
._SubsectionType
954 SectionType
= self
._SectionType
955 self
._ItemType
= SectionType
957 self
._ValueList
= ['', '', '']
958 self
._SectionParser
[SectionType
](self
)
959 if self
._ValueList
is None:
962 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
963 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
965 for Arch
, ModuleType
, DefaultStore
in self
._Scope
:
966 Owner
= self
._Owner
[-1]
967 if self
._SubsectionType
!= MODEL_UNKNOWN
:
968 Owner
= OwnerId
[Arch
]
969 self
._LastItem
= self
._Store
(
985 if self
._SubsectionType
== MODEL_UNKNOWN
and self
._InSubsection
:
986 OwnerId
[Arch
] = self
._LastItem
988 if self
._DirectiveStack
:
989 Type
, Line
, Text
= self
._DirectiveStack
[-1]
990 EdkLogger
.error('Parser', FORMAT_INVALID
, "No matching '!endif' found",
991 ExtraData
=Text
, File
=self
.MetaFile
, Line
=Line
)
994 ## <subsection_header> parser
995 def _SubsectionHeaderParser(self
):
996 self
._SubsectionName
= self
._CurrentLine
[1:-1].upper()
997 if self
._SubsectionName
in self
.DataType
:
998 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
1000 self
._SubsectionType
= MODEL_UNKNOWN
1001 EdkLogger
.warn("Parser", "Unrecognized sub-section", File
=self
.MetaFile
,
1002 Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1003 self
._ValueList
[0] = self
._SubsectionName
1005 ## Directive statement parser
1006 def _DirectiveParser(self
):
1007 self
._ValueList
= ['', '', '']
1008 TokenList
= GetSplitValueList(self
._CurrentLine
, ' ', 1)
1009 self
._ValueList
[0:len(TokenList
)] = TokenList
1012 DirectiveName
= self
._ValueList
[0].upper()
1013 if DirectiveName
not in self
.DataType
:
1014 EdkLogger
.error("Parser", FORMAT_INVALID
, "Unknown directive [%s]" % DirectiveName
,
1015 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1017 if DirectiveName
in ['!IF', '!IFDEF', '!IFNDEF']:
1018 self
._InDirective
+= 1
1020 if DirectiveName
in ['!ENDIF']:
1021 self
._InDirective
-= 1
1023 if DirectiveName
in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self
._ValueList
[1] == '':
1024 EdkLogger
.error("Parser", FORMAT_INVALID
, "Missing expression",
1025 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1026 ExtraData
=self
._CurrentLine
)
1028 ItemType
= self
.DataType
[DirectiveName
]
1029 Scope
= [[TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]]
1030 if ItemType
== MODEL_META_DATA_INCLUDE
:
1032 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1033 # Remove all directives between !if and !endif, including themselves
1034 while self
._DirectiveStack
:
1035 # Remove any !else or !elseif
1036 DirectiveInfo
= self
._DirectiveStack
.pop()
1037 if DirectiveInfo
[0] in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1038 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1039 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1042 EdkLogger
.error("Parser", FORMAT_INVALID
, "Redundant '!endif'",
1043 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1044 ExtraData
=self
._CurrentLine
)
1045 elif ItemType
!= MODEL_META_DATA_INCLUDE
:
1046 # Break if there's a !else is followed by a !elseif
1047 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
and \
1048 self
._DirectiveStack
and \
1049 self
._DirectiveStack
[-1][0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1050 EdkLogger
.error("Parser", FORMAT_INVALID
, "'!elseif' after '!else'",
1051 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1052 ExtraData
=self
._CurrentLine
)
1053 self
._DirectiveStack
.append((ItemType
, self
._LineIndex
+ 1, self
._CurrentLine
))
1056 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
1057 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
1059 for Arch
, ModuleType
, DefaultStore
in Scope
:
1060 self
._LastItem
= self
._Store
(
1070 self
._LineIndex
+ 1,
1072 self
._LineIndex
+ 1,
1077 ## [defines] section parser
1079 def _DefineParser(self
):
1080 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1081 self
._ValueList
[1:len(TokenList
)] = TokenList
1084 if not self
._ValueList
[1]:
1085 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
1086 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1087 if not self
._ValueList
[2]:
1088 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
1089 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1090 if (not self
._ValueList
[1] in self
.DefineKeywords
and
1091 (self
._InSubsection
and self
._ValueList
[1] not in self
.SubSectionDefineKeywords
)):
1092 EdkLogger
.error('Parser', FORMAT_INVALID
,
1093 "Unknown keyword found: %s. "
1094 "If this is a macro you must "
1095 "add it as a DEFINE in the DSC" % self
._ValueList
[1],
1096 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1097 if not self
._InSubsection
:
1098 self
._Defines
[self
._ValueList
[1]] = self
._ValueList
[2]
1099 self
._ItemType
= self
.DataType
[TAB_DSC_DEFINES
.upper()]
1102 def _SkuIdParser(self
):
1103 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1104 if len(TokenList
) not in (2,3):
1105 EdkLogger
.error('Parser', FORMAT_INVALID
, "Correct format is '<Number>|<UiName>[|<UiName>]'",
1106 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1107 self
._ValueList
[0:len(TokenList
)] = TokenList
1109 def _DefaultStoresParser(self
):
1110 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1111 if len(TokenList
) != 2:
1112 EdkLogger
.error('Parser', FORMAT_INVALID
, "Correct format is '<Number>|<UiName>'",
1113 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1114 self
._ValueList
[0:len(TokenList
)] = TokenList
1116 ## Parse Edk style of library modules
1118 def _LibraryInstanceParser(self
):
1119 self
._ValueList
[0] = self
._CurrentLine
1121 ## PCD sections parser
1123 # [PcdsFixedAtBuild]
1124 # [PcdsPatchableInModule]
1127 # [PcdsDynamicExDefault]
1128 # [PcdsDynamicExVpd]
1129 # [PcdsDynamicExHii]
1131 # [PcdsDynamicDefault]
1136 def _PcdParser(self
):
1137 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1138 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1139 PcdNameTockens
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1140 if len(PcdNameTockens
) == 2:
1141 self
._ValueList
[0], self
._ValueList
[1] = PcdNameTockens
[0], PcdNameTockens
[1]
1142 elif len(PcdNameTockens
) == 3:
1143 self
._ValueList
[0], self
._ValueList
[1] = ".".join((PcdNameTockens
[0], PcdNameTockens
[1])), PcdNameTockens
[2]
1144 elif len(PcdNameTockens
) > 3:
1145 self
._ValueList
[0], self
._ValueList
[1] = ".".join((PcdNameTockens
[0], PcdNameTockens
[1])), ".".join(PcdNameTockens
[2:])
1146 if len(TokenList
) == 2:
1147 self
._ValueList
[2] = TokenList
[1]
1148 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1149 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1150 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1151 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1152 if self
._ValueList
[2] == '':
1154 # The PCD values are optional for FIXEDATBUILD, PATCHABLEINMODULE, Dynamic/DynamicEx default
1156 if self
._SectionType
in (MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
):
1158 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD value given",
1159 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1160 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1162 # Validate the datum type of Dynamic Defaul PCD and DynamicEx Default PCD
1163 ValueList
= GetSplitValueList(self
._ValueList
[2])
1164 if len(ValueList
) > 1 and ValueList
[1] in [TAB_UINT8
, TAB_UINT16
, TAB_UINT32
, TAB_UINT64
] \
1165 and self
._ItemType
in [MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
]:
1166 EdkLogger
.error('Parser', FORMAT_INVALID
, "The datum type '%s' of PCD is wrong" % ValueList
[1],
1167 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1169 # Validate the VariableName of DynamicHii and DynamicExHii for PCD Entry must not be an empty string
1170 if self
._ItemType
in [MODEL_PCD_DYNAMIC_HII
, MODEL_PCD_DYNAMIC_EX_HII
]:
1171 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
1172 if len(DscPcdValueList
[0].replace('L','').replace('"','').strip()) == 0:
1173 EdkLogger
.error('Parser', FORMAT_INVALID
, "The VariableName field in the HII format PCD entry must not be an empty string",
1174 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1176 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
1177 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
1178 if DscPcdValueList
[0] in ['True', 'true', 'TRUE']:
1179 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '1', 1);
1180 elif DscPcdValueList
[0] in ['False', 'false', 'FALSE']:
1181 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '0', 1);
1184 ## [components] section parser
1186 def _ComponentParser(self
):
1187 if self
._CurrentLine
[-1] == '{':
1188 self
._ValueList
[0] = self
._CurrentLine
[0:-1].strip()
1189 self
._InSubsection
= True
1191 self
._ValueList
[0] = self
._CurrentLine
1193 ## [LibraryClasses] section
1195 def _LibraryClassParser(self
):
1196 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1197 if len(TokenList
) < 2:
1198 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class or instance specified",
1199 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1200 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1201 if TokenList
[0] == '':
1202 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class specified",
1203 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1204 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1205 if TokenList
[1] == '':
1206 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library instance specified",
1207 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1208 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1210 self
._ValueList
[0:len(TokenList
)] = TokenList
1212 def _CompponentSourceOverridePathParser(self
):
1213 self
._ValueList
[0] = self
._CurrentLine
1215 ## [BuildOptions] section parser
1217 def _BuildOptionParser(self
):
1218 self
._CurrentLine
= CleanString(self
._CurrentLine
, BuildOption
=True)
1219 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1220 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
1221 if len(TokenList2
) == 2:
1222 self
._ValueList
[0] = TokenList2
[0] # toolchain family
1223 self
._ValueList
[1] = TokenList2
[1] # keys
1225 self
._ValueList
[1] = TokenList
[0]
1226 if len(TokenList
) == 2: # value
1227 self
._ValueList
[2] = TokenList
[1]
1229 if self
._ValueList
[1].count('_') != 4:
1233 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
1234 ExtraData
=self
._CurrentLine
,
1236 Line
=self
._LineIndex
+ 1
1239 ## Override parent's method since we'll do all macro replacements in parser
1240 def _GetMacros(self
):
1242 Macros
.update(self
._FileLocalMacros
)
1243 Macros
.update(self
._GetApplicableSectionMacro
())
1244 Macros
.update(GlobalData
.gEdkGlobal
)
1245 Macros
.update(GlobalData
.gPlatformDefines
)
1246 Macros
.update(GlobalData
.gCommandLineDefines
)
1247 # PCD cannot be referenced in macro definition
1248 if self
._ItemType
not in [MODEL_META_DATA_DEFINE
, MODEL_META_DATA_GLOBAL_DEFINE
]:
1249 Macros
.update(self
._Symbols
)
1250 if GlobalData
.BuildOptionPcd
:
1251 for Item
in GlobalData
.BuildOptionPcd
:
1252 if type(Item
) is tuple:
1254 PcdName
, TmpValue
= Item
.split("=")
1255 TmpValue
= BuildOptionValue(TmpValue
, self
._GuidDict
)
1256 Macros
[PcdName
.strip()] = TmpValue
1259 def _PostProcess(self
):
1261 MODEL_META_DATA_SECTION_HEADER
: self
.__ProcessSectionHeader
,
1262 MODEL_META_DATA_SUBSECTION_HEADER
: self
.__ProcessSubsectionHeader
,
1263 MODEL_META_DATA_HEADER
: self
.__ProcessDefine
,
1264 MODEL_META_DATA_DEFINE
: self
.__ProcessDefine
,
1265 MODEL_META_DATA_GLOBAL_DEFINE
: self
.__ProcessDefine
,
1266 MODEL_META_DATA_INCLUDE
: self
.__ProcessDirective
,
1267 MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
: self
.__ProcessDirective
,
1268 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
: self
.__ProcessDirective
,
1269 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
: self
.__ProcessDirective
,
1270 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
: self
.__ProcessDirective
,
1271 MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
: self
.__ProcessDirective
,
1272 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
: self
.__ProcessDirective
,
1273 MODEL_EFI_SKU_ID
: self
.__ProcessSkuId
,
1274 MODEL_EFI_DEFAULT_STORES
: self
.__ProcessDefaultStores
,
1275 MODEL_EFI_LIBRARY_INSTANCE
: self
.__ProcessLibraryInstance
,
1276 MODEL_EFI_LIBRARY_CLASS
: self
.__ProcessLibraryClass
,
1277 MODEL_PCD_FIXED_AT_BUILD
: self
.__ProcessPcd
,
1278 MODEL_PCD_PATCHABLE_IN_MODULE
: self
.__ProcessPcd
,
1279 MODEL_PCD_FEATURE_FLAG
: self
.__ProcessPcd
,
1280 MODEL_PCD_DYNAMIC_DEFAULT
: self
.__ProcessPcd
,
1281 MODEL_PCD_DYNAMIC_HII
: self
.__ProcessPcd
,
1282 MODEL_PCD_DYNAMIC_VPD
: self
.__ProcessPcd
,
1283 MODEL_PCD_DYNAMIC_EX_DEFAULT
: self
.__ProcessPcd
,
1284 MODEL_PCD_DYNAMIC_EX_HII
: self
.__ProcessPcd
,
1285 MODEL_PCD_DYNAMIC_EX_VPD
: self
.__ProcessPcd
,
1286 MODEL_META_DATA_COMPONENT
: self
.__ProcessComponent
,
1287 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: self
.__ProcessSourceOverridePath
,
1288 MODEL_META_DATA_BUILD_OPTION
: self
.__ProcessBuildOption
,
1289 MODEL_UNKNOWN
: self
._Skip
,
1290 MODEL_META_DATA_USER_EXTENSION
: self
._SkipUserExtension
,
1293 self
._Table
= MetaFileStorage(self
._RawTable
.Cur
, self
.MetaFile
, MODEL_FILE_DSC
, True)
1294 self
._Table
.Create()
1295 self
._DirectiveStack
= []
1296 self
._DirectiveEvalStack
= []
1297 self
._FileWithError
= self
.MetaFile
1298 self
._FileLocalMacros
= {}
1299 self
._SectionsMacroDict
= {}
1300 GlobalData
.gPlatformDefines
= {}
1302 # Get all macro and PCD which has straitforward value
1303 self
.__RetrievePcdValue
()
1304 self
._Content
= self
._RawTable
.GetAll()
1305 self
._ContentIndex
= 0
1306 self
._InSubsection
= False
1307 while self
._ContentIndex
< len(self
._Content
) :
1308 Id
, self
._ItemType
, V1
, V2
, V3
, S1
, S2
, S3
,Owner
, self
._From
, \
1309 LineStart
, ColStart
, LineEnd
, ColEnd
, Enabled
= self
._Content
[self
._ContentIndex
]
1312 self
._FileWithError
= self
.MetaFile
1314 self
._ContentIndex
+= 1
1316 self
._Scope
= [[S1
, S2
, S3
]]
1318 # For !include directive, handle it specially,
1319 # merge arch and module type in case of duplicate items
1321 while self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1322 if self
._ContentIndex
>= len(self
._Content
):
1324 Record
= self
._Content
[self
._ContentIndex
]
1325 if LineStart
== Record
[10] and LineEnd
== Record
[12]:
1326 if [Record
[5], Record
[6],Record
[7]] not in self
._Scope
:
1327 self
._Scope
.append([Record
[5], Record
[6],Record
[7]])
1328 self
._ContentIndex
+= 1
1332 self
._LineIndex
= LineStart
- 1
1333 self
._ValueList
= [V1
, V2
, V3
]
1335 if Owner
> 0 and Owner
in self
._IdMapping
:
1336 self
._InSubsection
= True
1338 self
._InSubsection
= False
1340 Processer
[self
._ItemType
]()
1341 except EvaluationException
, Excpt
:
1343 # Only catch expression evaluation error here. We need to report
1344 # the precise number of line on which the error occurred
1346 if hasattr(Excpt
, 'Pcd'):
1347 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
1348 Info
= GlobalData
.gPlatformOtherPcds
[Excpt
.Pcd
]
1349 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
1350 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
1351 " of the DSC file, and it is currently defined in this section:"
1352 " %s, line #: %d." % (Excpt
.Pcd
, Info
[0], Info
[1]),
1353 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1354 Line
=self
._LineIndex
+ 1)
1356 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
1357 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1358 Line
=self
._LineIndex
+ 1)
1360 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
1361 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1362 Line
=self
._LineIndex
+ 1)
1363 except MacroException
, Excpt
:
1364 EdkLogger
.error('Parser', FORMAT_INVALID
, str(Excpt
),
1365 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1366 Line
=self
._LineIndex
+ 1)
1368 if self
._ValueList
is None:
1371 NewOwner
= self
._IdMapping
.get(Owner
, -1)
1372 self
._Enabled
= int((not self
._DirectiveEvalStack
) or (False not in self
._DirectiveEvalStack
))
1373 self
._LastItem
= self
._Store
(
1383 self
._LineIndex
+ 1,
1385 self
._LineIndex
+ 1,
1389 self
._IdMapping
[Id
] = self
._LastItem
1391 GlobalData
.gPlatformDefines
.update(self
._FileLocalMacros
)
1392 self
._PostProcessed
= True
1393 self
._Content
= None
1395 def __ProcessSectionHeader(self
):
1396 self
._SectionName
= self
._ValueList
[0]
1397 if self
._SectionName
in self
.DataType
:
1398 self
._SectionType
= self
.DataType
[self
._SectionName
]
1400 self
._SectionType
= MODEL_UNKNOWN
1402 def __ProcessSubsectionHeader(self
):
1403 self
._SubsectionName
= self
._ValueList
[0]
1404 if self
._SubsectionName
in self
.DataType
:
1405 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
1407 self
._SubsectionType
= MODEL_UNKNOWN
1409 def __RetrievePcdValue(self
):
1410 Content
= open(str(self
.MetaFile
), 'r').readlines()
1411 GlobalData
.gPlatformOtherPcds
['DSCFILE'] = str(self
.MetaFile
)
1412 for PcdType
in (MODEL_PCD_PATCHABLE_IN_MODULE
, MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_HII
,
1413 MODEL_PCD_DYNAMIC_VPD
, MODEL_PCD_DYNAMIC_EX_DEFAULT
, MODEL_PCD_DYNAMIC_EX_HII
,
1414 MODEL_PCD_DYNAMIC_EX_VPD
):
1415 Records
= self
._RawTable
.Query(PcdType
, BelongsToItem
= -1.0)
1416 for TokenSpaceGuid
, PcdName
, Value
, Dummy2
, Dummy3
, Dummy4
,ID
, Line
in Records
:
1417 Name
= TokenSpaceGuid
+ '.' + PcdName
1418 if Name
not in GlobalData
.gPlatformOtherPcds
:
1420 while not Content
[Line
- 1].lstrip().startswith(TAB_SECTION_START
):
1422 GlobalData
.gPlatformOtherPcds
[Name
] = (CleanString(Content
[Line
- 1]), PcdLine
, PcdType
)
1424 def __ProcessDefine(self
):
1425 if not self
._Enabled
:
1428 Type
, Name
, Value
= self
._ValueList
1429 Value
= ReplaceMacro(Value
, self
._Macros
, False)
1431 # If it is <Defines>, return
1433 if self
._InSubsection
:
1434 self
._ValueList
= [Type
, Name
, Value
]
1437 if self
._ItemType
== MODEL_META_DATA_DEFINE
:
1438 if self
._SectionType
== MODEL_META_DATA_HEADER
:
1439 self
._FileLocalMacros
[Name
] = Value
1441 self
._ConstructSectionMacroDict
(Name
, Value
)
1442 elif self
._ItemType
== MODEL_META_DATA_GLOBAL_DEFINE
:
1443 GlobalData
.gEdkGlobal
[Name
] = Value
1446 # Keyword in [Defines] section can be used as Macros
1448 if (self
._ItemType
== MODEL_META_DATA_HEADER
) and (self
._SectionType
== MODEL_META_DATA_HEADER
):
1449 self
._FileLocalMacros
[Name
] = Value
1451 self
._ValueList
= [Type
, Name
, Value
]
1453 def __ProcessDirective(self
):
1455 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1456 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
]:
1457 Macros
= self
._Macros
1458 Macros
.update(GlobalData
.gGlobalDefines
)
1460 Result
= ValueExpression(self
._ValueList
[1], Macros
)()
1461 except SymbolNotFound
, Exc
:
1462 EdkLogger
.debug(EdkLogger
.DEBUG_5
, str(Exc
), self
._ValueList
[1])
1464 except WrnExpression
, Excpt
:
1466 # Catch expression evaluation warning here. We need to report
1467 # the precise number of line and return the evaluation result
1469 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
1470 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1471 Line
=self
._LineIndex
+ 1)
1472 Result
= Excpt
.result
1474 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1475 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1476 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1477 self
._DirectiveStack
.append(self
._ItemType
)
1478 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
:
1479 Result
= bool(Result
)
1481 Macro
= self
._ValueList
[1]
1482 Macro
= Macro
[2:-1] if (Macro
.startswith("$(") and Macro
.endswith(")")) else Macro
1483 Result
= Macro
in self
._Macros
1484 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
:
1486 self
._DirectiveEvalStack
.append(Result
)
1487 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
:
1488 self
._DirectiveStack
.append(self
._ItemType
)
1489 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1490 self
._DirectiveEvalStack
.append(bool(Result
))
1491 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1492 self
._DirectiveStack
.append(self
._ItemType
)
1493 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1494 self
._DirectiveEvalStack
.append(True)
1495 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1496 # Back to the nearest !if/!ifdef/!ifndef
1497 while self
._DirectiveStack
:
1498 self
._DirectiveEvalStack
.pop()
1499 Directive
= self
._DirectiveStack
.pop()
1500 if Directive
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1501 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1502 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1504 elif self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1505 # The included file must be relative to workspace or same directory as DSC file
1506 __IncludeMacros
= {}
1508 # Allow using system environment variables in path after !include
1510 __IncludeMacros
['WORKSPACE'] = GlobalData
.gGlobalDefines
['WORKSPACE']
1511 if "ECP_SOURCE" in GlobalData
.gGlobalDefines
:
1512 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gGlobalDefines
['ECP_SOURCE']
1514 # During GenFds phase call DSC parser, will go into this branch.
1516 elif "ECP_SOURCE" in GlobalData
.gCommandLineDefines
:
1517 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gCommandLineDefines
['ECP_SOURCE']
1519 __IncludeMacros
['EFI_SOURCE'] = GlobalData
.gGlobalDefines
['EFI_SOURCE']
1520 __IncludeMacros
['EDK_SOURCE'] = GlobalData
.gGlobalDefines
['EDK_SOURCE']
1522 # Allow using MACROs comes from [Defines] section to keep compatible.
1524 __IncludeMacros
.update(self
._Macros
)
1526 IncludedFile
= NormPath(ReplaceMacro(self
._ValueList
[1], __IncludeMacros
, RaiseError
=True))
1528 # First search the include file under the same directory as DSC file
1530 IncludedFile1
= PathClass(IncludedFile
, self
.MetaFile
.Dir
)
1531 ErrorCode
, ErrorInfo1
= IncludedFile1
.Validate()
1534 # Also search file under the WORKSPACE directory
1536 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
1537 ErrorCode
, ErrorInfo2
= IncludedFile1
.Validate()
1539 EdkLogger
.error('parser', ErrorCode
, File
=self
._FileWithError
,
1540 Line
=self
._LineIndex
+ 1, ExtraData
=ErrorInfo1
+ "\n" + ErrorInfo2
)
1542 self
._FileWithError
= IncludedFile1
1544 IncludedFileTable
= MetaFileStorage(self
._Table
.Cur
, IncludedFile1
, MODEL_FILE_DSC
, False)
1545 FromItem
= self
._Content
[self
._ContentIndex
- 1][0]
1546 if self
._InSubsection
:
1547 Owner
= self
._Content
[self
._ContentIndex
- 1][8]
1549 Owner
= self
._Content
[self
._ContentIndex
- 1][0]
1550 Parser
= DscParser(IncludedFile1
, self
._FileType
, self
._Arch
, IncludedFileTable
,
1551 Owner
=Owner
, From
=FromItem
)
1553 self
.IncludedFiles
.add (IncludedFile1
)
1555 # Does not allow lower level included file to include upper level included file
1556 if Parser
._From
!= Owner
and int(Owner
) > int (Parser
._From
):
1557 EdkLogger
.error('parser', FILE_ALREADY_EXIST
, File
=self
._FileWithError
,
1558 Line
=self
._LineIndex
+ 1, ExtraData
="{0} is already included at a higher level.".format(IncludedFile1
))
1561 # set the parser status with current status
1562 Parser
._SectionName
= self
._SectionName
1563 if self
._InSubsection
:
1564 Parser
._SectionType
= self
._SubsectionType
1566 Parser
._SectionType
= self
._SectionType
1567 Parser
._Scope
= self
._Scope
1568 Parser
._Enabled
= self
._Enabled
1569 # Parse the included file
1572 # update current status with sub-parser's status
1573 self
._SectionName
= Parser
._SectionName
1574 self
._SectionType
= Parser
._SectionType
1575 self
._Scope
= Parser
._Scope
1576 self
._Enabled
= Parser
._Enabled
1578 # Insert all records in the table for the included file into dsc file table
1579 Records
= IncludedFileTable
.GetAll()
1581 self
._Content
[self
._ContentIndex
:self
._ContentIndex
] = Records
1582 self
._Content
.pop(self
._ContentIndex
- 1)
1583 self
._ValueList
= None
1584 self
._ContentIndex
-= 1
1586 def __ProcessSkuId(self
):
1587 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=True)
1588 for Value
in self
._ValueList
]
1589 def __ProcessDefaultStores(self
):
1590 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=True)
1591 for Value
in self
._ValueList
]
1593 def __ProcessLibraryInstance(self
):
1594 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
1596 def __ProcessLibraryClass(self
):
1597 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
, RaiseError
=True)
1599 def __ProcessPcd(self
):
1600 if self
._ItemType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
1601 self
._ValueList
[2] = ReplaceMacro(self
._ValueList
[2], self
._Macros
, RaiseError
=True)
1604 ValList
, Valid
, Index
= AnalyzeDscPcd(self
._ValueList
[2], self
._ItemType
)
1606 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
._FileWithError
, Line
=self
._LineIndex
+ 1,
1607 ExtraData
="%s.%s|%s" % (self
._ValueList
[0], self
._ValueList
[1], self
._ValueList
[2]))
1608 PcdValue
= ValList
[Index
]
1609 if PcdValue
and "." not in self
._ValueList
[0]:
1611 ValList
[Index
] = ValueExpression(PcdValue
, self
._Macros
)(True)
1612 except WrnExpression
, Value
:
1613 ValList
[Index
] = Value
.result
1617 if ValList
[Index
] == 'True':
1618 ValList
[Index
] = '1'
1619 if ValList
[Index
] == 'False':
1620 ValList
[Index
] = '0'
1622 if (not self
._DirectiveEvalStack
) or (False not in self
._DirectiveEvalStack
):
1623 GlobalData
.gPlatformPcds
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = PcdValue
1624 self
._Symbols
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = PcdValue
1626 self
._ValueList
[2] = '|'.join(ValList
)
1630 def __ProcessComponent(self
):
1631 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1633 def __ProcessSourceOverridePath(self
):
1634 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1636 def __ProcessBuildOption(self
):
1637 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=False)
1638 for Value
in self
._ValueList
]
1641 MODEL_META_DATA_HEADER
: _DefineParser
,
1642 MODEL_EFI_SKU_ID
: _SkuIdParser
,
1643 MODEL_EFI_DEFAULT_STORES
: _DefaultStoresParser
,
1644 MODEL_EFI_LIBRARY_INSTANCE
: _LibraryInstanceParser
,
1645 MODEL_EFI_LIBRARY_CLASS
: _LibraryClassParser
,
1646 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1647 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1648 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1649 MODEL_PCD_DYNAMIC_DEFAULT
: _PcdParser
,
1650 MODEL_PCD_DYNAMIC_HII
: _PcdParser
,
1651 MODEL_PCD_DYNAMIC_VPD
: _PcdParser
,
1652 MODEL_PCD_DYNAMIC_EX_DEFAULT
: _PcdParser
,
1653 MODEL_PCD_DYNAMIC_EX_HII
: _PcdParser
,
1654 MODEL_PCD_DYNAMIC_EX_VPD
: _PcdParser
,
1655 MODEL_META_DATA_COMPONENT
: _ComponentParser
,
1656 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: _CompponentSourceOverridePathParser
,
1657 MODEL_META_DATA_BUILD_OPTION
: _BuildOptionParser
,
1658 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1659 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
1660 MODEL_META_DATA_SECTION_HEADER
: MetaFileParser
._SectionHeaderParser
,
1661 MODEL_META_DATA_SUBSECTION_HEADER
: _SubsectionHeaderParser
,
1664 _Macros
= property(_GetMacros
)
1666 ## DEC file parser class
1668 # @param FilePath The path of platform description file
1669 # @param FileType The raw data of DSC file
1670 # @param Table Database used to retrieve module/package information
1671 # @param Macros Macros used for replacement in file
1673 class DecParser(MetaFileParser
):
1674 # DEC file supported data types (one type per section)
1676 TAB_DEC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
1677 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
1678 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
1679 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
1680 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
1681 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
1682 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
1683 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
1684 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
1685 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
1686 TAB_PCDS_DYNAMIC_NULL
.upper() : MODEL_PCD_DYNAMIC
,
1687 TAB_PCDS_DYNAMIC_EX_NULL
.upper() : MODEL_PCD_DYNAMIC_EX
,
1688 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
,
1691 ## Constructor of DecParser
1693 # Initialize object of DecParser
1695 # @param FilePath The path of platform description file
1696 # @param FileType The raw data of DSC file
1697 # @param Arch Default Arch value for filtering sections
1698 # @param Table Database used to retrieve module/package information
1700 def __init__(self
, FilePath
, FileType
, Arch
, Table
):
1701 # prevent re-initialization
1702 if hasattr(self
, "_Table"):
1704 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
, -1)
1706 self
._Version
= 0x00010005 # Only EDK2 dec file is supported
1707 self
._AllPCDs
= [] # Only for check duplicate PCD
1708 self
._AllPcdDict
= {}
1710 self
._CurrentStructurePcdName
= ""
1711 self
._include
_flag
= False
1712 self
._package
_flag
= False
1718 Content
= open(str(self
.MetaFile
), 'r').readlines()
1720 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
1722 self
._DefinesCount
= 0
1723 for Index
in range(0, len(Content
)):
1724 Line
, Comment
= CleanString2(Content
[Index
])
1725 self
._CurrentLine
= Line
1726 self
._LineIndex
= Index
1728 # save comment for later use
1730 self
._Comments
.append((Comment
, self
._LineIndex
+ 1))
1736 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
1737 self
._SectionHeaderParser
()
1738 if self
._SectionName
== TAB_DEC_DEFINES
.upper():
1739 self
._DefinesCount
+= 1
1742 if self
._SectionType
== MODEL_UNKNOWN
:
1743 EdkLogger
.error("Parser", FORMAT_INVALID
,
1745 "Not able to determine \"%s\" in which section."%self
._CurrentLine
,
1746 self
.MetaFile
, self
._LineIndex
+ 1)
1747 elif len(self
._SectionType
) == 0:
1752 self
._ValueList
= ['', '', '']
1753 self
._SectionParser
[self
._SectionType
[0]](self
)
1754 if self
._ValueList
is None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
1760 # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,
1761 # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1
1763 for Arch
, ModuleType
, Type
in self
._Scope
:
1764 self
._LastItem
= self
._Store
(
1772 self
._LineIndex
+ 1,
1774 self
._LineIndex
+ 1,
1778 for Comment
, LineNo
in self
._Comments
:
1780 MODEL_META_DATA_COMMENT
,
1794 if self
._DefinesCount
> 1:
1795 EdkLogger
.error('Parser', FORMAT_INVALID
, 'Multiple [Defines] section is exist.', self
.MetaFile
)
1796 if self
._DefinesCount
== 0:
1797 EdkLogger
.error('Parser', FORMAT_INVALID
, 'No [Defines] section exist.',self
.MetaFile
)
1801 ## Section header parser
1803 # The section header is always in following format:
1805 # [section_name.arch<.platform|module_type>]
1807 def _SectionHeaderParser(self
):
1809 self
._SectionName
= ''
1810 self
._SectionType
= []
1813 Line
= re
.sub(',[\s]*', TAB_COMMA_SPLIT
, self
._CurrentLine
)
1814 for Item
in Line
[1:-1].split(TAB_COMMA_SPLIT
):
1816 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
,
1817 "section name can NOT be empty or incorrectly use separator comma",
1818 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1819 ItemList
= Item
.split(TAB_SPLIT
)
1821 # different types of PCD are permissible in one section
1822 self
._SectionName
= ItemList
[0].upper()
1823 if self
._SectionName
== TAB_DEC_DEFINES
.upper() and (len(ItemList
) > 1 or len(Line
.split(TAB_COMMA_SPLIT
)) > 1):
1824 EdkLogger
.error("Parser", FORMAT_INVALID
, "Defines section format is invalid",
1825 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1826 if self
._SectionName
in self
.DataType
:
1827 if self
.DataType
[self
._SectionName
] not in self
._SectionType
:
1828 self
._SectionType
.append(self
.DataType
[self
._SectionName
])
1830 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
1831 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1833 if MODEL_PCD_FEATURE_FLAG
in self
._SectionType
and len(self
._SectionType
) > 1:
1837 "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL
,
1839 Line
=self
._LineIndex
+ 1,
1840 ExtraData
=self
._CurrentLine
1843 if len(ItemList
) > 1:
1844 S1
= ItemList
[1].upper()
1846 S1
= TAB_ARCH_COMMON
1848 # S2 may be Platform or ModuleType
1849 if len(ItemList
) > 2:
1850 S2
= ItemList
[2].upper()
1851 # only Includes, GUIDs, PPIs, Protocols section have Private tag
1852 if self
._SectionName
in [TAB_INCLUDES
.upper(), TAB_GUIDS
.upper(), TAB_PROTOCOLS
.upper(), TAB_PPIS
.upper()]:
1854 EdkLogger
.error("Parser", FORMAT_INVALID
, 'Please use keyword "Private" as section tag modifier.',
1855 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1859 if [S1
, S2
, self
.DataType
[self
._SectionName
]] not in self
._Scope
:
1860 self
._Scope
.append([S1
, S2
, self
.DataType
[self
._SectionName
]])
1862 # 'COMMON' must not be used with specific ARCHs at the same section
1863 if TAB_ARCH_COMMON
in ArchList
and len(ArchList
) > 1:
1864 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
1865 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1867 # It is not permissible to mix section tags without the Private attribute with section tags with the Private attribute
1868 if TAB_COMMON
in PrivateList
and len(PrivateList
) > 1:
1869 EdkLogger
.error('Parser', FORMAT_INVALID
, "Can't mix section tags without the Private attribute with section tags with the Private attribute",
1870 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1872 ## [guids], [ppis] and [protocols] section parser
1874 def _GuidParser(self
):
1875 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1876 if len(TokenList
) < 2:
1877 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name or value specified",
1878 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1879 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1880 if TokenList
[0] == '':
1881 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name specified",
1882 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1883 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1884 if TokenList
[1] == '':
1885 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID value specified",
1886 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1887 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1888 if TokenList
[1][0] != '{' or TokenList
[1][-1] != '}' or GuidStructureStringToGuidString(TokenList
[1]) == '':
1889 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid GUID value format",
1890 ExtraData
=self
._CurrentLine
+ \
1891 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
1892 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1893 self
._ValueList
[0] = TokenList
[0]
1894 self
._ValueList
[1] = TokenList
[1]
1895 if self
._ValueList
[0] not in self
._GuidDict
:
1896 self
._GuidDict
[self
._ValueList
[0]] = self
._ValueList
[1]
1898 ## PCD sections parser
1900 # [PcdsFixedAtBuild]
1901 # [PcdsPatchableInModule]
1907 def _PcdParser(self
):
1908 if self
._CurrentStructurePcdName
:
1909 self
._ValueList
[0] = self
._CurrentStructurePcdName
1911 if "|" not in self
._CurrentLine
:
1912 if "<HeaderFiles>" == self
._CurrentLine
:
1913 self
._include
_flag
= True
1914 self
._package
_flag
= False
1915 self
._ValueList
= None
1917 if "<Packages>" == self
._CurrentLine
:
1918 self
._package
_flag
= True
1919 self
._ValueList
= None
1920 self
._include
_flag
= False
1923 if self
._include
_flag
:
1924 self
._ValueList
[1] = "<HeaderFiles>_" + md5
.new(self
._CurrentLine
).hexdigest()
1925 self
._ValueList
[2] = self
._CurrentLine
1926 if self
._package
_flag
and "}" != self
._CurrentLine
:
1927 self
._ValueList
[1] = "<Packages>_" + md5
.new(self
._CurrentLine
).hexdigest()
1928 self
._ValueList
[2] = self
._CurrentLine
1929 if self
._CurrentLine
== "}":
1930 self
._package
_flag
= False
1931 self
._include
_flag
= False
1932 self
._ValueList
= None
1935 PcdTockens
= self
._CurrentLine
.split(TAB_VALUE_SPLIT
)
1936 PcdNames
= PcdTockens
[0].split(TAB_SPLIT
)
1937 if len(PcdNames
) == 2:
1938 self
._CurrentStructurePcdName
= ""
1940 if self
._CurrentStructurePcdName
!= TAB_SPLIT
.join(PcdNames
[:2]):
1941 EdkLogger
.error('Parser', FORMAT_INVALID
, "Pcd Name does not match: %s and %s " % (self
._CurrentStructurePcdName
, TAB_SPLIT
.join(PcdNames
[:2])),
1942 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1943 self
._ValueList
[1] = TAB_SPLIT
.join(PcdNames
[2:])
1944 self
._ValueList
[2] = PcdTockens
[1]
1945 if not self
._CurrentStructurePcdName
:
1946 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1947 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1948 ValueRe
= re
.compile(r
'^[a-zA-Z_][a-zA-Z0-9_]*')
1949 # check PCD information
1950 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1951 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1952 ExtraData
=self
._CurrentLine
+ \
1953 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1954 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1955 # check format of token space GUID CName
1956 if not ValueRe
.match(self
._ValueList
[0]):
1957 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_]*'",
1958 ExtraData
=self
._CurrentLine
+ \
1959 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1960 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1961 # check format of PCD CName
1962 if not ValueRe
.match(self
._ValueList
[1]):
1963 EdkLogger
.error('Parser', FORMAT_INVALID
, "The format of the PCD CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",
1964 ExtraData
=self
._CurrentLine
+ \
1965 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1966 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1967 # check PCD datum information
1968 if len(TokenList
) < 2 or TokenList
[1] == '':
1969 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD Datum information given",
1970 ExtraData
=self
._CurrentLine
+ \
1971 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1972 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1975 ValueRe
= re
.compile(r
'^\s*L?\".*\|.*\"')
1976 PtrValue
= ValueRe
.findall(TokenList
[1])
1978 # Has VOID* type string, may contain "|" character in the string.
1979 if len(PtrValue
) != 0:
1980 ptrValueList
= re
.sub(ValueRe
, '', TokenList
[1])
1981 ValueList
= AnalyzePcdExpression(ptrValueList
)
1982 ValueList
[0] = PtrValue
[0]
1984 ValueList
= AnalyzePcdExpression(TokenList
[1])
1987 # check if there's enough datum information given
1988 if len(ValueList
) != 3:
1989 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid PCD Datum information given",
1990 ExtraData
=self
._CurrentLine
+ \
1991 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1992 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1993 # check default value
1994 if ValueList
[0] == '':
1995 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DefaultValue in PCD Datum information",
1996 ExtraData
=self
._CurrentLine
+ \
1997 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1998 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2000 if ValueList
[1] == '':
2001 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DatumType in PCD Datum information",
2002 ExtraData
=self
._CurrentLine
+ \
2003 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2004 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2005 # check token of the PCD
2006 if ValueList
[2] == '':
2007 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing Token in PCD Datum information",
2008 ExtraData
=self
._CurrentLine
+ \
2009 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2010 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2012 PcdValue
= ValueList
[0]
2015 self
._GuidDict
.update(self
._AllPcdDict
)
2016 ValueList
[0] = ValueExpressionEx(ValueList
[0], ValueList
[1], self
._GuidDict
)(True)
2017 except BadExpression
, Value
:
2018 EdkLogger
.error('Parser', FORMAT_INVALID
, Value
, ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2019 # check format of default value against the datum type
2020 IsValid
, Cause
= CheckPcdDatum(ValueList
[1], ValueList
[0])
2022 EdkLogger
.error('Parser', FORMAT_INVALID
, Cause
, ExtraData
=self
._CurrentLine
,
2023 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2025 if Cause
== "StructurePcd":
2026 self
._CurrentStructurePcdName
= TAB_SPLIT
.join(self
._ValueList
[0:2])
2027 self
._ValueList
[0] = self
._CurrentStructurePcdName
2028 self
._ValueList
[1] = ValueList
[1].strip()
2030 if ValueList
[0] in ['True', 'true', 'TRUE']:
2032 elif ValueList
[0] in ['False', 'false', 'FALSE']:
2035 # check for duplicate PCD definition
2036 if (self
._Scope
[0], self
._ValueList
[0], self
._ValueList
[1]) in self
._AllPCDs
:
2037 EdkLogger
.error('Parser', FORMAT_INVALID
,
2038 "The same PCD name and GUID have been already defined",
2039 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2041 self
._AllPCDs
.append((self
._Scope
[0], self
._ValueList
[0], self
._ValueList
[1]))
2042 self
._AllPcdDict
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = ValueList
[0]
2044 self
._ValueList
[2] = ValueList
[0].strip() + '|' + ValueList
[1].strip() + '|' + ValueList
[2].strip()
2047 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
2048 MODEL_EFI_INCLUDE
: MetaFileParser
._PathParser
,
2049 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
2050 MODEL_EFI_GUID
: _GuidParser
,
2051 MODEL_EFI_PPI
: _GuidParser
,
2052 MODEL_EFI_PROTOCOL
: _GuidParser
,
2053 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
2054 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
2055 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
2056 MODEL_PCD_DYNAMIC
: _PcdParser
,
2057 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
2058 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
2059 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
2064 # This acts like the main() function for the script, unless it is 'import'ed into another
2067 if __name__
== '__main__':