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
, StructPattern
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+')
43 CODEPattern
= re
.compile(r
"{CODE\([a-fA-F0-9Xx\{\},\s]*\)}")
45 ## A decorator used to parse macro definition
46 def ParseMacro(Parser
):
47 def MacroParser(self
):
48 Match
= gMacroDefPattern
.match(self
._CurrentLine
)
50 # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method
54 TokenList
= GetSplitValueList(self
._CurrentLine
[Match
.end(1):], TAB_EQUAL_SPLIT
, 1)
57 EdkLogger
.error('Parser', FORMAT_INVALID
, "No macro name given",
58 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
59 if len(TokenList
) < 2:
63 Name
, Value
= TokenList
64 # Global macros can be only defined via environment variable
65 if Name
in GlobalData
.gGlobalDefines
:
66 EdkLogger
.error('Parser', FORMAT_INVALID
, "%s can only be defined via environment variable" % Name
,
67 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
68 # Only upper case letters, digit and '_' are allowed
69 if not gMacroNamePattern
.match(Name
):
70 EdkLogger
.error('Parser', FORMAT_INVALID
, "The macro name must be in the pattern [A-Z][A-Z0-9_]*",
71 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
73 Value
= ReplaceMacro(Value
, self
._Macros
)
74 if Type
in self
.DataType
:
75 self
._ItemType
= self
.DataType
[Type
]
77 self
._ItemType
= MODEL_META_DATA_DEFINE
78 # DEFINE defined macros
79 if Type
== TAB_DSC_DEFINES_DEFINE
:
81 # First judge whether this DEFINE is in conditional directive statements or not.
83 if isinstance(self
, DscParser
) and self
._InDirective
> -1:
86 if isinstance(self
, DecParser
):
87 if MODEL_META_DATA_HEADER
in self
._SectionType
:
88 self
._FileLocalMacros
[Name
] = Value
90 self
._ConstructSectionMacroDict
(Name
, Value
)
91 elif self
._SectionType
== MODEL_META_DATA_HEADER
:
92 self
._FileLocalMacros
[Name
] = Value
94 self
._ConstructSectionMacroDict
(Name
, Value
)
96 # EDK_GLOBAL defined macros
97 elif not isinstance(self
, DscParser
):
98 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL can only be used in .dsc file",
99 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
100 elif self
._SectionType
!= MODEL_META_DATA_HEADER
:
101 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL can only be used under [Defines] section",
102 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
103 elif (Name
in self
._FileLocalMacros
) and (self
._FileLocalMacros
[Name
] != Value
):
104 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL defined a macro with the same name and different value as one defined by 'DEFINE'",
105 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
107 self
._ValueList
= [Type
, Name
, Value
]
111 ## Base class of parser
113 # This class is used for derivation purpose. The specific parser for one kind
114 # type file must derive this class and implement some public interfaces.
116 # @param FilePath The path of platform description file
117 # @param FileType The raw data of DSC file
118 # @param Table Database used to retrieve module/package information
119 # @param Macros Macros used for replacement in file
120 # @param Owner Owner ID (for sub-section parsing)
121 # @param From ID from which the data comes (for !INCLUDE directive)
123 class MetaFileParser(object):
124 # data type (file content) for specific file type
127 # Parser objects used to implement singleton
132 # One file, one parser object. This factory method makes sure that there's
133 # only one object constructed for one meta file.
135 # @param Class class object of real AutoGen class
136 # (InfParser, DecParser or DscParser)
137 # @param FilePath The path of meta file
138 # @param *args The specific class related parameters
139 # @param **kwargs The specific class related dict parameters
141 def __new__(Class
, FilePath
, *args
, **kwargs
):
142 if FilePath
in Class
.MetaFiles
:
143 return Class
.MetaFiles
[FilePath
]
145 ParserObject
= super(MetaFileParser
, Class
).__new
__(Class
)
146 Class
.MetaFiles
[FilePath
] = ParserObject
149 ## Constructor of MetaFileParser
151 # Initialize object of MetaFileParser
153 # @param FilePath The path of platform description file
154 # @param FileType The raw data of DSC file
155 # @param Arch Default Arch value for filtering sections
156 # @param Table Database used to retrieve module/package information
157 # @param Owner Owner ID (for sub-section parsing)
158 # @param From ID from which the data comes (for !INCLUDE directive)
160 def __init__(self
, FilePath
, FileType
, Arch
, Table
, Owner
= -1, From
= -1):
162 self
._RawTable
= Table
164 self
._FileType
= FileType
165 self
.MetaFile
= FilePath
166 self
._FileDir
= self
.MetaFile
.Dir
168 self
._FileLocalMacros
= {}
169 self
._SectionsMacroDict
= defaultdict(dict)
171 # for recursive parsing
172 self
._Owner
= [Owner
]
175 # parsr status for parsing
176 self
._ValueList
= ['', '', '', '', '']
179 self
._CurrentLine
= ''
180 self
._SectionType
= MODEL_UNKNOWN
181 self
._SectionName
= ''
182 self
._InSubsection
= False
183 self
._SubsectionType
= MODEL_UNKNOWN
184 self
._SubsectionName
= ''
185 self
._ItemType
= MODEL_UNKNOWN
188 self
._Finished
= False
189 self
._PostProcessed
= False
190 # Different version of meta-file has different way to parse.
192 self
._GuidDict
= {} # for Parser PCD value {GUID(gTokeSpaceGuidName)}
194 ## Store the parsed data in table
195 def _Store(self
, *Args
):
196 return self
._Table
.Insert(*Args
)
198 ## Virtual method for starting parse
200 raise NotImplementedError
202 ## Notify a post-process is needed
203 def DoPostProcess(self
):
204 self
._PostProcessed
= False
206 ## Set parsing complete flag in both class and table
208 self
._Finished
= True
209 ## Do not set end flag when processing included files
211 self
._Table
.SetEndFlag()
213 def _PostProcess(self
):
214 self
._PostProcessed
= True
216 ## Get the parse complete flag
219 return self
._Finished
221 ## Set the complete flag
223 def Finished(self
, Value
):
224 self
._Finished
= Value
226 ## Remove records that do not match given Filter Arch
227 def _FilterRecordList(self
, RecordList
, FilterArch
):
229 for Record
in RecordList
:
231 if Arch
== TAB_ARCH_COMMON
or Arch
== FilterArch
:
232 NewRecordList
.append(Record
)
235 ## Use [] style to query data in table, just for readability
237 # DataInfo = [data_type, scope1(arch), scope2(platform/moduletype)]
239 def __getitem__(self
, DataInfo
):
240 if not isinstance(DataInfo
, type(())):
241 DataInfo
= (DataInfo
,)
243 # Parse the file first, if necessary
244 if not self
._Finished
:
245 if self
._RawTable
.IsIntegrity():
246 self
._Finished
= True
248 self
._Table
= self
._RawTable
249 self
._PostProcessed
= False
252 # No specific ARCH or Platform given, use raw data
253 if self
._RawTable
and (len(DataInfo
) == 1 or DataInfo
[1] is None):
254 return self
._FilterRecordList
(self
._RawTable
.Query(*DataInfo
), self
._Arch
)
256 # Do post-process if necessary
257 if not self
._PostProcessed
:
260 return self
._FilterRecordList
(self
._Table
.Query(*DataInfo
), DataInfo
[1])
262 ## Data parser for the common format in different type of file
264 # The common format in the meatfile is like
269 def _CommonParser(self
):
270 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
271 self
._ValueList
[0:len(TokenList
)] = TokenList
273 ## Data parser for the format in which there's path
275 # Only path can have macro used. So we need to replace them before use.
278 def _PathParser(self
):
279 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
280 self
._ValueList
[0:len(TokenList
)] = TokenList
281 # Don't do macro replacement for dsc file at this point
282 if not isinstance(self
, DscParser
):
283 Macros
= self
._Macros
284 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
286 ## Skip unsupported data
288 EdkLogger
.warn("Parser", "Unrecognized content", File
=self
.MetaFile
,
289 Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
);
290 self
._ValueList
[0:1] = [self
._CurrentLine
]
292 ## Skip unsupported data for UserExtension Section
293 def _SkipUserExtension(self
):
294 self
._ValueList
[0:1] = [self
._CurrentLine
]
296 ## Section header parser
298 # The section header is always in following format:
300 # [section_name.arch<.platform|module_type>]
302 def _SectionHeaderParser(self
):
304 self
._SectionName
= ''
306 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
309 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
, 3)
310 # different section should not mix in one section
311 if self
._SectionName
!= '' and self
._SectionName
!= ItemList
[0].upper():
312 EdkLogger
.error('Parser', FORMAT_INVALID
, "Different section names in the same section",
313 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
314 self
._SectionName
= ItemList
[0].upper()
315 if self
._SectionName
in self
.DataType
:
316 self
._SectionType
= self
.DataType
[self
._SectionName
]
317 # Check if the section name is valid
318 if self
._SectionName
not in SECTIONS_HAVE_ITEM_AFTER_ARCH_SET
and len(ItemList
) > 3:
319 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
320 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
321 elif self
._Version
>= 0x00010005:
322 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
323 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
325 self
._SectionType
= MODEL_UNKNOWN
328 if len(ItemList
) > 1:
329 S1
= ItemList
[1].upper()
334 # S2 may be Platform or ModuleType
335 if len(ItemList
) > 2:
336 if self
._SectionName
.upper() in SECTIONS_HAVE_ITEM_PCD_SET
:
339 S2
= ItemList
[2].upper()
342 if len(ItemList
) > 3:
346 self
._Scope
.append([S1
, S2
, S3
])
348 # 'COMMON' must not be used with specific ARCHs at the same section
349 if TAB_ARCH_COMMON
in ArchList
and len(ArchList
) > 1:
350 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
351 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
352 # If the section information is needed later, it should be stored in database
353 self
._ValueList
[0] = self
._SectionName
355 ## [defines] section parser
357 def _DefineParser(self
):
358 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
359 self
._ValueList
[1:len(TokenList
)] = TokenList
360 if not self
._ValueList
[1]:
361 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
362 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
363 if not self
._ValueList
[2]:
364 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
365 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
367 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
368 Name
, Value
= self
._ValueList
[1], self
._ValueList
[2]
369 MacroUsed
= GlobalData
.gMacroRefPattern
.findall(Value
)
370 if len(MacroUsed
) != 0:
371 for Macro
in MacroUsed
:
372 if Macro
in GlobalData
.gGlobalDefines
:
373 EdkLogger
.error("Parser", FORMAT_INVALID
, "Global macro %s is not permitted." % (Macro
), ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
375 EdkLogger
.error("Parser", FORMAT_INVALID
, "%s not defined" % (Macro
), ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
376 # Sometimes, we need to make differences between EDK and EDK2 modules
377 if Name
== 'INF_VERSION':
378 if hexVersionPattern
.match(Value
):
379 self
._Version
= int(Value
, 0)
380 elif decVersionPattern
.match(Value
):
381 ValueList
= Value
.split('.')
382 Major
= int(ValueList
[0], 0)
383 Minor
= int(ValueList
[1], 0)
384 if Major
> 0xffff or Minor
> 0xffff:
385 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid version number",
386 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
387 self
._Version
= int('0x{0:04x}{1:04x}'.format(Major
, Minor
), 0)
389 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid version number",
390 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
392 if isinstance(self
, InfParser
) and self
._Version
< 0x00010005:
393 # EDK module allows using defines as macros
394 self
._FileLocalMacros
[Name
] = Value
395 self
._Defines
[Name
] = Value
397 ## [BuildOptions] section parser
399 def _BuildOptionParser(self
):
400 self
._CurrentLine
= CleanString(self
._CurrentLine
, BuildOption
=True)
401 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
402 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
403 if len(TokenList2
) == 2:
404 self
._ValueList
[0] = TokenList2
[0] # toolchain family
405 self
._ValueList
[1] = TokenList2
[1] # keys
407 self
._ValueList
[1] = TokenList
[0]
408 if len(TokenList
) == 2 and not isinstance(self
, DscParser
): # value
409 self
._ValueList
[2] = ReplaceMacro(TokenList
[1], self
._Macros
)
411 if self
._ValueList
[1].count('_') != 4:
415 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
416 ExtraData
=self
._CurrentLine
,
418 Line
=self
._LineIndex
+ 1
420 def GetValidExpression(self
, TokenSpaceGuid
, PcdCName
):
421 return self
._Table
.GetValidExpression(TokenSpaceGuid
, PcdCName
)
426 Macros
.update(self
._FileLocalMacros
)
427 Macros
.update(self
._GetApplicableSectionMacro
())
430 ## Construct section Macro dict
431 def _ConstructSectionMacroDict(self
, Name
, Value
):
432 ScopeKey
= [(Scope
[0], Scope
[1], Scope
[2]) for Scope
in self
._Scope
]
433 ScopeKey
= tuple(ScopeKey
)
435 # DecParser SectionType is a list, will contain more than one item only in Pcd Section
436 # As Pcd section macro usage is not alllowed, so here it is safe
438 if isinstance(self
, DecParser
):
439 SectionDictKey
= self
._SectionType
[0], ScopeKey
441 SectionDictKey
= self
._SectionType
, ScopeKey
443 self
._SectionsMacroDict
[SectionDictKey
][Name
] = Value
445 ## Get section Macros that are applicable to current line, which may come from other sections
446 ## that share the same name while scope is wider
447 def _GetApplicableSectionMacro(self
):
454 ActiveSectionType
= self
._SectionType
455 if isinstance(self
, DecParser
):
456 ActiveSectionType
= self
._SectionType
[0]
458 for (SectionType
, Scope
) in self
._SectionsMacroDict
:
459 if SectionType
!= ActiveSectionType
:
462 for ActiveScope
in self
._Scope
:
463 Scope0
, Scope1
, Scope2
= ActiveScope
[0], ActiveScope
[1], ActiveScope
[2]
464 if(Scope0
, Scope1
, Scope2
) not in Scope
:
467 SpeSpeMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
469 for ActiveScope
in self
._Scope
:
470 Scope0
, Scope1
, Scope2
= ActiveScope
[0], ActiveScope
[1], ActiveScope
[2]
471 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
:
474 ComSpeMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
476 if (TAB_COMMON
, TAB_COMMON
, TAB_COMMON
) in Scope
:
477 ComComMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
479 Macros
.update(ComComMacroDict
)
480 Macros
.update(ComSpeMacroDict
)
481 Macros
.update(SpeSpeMacroDict
)
487 ## INF file parser class
489 # @param FilePath The path of platform description file
490 # @param FileType The raw data of DSC file
491 # @param Table Database used to retrieve module/package information
492 # @param Macros Macros used for replacement in file
494 class InfParser(MetaFileParser
):
495 # INF file supported data types (one type per section)
497 TAB_UNKNOWN
.upper() : MODEL_UNKNOWN
,
498 TAB_INF_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
499 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
500 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
501 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
502 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
503 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
504 TAB_PACKAGES
.upper() : MODEL_META_DATA_PACKAGE
,
505 TAB_NMAKE
.upper() : MODEL_META_DATA_NMAKE
,
506 TAB_INF_FIXED_PCD
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
507 TAB_INF_PATCH_PCD
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
508 TAB_INF_FEATURE_PCD
.upper() : MODEL_PCD_FEATURE_FLAG
,
509 TAB_INF_PCD_EX
.upper() : MODEL_PCD_DYNAMIC_EX
,
510 TAB_INF_PCD
.upper() : MODEL_PCD_DYNAMIC
,
511 TAB_SOURCES
.upper() : MODEL_EFI_SOURCE_FILE
,
512 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
513 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
514 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
515 TAB_DEPEX
.upper() : MODEL_EFI_DEPEX
,
516 TAB_BINARIES
.upper() : MODEL_EFI_BINARY_FILE
,
517 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
520 ## Constructor of InfParser
522 # Initialize object of InfParser
524 # @param FilePath The path of module description file
525 # @param FileType The raw data of DSC file
526 # @param Arch Default Arch value for filtering sections
527 # @param Table Database used to retrieve module/package information
529 def __init__(self
, FilePath
, FileType
, Arch
, Table
):
530 # prevent re-initialization
531 if hasattr(self
, "_Table"):
533 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
)
541 Content
= open(str(self
.MetaFile
), 'r').readlines()
543 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
545 # parse the file line by line
546 IsFindBlockComment
= False
547 GetHeaderComment
= False
552 for Index
in range(0, len(Content
)):
553 # skip empty, commented, block commented lines
554 Line
, Comment
= CleanString2(Content
[Index
], AllowCppStyleComment
=True)
556 if Index
+ 1 < len(Content
):
557 NextLine
, NextComment
= CleanString2(Content
[Index
+ 1])
560 Comments
.append((Comment
, Index
+ 1))
561 elif GetHeaderComment
:
562 SectionComments
.extend(Comments
)
565 if Line
.find(DataType
.TAB_COMMENT_EDK_START
) > -1:
566 IsFindBlockComment
= True
568 if Line
.find(DataType
.TAB_COMMENT_EDK_END
) > -1:
569 IsFindBlockComment
= False
571 if IsFindBlockComment
:
574 self
._LineIndex
= Index
575 self
._CurrentLine
= Line
578 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
579 if not GetHeaderComment
:
580 for Cmt
, LNo
in Comments
:
581 self
._Store
(MODEL_META_DATA_HEADER_COMMENT
, Cmt
, '', '', TAB_COMMON
,
582 TAB_COMMON
, self
._Owner
[-1], LNo
, -1, LNo
, -1, 0)
583 GetHeaderComment
= True
585 TailComments
.extend(SectionComments
+ Comments
)
587 self
._SectionHeaderParser
()
588 # Check invalid sections
589 if self
._Version
< 0x00010005:
590 if self
._SectionType
in [MODEL_META_DATA_BUILD_OPTION
,
591 MODEL_EFI_LIBRARY_CLASS
,
592 MODEL_META_DATA_PACKAGE
,
593 MODEL_PCD_FIXED_AT_BUILD
,
594 MODEL_PCD_PATCHABLE_IN_MODULE
,
595 MODEL_PCD_FEATURE_FLAG
,
596 MODEL_PCD_DYNAMIC_EX
,
601 MODEL_META_DATA_USER_EXTENSION
]:
602 EdkLogger
.error('Parser', FORMAT_INVALID
,
603 "Section [%s] is not allowed in inf file without version" % (self
._SectionName
),
604 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
605 elif self
._SectionType
in [MODEL_EFI_INCLUDE
,
606 MODEL_EFI_LIBRARY_INSTANCE
,
607 MODEL_META_DATA_NMAKE
]:
608 EdkLogger
.error('Parser', FORMAT_INVALID
,
609 "Section [%s] is not allowed in inf file with version 0x%08x" % (self
._SectionName
, self
._Version
),
610 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
612 # merge two lines specified by '\' in section NMAKE
613 elif self
._SectionType
== MODEL_META_DATA_NMAKE
:
616 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
619 if NextLine
[0] == TAB_SECTION_START
and NextLine
[-1] == TAB_SECTION_END
:
620 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
623 NmakeLine
= NmakeLine
+ ' ' + Line
[0:-1]
626 self
._CurrentLine
= NmakeLine
+ Line
630 self
._ValueList
= ['', '', '']
631 # parse current line, result will be put in self._ValueList
632 self
._SectionParser
[self
._SectionType
](self
)
633 if self
._ValueList
is None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
638 Comments
.append((Comment
, Index
+ 1))
639 if GlobalData
.gOptions
and GlobalData
.gOptions
.CheckUsage
:
640 CheckInfComment(self
._SectionType
, Comments
, str(self
.MetaFile
), Index
+ 1, self
._ValueList
)
642 # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
643 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
645 for Arch
, Platform
, _
in self
._Scope
:
646 LastItem
= self
._Store
(self
._SectionType
,
659 for Comment
, LineNo
in Comments
:
660 self
._Store
(MODEL_META_DATA_COMMENT
, Comment
, '', '', Arch
, Platform
,
661 LastItem
, LineNo
, -1, LineNo
, -1, 0)
664 TailComments
.extend(SectionComments
+ Comments
)
665 if IsFindBlockComment
:
666 EdkLogger
.error("Parser", FORMAT_INVALID
, "Open block comments (starting with /*) are expected to end with */",
669 # If there are tail comments in INF file, save to database whatever the comments are
670 for Comment
in TailComments
:
671 self
._Store
(MODEL_META_DATA_TAIL_COMMENT
, Comment
[0], '', '', TAB_COMMON
,
672 TAB_COMMON
, self
._Owner
[-1], -1, -1, -1, -1, 0)
675 ## Data parser for the format in which there's path
677 # Only path can have macro used. So we need to replace them before use.
679 def _IncludeParser(self
):
680 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
681 self
._ValueList
[0:len(TokenList
)] = TokenList
682 Macros
= self
._Macros
684 for Index
in range(0, len(self
._ValueList
)):
685 Value
= self
._ValueList
[Index
]
689 if Value
.upper().find('$(EFI_SOURCE)\Edk'.upper()) > -1 or Value
.upper().find('$(EFI_SOURCE)/Edk'.upper()) > -1:
690 Value
= '$(EDK_SOURCE)' + Value
[17:]
691 if Value
.find('$(EFI_SOURCE)') > -1 or Value
.find('$(EDK_SOURCE)') > -1:
693 elif Value
.startswith('.'):
695 elif Value
.startswith('$('):
698 Value
= '$(EFI_SOURCE)/' + Value
700 self
._ValueList
[Index
] = ReplaceMacro(Value
, Macros
)
702 ## Parse [Sources] section
704 # Only path can have macro used. So we need to replace them before use.
707 def _SourceFileParser(self
):
708 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
709 self
._ValueList
[0:len(TokenList
)] = TokenList
710 Macros
= self
._Macros
711 # For Acpi tables, remove macro like ' TABLE_NAME=Sata1'
712 if 'COMPONENT_TYPE' in Macros
:
713 if self
._Defines
['COMPONENT_TYPE'].upper() == 'ACPITABLE':
714 self
._ValueList
[0] = GetSplitValueList(self
._ValueList
[0], ' ', 1)[0]
715 if self
._Defines
['BASE_NAME'] == 'Microcode':
717 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
719 ## Parse [Binaries] section
721 # Only path can have macro used. So we need to replace them before use.
724 def _BinaryFileParser(self
):
725 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 2)
726 if len(TokenList
) < 2:
727 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type or path specified",
728 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
729 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
731 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type specified",
732 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
733 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
735 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file path specified",
736 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
737 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
738 self
._ValueList
[0:len(TokenList
)] = TokenList
739 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
741 ## [nmake] section parser (Edk.x style only)
742 def _NmakeParser(self
):
743 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
744 self
._ValueList
[0:len(TokenList
)] = TokenList
746 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
747 # remove self-reference in macro setting
748 #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
750 ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
752 def _PcdParser(self
):
753 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
754 ValueList
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
755 if len(ValueList
) != 2:
756 EdkLogger
.error('Parser', FORMAT_INVALID
, "Illegal token space GUID and PCD name format",
757 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
758 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
759 self
._ValueList
[0:1] = ValueList
760 if len(TokenList
) > 1:
761 self
._ValueList
[2] = TokenList
[1]
762 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
763 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
764 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
765 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
767 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
768 if self
._ValueList
[2] != '':
769 InfPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
770 if InfPcdValueList
[0] in ['True', 'true', 'TRUE']:
771 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '1', 1);
772 elif InfPcdValueList
[0] in ['False', 'false', 'FALSE']:
773 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '0', 1);
774 if (self
._ValueList
[0], self
._ValueList
[1]) not in self
.PcdsDict
:
775 self
.PcdsDict
[self
._ValueList
[0], self
._ValueList
[1]] = self
._SectionType
776 elif self
.PcdsDict
[self
._ValueList
[0], self
._ValueList
[1]] != self
._SectionType
:
777 EdkLogger
.error('Parser', FORMAT_INVALID
, "It is not permissible to list a specified PCD in different PCD type sections.",
778 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
779 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
781 ## [depex] section parser
783 def _DepexParser(self
):
784 self
._ValueList
[0:1] = [self
._CurrentLine
]
787 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
788 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
789 MODEL_META_DATA_BUILD_OPTION
: MetaFileParser
._BuildOptionParser
,
790 MODEL_EFI_INCLUDE
: _IncludeParser
, # for Edk.x modules
791 MODEL_EFI_LIBRARY_INSTANCE
: MetaFileParser
._CommonParser
, # for Edk.x modules
792 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
793 MODEL_META_DATA_PACKAGE
: MetaFileParser
._PathParser
,
794 MODEL_META_DATA_NMAKE
: _NmakeParser
, # for Edk.x modules
795 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
796 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
797 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
798 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
799 MODEL_PCD_DYNAMIC
: _PcdParser
,
800 MODEL_EFI_SOURCE_FILE
: _SourceFileParser
,
801 MODEL_EFI_GUID
: MetaFileParser
._CommonParser
,
802 MODEL_EFI_PROTOCOL
: MetaFileParser
._CommonParser
,
803 MODEL_EFI_PPI
: MetaFileParser
._CommonParser
,
804 MODEL_EFI_DEPEX
: _DepexParser
,
805 MODEL_EFI_BINARY_FILE
: _BinaryFileParser
,
806 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
809 ## DSC file parser class
811 # @param FilePath The path of platform description file
812 # @param FileType The raw data of DSC file
813 # @param Table Database used to retrieve module/package information
814 # @param Macros Macros used for replacement in file
815 # @param Owner Owner ID (for sub-section parsing)
816 # @param From ID from which the data comes (for !INCLUDE directive)
818 class DscParser(MetaFileParser
):
819 # DSC file supported data types (one type per section)
821 TAB_SKUIDS
.upper() : MODEL_EFI_SKU_ID
,
822 TAB_DEFAULT_STORES
.upper() : MODEL_EFI_DEFAULT_STORES
,
823 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
824 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
825 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
826 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
827 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
828 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
829 TAB_PCDS_DYNAMIC_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_DEFAULT
,
830 TAB_PCDS_DYNAMIC_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_HII
,
831 TAB_PCDS_DYNAMIC_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_VPD
,
832 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT
,
833 TAB_PCDS_DYNAMIC_EX_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_HII
,
834 TAB_PCDS_DYNAMIC_EX_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_VPD
,
835 TAB_COMPONENTS
.upper() : MODEL_META_DATA_COMPONENT
,
836 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
.upper() : MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
,
837 TAB_DSC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
838 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
839 TAB_DSC_DEFINES_EDKGLOBAL
: MODEL_META_DATA_GLOBAL_DEFINE
,
840 TAB_INCLUDE
.upper() : MODEL_META_DATA_INCLUDE
,
841 TAB_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
842 TAB_IF_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
843 TAB_IF_N_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
,
844 TAB_ELSE_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
,
845 TAB_ELSE
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
,
846 TAB_END_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
,
847 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
,
848 TAB_ERROR
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR
,
851 # Valid names in define section
858 "PCD_INFO_GENERATION",
859 "PCD_VAR_CHECK_GENERATION",
860 "SUPPORTED_ARCHITECTURES",
869 "FIX_LOAD_TOP_MEMORY_ADDRESS",
874 SubSectionDefineKeywords
= [
878 SymbolPattern
= ValueExpression
.SymbolPattern
880 IncludedFiles
= set()
882 ## Constructor of DscParser
884 # Initialize object of DscParser
886 # @param FilePath The path of platform description file
887 # @param FileType The raw data of DSC file
888 # @param Arch Default Arch value for filtering sections
889 # @param Table Database used to retrieve module/package information
890 # @param Owner Owner ID (for sub-section parsing)
891 # @param From ID from which the data comes (for !INCLUDE directive)
893 def __init__(self
, FilePath
, FileType
, Arch
, Table
, Owner
= -1, From
= -1):
894 # prevent re-initialization
895 if hasattr(self
, "_Table") and self
._Table
is Table
:
897 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
, Owner
, From
)
898 self
._Version
= 0x00010005 # Only EDK2 dsc file is supported
899 # to store conditional directive evaluation result
900 self
._DirectiveStack
= []
901 self
._DirectiveEvalStack
= []
905 # Specify whether current line is in uncertain condition
907 self
._InDirective
= -1
909 # Final valid replacable symbols
912 # Map the ID between the original table and new table to track
915 self
._IdMapping
= {-1:-1}
917 self
._PcdCodeValue
= ""
918 self
._PcdDataTypeCODE
= False
919 self
._CurrentPcdName
= ""
925 Content
= open(str(self
.MetaFile
), 'r').readlines()
927 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
931 Content
= self
.ProcessMultipleLineCODEValue(Content
)
933 for Index
in range(0, len(Content
)):
934 Line
= CleanString(Content
[Index
])
939 self
._CurrentLine
= Line
940 self
._LineIndex
= Index
941 if self
._InSubsection
and self
._Owner
[-1] == -1:
942 self
._Owner
.append(self
._LastItem
)
945 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
946 self
._SectionType
= MODEL_META_DATA_SECTION_HEADER
948 elif Line
[0] == '}' and self
._InSubsection
:
949 self
._InSubsection
= False
950 self
._SubsectionType
= MODEL_UNKNOWN
951 self
._SubsectionName
= ''
956 elif Line
[0] == TAB_OPTION_START
and Line
[-1] == TAB_OPTION_END
:
957 self
._SubsectionType
= MODEL_META_DATA_SUBSECTION_HEADER
960 TokenList
= GetSplitValueList(Line
, ' ', 1)
961 if TokenList
[0] == TAB_INCLUDE
:
962 for Arch
, ModuleType
, DefaultStore
in self
._Scope
:
963 if self
._SubsectionType
!= MODEL_UNKNOWN
and Arch
in OwnerId
:
964 self
._Owner
[-1] = OwnerId
[Arch
]
965 self
._DirectiveParser
()
967 self
._DirectiveParser
()
969 if Line
[0] == TAB_OPTION_START
and not self
._InSubsection
:
970 EdkLogger
.error("Parser", FILE_READ_FAILURE
, "Missing the '{' before %s in Line %s" % (Line
, Index
+1), ExtraData
=self
.MetaFile
)
972 if self
._InSubsection
:
973 SectionType
= self
._SubsectionType
975 SectionType
= self
._SectionType
976 self
._ItemType
= SectionType
978 self
._ValueList
= ['', '', '']
979 self
._SectionParser
[SectionType
](self
)
980 if self
._ValueList
is None:
983 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
984 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
986 for Arch
, ModuleType
, DefaultStore
in self
._Scope
:
987 Owner
= self
._Owner
[-1]
988 if self
._SubsectionType
!= MODEL_UNKNOWN
and Arch
in OwnerId
:
989 Owner
= OwnerId
[Arch
]
990 self
._LastItem
= self
._Store
(
1000 self
._LineIndex
+ 1,
1002 self
._LineIndex
+ 1,
1006 if self
._SubsectionType
== MODEL_UNKNOWN
and self
._InSubsection
:
1007 OwnerId
[Arch
] = self
._LastItem
1009 if self
._DirectiveStack
:
1010 Type
, Line
, Text
= self
._DirectiveStack
[-1]
1011 EdkLogger
.error('Parser', FORMAT_INVALID
, "No matching '!endif' found",
1012 ExtraData
=Text
, File
=self
.MetaFile
, Line
=Line
)
1015 ## <subsection_header> parser
1016 def _SubsectionHeaderParser(self
):
1017 self
._SubsectionName
= self
._CurrentLine
[1:-1].upper()
1018 if self
._SubsectionName
in self
.DataType
:
1019 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
1021 self
._SubsectionType
= MODEL_UNKNOWN
1022 EdkLogger
.warn("Parser", "Unrecognized sub-section", File
=self
.MetaFile
,
1023 Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1024 self
._ValueList
[0] = self
._SubsectionName
1026 ## Directive statement parser
1027 def _DirectiveParser(self
):
1028 self
._ValueList
= ['', '', '']
1029 TokenList
= GetSplitValueList(self
._CurrentLine
, ' ', 1)
1030 self
._ValueList
[0:len(TokenList
)] = TokenList
1033 DirectiveName
= self
._ValueList
[0].upper()
1034 if DirectiveName
not in self
.DataType
:
1035 EdkLogger
.error("Parser", FORMAT_INVALID
, "Unknown directive [%s]" % DirectiveName
,
1036 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1038 if DirectiveName
in ['!IF', '!IFDEF', '!IFNDEF']:
1039 self
._InDirective
+= 1
1041 if DirectiveName
in ['!ENDIF']:
1042 self
._InDirective
-= 1
1044 if DirectiveName
in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self
._ValueList
[1] == '':
1045 EdkLogger
.error("Parser", FORMAT_INVALID
, "Missing expression",
1046 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1047 ExtraData
=self
._CurrentLine
)
1049 ItemType
= self
.DataType
[DirectiveName
]
1050 Scope
= [[TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]]
1051 if ItemType
== MODEL_META_DATA_INCLUDE
:
1053 elif ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR
:
1055 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1056 # Remove all directives between !if and !endif, including themselves
1057 while self
._DirectiveStack
:
1058 # Remove any !else or !elseif
1059 DirectiveInfo
= self
._DirectiveStack
.pop()
1060 if DirectiveInfo
[0] in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1061 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1062 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1065 EdkLogger
.error("Parser", FORMAT_INVALID
, "Redundant '!endif'",
1066 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1067 ExtraData
=self
._CurrentLine
)
1068 elif ItemType
not in {MODEL_META_DATA_INCLUDE
, MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR
}:
1069 # Break if there's a !else is followed by a !elseif
1070 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
and \
1071 self
._DirectiveStack
and \
1072 self
._DirectiveStack
[-1][0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1073 EdkLogger
.error("Parser", FORMAT_INVALID
, "'!elseif' after '!else'",
1074 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1075 ExtraData
=self
._CurrentLine
)
1076 self
._DirectiveStack
.append((ItemType
, self
._LineIndex
+ 1, self
._CurrentLine
))
1079 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
1080 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
1082 for Arch
, ModuleType
, DefaultStore
in Scope
:
1083 self
._LastItem
= self
._Store
(
1093 self
._LineIndex
+ 1,
1095 self
._LineIndex
+ 1,
1100 ## [defines] section parser
1102 def _DefineParser(self
):
1103 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1104 self
._ValueList
[1:len(TokenList
)] = TokenList
1107 if not self
._ValueList
[1]:
1108 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
1109 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1110 if not self
._ValueList
[2]:
1111 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
1112 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1113 if (not self
._ValueList
[1] in self
.DefineKeywords
and
1114 (self
._InSubsection
and self
._ValueList
[1] not in self
.SubSectionDefineKeywords
)):
1115 EdkLogger
.error('Parser', FORMAT_INVALID
,
1116 "Unknown keyword found: %s. "
1117 "If this is a macro you must "
1118 "add it as a DEFINE in the DSC" % self
._ValueList
[1],
1119 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1120 if not self
._InSubsection
:
1121 self
._Defines
[self
._ValueList
[1]] = self
._ValueList
[2]
1122 self
._ItemType
= self
.DataType
[TAB_DSC_DEFINES
.upper()]
1125 def _SkuIdParser(self
):
1126 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1127 if len(TokenList
) not in (2, 3):
1128 EdkLogger
.error('Parser', FORMAT_INVALID
, "Correct format is '<Number>|<UiName>[|<UiName>]'",
1129 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1130 self
._ValueList
[0:len(TokenList
)] = TokenList
1132 def _DefaultStoresParser(self
):
1133 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1134 if len(TokenList
) != 2:
1135 EdkLogger
.error('Parser', FORMAT_INVALID
, "Correct format is '<Number>|<UiName>'",
1136 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1137 self
._ValueList
[0:len(TokenList
)] = TokenList
1139 ## Parse Edk style of library modules
1141 def _LibraryInstanceParser(self
):
1142 self
._ValueList
[0] = self
._CurrentLine
1144 def ProcessMultipleLineCODEValue(self
,Content
):
1147 continuelinecount
= 0
1149 for Index
in range(0, len(Content
)):
1150 Line
= Content
[Index
]
1152 CODELine
= CODELine
+ Line
1153 continuelinecount
+=1
1155 newContent
.append(CODELine
)
1156 for _
in range(continuelinecount
):
1157 newContent
.append("")
1160 continuelinecount
= 0
1163 newContent
.append(Line
)
1165 if "{CODE(" not in Line
:
1166 newContent
.append(Line
)
1168 elif CODEPattern
.findall(Line
):
1169 newContent
.append(Line
)
1177 def _DecodeCODEData(self
):
1179 ## PCD sections parser
1181 # [PcdsFixedAtBuild]
1182 # [PcdsPatchableInModule]
1185 # [PcdsDynamicExDefault]
1186 # [PcdsDynamicExVpd]
1187 # [PcdsDynamicExHii]
1189 # [PcdsDynamicDefault]
1194 def _PcdParser(self
):
1195 if self
._PcdDataTypeCODE
:
1196 self
._PcdCodeValue
= self
._PcdCodeValue
+ "\n " + self
._CurrentLine
1197 if self
._CurrentLine
.endswith(")}"):
1198 self
._CurrentLine
= "|".join((self
._CurrentPcdName
, self
._PcdCodeValue
))
1199 self
._PcdDataTypeCODE
= False
1200 self
._PcdCodeValue
= ""
1202 self
._ValueList
= None
1204 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1205 self
._CurrentPcdName
= TokenList
[0]
1206 if len(TokenList
) == 2 and TokenList
[1].strip().startswith("{CODE"):
1207 self
._PcdDataTypeCODE
= True
1208 self
._PcdCodeValue
= TokenList
[1].strip()
1210 if self
._PcdDataTypeCODE
:
1211 if self
._CurrentLine
.endswith(")}"):
1212 self
._PcdDataTypeCODE
= False
1213 self
._PcdCodeValue
= ""
1215 self
._ValueList
= None
1217 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1218 PcdNameTockens
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1219 if len(PcdNameTockens
) == 2:
1220 self
._ValueList
[0], self
._ValueList
[1] = PcdNameTockens
[0], PcdNameTockens
[1]
1221 elif len(PcdNameTockens
) == 3:
1222 self
._ValueList
[0], self
._ValueList
[1] = ".".join((PcdNameTockens
[0], PcdNameTockens
[1])), PcdNameTockens
[2]
1223 elif len(PcdNameTockens
) > 3:
1224 self
._ValueList
[0], self
._ValueList
[1] = ".".join((PcdNameTockens
[0], PcdNameTockens
[1])), ".".join(PcdNameTockens
[2:])
1225 if len(TokenList
) == 2:
1226 self
._ValueList
[2] = TokenList
[1]
1227 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1228 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1229 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1230 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1231 if self
._ValueList
[2] == '':
1233 # The PCD values are optional for FIXEDATBUILD, PATCHABLEINMODULE, Dynamic/DynamicEx default
1235 if self
._SectionType
in (MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
):
1237 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD value given",
1238 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1239 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1241 # Validate the datum type of Dynamic Defaul PCD and DynamicEx Default PCD
1242 ValueList
= GetSplitValueList(self
._ValueList
[2])
1243 if len(ValueList
) > 1 and ValueList
[1] in [TAB_UINT8
, TAB_UINT16
, TAB_UINT32
, TAB_UINT64
] \
1244 and self
._ItemType
in [MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
]:
1245 EdkLogger
.error('Parser', FORMAT_INVALID
, "The datum type '%s' of PCD is wrong" % ValueList
[1],
1246 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1248 # Validate the VariableName of DynamicHii and DynamicExHii for PCD Entry must not be an empty string
1249 if self
._ItemType
in [MODEL_PCD_DYNAMIC_HII
, MODEL_PCD_DYNAMIC_EX_HII
]:
1250 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
1251 if len(DscPcdValueList
[0].replace('L', '').replace('"', '').strip()) == 0:
1252 EdkLogger
.error('Parser', FORMAT_INVALID
, "The VariableName field in the HII format PCD entry must not be an empty string",
1253 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1255 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
1256 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
1257 if DscPcdValueList
[0] in ['True', 'true', 'TRUE']:
1258 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '1', 1);
1259 elif DscPcdValueList
[0] in ['False', 'false', 'FALSE']:
1260 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '0', 1);
1263 ## [components] section parser
1265 def _ComponentParser(self
):
1266 if self
._CurrentLine
[-1] == '{':
1267 self
._ValueList
[0] = self
._CurrentLine
[0:-1].strip()
1268 self
._InSubsection
= True
1269 self
._SubsectionType
= MODEL_UNKNOWN
1271 self
._ValueList
[0] = self
._CurrentLine
1273 ## [LibraryClasses] section
1275 def _LibraryClassParser(self
):
1276 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1277 if len(TokenList
) < 2:
1278 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class or instance specified",
1279 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1280 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1281 if TokenList
[0] == '':
1282 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class specified",
1283 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1284 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1285 if TokenList
[1] == '':
1286 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library instance specified",
1287 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1288 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1290 self
._ValueList
[0:len(TokenList
)] = TokenList
1292 def _CompponentSourceOverridePathParser(self
):
1293 self
._ValueList
[0] = self
._CurrentLine
1295 ## [BuildOptions] section parser
1297 def _BuildOptionParser(self
):
1298 self
._CurrentLine
= CleanString(self
._CurrentLine
, BuildOption
=True)
1299 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1300 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
1301 if len(TokenList2
) == 2:
1302 self
._ValueList
[0] = TokenList2
[0] # toolchain family
1303 self
._ValueList
[1] = TokenList2
[1] # keys
1305 self
._ValueList
[1] = TokenList
[0]
1306 if len(TokenList
) == 2: # value
1307 self
._ValueList
[2] = TokenList
[1]
1309 if self
._ValueList
[1].count('_') != 4:
1313 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
1314 ExtraData
=self
._CurrentLine
,
1316 Line
=self
._LineIndex
+ 1
1319 ## Override parent's method since we'll do all macro replacements in parser
1323 Macros
.update(self
._FileLocalMacros
)
1324 Macros
.update(self
._GetApplicableSectionMacro
())
1325 Macros
.update(GlobalData
.gEdkGlobal
)
1326 Macros
.update(GlobalData
.gPlatformDefines
)
1327 Macros
.update(GlobalData
.gCommandLineDefines
)
1328 # PCD cannot be referenced in macro definition
1329 if self
._ItemType
not in [MODEL_META_DATA_DEFINE
, MODEL_META_DATA_GLOBAL_DEFINE
]:
1330 Macros
.update(self
._Symbols
)
1331 if GlobalData
.BuildOptionPcd
:
1332 for Item
in GlobalData
.BuildOptionPcd
:
1333 if isinstance(Item
, tuple):
1335 PcdName
, TmpValue
= Item
.split("=")
1336 TmpValue
= BuildOptionValue(TmpValue
, self
._GuidDict
)
1337 Macros
[PcdName
.strip()] = TmpValue
1340 def _PostProcess(self
):
1342 MODEL_META_DATA_SECTION_HEADER
: self
.__ProcessSectionHeader
,
1343 MODEL_META_DATA_SUBSECTION_HEADER
: self
.__ProcessSubsectionHeader
,
1344 MODEL_META_DATA_HEADER
: self
.__ProcessDefine
,
1345 MODEL_META_DATA_DEFINE
: self
.__ProcessDefine
,
1346 MODEL_META_DATA_GLOBAL_DEFINE
: self
.__ProcessDefine
,
1347 MODEL_META_DATA_INCLUDE
: self
.__ProcessDirective
,
1348 MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
: self
.__ProcessDirective
,
1349 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
: self
.__ProcessDirective
,
1350 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
: self
.__ProcessDirective
,
1351 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
: self
.__ProcessDirective
,
1352 MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
: self
.__ProcessDirective
,
1353 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
: self
.__ProcessDirective
,
1354 MODEL_EFI_SKU_ID
: self
.__ProcessSkuId
,
1355 MODEL_EFI_DEFAULT_STORES
: self
.__ProcessDefaultStores
,
1356 MODEL_EFI_LIBRARY_INSTANCE
: self
.__ProcessLibraryInstance
,
1357 MODEL_EFI_LIBRARY_CLASS
: self
.__ProcessLibraryClass
,
1358 MODEL_PCD_FIXED_AT_BUILD
: self
.__ProcessPcd
,
1359 MODEL_PCD_PATCHABLE_IN_MODULE
: self
.__ProcessPcd
,
1360 MODEL_PCD_FEATURE_FLAG
: self
.__ProcessPcd
,
1361 MODEL_PCD_DYNAMIC_DEFAULT
: self
.__ProcessPcd
,
1362 MODEL_PCD_DYNAMIC_HII
: self
.__ProcessPcd
,
1363 MODEL_PCD_DYNAMIC_VPD
: self
.__ProcessPcd
,
1364 MODEL_PCD_DYNAMIC_EX_DEFAULT
: self
.__ProcessPcd
,
1365 MODEL_PCD_DYNAMIC_EX_HII
: self
.__ProcessPcd
,
1366 MODEL_PCD_DYNAMIC_EX_VPD
: self
.__ProcessPcd
,
1367 MODEL_META_DATA_COMPONENT
: self
.__ProcessComponent
,
1368 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: self
.__ProcessSourceOverridePath
,
1369 MODEL_META_DATA_BUILD_OPTION
: self
.__ProcessBuildOption
,
1370 MODEL_UNKNOWN
: self
._Skip
,
1371 MODEL_META_DATA_USER_EXTENSION
: self
._SkipUserExtension
,
1372 MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR
: self
._ProcessError
,
1375 self
._Table
= MetaFileStorage(self
._RawTable
.DB
, self
.MetaFile
, MODEL_FILE_DSC
, True)
1376 self
._DirectiveStack
= []
1377 self
._DirectiveEvalStack
= []
1378 self
._FileWithError
= self
.MetaFile
1379 self
._FileLocalMacros
= {}
1380 self
._SectionsMacroDict
.clear()
1381 GlobalData
.gPlatformDefines
= {}
1383 # Get all macro and PCD which has straitforward value
1384 self
.__RetrievePcdValue
()
1385 self
._Content
= self
._RawTable
.GetAll()
1386 self
._ContentIndex
= 0
1387 self
._InSubsection
= False
1388 while self
._ContentIndex
< len(self
._Content
) :
1389 Id
, self
._ItemType
, V1
, V2
, V3
, S1
, S2
, S3
, Owner
, self
._From
, \
1390 LineStart
, ColStart
, LineEnd
, ColEnd
, Enabled
= self
._Content
[self
._ContentIndex
]
1393 self
._FileWithError
= self
.MetaFile
1395 self
._ContentIndex
+= 1
1397 self
._Scope
= [[S1
, S2
, S3
]]
1399 # For !include directive, handle it specially,
1400 # merge arch and module type in case of duplicate items
1402 while self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1403 if self
._ContentIndex
>= len(self
._Content
):
1405 Record
= self
._Content
[self
._ContentIndex
]
1406 if LineStart
== Record
[10] and LineEnd
== Record
[12]:
1407 if [Record
[5], Record
[6], Record
[7]] not in self
._Scope
:
1408 self
._Scope
.append([Record
[5], Record
[6], Record
[7]])
1409 self
._ContentIndex
+= 1
1413 self
._LineIndex
= LineStart
- 1
1414 self
._ValueList
= [V1
, V2
, V3
]
1416 if Owner
> 0 and Owner
in self
._IdMapping
:
1417 self
._InSubsection
= True
1419 self
._InSubsection
= False
1421 Processer
[self
._ItemType
]()
1422 except EvaluationException
as Excpt
:
1424 # Only catch expression evaluation error here. We need to report
1425 # the precise number of line on which the error occurred
1427 if hasattr(Excpt
, 'Pcd'):
1428 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
1429 Info
= GlobalData
.gPlatformOtherPcds
[Excpt
.Pcd
]
1430 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
1431 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
1432 " of the DSC file, and it is currently defined in this section:"
1433 " %s, line #: %d." % (Excpt
.Pcd
, Info
[0], Info
[1]),
1434 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1435 Line
=self
._LineIndex
+ 1)
1437 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
1438 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1439 Line
=self
._LineIndex
+ 1)
1441 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
1442 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1443 Line
=self
._LineIndex
+ 1)
1444 except MacroException
as Excpt
:
1445 EdkLogger
.error('Parser', FORMAT_INVALID
, str(Excpt
),
1446 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1447 Line
=self
._LineIndex
+ 1)
1449 if self
._ValueList
is None:
1452 NewOwner
= self
._IdMapping
.get(Owner
, -1)
1453 self
._Enabled
= int((not self
._DirectiveEvalStack
) or (False not in self
._DirectiveEvalStack
))
1454 self
._LastItem
= self
._Store
(
1464 self
._LineIndex
+ 1,
1466 self
._LineIndex
+ 1,
1470 self
._IdMapping
[Id
] = self
._LastItem
1472 GlobalData
.gPlatformDefines
.update(self
._FileLocalMacros
)
1473 self
._PostProcessed
= True
1474 self
._Content
= None
1475 def _ProcessError(self
):
1476 if not self
._Enabled
:
1478 EdkLogger
.error('Parser', ERROR_STATEMENT
, self
._ValueList
[1], File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1480 def __ProcessSectionHeader(self
):
1481 self
._SectionName
= self
._ValueList
[0]
1482 if self
._SectionName
in self
.DataType
:
1483 self
._SectionType
= self
.DataType
[self
._SectionName
]
1485 self
._SectionType
= MODEL_UNKNOWN
1487 def __ProcessSubsectionHeader(self
):
1488 self
._SubsectionName
= self
._ValueList
[0]
1489 if self
._SubsectionName
in self
.DataType
:
1490 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
1492 self
._SubsectionType
= MODEL_UNKNOWN
1494 def __RetrievePcdValue(self
):
1495 Content
= open(str(self
.MetaFile
), 'r').readlines()
1496 GlobalData
.gPlatformOtherPcds
['DSCFILE'] = str(self
.MetaFile
)
1497 for PcdType
in (MODEL_PCD_PATCHABLE_IN_MODULE
, MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_HII
,
1498 MODEL_PCD_DYNAMIC_VPD
, MODEL_PCD_DYNAMIC_EX_DEFAULT
, MODEL_PCD_DYNAMIC_EX_HII
,
1499 MODEL_PCD_DYNAMIC_EX_VPD
):
1500 Records
= self
._RawTable
.Query(PcdType
, BelongsToItem
= -1.0)
1501 for TokenSpaceGuid
, PcdName
, Value
, Dummy2
, Dummy3
, Dummy4
, ID
, Line
in Records
:
1502 Name
= TokenSpaceGuid
+ '.' + PcdName
1503 if Name
not in GlobalData
.gPlatformOtherPcds
:
1505 while not Content
[Line
- 1].lstrip().startswith(TAB_SECTION_START
):
1507 GlobalData
.gPlatformOtherPcds
[Name
] = (CleanString(Content
[Line
- 1]), PcdLine
, PcdType
)
1509 def __ProcessDefine(self
):
1510 if not self
._Enabled
:
1513 Type
, Name
, Value
= self
._ValueList
1514 Value
= ReplaceMacro(Value
, self
._Macros
, False)
1516 # If it is <Defines>, return
1518 if self
._InSubsection
:
1519 self
._ValueList
= [Type
, Name
, Value
]
1522 if self
._ItemType
== MODEL_META_DATA_DEFINE
:
1523 if self
._SectionType
== MODEL_META_DATA_HEADER
:
1524 self
._FileLocalMacros
[Name
] = Value
1526 self
._ConstructSectionMacroDict
(Name
, Value
)
1527 elif self
._ItemType
== MODEL_META_DATA_GLOBAL_DEFINE
:
1528 GlobalData
.gEdkGlobal
[Name
] = Value
1531 # Keyword in [Defines] section can be used as Macros
1533 if (self
._ItemType
== MODEL_META_DATA_HEADER
) and (self
._SectionType
== MODEL_META_DATA_HEADER
):
1534 self
._FileLocalMacros
[Name
] = Value
1536 self
._ValueList
= [Type
, Name
, Value
]
1538 def __ProcessDirective(self
):
1540 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1541 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
]:
1542 Macros
= self
._Macros
1543 Macros
.update(GlobalData
.gGlobalDefines
)
1545 Result
= ValueExpression(self
._ValueList
[1], Macros
)()
1546 except SymbolNotFound
as Exc
:
1547 EdkLogger
.debug(EdkLogger
.DEBUG_5
, str(Exc
), self
._ValueList
[1])
1549 except WrnExpression
as Excpt
:
1551 # Catch expression evaluation warning here. We need to report
1552 # the precise number of line and return the evaluation result
1554 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
1555 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1556 Line
=self
._LineIndex
+ 1)
1557 Result
= Excpt
.result
1559 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1560 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1561 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1562 self
._DirectiveStack
.append(self
._ItemType
)
1563 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
:
1564 Result
= bool(Result
)
1566 Macro
= self
._ValueList
[1]
1567 Macro
= Macro
[2:-1] if (Macro
.startswith("$(") and Macro
.endswith(")")) else Macro
1568 Result
= Macro
in self
._Macros
1569 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
:
1571 self
._DirectiveEvalStack
.append(Result
)
1572 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
:
1573 self
._DirectiveStack
.append(self
._ItemType
)
1574 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1575 self
._DirectiveEvalStack
.append(bool(Result
))
1576 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1577 self
._DirectiveStack
.append(self
._ItemType
)
1578 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1579 self
._DirectiveEvalStack
.append(True)
1580 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1581 # Back to the nearest !if/!ifdef/!ifndef
1582 while self
._DirectiveStack
:
1583 self
._DirectiveEvalStack
.pop()
1584 Directive
= self
._DirectiveStack
.pop()
1585 if Directive
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1586 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1587 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1589 elif self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1590 # The included file must be relative to workspace or same directory as DSC file
1591 __IncludeMacros
= {}
1593 # Allow using system environment variables in path after !include
1595 __IncludeMacros
['WORKSPACE'] = GlobalData
.gGlobalDefines
['WORKSPACE']
1596 if "ECP_SOURCE" in GlobalData
.gGlobalDefines
:
1597 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gGlobalDefines
['ECP_SOURCE']
1599 # During GenFds phase call DSC parser, will go into this branch.
1601 elif "ECP_SOURCE" in GlobalData
.gCommandLineDefines
:
1602 __IncludeMacros
['ECP_SOURCE'] = GlobalData
.gCommandLineDefines
['ECP_SOURCE']
1604 __IncludeMacros
['EFI_SOURCE'] = GlobalData
.gGlobalDefines
['EFI_SOURCE']
1605 __IncludeMacros
['EDK_SOURCE'] = GlobalData
.gGlobalDefines
['EDK_SOURCE']
1607 # Allow using MACROs comes from [Defines] section to keep compatible.
1609 __IncludeMacros
.update(self
._Macros
)
1611 IncludedFile
= NormPath(ReplaceMacro(self
._ValueList
[1], __IncludeMacros
, RaiseError
=True))
1613 # First search the include file under the same directory as DSC file
1615 IncludedFile1
= PathClass(IncludedFile
, self
.MetaFile
.Dir
)
1616 ErrorCode
, ErrorInfo1
= IncludedFile1
.Validate()
1619 # Also search file under the WORKSPACE directory
1621 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
1622 ErrorCode
, ErrorInfo2
= IncludedFile1
.Validate()
1624 EdkLogger
.error('parser', ErrorCode
, File
=self
._FileWithError
,
1625 Line
=self
._LineIndex
+ 1, ExtraData
=ErrorInfo1
+ "\n" + ErrorInfo2
)
1627 self
._FileWithError
= IncludedFile1
1629 FromItem
= self
._Content
[self
._ContentIndex
- 1][0]
1630 if self
._InSubsection
:
1631 Owner
= self
._Content
[self
._ContentIndex
- 1][8]
1633 Owner
= self
._Content
[self
._ContentIndex
- 1][0]
1634 IncludedFileTable
= MetaFileStorage(self
._RawTable
.DB
, IncludedFile1
, MODEL_FILE_DSC
, False, FromItem
=FromItem
)
1635 Parser
= DscParser(IncludedFile1
, self
._FileType
, self
._Arch
, IncludedFileTable
,
1636 Owner
=Owner
, From
=FromItem
)
1638 self
.IncludedFiles
.add (IncludedFile1
)
1640 # set the parser status with current status
1641 Parser
._SectionName
= self
._SectionName
1642 Parser
._SubsectionType
= self
._SubsectionType
1643 Parser
._InSubsection
= self
._InSubsection
1644 Parser
._SectionType
= self
._SectionType
1645 Parser
._Scope
= self
._Scope
1646 Parser
._Enabled
= self
._Enabled
1647 # Parse the included file
1651 # Insert all records in the table for the included file into dsc file table
1652 Records
= IncludedFileTable
.GetAll()
1654 self
._Content
[self
._ContentIndex
:self
._ContentIndex
] = Records
1655 self
._Content
.pop(self
._ContentIndex
- 1)
1656 self
._ValueList
= None
1657 self
._ContentIndex
-= 1
1659 def __ProcessSkuId(self
):
1660 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=True)
1661 for Value
in self
._ValueList
]
1662 def __ProcessDefaultStores(self
):
1663 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=True)
1664 for Value
in self
._ValueList
]
1666 def __ProcessLibraryInstance(self
):
1667 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
1669 def __ProcessLibraryClass(self
):
1670 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
, RaiseError
=True)
1672 def __ProcessPcd(self
):
1673 if self
._ItemType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
1674 self
._ValueList
[2] = ReplaceMacro(self
._ValueList
[2], self
._Macros
, RaiseError
=True)
1677 ValList
, Valid
, Index
= AnalyzeDscPcd(self
._ValueList
[2], self
._ItemType
)
1679 if self
._ItemType
in (MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
, MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
):
1680 if ValList
[1] != TAB_VOID
and StructPattern
.match(ValList
[1]) is None and ValList
[2]:
1681 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect. The datum type info should be VOID* or a valid struct name.", File
=self
._FileWithError
,
1682 Line
=self
._LineIndex
+ 1, ExtraData
="%s.%s|%s" % (self
._ValueList
[0], self
._ValueList
[1], self
._ValueList
[2]))
1683 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
._FileWithError
, Line
=self
._LineIndex
+ 1,
1684 ExtraData
="%s.%s|%s" % (self
._ValueList
[0], self
._ValueList
[1], self
._ValueList
[2]))
1685 PcdValue
= ValList
[Index
]
1686 if PcdValue
and "." not in self
._ValueList
[0]:
1688 ValList
[Index
] = ValueExpression(PcdValue
, self
._Macros
)(True)
1689 except WrnExpression
as Value
:
1690 ValList
[Index
] = Value
.result
1694 if ValList
[Index
] == 'True':
1695 ValList
[Index
] = '1'
1696 if ValList
[Index
] == 'False':
1697 ValList
[Index
] = '0'
1699 if (not self
._DirectiveEvalStack
) or (False not in self
._DirectiveEvalStack
):
1700 GlobalData
.gPlatformPcds
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = PcdValue
1701 self
._Symbols
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = PcdValue
1703 self
._ValueList
[2] = '|'.join(ValList
)
1707 def __ProcessComponent(self
):
1708 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1710 def __ProcessSourceOverridePath(self
):
1711 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1713 def __ProcessBuildOption(self
):
1714 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=False)
1715 for Value
in self
._ValueList
]
1718 MODEL_META_DATA_HEADER
: _DefineParser
,
1719 MODEL_EFI_SKU_ID
: _SkuIdParser
,
1720 MODEL_EFI_DEFAULT_STORES
: _DefaultStoresParser
,
1721 MODEL_EFI_LIBRARY_INSTANCE
: _LibraryInstanceParser
,
1722 MODEL_EFI_LIBRARY_CLASS
: _LibraryClassParser
,
1723 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1724 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1725 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1726 MODEL_PCD_DYNAMIC_DEFAULT
: _PcdParser
,
1727 MODEL_PCD_DYNAMIC_HII
: _PcdParser
,
1728 MODEL_PCD_DYNAMIC_VPD
: _PcdParser
,
1729 MODEL_PCD_DYNAMIC_EX_DEFAULT
: _PcdParser
,
1730 MODEL_PCD_DYNAMIC_EX_HII
: _PcdParser
,
1731 MODEL_PCD_DYNAMIC_EX_VPD
: _PcdParser
,
1732 MODEL_META_DATA_COMPONENT
: _ComponentParser
,
1733 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: _CompponentSourceOverridePathParser
,
1734 MODEL_META_DATA_BUILD_OPTION
: _BuildOptionParser
,
1735 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1736 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
1737 MODEL_META_DATA_SECTION_HEADER
: MetaFileParser
._SectionHeaderParser
,
1738 MODEL_META_DATA_SUBSECTION_HEADER
: _SubsectionHeaderParser
,
1741 ## DEC file parser class
1743 # @param FilePath The path of platform description file
1744 # @param FileType The raw data of DSC file
1745 # @param Table Database used to retrieve module/package information
1746 # @param Macros Macros used for replacement in file
1748 class DecParser(MetaFileParser
):
1749 # DEC file supported data types (one type per section)
1751 TAB_DEC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
1752 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
1753 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
1754 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
1755 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
1756 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
1757 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
1758 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
1759 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
1760 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
1761 TAB_PCDS_DYNAMIC_NULL
.upper() : MODEL_PCD_DYNAMIC
,
1762 TAB_PCDS_DYNAMIC_EX_NULL
.upper() : MODEL_PCD_DYNAMIC_EX
,
1763 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
,
1766 ## Constructor of DecParser
1768 # Initialize object of DecParser
1770 # @param FilePath The path of platform description file
1771 # @param FileType The raw data of DSC file
1772 # @param Arch Default Arch value for filtering sections
1773 # @param Table Database used to retrieve module/package information
1775 def __init__(self
, FilePath
, FileType
, Arch
, Table
):
1776 # prevent re-initialization
1777 if hasattr(self
, "_Table"):
1779 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
, -1)
1781 self
._Version
= 0x00010005 # Only EDK2 dec file is supported
1782 self
._AllPCDs
= [] # Only for check duplicate PCD
1783 self
._AllPcdDict
= {}
1785 self
._CurrentStructurePcdName
= ""
1786 self
._include
_flag
= False
1787 self
._package
_flag
= False
1793 Content
= open(str(self
.MetaFile
), 'r').readlines()
1795 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
1797 self
._DefinesCount
= 0
1798 for Index
in range(0, len(Content
)):
1799 Line
, Comment
= CleanString2(Content
[Index
])
1800 self
._CurrentLine
= Line
1801 self
._LineIndex
= Index
1803 # save comment for later use
1805 self
._Comments
.append((Comment
, self
._LineIndex
+ 1))
1811 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
1812 self
._SectionHeaderParser
()
1813 if self
._SectionName
== TAB_DEC_DEFINES
.upper():
1814 self
._DefinesCount
+= 1
1817 if self
._SectionType
== MODEL_UNKNOWN
:
1818 EdkLogger
.error("Parser", FORMAT_INVALID
,
1820 "Not able to determine \"%s\" in which section."%self
._CurrentLine
,
1821 self
.MetaFile
, self
._LineIndex
+ 1)
1822 elif len(self
._SectionType
) == 0:
1827 self
._ValueList
= ['', '', '']
1828 self
._SectionParser
[self
._SectionType
[0]](self
)
1829 if self
._ValueList
is None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
1835 # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,
1836 # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1
1838 for Arch
, ModuleType
, Type
in self
._Scope
:
1839 self
._LastItem
= self
._Store
(
1847 self
._LineIndex
+ 1,
1849 self
._LineIndex
+ 1,
1853 for Comment
, LineNo
in self
._Comments
:
1855 MODEL_META_DATA_COMMENT
,
1869 if self
._DefinesCount
> 1:
1870 EdkLogger
.error('Parser', FORMAT_INVALID
, 'Multiple [Defines] section is exist.', self
.MetaFile
)
1871 if self
._DefinesCount
== 0:
1872 EdkLogger
.error('Parser', FORMAT_INVALID
, 'No [Defines] section exist.', self
.MetaFile
)
1876 ## Section header parser
1878 # The section header is always in following format:
1880 # [section_name.arch<.platform|module_type>]
1882 def _SectionHeaderParser(self
):
1884 self
._SectionName
= ''
1885 self
._SectionType
= []
1888 Line
= re
.sub(',[\s]*', TAB_COMMA_SPLIT
, self
._CurrentLine
)
1889 for Item
in Line
[1:-1].split(TAB_COMMA_SPLIT
):
1891 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
,
1892 "section name can NOT be empty or incorrectly use separator comma",
1893 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1894 ItemList
= Item
.split(TAB_SPLIT
)
1896 # different types of PCD are permissible in one section
1897 self
._SectionName
= ItemList
[0].upper()
1898 if self
._SectionName
== TAB_DEC_DEFINES
.upper() and (len(ItemList
) > 1 or len(Line
.split(TAB_COMMA_SPLIT
)) > 1):
1899 EdkLogger
.error("Parser", FORMAT_INVALID
, "Defines section format is invalid",
1900 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1901 if self
._SectionName
in self
.DataType
:
1902 if self
.DataType
[self
._SectionName
] not in self
._SectionType
:
1903 self
._SectionType
.append(self
.DataType
[self
._SectionName
])
1905 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
1906 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1908 if MODEL_PCD_FEATURE_FLAG
in self
._SectionType
and len(self
._SectionType
) > 1:
1912 "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL
,
1914 Line
=self
._LineIndex
+ 1,
1915 ExtraData
=self
._CurrentLine
1918 if len(ItemList
) > 1:
1919 S1
= ItemList
[1].upper()
1921 S1
= TAB_ARCH_COMMON
1923 # S2 may be Platform or ModuleType
1924 if len(ItemList
) > 2:
1925 S2
= ItemList
[2].upper()
1926 # only Includes, GUIDs, PPIs, Protocols section have Private tag
1927 if self
._SectionName
in [TAB_INCLUDES
.upper(), TAB_GUIDS
.upper(), TAB_PROTOCOLS
.upper(), TAB_PPIS
.upper()]:
1929 EdkLogger
.error("Parser", FORMAT_INVALID
, 'Please use keyword "Private" as section tag modifier.',
1930 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1934 if [S1
, S2
, self
.DataType
[self
._SectionName
]] not in self
._Scope
:
1935 self
._Scope
.append([S1
, S2
, self
.DataType
[self
._SectionName
]])
1937 # 'COMMON' must not be used with specific ARCHs at the same section
1938 if TAB_ARCH_COMMON
in ArchList
and len(ArchList
) > 1:
1939 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
1940 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1942 # It is not permissible to mix section tags without the Private attribute with section tags with the Private attribute
1943 if TAB_COMMON
in PrivateList
and len(PrivateList
) > 1:
1944 EdkLogger
.error('Parser', FORMAT_INVALID
, "Can't mix section tags without the Private attribute with section tags with the Private attribute",
1945 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1947 ## [guids], [ppis] and [protocols] section parser
1949 def _GuidParser(self
):
1950 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1951 if len(TokenList
) < 2:
1952 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name or value specified",
1953 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1954 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1955 if TokenList
[0] == '':
1956 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name specified",
1957 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1958 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1959 if TokenList
[1] == '':
1960 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID value specified",
1961 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1962 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1963 if TokenList
[1][0] != '{' or TokenList
[1][-1] != '}' or GuidStructureStringToGuidString(TokenList
[1]) == '':
1964 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid GUID value format",
1965 ExtraData
=self
._CurrentLine
+ \
1966 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
1967 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1968 self
._ValueList
[0] = TokenList
[0]
1969 self
._ValueList
[1] = TokenList
[1]
1970 if self
._ValueList
[0] not in self
._GuidDict
:
1971 self
._GuidDict
[self
._ValueList
[0]] = self
._ValueList
[1]
1973 def ParsePcdName(self
,namelist
):
1974 if "[" in namelist
[1]:
1975 pcdname
= namelist
[1][:namelist
[1].index("[")]
1976 arrayindex
= namelist
[1][namelist
[1].index("["):]
1977 namelist
[1] = pcdname
1978 if len(namelist
) == 2:
1979 namelist
.append(arrayindex
)
1981 namelist
[2] = ".".join((arrayindex
,namelist
[2]))
1984 ## PCD sections parser
1986 # [PcdsFixedAtBuild]
1987 # [PcdsPatchableInModule]
1993 def _PcdParser(self
):
1994 if self
._CurrentStructurePcdName
:
1995 self
._ValueList
[0] = self
._CurrentStructurePcdName
1997 if "|" not in self
._CurrentLine
:
1998 if "<HeaderFiles>" == self
._CurrentLine
:
1999 self
._include
_flag
= True
2000 self
._package
_flag
= False
2001 self
._ValueList
= None
2003 if "<Packages>" == self
._CurrentLine
:
2004 self
._package
_flag
= True
2005 self
._ValueList
= None
2006 self
._include
_flag
= False
2009 if self
._include
_flag
:
2010 self
._ValueList
[1] = "<HeaderFiles>_" + md5(self
._CurrentLine
).hexdigest()
2011 self
._ValueList
[2] = self
._CurrentLine
2012 if self
._package
_flag
and "}" != self
._CurrentLine
:
2013 self
._ValueList
[1] = "<Packages>_" + md5(self
._CurrentLine
).hexdigest()
2014 self
._ValueList
[2] = self
._CurrentLine
2015 if self
._CurrentLine
== "}":
2016 self
._package
_flag
= False
2017 self
._include
_flag
= False
2018 self
._ValueList
= None
2021 PcdTockens
= self
._CurrentLine
.split(TAB_VALUE_SPLIT
)
2022 PcdNames
= self
.ParsePcdName(PcdTockens
[0].split(TAB_SPLIT
))
2023 if len(PcdNames
) == 2:
2024 if PcdNames
[1].strip().endswith("]"):
2025 PcdName
= PcdNames
[1][:PcdNames
[1].index('[')]
2026 Index
= PcdNames
[1][PcdNames
[1].index('['):]
2027 self
._ValueList
[0] = TAB_SPLIT
.join((PcdNames
[0],PcdName
))
2028 self
._ValueList
[1] = Index
2029 self
._ValueList
[2] = PcdTockens
[1]
2031 self
._CurrentStructurePcdName
= ""
2033 if self
._CurrentStructurePcdName
!= TAB_SPLIT
.join(PcdNames
[:2]):
2034 EdkLogger
.error('Parser', FORMAT_INVALID
, "Pcd Name does not match: %s and %s " % (self
._CurrentStructurePcdName
, TAB_SPLIT
.join(PcdNames
[:2])),
2035 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2036 self
._ValueList
[1] = TAB_SPLIT
.join(PcdNames
[2:])
2037 self
._ValueList
[2] = PcdTockens
[1]
2038 if not self
._CurrentStructurePcdName
:
2039 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
2040 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
2041 ValueRe
= re
.compile(r
'^[a-zA-Z_][a-zA-Z0-9_]*')
2042 # check PCD information
2043 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
2044 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
2045 ExtraData
=self
._CurrentLine
+ \
2046 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2047 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2048 # check format of token space GUID CName
2049 if not ValueRe
.match(self
._ValueList
[0]):
2050 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_]*'",
2051 ExtraData
=self
._CurrentLine
+ \
2052 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2053 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2054 # check format of PCD CName
2055 if not ValueRe
.match(self
._ValueList
[1]):
2056 EdkLogger
.error('Parser', FORMAT_INVALID
, "The format of the PCD CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",
2057 ExtraData
=self
._CurrentLine
+ \
2058 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2059 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2060 # check PCD datum information
2061 if len(TokenList
) < 2 or TokenList
[1] == '':
2062 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD Datum information given",
2063 ExtraData
=self
._CurrentLine
+ \
2064 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2065 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2068 ValueRe
= re
.compile(r
'^\s*L?\".*\|.*\"')
2069 PtrValue
= ValueRe
.findall(TokenList
[1])
2071 # Has VOID* type string, may contain "|" character in the string.
2072 if len(PtrValue
) != 0:
2073 ptrValueList
= re
.sub(ValueRe
, '', TokenList
[1])
2074 ValueList
= AnalyzePcdExpression(ptrValueList
)
2075 ValueList
[0] = PtrValue
[0]
2077 ValueList
= AnalyzePcdExpression(TokenList
[1])
2080 # check if there's enough datum information given
2081 if len(ValueList
) != 3:
2082 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid PCD Datum information given",
2083 ExtraData
=self
._CurrentLine
+ \
2084 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2085 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2086 # check default value
2087 if ValueList
[0] == '':
2088 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DefaultValue in PCD Datum information",
2089 ExtraData
=self
._CurrentLine
+ \
2090 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2091 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2093 if ValueList
[1] == '':
2094 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DatumType in PCD Datum information",
2095 ExtraData
=self
._CurrentLine
+ \
2096 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2097 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2098 # check token of the PCD
2099 if ValueList
[2] == '':
2100 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing Token in PCD Datum information",
2101 ExtraData
=self
._CurrentLine
+ \
2102 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2103 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2105 PcdValue
= ValueList
[0]
2108 self
._GuidDict
.update(self
._AllPcdDict
)
2109 ValueList
[0] = ValueExpressionEx(ValueList
[0], ValueList
[1], self
._GuidDict
)(True)
2110 except BadExpression
as Value
:
2111 EdkLogger
.error('Parser', FORMAT_INVALID
, Value
, ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2112 # check format of default value against the datum type
2113 IsValid
, Cause
= CheckPcdDatum(ValueList
[1], ValueList
[0])
2115 EdkLogger
.error('Parser', FORMAT_INVALID
, Cause
, ExtraData
=self
._CurrentLine
,
2116 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2118 if Cause
== "StructurePcd":
2119 self
._CurrentStructurePcdName
= TAB_SPLIT
.join(self
._ValueList
[0:2])
2120 self
._ValueList
[0] = self
._CurrentStructurePcdName
2121 self
._ValueList
[1] = ValueList
[1].strip()
2123 if ValueList
[0] in ['True', 'true', 'TRUE']:
2125 elif ValueList
[0] in ['False', 'false', 'FALSE']:
2128 # check for duplicate PCD definition
2129 if (self
._Scope
[0], self
._ValueList
[0], self
._ValueList
[1]) in self
._AllPCDs
:
2130 EdkLogger
.error('Parser', FORMAT_INVALID
,
2131 "The same PCD name and GUID have been already defined",
2132 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2134 self
._AllPCDs
.append((self
._Scope
[0], self
._ValueList
[0], self
._ValueList
[1]))
2135 self
._AllPcdDict
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = ValueList
[0]
2137 self
._ValueList
[2] = ValueList
[0].strip() + '|' + ValueList
[1].strip() + '|' + ValueList
[2].strip()
2140 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
2141 MODEL_EFI_INCLUDE
: MetaFileParser
._PathParser
,
2142 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
2143 MODEL_EFI_GUID
: _GuidParser
,
2144 MODEL_EFI_PPI
: _GuidParser
,
2145 MODEL_EFI_PROTOCOL
: _GuidParser
,
2146 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
2147 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
2148 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
2149 MODEL_PCD_DYNAMIC
: _PcdParser
,
2150 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
2151 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
2152 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
2157 # This acts like the main() function for the script, unless it is 'import'ed into another
2160 if __name__
== '__main__':