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 from __future__
import print_function
19 from __future__
import absolute_import
20 import Common
.LongFilePathOs
as os
24 from hashlib
import md5
26 import Common
.EdkLogger
as EdkLogger
27 import Common
.GlobalData
as GlobalData
29 from CommonDataClass
.DataClass
import *
30 from Common
.DataType
import *
31 from Common
.StringUtils
import *
32 from Common
.Misc
import GuidStructureStringToGuidString
, CheckPcdDatum
, PathClass
, AnalyzePcdData
, AnalyzeDscPcd
, AnalyzePcdExpression
, ParseFieldValue
33 from Common
.Expression
import *
34 from CommonDataClass
.Exceptions
import *
35 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
36 from collections
import defaultdict
37 from .MetaFileTable
import MetaFileStorage
38 from .MetaFileCommentParser
import CheckInfComment
40 ## RegEx for finding file versions
41 hexVersionPattern
= re
.compile(r
'0[xX][\da-f-A-F]{5,8}')
42 decVersionPattern
= re
.compile(r
'\d+\.\d+')
44 ## A decorator used to parse macro definition
45 def ParseMacro(Parser
):
46 def MacroParser(self
):
47 Match
= gMacroDefPattern
.match(self
._CurrentLine
)
49 # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method
53 TokenList
= GetSplitValueList(self
._CurrentLine
[Match
.end(1):], TAB_EQUAL_SPLIT
, 1)
56 EdkLogger
.error('Parser', FORMAT_INVALID
, "No macro name given",
57 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
58 if len(TokenList
) < 2:
62 Name
, Value
= TokenList
63 # Global macros can be only defined via environment variable
64 if Name
in GlobalData
.gGlobalDefines
:
65 EdkLogger
.error('Parser', FORMAT_INVALID
, "%s can only be defined via environment variable" % Name
,
66 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
67 # Only upper case letters, digit and '_' are allowed
68 if not gMacroNamePattern
.match(Name
):
69 EdkLogger
.error('Parser', FORMAT_INVALID
, "The macro name must be in the pattern [A-Z][A-Z0-9_]*",
70 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
72 Value
= ReplaceMacro(Value
, self
._Macros
)
73 if Type
in self
.DataType
:
74 self
._ItemType
= self
.DataType
[Type
]
76 self
._ItemType
= MODEL_META_DATA_DEFINE
77 # DEFINE defined macros
78 if Type
== TAB_DSC_DEFINES_DEFINE
:
80 # First judge whether this DEFINE is in conditional directive statements or not.
82 if isinstance(self
, DscParser
) and self
._InDirective
> -1:
85 if isinstance(self
, DecParser
):
86 if MODEL_META_DATA_HEADER
in self
._SectionType
:
87 self
._FileLocalMacros
[Name
] = Value
89 self
._ConstructSectionMacroDict
(Name
, Value
)
90 elif self
._SectionType
== MODEL_META_DATA_HEADER
:
91 self
._FileLocalMacros
[Name
] = Value
93 self
._ConstructSectionMacroDict
(Name
, Value
)
95 # EDK_GLOBAL defined macros
96 elif not isinstance(self
, DscParser
):
97 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL can only be used in .dsc file",
98 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
99 elif self
._SectionType
!= MODEL_META_DATA_HEADER
:
100 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL can only be used under [Defines] section",
101 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
102 elif (Name
in self
._FileLocalMacros
) and (self
._FileLocalMacros
[Name
] != Value
):
103 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL defined a macro with the same name and different value as one defined by 'DEFINE'",
104 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
106 self
._ValueList
= [Type
, Name
, Value
]
110 ## Base class of parser
112 # This class is used for derivation purpose. The specific parser for one kind
113 # type file must derive this class and implement some public interfaces.
115 # @param FilePath The path of platform description file
116 # @param FileType The raw data of DSC file
117 # @param Table Database used to retrieve module/package information
118 # @param Macros Macros used for replacement in file
119 # @param Owner Owner ID (for sub-section parsing)
120 # @param From ID from which the data comes (for !INCLUDE directive)
122 class MetaFileParser(object):
123 # data type (file content) for specific file type
126 # Parser objects used to implement singleton
131 # One file, one parser object. This factory method makes sure that there's
132 # only one object constructed for one meta file.
134 # @param Class class object of real AutoGen class
135 # (InfParser, DecParser or DscParser)
136 # @param FilePath The path of meta file
137 # @param *args The specific class related parameters
138 # @param **kwargs The specific class related dict parameters
140 def __new__(Class
, FilePath
, *args
, **kwargs
):
141 if FilePath
in Class
.MetaFiles
:
142 return Class
.MetaFiles
[FilePath
]
144 ParserObject
= super(MetaFileParser
, Class
).__new
__(Class
)
145 Class
.MetaFiles
[FilePath
] = ParserObject
148 ## Constructor of MetaFileParser
150 # Initialize object of MetaFileParser
152 # @param FilePath The path of platform description file
153 # @param FileType The raw data of DSC file
154 # @param Arch Default Arch value for filtering sections
155 # @param Table Database used to retrieve module/package information
156 # @param Owner Owner ID (for sub-section parsing)
157 # @param From ID from which the data comes (for !INCLUDE directive)
159 def __init__(self
, FilePath
, FileType
, Arch
, Table
, Owner
= -1, From
= -1):
161 self
._RawTable
= Table
163 self
._FileType
= FileType
164 self
.MetaFile
= FilePath
165 self
._FileDir
= self
.MetaFile
.Dir
167 self
._FileLocalMacros
= {}
168 self
._SectionsMacroDict
= defaultdict(dict)
170 # for recursive parsing
171 self
._Owner
= [Owner
]
174 # parsr status for parsing
175 self
._ValueList
= ['', '', '', '', '']
178 self
._CurrentLine
= ''
179 self
._SectionType
= MODEL_UNKNOWN
180 self
._SectionName
= ''
181 self
._InSubsection
= False
182 self
._SubsectionType
= MODEL_UNKNOWN
183 self
._SubsectionName
= ''
184 self
._ItemType
= MODEL_UNKNOWN
187 self
._Finished
= False
188 self
._PostProcessed
= False
189 # Different version of meta-file has different way to parse.
191 self
._GuidDict
= {} # for Parser PCD value {GUID(gTokeSpaceGuidName)}
193 ## Store the parsed data in table
194 def _Store(self
, *Args
):
195 return self
._Table
.Insert(*Args
)
197 ## Virtual method for starting parse
199 raise NotImplementedError
201 ## Notify a post-process is needed
202 def DoPostProcess(self
):
203 self
._PostProcessed
= False
205 ## Set parsing complete flag in both class and table
207 self
._Finished
= True
208 ## Do not set end flag when processing included files
210 self
._Table
.SetEndFlag()
212 def _PostProcess(self
):
213 self
._PostProcessed
= True
215 ## Get the parse complete flag
218 return self
._Finished
220 ## Set the complete flag
222 def Finished(self
, Value
):
223 self
._Finished
= Value
225 ## Remove records that do not match given Filter Arch
226 def _FilterRecordList(self
, RecordList
, FilterArch
):
228 for Record
in RecordList
:
230 if Arch
== TAB_ARCH_COMMON
or Arch
== FilterArch
:
231 NewRecordList
.append(Record
)
234 ## Use [] style to query data in table, just for readability
236 # DataInfo = [data_type, scope1(arch), scope2(platform/moduletype)]
238 def __getitem__(self
, DataInfo
):
239 if not isinstance(DataInfo
, type(())):
240 DataInfo
= (DataInfo
,)
242 # Parse the file first, if necessary
243 if not self
._Finished
:
244 if self
._RawTable
.IsIntegrity():
245 self
._Finished
= True
247 self
._Table
= self
._RawTable
248 self
._PostProcessed
= False
251 # No specific ARCH or Platform given, use raw data
252 if self
._RawTable
and (len(DataInfo
) == 1 or DataInfo
[1] is None):
253 return self
._FilterRecordList
(self
._RawTable
.Query(*DataInfo
), self
._Arch
)
255 # Do post-process if necessary
256 if not self
._PostProcessed
:
259 return self
._FilterRecordList
(self
._Table
.Query(*DataInfo
), DataInfo
[1])
261 ## Data parser for the common format in different type of file
263 # The common format in the meatfile is like
268 def _CommonParser(self
):
269 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
270 self
._ValueList
[0:len(TokenList
)] = TokenList
272 ## Data parser for the format in which there's path
274 # Only path can have macro used. So we need to replace them before use.
277 def _PathParser(self
):
278 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
279 self
._ValueList
[0:len(TokenList
)] = TokenList
280 # Don't do macro replacement for dsc file at this point
281 if not isinstance(self
, DscParser
):
282 Macros
= self
._Macros
283 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
285 ## Skip unsupported data
287 EdkLogger
.warn("Parser", "Unrecognized content", File
=self
.MetaFile
,
288 Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
);
289 self
._ValueList
[0:1] = [self
._CurrentLine
]
291 ## Skip unsupported data for UserExtension Section
292 def _SkipUserExtension(self
):
293 self
._ValueList
[0:1] = [self
._CurrentLine
]
295 ## Section header parser
297 # The section header is always in following format:
299 # [section_name.arch<.platform|module_type>]
301 def _SectionHeaderParser(self
):
303 self
._SectionName
= ''
305 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
308 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
, 3)
309 # different section should not mix in one section
310 if self
._SectionName
!= '' and self
._SectionName
!= ItemList
[0].upper():
311 EdkLogger
.error('Parser', FORMAT_INVALID
, "Different section names in the same section",
312 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
313 self
._SectionName
= ItemList
[0].upper()
314 if self
._SectionName
in self
.DataType
:
315 self
._SectionType
= self
.DataType
[self
._SectionName
]
316 # Check if the section name is valid
317 if self
._SectionName
not in SECTIONS_HAVE_ITEM_AFTER_ARCH_SET
and len(ItemList
) > 3:
318 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
319 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
320 elif self
._Version
>= 0x00010005:
321 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
322 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
324 self
._SectionType
= MODEL_UNKNOWN
327 if len(ItemList
) > 1:
328 S1
= ItemList
[1].upper()
333 # S2 may be Platform or ModuleType
334 if len(ItemList
) > 2:
335 if self
._SectionName
.upper() in SECTIONS_HAVE_ITEM_PCD_SET
:
338 S2
= ItemList
[2].upper()
341 if len(ItemList
) > 3:
345 self
._Scope
.append([S1
, S2
, S3
])
347 # 'COMMON' must not be used with specific ARCHs at the same section
348 if TAB_ARCH_COMMON
in ArchList
and len(ArchList
) > 1:
349 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
350 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
351 # If the section information is needed later, it should be stored in database
352 self
._ValueList
[0] = self
._SectionName
354 ## [defines] section parser
356 def _DefineParser(self
):
357 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
358 self
._ValueList
[1:len(TokenList
)] = TokenList
359 if not self
._ValueList
[1]:
360 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
361 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
362 if not self
._ValueList
[2]:
363 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
364 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
366 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
367 Name
, Value
= self
._ValueList
[1], self
._ValueList
[2]
368 MacroUsed
= GlobalData
.gMacroRefPattern
.findall(Value
)
369 if len(MacroUsed
) != 0:
370 for Macro
in MacroUsed
:
371 if Macro
in GlobalData
.gGlobalDefines
:
372 EdkLogger
.error("Parser", FORMAT_INVALID
, "Global macro %s is not permitted." % (Macro
), ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
374 EdkLogger
.error("Parser", FORMAT_INVALID
, "%s not defined" % (Macro
), ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
375 # Sometimes, we need to make differences between EDK and EDK2 modules
376 if Name
== 'INF_VERSION':
377 if hexVersionPattern
.match(Value
):
378 self
._Version
= int(Value
, 0)
379 elif decVersionPattern
.match(Value
):
380 ValueList
= Value
.split('.')
381 Major
= int(ValueList
[0], 0)
382 Minor
= int(ValueList
[1], 0)
383 if Major
> 0xffff or Minor
> 0xffff:
384 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid version number",
385 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
386 self
._Version
= int('0x{0:04x}{1:04x}'.format(Major
, Minor
), 0)
388 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid version number",
389 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
391 if isinstance(self
, InfParser
) and self
._Version
< 0x00010005:
392 # EDK module allows using defines as macros
393 self
._FileLocalMacros
[Name
] = Value
394 self
._Defines
[Name
] = Value
396 ## [BuildOptions] section parser
398 def _BuildOptionParser(self
):
399 self
._CurrentLine
= CleanString(self
._CurrentLine
, BuildOption
=True)
400 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
401 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
402 if len(TokenList2
) == 2:
403 self
._ValueList
[0] = TokenList2
[0] # toolchain family
404 self
._ValueList
[1] = TokenList2
[1] # keys
406 self
._ValueList
[1] = TokenList
[0]
407 if len(TokenList
) == 2 and not isinstance(self
, DscParser
): # value
408 self
._ValueList
[2] = ReplaceMacro(TokenList
[1], self
._Macros
)
410 if self
._ValueList
[1].count('_') != 4:
414 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
415 ExtraData
=self
._CurrentLine
,
417 Line
=self
._LineIndex
+ 1
419 def GetValidExpression(self
, TokenSpaceGuid
, PcdCName
):
420 return self
._Table
.GetValidExpression(TokenSpaceGuid
, PcdCName
)
425 Macros
.update(self
._FileLocalMacros
)
426 Macros
.update(self
._GetApplicableSectionMacro
())
429 ## Construct section Macro dict
430 def _ConstructSectionMacroDict(self
, Name
, Value
):
431 ScopeKey
= [(Scope
[0], Scope
[1], Scope
[2]) for Scope
in self
._Scope
]
432 ScopeKey
= tuple(ScopeKey
)
434 # DecParser SectionType is a list, will contain more than one item only in Pcd Section
435 # As Pcd section macro usage is not alllowed, so here it is safe
437 if isinstance(self
, DecParser
):
438 SectionDictKey
= self
._SectionType
[0], ScopeKey
440 SectionDictKey
= self
._SectionType
, ScopeKey
442 self
._SectionsMacroDict
[SectionDictKey
][Name
] = Value
444 ## Get section Macros that are applicable to current line, which may come from other sections
445 ## that share the same name while scope is wider
446 def _GetApplicableSectionMacro(self
):
453 ActiveSectionType
= self
._SectionType
454 if isinstance(self
, DecParser
):
455 ActiveSectionType
= self
._SectionType
[0]
457 for (SectionType
, Scope
) in self
._SectionsMacroDict
:
458 if SectionType
!= ActiveSectionType
:
461 for ActiveScope
in self
._Scope
:
462 Scope0
, Scope1
, Scope2
= ActiveScope
[0], ActiveScope
[1], ActiveScope
[2]
463 if(Scope0
, Scope1
, Scope2
) not in Scope
:
466 SpeSpeMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
468 for ActiveScope
in self
._Scope
:
469 Scope0
, Scope1
, Scope2
= ActiveScope
[0], ActiveScope
[1], ActiveScope
[2]
470 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
:
473 ComSpeMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
475 if (TAB_COMMON
, TAB_COMMON
, TAB_COMMON
) in Scope
:
476 ComComMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
478 Macros
.update(ComComMacroDict
)
479 Macros
.update(ComSpeMacroDict
)
480 Macros
.update(SpeSpeMacroDict
)
486 ## INF file parser class
488 # @param FilePath The path of platform description file
489 # @param FileType The raw data of DSC file
490 # @param Table Database used to retrieve module/package information
491 # @param Macros Macros used for replacement in file
493 class InfParser(MetaFileParser
):
494 # INF file supported data types (one type per section)
496 TAB_UNKNOWN
.upper() : MODEL_UNKNOWN
,
497 TAB_INF_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
498 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
499 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
500 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
501 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
502 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
503 TAB_PACKAGES
.upper() : MODEL_META_DATA_PACKAGE
,
504 TAB_NMAKE
.upper() : MODEL_META_DATA_NMAKE
,
505 TAB_INF_FIXED_PCD
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
506 TAB_INF_PATCH_PCD
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
507 TAB_INF_FEATURE_PCD
.upper() : MODEL_PCD_FEATURE_FLAG
,
508 TAB_INF_PCD_EX
.upper() : MODEL_PCD_DYNAMIC_EX
,
509 TAB_INF_PCD
.upper() : MODEL_PCD_DYNAMIC
,
510 TAB_SOURCES
.upper() : MODEL_EFI_SOURCE_FILE
,
511 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
512 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
513 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
514 TAB_DEPEX
.upper() : MODEL_EFI_DEPEX
,
515 TAB_BINARIES
.upper() : MODEL_EFI_BINARY_FILE
,
516 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
519 ## Constructor of InfParser
521 # Initialize object of InfParser
523 # @param FilePath The path of module description file
524 # @param FileType The raw data of DSC file
525 # @param Arch Default Arch value for filtering sections
526 # @param Table Database used to retrieve module/package information
528 def __init__(self
, FilePath
, FileType
, Arch
, Table
):
529 # prevent re-initialization
530 if hasattr(self
, "_Table"):
532 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
)
540 Content
= open(str(self
.MetaFile
), 'r').readlines()
542 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
544 # parse the file line by line
545 IsFindBlockComment
= False
546 GetHeaderComment
= False
551 for Index
in range(0, len(Content
)):
552 # skip empty, commented, block commented lines
553 Line
, Comment
= CleanString2(Content
[Index
], AllowCppStyleComment
=True)
555 if Index
+ 1 < len(Content
):
556 NextLine
, NextComment
= CleanString2(Content
[Index
+ 1])
559 Comments
.append((Comment
, Index
+ 1))
560 elif GetHeaderComment
:
561 SectionComments
.extend(Comments
)
564 if Line
.find(DataType
.TAB_COMMENT_EDK_START
) > -1:
565 IsFindBlockComment
= True
567 if Line
.find(DataType
.TAB_COMMENT_EDK_END
) > -1:
568 IsFindBlockComment
= False
570 if IsFindBlockComment
:
573 self
._LineIndex
= Index
574 self
._CurrentLine
= Line
577 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
578 if not GetHeaderComment
:
579 for Cmt
, LNo
in Comments
:
580 self
._Store
(MODEL_META_DATA_HEADER_COMMENT
, Cmt
, '', '', TAB_COMMON
,
581 TAB_COMMON
, self
._Owner
[-1], LNo
, -1, LNo
, -1, 0)
582 GetHeaderComment
= True
584 TailComments
.extend(SectionComments
+ Comments
)
586 self
._SectionHeaderParser
()
587 # Check invalid sections
588 if self
._Version
< 0x00010005:
589 if self
._SectionType
in [MODEL_META_DATA_BUILD_OPTION
,
590 MODEL_EFI_LIBRARY_CLASS
,
591 MODEL_META_DATA_PACKAGE
,
592 MODEL_PCD_FIXED_AT_BUILD
,
593 MODEL_PCD_PATCHABLE_IN_MODULE
,
594 MODEL_PCD_FEATURE_FLAG
,
595 MODEL_PCD_DYNAMIC_EX
,
600 MODEL_META_DATA_USER_EXTENSION
]:
601 EdkLogger
.error('Parser', FORMAT_INVALID
,
602 "Section [%s] is not allowed in inf file without version" % (self
._SectionName
),
603 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
604 elif self
._SectionType
in [MODEL_EFI_INCLUDE
,
605 MODEL_EFI_LIBRARY_INSTANCE
,
606 MODEL_META_DATA_NMAKE
]:
607 EdkLogger
.error('Parser', FORMAT_INVALID
,
608 "Section [%s] is not allowed in inf file with version 0x%08x" % (self
._SectionName
, self
._Version
),
609 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
611 # merge two lines specified by '\' in section NMAKE
612 elif self
._SectionType
== MODEL_META_DATA_NMAKE
:
615 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
618 if NextLine
[0] == TAB_SECTION_START
and NextLine
[-1] == TAB_SECTION_END
:
619 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
622 NmakeLine
= NmakeLine
+ ' ' + Line
[0:-1]
625 self
._CurrentLine
= NmakeLine
+ Line
629 self
._ValueList
= ['', '', '']
630 # parse current line, result will be put in self._ValueList
631 self
._SectionParser
[self
._SectionType
](self
)
632 if self
._ValueList
is None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
637 Comments
.append((Comment
, Index
+ 1))
638 if GlobalData
.gOptions
and GlobalData
.gOptions
.CheckUsage
:
639 CheckInfComment(self
._SectionType
, Comments
, str(self
.MetaFile
), Index
+ 1, self
._ValueList
)
641 # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
642 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
644 for Arch
, Platform
, _
in self
._Scope
:
645 LastItem
= self
._Store
(self
._SectionType
,
658 for Comment
, LineNo
in Comments
:
659 self
._Store
(MODEL_META_DATA_COMMENT
, Comment
, '', '', Arch
, Platform
,
660 LastItem
, LineNo
, -1, LineNo
, -1, 0)
663 TailComments
.extend(SectionComments
+ Comments
)
664 if IsFindBlockComment
:
665 EdkLogger
.error("Parser", FORMAT_INVALID
, "Open block comments (starting with /*) are expected to end with */",
668 # If there are tail comments in INF file, save to database whatever the comments are
669 for Comment
in TailComments
:
670 self
._Store
(MODEL_META_DATA_TAIL_COMMENT
, Comment
[0], '', '', TAB_COMMON
,
671 TAB_COMMON
, self
._Owner
[-1], -1, -1, -1, -1, 0)
674 ## Data parser for the format in which there's path
676 # Only path can have macro used. So we need to replace them before use.
678 def _IncludeParser(self
):
679 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
680 self
._ValueList
[0:len(TokenList
)] = TokenList
681 Macros
= self
._Macros
683 for Index
in range(0, len(self
._ValueList
)):
684 Value
= self
._ValueList
[Index
]
688 if Value
.upper().find('$(EFI_SOURCE)\Edk'.upper()) > -1 or Value
.upper().find('$(EFI_SOURCE)/Edk'.upper()) > -1:
689 Value
= '$(EDK_SOURCE)' + Value
[17:]
690 if Value
.find('$(EFI_SOURCE)') > -1 or Value
.find('$(EDK_SOURCE)') > -1:
692 elif Value
.startswith('.'):
694 elif Value
.startswith('$('):
697 Value
= '$(EFI_SOURCE)/' + Value
699 self
._ValueList
[Index
] = ReplaceMacro(Value
, Macros
)
701 ## Parse [Sources] section
703 # Only path can have macro used. So we need to replace them before use.
706 def _SourceFileParser(self
):
707 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
708 self
._ValueList
[0:len(TokenList
)] = TokenList
709 Macros
= self
._Macros
710 # For Acpi tables, remove macro like ' TABLE_NAME=Sata1'
711 if 'COMPONENT_TYPE' in Macros
:
712 if self
._Defines
['COMPONENT_TYPE'].upper() == 'ACPITABLE':
713 self
._ValueList
[0] = GetSplitValueList(self
._ValueList
[0], ' ', 1)[0]
714 if self
._Defines
['BASE_NAME'] == 'Microcode':
716 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
718 ## Parse [Binaries] section
720 # Only path can have macro used. So we need to replace them before use.
723 def _BinaryFileParser(self
):
724 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 2)
725 if len(TokenList
) < 2:
726 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type or path specified",
727 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
728 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
730 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type specified",
731 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
732 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
734 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file path specified",
735 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
736 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
737 self
._ValueList
[0:len(TokenList
)] = TokenList
738 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
740 ## [nmake] section parser (Edk.x style only)
741 def _NmakeParser(self
):
742 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
743 self
._ValueList
[0:len(TokenList
)] = TokenList
745 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
746 # remove self-reference in macro setting
747 #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
749 ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
751 def _PcdParser(self
):
752 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
753 ValueList
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
754 if len(ValueList
) != 2:
755 EdkLogger
.error('Parser', FORMAT_INVALID
, "Illegal token space GUID and PCD name format",
756 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
757 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
758 self
._ValueList
[0:1] = ValueList
759 if len(TokenList
) > 1:
760 self
._ValueList
[2] = TokenList
[1]
761 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
762 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
763 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
764 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
766 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
767 if self
._ValueList
[2] != '':
768 InfPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
769 if InfPcdValueList
[0] in ['True', 'true', 'TRUE']:
770 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '1', 1);
771 elif InfPcdValueList
[0] in ['False', 'false', 'FALSE']:
772 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '0', 1);
773 if (self
._ValueList
[0], self
._ValueList
[1]) not in self
.PcdsDict
:
774 self
.PcdsDict
[self
._ValueList
[0], self
._ValueList
[1]] = self
._SectionType
775 elif self
.PcdsDict
[self
._ValueList
[0], self
._ValueList
[1]] != self
._SectionType
:
776 EdkLogger
.error('Parser', FORMAT_INVALID
, "It is not permissible to list a specified PCD in different PCD type sections.",
777 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
778 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
780 ## [depex] section parser
782 def _DepexParser(self
):
783 self
._ValueList
[0:1] = [self
._CurrentLine
]
786 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
787 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
788 MODEL_META_DATA_BUILD_OPTION
: MetaFileParser
._BuildOptionParser
,
789 MODEL_EFI_INCLUDE
: _IncludeParser
, # for Edk.x modules
790 MODEL_EFI_LIBRARY_INSTANCE
: MetaFileParser
._CommonParser
, # for Edk.x modules
791 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
792 MODEL_META_DATA_PACKAGE
: MetaFileParser
._PathParser
,
793 MODEL_META_DATA_NMAKE
: _NmakeParser
, # for Edk.x modules
794 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
795 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
796 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
797 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
798 MODEL_PCD_DYNAMIC
: _PcdParser
,
799 MODEL_EFI_SOURCE_FILE
: _SourceFileParser
,
800 MODEL_EFI_GUID
: MetaFileParser
._CommonParser
,
801 MODEL_EFI_PROTOCOL
: MetaFileParser
._CommonParser
,
802 MODEL_EFI_PPI
: MetaFileParser
._CommonParser
,
803 MODEL_EFI_DEPEX
: _DepexParser
,
804 MODEL_EFI_BINARY_FILE
: _BinaryFileParser
,
805 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
808 ## DSC file parser class
810 # @param FilePath The path of platform description file
811 # @param FileType The raw data of DSC file
812 # @param Table Database used to retrieve module/package information
813 # @param Macros Macros used for replacement in file
814 # @param Owner Owner ID (for sub-section parsing)
815 # @param From ID from which the data comes (for !INCLUDE directive)
817 class DscParser(MetaFileParser
):
818 # DSC file supported data types (one type per section)
820 TAB_SKUIDS
.upper() : MODEL_EFI_SKU_ID
,
821 TAB_DEFAULT_STORES
.upper() : MODEL_EFI_DEFAULT_STORES
,
822 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
823 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
824 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
825 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
826 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
827 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
828 TAB_PCDS_DYNAMIC_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_DEFAULT
,
829 TAB_PCDS_DYNAMIC_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_HII
,
830 TAB_PCDS_DYNAMIC_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_VPD
,
831 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT
,
832 TAB_PCDS_DYNAMIC_EX_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_HII
,
833 TAB_PCDS_DYNAMIC_EX_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_VPD
,
834 TAB_COMPONENTS
.upper() : MODEL_META_DATA_COMPONENT
,
835 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
.upper() : MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
,
836 TAB_DSC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
837 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
838 TAB_DSC_DEFINES_EDKGLOBAL
: MODEL_META_DATA_GLOBAL_DEFINE
,
839 TAB_INCLUDE
.upper() : MODEL_META_DATA_INCLUDE
,
840 TAB_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
841 TAB_IF_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
842 TAB_IF_N_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
,
843 TAB_ELSE_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
,
844 TAB_ELSE
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
,
845 TAB_END_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
,
846 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
,
847 TAB_ERROR
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR
,
850 # Valid names in define section
857 "PCD_INFO_GENERATION",
858 "PCD_VAR_CHECK_GENERATION",
859 "SUPPORTED_ARCHITECTURES",
868 "FIX_LOAD_TOP_MEMORY_ADDRESS",
873 SubSectionDefineKeywords
= [
877 SymbolPattern
= ValueExpression
.SymbolPattern
879 IncludedFiles
= set()
881 ## Constructor of DscParser
883 # Initialize object of DscParser
885 # @param FilePath The path of platform description file
886 # @param FileType The raw data of DSC file
887 # @param Arch Default Arch value for filtering sections
888 # @param Table Database used to retrieve module/package information
889 # @param Owner Owner ID (for sub-section parsing)
890 # @param From ID from which the data comes (for !INCLUDE directive)
892 def __init__(self
, FilePath
, FileType
, Arch
, Table
, Owner
= -1, From
= -1):
893 # prevent re-initialization
894 if hasattr(self
, "_Table") and self
._Table
is Table
:
896 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
, Owner
, From
)
897 self
._Version
= 0x00010005 # Only EDK2 dsc file is supported
898 # to store conditional directive evaluation result
899 self
._DirectiveStack
= []
900 self
._DirectiveEvalStack
= []
904 # Specify whether current line is in uncertain condition
906 self
._InDirective
= -1
908 # Final valid replacable symbols
911 # Map the ID between the original table and new table to track
914 self
._IdMapping
= {-1:-1}
920 Content
= open(str(self
.MetaFile
), 'r').readlines()
922 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
925 for Index
in range(0, len(Content
)):
926 Line
= CleanString(Content
[Index
])
931 self
._CurrentLine
= Line
932 self
._LineIndex
= Index
933 if self
._InSubsection
and self
._Owner
[-1] == -1:
934 self
._Owner
.append(self
._LastItem
)
937 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
938 self
._SectionType
= MODEL_META_DATA_SECTION_HEADER
940 elif Line
[0] == '}' and self
._InSubsection
:
941 self
._InSubsection
= False
942 self
._SubsectionType
= MODEL_UNKNOWN
943 self
._SubsectionName
= ''
948 elif Line
[0] == TAB_OPTION_START
and Line
[-1] == TAB_OPTION_END
:
949 self
._SubsectionType
= MODEL_META_DATA_SUBSECTION_HEADER
952 TokenList
= GetSplitValueList(Line
, ' ', 1)
953 if TokenList
[0] == TAB_INCLUDE
:
954 for Arch
, ModuleType
, DefaultStore
in self
._Scope
:
955 if self
._SubsectionType
!= MODEL_UNKNOWN
and Arch
in OwnerId
:
956 self
._Owner
[-1] = OwnerId
[Arch
]
957 self
._DirectiveParser
()
959 self
._DirectiveParser
()
961 if Line
[0] == TAB_OPTION_START
and not self
._InSubsection
:
962 EdkLogger
.error("Parser", FILE_READ_FAILURE
, "Missing the '{' before %s in Line %s" % (Line
, Index
+1), ExtraData
=self
.MetaFile
)
964 if self
._InSubsection
:
965 SectionType
= self
._SubsectionType
967 SectionType
= self
._SectionType
968 self
._ItemType
= SectionType
970 self
._ValueList
= ['', '', '']
971 self
._SectionParser
[SectionType
](self
)
972 if self
._ValueList
is None:
975 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
976 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
978 for Arch
, ModuleType
, DefaultStore
in self
._Scope
:
979 Owner
= self
._Owner
[-1]
980 if self
._SubsectionType
!= MODEL_UNKNOWN
and Arch
in OwnerId
:
981 Owner
= OwnerId
[Arch
]
982 self
._LastItem
= self
._Store
(
998 if self
._SubsectionType
== MODEL_UNKNOWN
and self
._InSubsection
:
999 OwnerId
[Arch
] = self
._LastItem
1001 if self
._DirectiveStack
:
1002 Type
, Line
, Text
= self
._DirectiveStack
[-1]
1003 EdkLogger
.error('Parser', FORMAT_INVALID
, "No matching '!endif' found",
1004 ExtraData
=Text
, File
=self
.MetaFile
, Line
=Line
)
1007 ## <subsection_header> parser
1008 def _SubsectionHeaderParser(self
):
1009 self
._SubsectionName
= self
._CurrentLine
[1:-1].upper()
1010 if self
._SubsectionName
in self
.DataType
:
1011 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
1013 self
._SubsectionType
= MODEL_UNKNOWN
1014 EdkLogger
.warn("Parser", "Unrecognized sub-section", File
=self
.MetaFile
,
1015 Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1016 self
._ValueList
[0] = self
._SubsectionName
1018 ## Directive statement parser
1019 def _DirectiveParser(self
):
1020 self
._ValueList
= ['', '', '']
1021 TokenList
= GetSplitValueList(self
._CurrentLine
, ' ', 1)
1022 self
._ValueList
[0:len(TokenList
)] = TokenList
1025 DirectiveName
= self
._ValueList
[0].upper()
1026 if DirectiveName
not in self
.DataType
:
1027 EdkLogger
.error("Parser", FORMAT_INVALID
, "Unknown directive [%s]" % DirectiveName
,
1028 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1030 if DirectiveName
in ['!IF', '!IFDEF', '!IFNDEF']:
1031 self
._InDirective
+= 1
1033 if DirectiveName
in ['!ENDIF']:
1034 self
._InDirective
-= 1
1036 if DirectiveName
in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self
._ValueList
[1] == '':
1037 EdkLogger
.error("Parser", FORMAT_INVALID
, "Missing expression",
1038 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1039 ExtraData
=self
._CurrentLine
)
1041 ItemType
= self
.DataType
[DirectiveName
]
1042 Scope
= [[TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]]
1043 if ItemType
== MODEL_META_DATA_INCLUDE
:
1045 elif ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR
:
1047 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1048 # Remove all directives between !if and !endif, including themselves
1049 while self
._DirectiveStack
:
1050 # Remove any !else or !elseif
1051 DirectiveInfo
= self
._DirectiveStack
.pop()
1052 if DirectiveInfo
[0] in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1053 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1054 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1057 EdkLogger
.error("Parser", FORMAT_INVALID
, "Redundant '!endif'",
1058 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1059 ExtraData
=self
._CurrentLine
)
1060 elif ItemType
not in {MODEL_META_DATA_INCLUDE
, MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR
}:
1061 # Break if there's a !else is followed by a !elseif
1062 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
and \
1063 self
._DirectiveStack
and \
1064 self
._DirectiveStack
[-1][0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1065 EdkLogger
.error("Parser", FORMAT_INVALID
, "'!elseif' after '!else'",
1066 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1067 ExtraData
=self
._CurrentLine
)
1068 self
._DirectiveStack
.append((ItemType
, self
._LineIndex
+ 1, self
._CurrentLine
))
1071 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
1072 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
1074 for Arch
, ModuleType
, DefaultStore
in Scope
:
1075 self
._LastItem
= self
._Store
(
1085 self
._LineIndex
+ 1,
1087 self
._LineIndex
+ 1,
1092 ## [defines] section parser
1094 def _DefineParser(self
):
1095 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1096 self
._ValueList
[1:len(TokenList
)] = TokenList
1099 if not self
._ValueList
[1]:
1100 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
1101 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1102 if not self
._ValueList
[2]:
1103 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
1104 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1105 if (not self
._ValueList
[1] in self
.DefineKeywords
and
1106 (self
._InSubsection
and self
._ValueList
[1] not in self
.SubSectionDefineKeywords
)):
1107 EdkLogger
.error('Parser', FORMAT_INVALID
,
1108 "Unknown keyword found: %s. "
1109 "If this is a macro you must "
1110 "add it as a DEFINE in the DSC" % self
._ValueList
[1],
1111 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1112 if not self
._InSubsection
:
1113 self
._Defines
[self
._ValueList
[1]] = self
._ValueList
[2]
1114 self
._ItemType
= self
.DataType
[TAB_DSC_DEFINES
.upper()]
1117 def _SkuIdParser(self
):
1118 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1119 if len(TokenList
) not in (2, 3):
1120 EdkLogger
.error('Parser', FORMAT_INVALID
, "Correct format is '<Number>|<UiName>[|<UiName>]'",
1121 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1122 self
._ValueList
[0:len(TokenList
)] = TokenList
1124 def _DefaultStoresParser(self
):
1125 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1126 if len(TokenList
) != 2:
1127 EdkLogger
.error('Parser', FORMAT_INVALID
, "Correct format is '<Number>|<UiName>'",
1128 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1129 self
._ValueList
[0:len(TokenList
)] = TokenList
1131 ## Parse Edk style of library modules
1133 def _LibraryInstanceParser(self
):
1134 self
._ValueList
[0] = self
._CurrentLine
1136 ## PCD sections parser
1138 # [PcdsFixedAtBuild]
1139 # [PcdsPatchableInModule]
1142 # [PcdsDynamicExDefault]
1143 # [PcdsDynamicExVpd]
1144 # [PcdsDynamicExHii]
1146 # [PcdsDynamicDefault]
1151 def _PcdParser(self
):
1152 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1153 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1154 PcdNameTockens
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1155 if len(PcdNameTockens
) == 2:
1156 self
._ValueList
[0], self
._ValueList
[1] = PcdNameTockens
[0], PcdNameTockens
[1]
1157 elif len(PcdNameTockens
) == 3:
1158 self
._ValueList
[0], self
._ValueList
[1] = ".".join((PcdNameTockens
[0], PcdNameTockens
[1])), PcdNameTockens
[2]
1159 elif len(PcdNameTockens
) > 3:
1160 self
._ValueList
[0], self
._ValueList
[1] = ".".join((PcdNameTockens
[0], PcdNameTockens
[1])), ".".join(PcdNameTockens
[2:])
1161 if len(TokenList
) == 2:
1162 self
._ValueList
[2] = TokenList
[1]
1163 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1164 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1165 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1166 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1167 if self
._ValueList
[2] == '':
1169 # The PCD values are optional for FIXEDATBUILD, PATCHABLEINMODULE, Dynamic/DynamicEx default
1171 if self
._SectionType
in (MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
):
1173 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD value given",
1174 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1175 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1177 # Validate the datum type of Dynamic Defaul PCD and DynamicEx Default PCD
1178 ValueList
= GetSplitValueList(self
._ValueList
[2])
1179 if len(ValueList
) > 1 and ValueList
[1] in [TAB_UINT8
, TAB_UINT16
, TAB_UINT32
, TAB_UINT64
] \
1180 and self
._ItemType
in [MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
]:
1181 EdkLogger
.error('Parser', FORMAT_INVALID
, "The datum type '%s' of PCD is wrong" % ValueList
[1],
1182 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1184 # Validate the VariableName of DynamicHii and DynamicExHii for PCD Entry must not be an empty string
1185 if self
._ItemType
in [MODEL_PCD_DYNAMIC_HII
, MODEL_PCD_DYNAMIC_EX_HII
]:
1186 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
1187 if len(DscPcdValueList
[0].replace('L', '').replace('"', '').strip()) == 0:
1188 EdkLogger
.error('Parser', FORMAT_INVALID
, "The VariableName field in the HII format PCD entry must not be an empty string",
1189 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1191 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
1192 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
1193 if DscPcdValueList
[0] in ['True', 'true', 'TRUE']:
1194 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '1', 1);
1195 elif DscPcdValueList
[0] in ['False', 'false', 'FALSE']:
1196 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '0', 1);
1199 ## [components] section parser
1201 def _ComponentParser(self
):
1202 if self
._CurrentLine
[-1] == '{':
1203 self
._ValueList
[0] = self
._CurrentLine
[0:-1].strip()
1204 self
._InSubsection
= True
1205 self
._SubsectionType
= MODEL_UNKNOWN
1207 self
._ValueList
[0] = self
._CurrentLine
1209 ## [LibraryClasses] section
1211 def _LibraryClassParser(self
):
1212 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1213 if len(TokenList
) < 2:
1214 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class or instance specified",
1215 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1216 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1217 if TokenList
[0] == '':
1218 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class specified",
1219 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1220 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1221 if TokenList
[1] == '':
1222 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library instance specified",
1223 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1224 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1226 self
._ValueList
[0:len(TokenList
)] = TokenList
1228 def _CompponentSourceOverridePathParser(self
):
1229 self
._ValueList
[0] = self
._CurrentLine
1231 ## [BuildOptions] section parser
1233 def _BuildOptionParser(self
):
1234 self
._CurrentLine
= CleanString(self
._CurrentLine
, BuildOption
=True)
1235 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1236 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
1237 if len(TokenList2
) == 2:
1238 self
._ValueList
[0] = TokenList2
[0] # toolchain family
1239 self
._ValueList
[1] = TokenList2
[1] # keys
1241 self
._ValueList
[1] = TokenList
[0]
1242 if len(TokenList
) == 2: # value
1243 self
._ValueList
[2] = TokenList
[1]
1245 if self
._ValueList
[1].count('_') != 4:
1249 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
1250 ExtraData
=self
._CurrentLine
,
1252 Line
=self
._LineIndex
+ 1
1255 ## Override parent's method since we'll do all macro replacements in parser
1259 Macros
.update(self
._FileLocalMacros
)
1260 Macros
.update(self
._GetApplicableSectionMacro
())
1261 Macros
.update(GlobalData
.gEdkGlobal
)
1262 Macros
.update(GlobalData
.gPlatformDefines
)
1263 Macros
.update(GlobalData
.gCommandLineDefines
)
1264 # PCD cannot be referenced in macro definition
1265 if self
._ItemType
not in [MODEL_META_DATA_DEFINE
, MODEL_META_DATA_GLOBAL_DEFINE
]:
1266 Macros
.update(self
._Symbols
)
1267 if GlobalData
.BuildOptionPcd
:
1268 for Item
in GlobalData
.BuildOptionPcd
:
1269 if isinstance(Item
, tuple):
1271 PcdName
, TmpValue
= Item
.split("=")
1272 TmpValue
= BuildOptionValue(TmpValue
, self
._GuidDict
)
1273 Macros
[PcdName
.strip()] = TmpValue
1276 def _PostProcess(self
):
1278 MODEL_META_DATA_SECTION_HEADER
: self
.__ProcessSectionHeader
,
1279 MODEL_META_DATA_SUBSECTION_HEADER
: self
.__ProcessSubsectionHeader
,
1280 MODEL_META_DATA_HEADER
: self
.__ProcessDefine
,
1281 MODEL_META_DATA_DEFINE
: self
.__ProcessDefine
,
1282 MODEL_META_DATA_GLOBAL_DEFINE
: self
.__ProcessDefine
,
1283 MODEL_META_DATA_INCLUDE
: self
.__ProcessDirective
,
1284 MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
: self
.__ProcessDirective
,
1285 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
: self
.__ProcessDirective
,
1286 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
: self
.__ProcessDirective
,
1287 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
: self
.__ProcessDirective
,
1288 MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
: self
.__ProcessDirective
,
1289 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
: self
.__ProcessDirective
,
1290 MODEL_EFI_SKU_ID
: self
.__ProcessSkuId
,
1291 MODEL_EFI_DEFAULT_STORES
: self
.__ProcessDefaultStores
,
1292 MODEL_EFI_LIBRARY_INSTANCE
: self
.__ProcessLibraryInstance
,
1293 MODEL_EFI_LIBRARY_CLASS
: self
.__ProcessLibraryClass
,
1294 MODEL_PCD_FIXED_AT_BUILD
: self
.__ProcessPcd
,
1295 MODEL_PCD_PATCHABLE_IN_MODULE
: self
.__ProcessPcd
,
1296 MODEL_PCD_FEATURE_FLAG
: self
.__ProcessPcd
,
1297 MODEL_PCD_DYNAMIC_DEFAULT
: self
.__ProcessPcd
,
1298 MODEL_PCD_DYNAMIC_HII
: self
.__ProcessPcd
,
1299 MODEL_PCD_DYNAMIC_VPD
: self
.__ProcessPcd
,
1300 MODEL_PCD_DYNAMIC_EX_DEFAULT
: self
.__ProcessPcd
,
1301 MODEL_PCD_DYNAMIC_EX_HII
: self
.__ProcessPcd
,
1302 MODEL_PCD_DYNAMIC_EX_VPD
: self
.__ProcessPcd
,
1303 MODEL_META_DATA_COMPONENT
: self
.__ProcessComponent
,
1304 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: self
.__ProcessSourceOverridePath
,
1305 MODEL_META_DATA_BUILD_OPTION
: self
.__ProcessBuildOption
,
1306 MODEL_UNKNOWN
: self
._Skip
,
1307 MODEL_META_DATA_USER_EXTENSION
: self
._SkipUserExtension
,
1308 MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR
: self
._ProcessError
,
1311 self
._Table
= MetaFileStorage(self
._RawTable
.Cur
, self
.MetaFile
, MODEL_FILE_DSC
, True)
1312 self
._Table
.Create()
1313 self
._DirectiveStack
= []
1314 self
._DirectiveEvalStack
= []
1315 self
._FileWithError
= self
.MetaFile
1316 self
._FileLocalMacros
= {}
1317 self
._SectionsMacroDict
.clear()
1318 GlobalData
.gPlatformDefines
= {}
1320 # Get all macro and PCD which has straitforward value
1321 self
.__RetrievePcdValue
()
1322 self
._Content
= self
._RawTable
.GetAll()
1323 self
._ContentIndex
= 0
1324 self
._InSubsection
= False
1325 while self
._ContentIndex
< len(self
._Content
) :
1326 Id
, self
._ItemType
, V1
, V2
, V3
, S1
, S2
, S3
, Owner
, self
._From
, \
1327 LineStart
, ColStart
, LineEnd
, ColEnd
, Enabled
= self
._Content
[self
._ContentIndex
]
1330 self
._FileWithError
= self
.MetaFile
1332 self
._ContentIndex
+= 1
1334 self
._Scope
= [[S1
, S2
, S3
]]
1336 # For !include directive, handle it specially,
1337 # merge arch and module type in case of duplicate items
1339 while self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1340 if self
._ContentIndex
>= len(self
._Content
):
1342 Record
= self
._Content
[self
._ContentIndex
]
1343 if LineStart
== Record
[10] and LineEnd
== Record
[12]:
1344 if [Record
[5], Record
[6], Record
[7]] not in self
._Scope
:
1345 self
._Scope
.append([Record
[5], Record
[6], Record
[7]])
1346 self
._ContentIndex
+= 1
1350 self
._LineIndex
= LineStart
- 1
1351 self
._ValueList
= [V1
, V2
, V3
]
1353 if Owner
> 0 and Owner
in self
._IdMapping
:
1354 self
._InSubsection
= True
1356 self
._InSubsection
= False
1358 Processer
[self
._ItemType
]()
1359 except EvaluationException
as Excpt
:
1361 # Only catch expression evaluation error here. We need to report
1362 # the precise number of line on which the error occurred
1364 if hasattr(Excpt
, 'Pcd'):
1365 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
1366 Info
= GlobalData
.gPlatformOtherPcds
[Excpt
.Pcd
]
1367 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
1368 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
1369 " of the DSC file, and it is currently defined in this section:"
1370 " %s, line #: %d." % (Excpt
.Pcd
, Info
[0], Info
[1]),
1371 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1372 Line
=self
._LineIndex
+ 1)
1374 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
1375 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1376 Line
=self
._LineIndex
+ 1)
1378 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
1379 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1380 Line
=self
._LineIndex
+ 1)
1381 except MacroException
as Excpt
:
1382 EdkLogger
.error('Parser', FORMAT_INVALID
, str(Excpt
),
1383 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1384 Line
=self
._LineIndex
+ 1)
1386 if self
._ValueList
is None:
1389 NewOwner
= self
._IdMapping
.get(Owner
, -1)
1390 self
._Enabled
= int((not self
._DirectiveEvalStack
) or (False not in self
._DirectiveEvalStack
))
1391 self
._LastItem
= self
._Store
(
1401 self
._LineIndex
+ 1,
1403 self
._LineIndex
+ 1,
1407 self
._IdMapping
[Id
] = self
._LastItem
1409 GlobalData
.gPlatformDefines
.update(self
._FileLocalMacros
)
1410 self
._PostProcessed
= True
1411 self
._Content
= None
1412 def _ProcessError(self
):
1413 if not self
._Enabled
:
1415 EdkLogger
.error('Parser', ERROR_STATEMENT
, self
._ValueList
[1], File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1417 def __ProcessSectionHeader(self
):
1418 self
._SectionName
= self
._ValueList
[0]
1419 if self
._SectionName
in self
.DataType
:
1420 self
._SectionType
= self
.DataType
[self
._SectionName
]
1422 self
._SectionType
= MODEL_UNKNOWN
1424 def __ProcessSubsectionHeader(self
):
1425 self
._SubsectionName
= self
._ValueList
[0]
1426 if self
._SubsectionName
in self
.DataType
:
1427 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
1429 self
._SubsectionType
= MODEL_UNKNOWN
1431 def __RetrievePcdValue(self
):
1432 Content
= open(str(self
.MetaFile
), 'r').readlines()
1433 GlobalData
.gPlatformOtherPcds
['DSCFILE'] = str(self
.MetaFile
)
1434 for PcdType
in (MODEL_PCD_PATCHABLE_IN_MODULE
, MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_HII
,
1435 MODEL_PCD_DYNAMIC_VPD
, MODEL_PCD_DYNAMIC_EX_DEFAULT
, MODEL_PCD_DYNAMIC_EX_HII
,
1436 MODEL_PCD_DYNAMIC_EX_VPD
):
1437 Records
= self
._RawTable
.Query(PcdType
, BelongsToItem
= -1.0)
1438 for TokenSpaceGuid
, PcdName
, Value
, Dummy2
, Dummy3
, Dummy4
, ID
, Line
in Records
:
1439 Name
= TokenSpaceGuid
+ '.' + PcdName
1440 if Name
not in GlobalData
.gPlatformOtherPcds
:
1442 while not Content
[Line
- 1].lstrip().startswith(TAB_SECTION_START
):
1444 GlobalData
.gPlatformOtherPcds
[Name
] = (CleanString(Content
[Line
- 1]), PcdLine
, PcdType
)
1446 def __ProcessDefine(self
):
1447 if not self
._Enabled
:
1450 Type
, Name
, Value
= self
._ValueList
1451 Value
= ReplaceMacro(Value
, self
._Macros
, False)
1453 # If it is <Defines>, return
1455 if self
._InSubsection
:
1456 self
._ValueList
= [Type
, Name
, Value
]
1459 if self
._ItemType
== MODEL_META_DATA_DEFINE
:
1460 if self
._SectionType
== MODEL_META_DATA_HEADER
:
1461 self
._FileLocalMacros
[Name
] = Value
1463 self
._ConstructSectionMacroDict
(Name
, Value
)
1464 elif self
._ItemType
== MODEL_META_DATA_GLOBAL_DEFINE
:
1465 GlobalData
.gEdkGlobal
[Name
] = Value
1468 # Keyword in [Defines] section can be used as Macros
1470 if (self
._ItemType
== MODEL_META_DATA_HEADER
) and (self
._SectionType
== MODEL_META_DATA_HEADER
):
1471 self
._FileLocalMacros
[Name
] = Value
1473 self
._ValueList
= [Type
, Name
, Value
]
1475 def __ProcessDirective(self
):
1477 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1478 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
]:
1479 Macros
= self
._Macros
1480 Macros
.update(GlobalData
.gGlobalDefines
)
1482 Result
= ValueExpression(self
._ValueList
[1], Macros
)()
1483 except SymbolNotFound
as Exc
:
1484 EdkLogger
.debug(EdkLogger
.DEBUG_5
, str(Exc
), self
._ValueList
[1])
1486 except WrnExpression
as Excpt
:
1488 # Catch expression evaluation warning here. We need to report
1489 # the precise number of line and return the evaluation result
1491 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
1492 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1493 Line
=self
._LineIndex
+ 1)
1494 Result
= Excpt
.result
1496 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1497 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1498 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1499 self
._DirectiveStack
.append(self
._ItemType
)
1500 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
:
1501 Result
= bool(Result
)
1503 Macro
= self
._ValueList
[1]
1504 Macro
= Macro
[2:-1] if (Macro
.startswith("$(") and Macro
.endswith(")")) else Macro
1505 Result
= Macro
in self
._Macros
1506 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
:
1508 self
._DirectiveEvalStack
.append(Result
)
1509 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
:
1510 self
._DirectiveStack
.append(self
._ItemType
)
1511 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1512 self
._DirectiveEvalStack
.append(bool(Result
))
1513 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1514 self
._DirectiveStack
.append(self
._ItemType
)
1515 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1516 self
._DirectiveEvalStack
.append(True)
1517 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1518 # Back to the nearest !if/!ifdef/!ifndef
1519 while self
._DirectiveStack
:
1520 self
._DirectiveEvalStack
.pop()
1521 Directive
= self
._DirectiveStack
.pop()
1522 if Directive
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1523 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1524 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1526 elif self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1527 # The included file must be relative to workspace or same directory as DSC file
1528 __IncludeMacros
= {}
1530 # Allow using system environment variables in path after !include
1532 __IncludeMacros
['WORKSPACE'] = GlobalData
.gGlobalDefines
['WORKSPACE']
1533 if "ECP_SOURCE" in GlobalData
.gGlobalDefines
:
1534 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gGlobalDefines
['ECP_SOURCE']
1536 # During GenFds phase call DSC parser, will go into this branch.
1538 elif "ECP_SOURCE" in GlobalData
.gCommandLineDefines
:
1539 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gCommandLineDefines
['ECP_SOURCE']
1541 __IncludeMacros
['EFI_SOURCE'] = GlobalData
.gGlobalDefines
['EFI_SOURCE']
1542 __IncludeMacros
['EDK_SOURCE'] = GlobalData
.gGlobalDefines
['EDK_SOURCE']
1544 # Allow using MACROs comes from [Defines] section to keep compatible.
1546 __IncludeMacros
.update(self
._Macros
)
1548 IncludedFile
= NormPath(ReplaceMacro(self
._ValueList
[1], __IncludeMacros
, RaiseError
=True))
1550 # First search the include file under the same directory as DSC file
1552 IncludedFile1
= PathClass(IncludedFile
, self
.MetaFile
.Dir
)
1553 ErrorCode
, ErrorInfo1
= IncludedFile1
.Validate()
1556 # Also search file under the WORKSPACE directory
1558 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
1559 ErrorCode
, ErrorInfo2
= IncludedFile1
.Validate()
1561 EdkLogger
.error('parser', ErrorCode
, File
=self
._FileWithError
,
1562 Line
=self
._LineIndex
+ 1, ExtraData
=ErrorInfo1
+ "\n" + ErrorInfo2
)
1564 self
._FileWithError
= IncludedFile1
1566 FromItem
= self
._Content
[self
._ContentIndex
- 1][0]
1567 if self
._InSubsection
:
1568 Owner
= self
._Content
[self
._ContentIndex
- 1][8]
1570 Owner
= self
._Content
[self
._ContentIndex
- 1][0]
1571 IncludedFileTable
= MetaFileStorage(self
._Table
.Cur
, IncludedFile1
, MODEL_FILE_DSC
, False, FromItem
=FromItem
)
1572 Parser
= DscParser(IncludedFile1
, self
._FileType
, self
._Arch
, IncludedFileTable
,
1573 Owner
=Owner
, From
=FromItem
)
1575 self
.IncludedFiles
.add (IncludedFile1
)
1577 # set the parser status with current status
1578 Parser
._SectionName
= self
._SectionName
1579 Parser
._SubsectionType
= self
._SubsectionType
1580 Parser
._InSubsection
= self
._InSubsection
1581 Parser
._SectionType
= self
._SectionType
1582 Parser
._Scope
= self
._Scope
1583 Parser
._Enabled
= self
._Enabled
1584 # Parse the included file
1588 # Insert all records in the table for the included file into dsc file table
1589 Records
= IncludedFileTable
.GetAll()
1591 self
._Content
[self
._ContentIndex
:self
._ContentIndex
] = Records
1592 self
._Content
.pop(self
._ContentIndex
- 1)
1593 self
._ValueList
= None
1594 self
._ContentIndex
-= 1
1596 def __ProcessSkuId(self
):
1597 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=True)
1598 for Value
in self
._ValueList
]
1599 def __ProcessDefaultStores(self
):
1600 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=True)
1601 for Value
in self
._ValueList
]
1603 def __ProcessLibraryInstance(self
):
1604 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
1606 def __ProcessLibraryClass(self
):
1607 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
, RaiseError
=True)
1609 def __ProcessPcd(self
):
1610 if self
._ItemType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
1611 self
._ValueList
[2] = ReplaceMacro(self
._ValueList
[2], self
._Macros
, RaiseError
=True)
1614 ValList
, Valid
, Index
= AnalyzeDscPcd(self
._ValueList
[2], self
._ItemType
)
1616 if self
._ItemType
in (MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
, MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
):
1617 if ValList
[1] != TAB_VOID
and ValList
[2]:
1618 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect. Only VOID* type PCD need the maxsize info.", File
=self
._FileWithError
,
1619 Line
=self
._LineIndex
+ 1, ExtraData
="%s.%s|%s" % (self
._ValueList
[0], self
._ValueList
[1], self
._ValueList
[2]))
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
as 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 ## DEC file parser class
1680 # @param FilePath The path of platform description file
1681 # @param FileType The raw data of DSC file
1682 # @param Table Database used to retrieve module/package information
1683 # @param Macros Macros used for replacement in file
1685 class DecParser(MetaFileParser
):
1686 # DEC file supported data types (one type per section)
1688 TAB_DEC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
1689 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
1690 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
1691 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
1692 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
1693 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
1694 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
1695 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
1696 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
1697 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
1698 TAB_PCDS_DYNAMIC_NULL
.upper() : MODEL_PCD_DYNAMIC
,
1699 TAB_PCDS_DYNAMIC_EX_NULL
.upper() : MODEL_PCD_DYNAMIC_EX
,
1700 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
,
1703 ## Constructor of DecParser
1705 # Initialize object of DecParser
1707 # @param FilePath The path of platform description file
1708 # @param FileType The raw data of DSC file
1709 # @param Arch Default Arch value for filtering sections
1710 # @param Table Database used to retrieve module/package information
1712 def __init__(self
, FilePath
, FileType
, Arch
, Table
):
1713 # prevent re-initialization
1714 if hasattr(self
, "_Table"):
1716 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
, -1)
1718 self
._Version
= 0x00010005 # Only EDK2 dec file is supported
1719 self
._AllPCDs
= [] # Only for check duplicate PCD
1720 self
._AllPcdDict
= {}
1722 self
._CurrentStructurePcdName
= ""
1723 self
._include
_flag
= False
1724 self
._package
_flag
= False
1730 Content
= open(str(self
.MetaFile
), 'r').readlines()
1732 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
1734 self
._DefinesCount
= 0
1735 for Index
in range(0, len(Content
)):
1736 Line
, Comment
= CleanString2(Content
[Index
])
1737 self
._CurrentLine
= Line
1738 self
._LineIndex
= Index
1740 # save comment for later use
1742 self
._Comments
.append((Comment
, self
._LineIndex
+ 1))
1748 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
1749 self
._SectionHeaderParser
()
1750 if self
._SectionName
== TAB_DEC_DEFINES
.upper():
1751 self
._DefinesCount
+= 1
1754 if self
._SectionType
== MODEL_UNKNOWN
:
1755 EdkLogger
.error("Parser", FORMAT_INVALID
,
1757 "Not able to determine \"%s\" in which section."%self
._CurrentLine
,
1758 self
.MetaFile
, self
._LineIndex
+ 1)
1759 elif len(self
._SectionType
) == 0:
1764 self
._ValueList
= ['', '', '']
1765 self
._SectionParser
[self
._SectionType
[0]](self
)
1766 if self
._ValueList
is None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
1772 # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,
1773 # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1
1775 for Arch
, ModuleType
, Type
in self
._Scope
:
1776 self
._LastItem
= self
._Store
(
1784 self
._LineIndex
+ 1,
1786 self
._LineIndex
+ 1,
1790 for Comment
, LineNo
in self
._Comments
:
1792 MODEL_META_DATA_COMMENT
,
1806 if self
._DefinesCount
> 1:
1807 EdkLogger
.error('Parser', FORMAT_INVALID
, 'Multiple [Defines] section is exist.', self
.MetaFile
)
1808 if self
._DefinesCount
== 0:
1809 EdkLogger
.error('Parser', FORMAT_INVALID
, 'No [Defines] section exist.', self
.MetaFile
)
1813 ## Section header parser
1815 # The section header is always in following format:
1817 # [section_name.arch<.platform|module_type>]
1819 def _SectionHeaderParser(self
):
1821 self
._SectionName
= ''
1822 self
._SectionType
= []
1825 Line
= re
.sub(',[\s]*', TAB_COMMA_SPLIT
, self
._CurrentLine
)
1826 for Item
in Line
[1:-1].split(TAB_COMMA_SPLIT
):
1828 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
,
1829 "section name can NOT be empty or incorrectly use separator comma",
1830 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1831 ItemList
= Item
.split(TAB_SPLIT
)
1833 # different types of PCD are permissible in one section
1834 self
._SectionName
= ItemList
[0].upper()
1835 if self
._SectionName
== TAB_DEC_DEFINES
.upper() and (len(ItemList
) > 1 or len(Line
.split(TAB_COMMA_SPLIT
)) > 1):
1836 EdkLogger
.error("Parser", FORMAT_INVALID
, "Defines section format is invalid",
1837 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1838 if self
._SectionName
in self
.DataType
:
1839 if self
.DataType
[self
._SectionName
] not in self
._SectionType
:
1840 self
._SectionType
.append(self
.DataType
[self
._SectionName
])
1842 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
1843 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1845 if MODEL_PCD_FEATURE_FLAG
in self
._SectionType
and len(self
._SectionType
) > 1:
1849 "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL
,
1851 Line
=self
._LineIndex
+ 1,
1852 ExtraData
=self
._CurrentLine
1855 if len(ItemList
) > 1:
1856 S1
= ItemList
[1].upper()
1858 S1
= TAB_ARCH_COMMON
1860 # S2 may be Platform or ModuleType
1861 if len(ItemList
) > 2:
1862 S2
= ItemList
[2].upper()
1863 # only Includes, GUIDs, PPIs, Protocols section have Private tag
1864 if self
._SectionName
in [TAB_INCLUDES
.upper(), TAB_GUIDS
.upper(), TAB_PROTOCOLS
.upper(), TAB_PPIS
.upper()]:
1866 EdkLogger
.error("Parser", FORMAT_INVALID
, 'Please use keyword "Private" as section tag modifier.',
1867 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1871 if [S1
, S2
, self
.DataType
[self
._SectionName
]] not in self
._Scope
:
1872 self
._Scope
.append([S1
, S2
, self
.DataType
[self
._SectionName
]])
1874 # 'COMMON' must not be used with specific ARCHs at the same section
1875 if TAB_ARCH_COMMON
in ArchList
and len(ArchList
) > 1:
1876 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
1877 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1879 # It is not permissible to mix section tags without the Private attribute with section tags with the Private attribute
1880 if TAB_COMMON
in PrivateList
and len(PrivateList
) > 1:
1881 EdkLogger
.error('Parser', FORMAT_INVALID
, "Can't mix section tags without the Private attribute with section tags with the Private attribute",
1882 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1884 ## [guids], [ppis] and [protocols] section parser
1886 def _GuidParser(self
):
1887 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1888 if len(TokenList
) < 2:
1889 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name or value specified",
1890 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1891 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1892 if TokenList
[0] == '':
1893 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name specified",
1894 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1895 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1896 if TokenList
[1] == '':
1897 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID value specified",
1898 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1899 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1900 if TokenList
[1][0] != '{' or TokenList
[1][-1] != '}' or GuidStructureStringToGuidString(TokenList
[1]) == '':
1901 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid GUID value format",
1902 ExtraData
=self
._CurrentLine
+ \
1903 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
1904 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1905 self
._ValueList
[0] = TokenList
[0]
1906 self
._ValueList
[1] = TokenList
[1]
1907 if self
._ValueList
[0] not in self
._GuidDict
:
1908 self
._GuidDict
[self
._ValueList
[0]] = self
._ValueList
[1]
1910 ## PCD sections parser
1912 # [PcdsFixedAtBuild]
1913 # [PcdsPatchableInModule]
1919 def _PcdParser(self
):
1920 if self
._CurrentStructurePcdName
:
1921 self
._ValueList
[0] = self
._CurrentStructurePcdName
1923 if "|" not in self
._CurrentLine
:
1924 if "<HeaderFiles>" == self
._CurrentLine
:
1925 self
._include
_flag
= True
1926 self
._package
_flag
= False
1927 self
._ValueList
= None
1929 if "<Packages>" == self
._CurrentLine
:
1930 self
._package
_flag
= True
1931 self
._ValueList
= None
1932 self
._include
_flag
= False
1935 if self
._include
_flag
:
1936 self
._ValueList
[1] = "<HeaderFiles>_" + md5(self
._CurrentLine
).hexdigest()
1937 self
._ValueList
[2] = self
._CurrentLine
1938 if self
._package
_flag
and "}" != self
._CurrentLine
:
1939 self
._ValueList
[1] = "<Packages>_" + md5(self
._CurrentLine
).hexdigest()
1940 self
._ValueList
[2] = self
._CurrentLine
1941 if self
._CurrentLine
== "}":
1942 self
._package
_flag
= False
1943 self
._include
_flag
= False
1944 self
._ValueList
= None
1947 PcdTockens
= self
._CurrentLine
.split(TAB_VALUE_SPLIT
)
1948 PcdNames
= PcdTockens
[0].split(TAB_SPLIT
)
1949 if len(PcdNames
) == 2:
1950 self
._CurrentStructurePcdName
= ""
1952 if self
._CurrentStructurePcdName
!= TAB_SPLIT
.join(PcdNames
[:2]):
1953 EdkLogger
.error('Parser', FORMAT_INVALID
, "Pcd Name does not match: %s and %s " % (self
._CurrentStructurePcdName
, TAB_SPLIT
.join(PcdNames
[:2])),
1954 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1955 self
._ValueList
[1] = TAB_SPLIT
.join(PcdNames
[2:])
1956 self
._ValueList
[2] = PcdTockens
[1]
1957 if not self
._CurrentStructurePcdName
:
1958 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1959 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1960 ValueRe
= re
.compile(r
'^[a-zA-Z_][a-zA-Z0-9_]*')
1961 # check PCD information
1962 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1963 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1964 ExtraData
=self
._CurrentLine
+ \
1965 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1966 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1967 # check format of token space GUID CName
1968 if not ValueRe
.match(self
._ValueList
[0]):
1969 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_]*'",
1970 ExtraData
=self
._CurrentLine
+ \
1971 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1972 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1973 # check format of PCD CName
1974 if not ValueRe
.match(self
._ValueList
[1]):
1975 EdkLogger
.error('Parser', FORMAT_INVALID
, "The format of the PCD CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",
1976 ExtraData
=self
._CurrentLine
+ \
1977 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1978 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1979 # check PCD datum information
1980 if len(TokenList
) < 2 or TokenList
[1] == '':
1981 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD Datum information given",
1982 ExtraData
=self
._CurrentLine
+ \
1983 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1984 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1987 ValueRe
= re
.compile(r
'^\s*L?\".*\|.*\"')
1988 PtrValue
= ValueRe
.findall(TokenList
[1])
1990 # Has VOID* type string, may contain "|" character in the string.
1991 if len(PtrValue
) != 0:
1992 ptrValueList
= re
.sub(ValueRe
, '', TokenList
[1])
1993 ValueList
= AnalyzePcdExpression(ptrValueList
)
1994 ValueList
[0] = PtrValue
[0]
1996 ValueList
= AnalyzePcdExpression(TokenList
[1])
1999 # check if there's enough datum information given
2000 if len(ValueList
) != 3:
2001 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid PCD Datum information given",
2002 ExtraData
=self
._CurrentLine
+ \
2003 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2004 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2005 # check default value
2006 if ValueList
[0] == '':
2007 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DefaultValue in PCD Datum information",
2008 ExtraData
=self
._CurrentLine
+ \
2009 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2010 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2012 if ValueList
[1] == '':
2013 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DatumType in PCD Datum information",
2014 ExtraData
=self
._CurrentLine
+ \
2015 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2016 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2017 # check token of the PCD
2018 if ValueList
[2] == '':
2019 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing Token in PCD Datum information",
2020 ExtraData
=self
._CurrentLine
+ \
2021 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2022 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2024 PcdValue
= ValueList
[0]
2027 self
._GuidDict
.update(self
._AllPcdDict
)
2028 ValueList
[0] = ValueExpressionEx(ValueList
[0], ValueList
[1], self
._GuidDict
)(True)
2029 except BadExpression
as Value
:
2030 EdkLogger
.error('Parser', FORMAT_INVALID
, Value
, ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2031 # check format of default value against the datum type
2032 IsValid
, Cause
= CheckPcdDatum(ValueList
[1], ValueList
[0])
2034 EdkLogger
.error('Parser', FORMAT_INVALID
, Cause
, ExtraData
=self
._CurrentLine
,
2035 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2037 if Cause
== "StructurePcd":
2038 self
._CurrentStructurePcdName
= TAB_SPLIT
.join(self
._ValueList
[0:2])
2039 self
._ValueList
[0] = self
._CurrentStructurePcdName
2040 self
._ValueList
[1] = ValueList
[1].strip()
2042 if ValueList
[0] in ['True', 'true', 'TRUE']:
2044 elif ValueList
[0] in ['False', 'false', 'FALSE']:
2047 # check for duplicate PCD definition
2048 if (self
._Scope
[0], self
._ValueList
[0], self
._ValueList
[1]) in self
._AllPCDs
:
2049 EdkLogger
.error('Parser', FORMAT_INVALID
,
2050 "The same PCD name and GUID have been already defined",
2051 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2053 self
._AllPCDs
.append((self
._Scope
[0], self
._ValueList
[0], self
._ValueList
[1]))
2054 self
._AllPcdDict
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = ValueList
[0]
2056 self
._ValueList
[2] = ValueList
[0].strip() + '|' + ValueList
[1].strip() + '|' + ValueList
[2].strip()
2059 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
2060 MODEL_EFI_INCLUDE
: MetaFileParser
._PathParser
,
2061 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
2062 MODEL_EFI_GUID
: _GuidParser
,
2063 MODEL_EFI_PPI
: _GuidParser
,
2064 MODEL_EFI_PROTOCOL
: _GuidParser
,
2065 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
2066 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
2067 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
2068 MODEL_PCD_DYNAMIC
: _PcdParser
,
2069 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
2070 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
2071 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
2076 # This acts like the main() function for the script, unless it is 'import'ed into another
2079 if __name__
== '__main__':