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
39 from Common
.DataType
import TAB_COMMENT_EDK_START
, TAB_COMMENT_EDK_END
41 ## RegEx for finding file versions
42 hexVersionPattern
= re
.compile(r
'0[xX][\da-f-A-F]{5,8}')
43 decVersionPattern
= re
.compile(r
'\d+\.\d+')
44 CODEPattern
= re
.compile(r
"{CODE\([a-fA-F0-9Xx\{\},\s]*\)}")
46 ## A decorator used to parse macro definition
47 def ParseMacro(Parser
):
48 def MacroParser(self
):
49 Match
= GlobalData
.gMacroDefPattern
.match(self
._CurrentLine
)
51 # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method
55 TokenList
= GetSplitValueList(self
._CurrentLine
[Match
.end(1):], TAB_EQUAL_SPLIT
, 1)
58 EdkLogger
.error('Parser', FORMAT_INVALID
, "No macro name given",
59 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
60 if len(TokenList
) < 2:
64 Name
, Value
= TokenList
65 # Global macros can be only defined via environment variable
66 if Name
in GlobalData
.gGlobalDefines
:
67 EdkLogger
.error('Parser', FORMAT_INVALID
, "%s can only be defined via environment variable" % Name
,
68 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
69 # Only upper case letters, digit and '_' are allowed
70 if not GlobalData
.gMacroNamePattern
.match(Name
):
71 EdkLogger
.error('Parser', FORMAT_INVALID
, "The macro name must be in the pattern [A-Z][A-Z0-9_]*",
72 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
74 Value
= ReplaceMacro(Value
, self
._Macros
)
75 if Type
in self
.DataType
:
76 self
._ItemType
= self
.DataType
[Type
]
78 self
._ItemType
= MODEL_META_DATA_DEFINE
79 # DEFINE defined macros
80 if Type
== TAB_DSC_DEFINES_DEFINE
:
82 # First judge whether this DEFINE is in conditional directive statements or not.
84 if isinstance(self
, DscParser
) and self
._InDirective
> -1:
87 if isinstance(self
, DecParser
):
88 if MODEL_META_DATA_HEADER
in self
._SectionType
:
89 self
._FileLocalMacros
[Name
] = Value
91 self
._ConstructSectionMacroDict
(Name
, Value
)
92 elif self
._SectionType
== MODEL_META_DATA_HEADER
:
93 self
._FileLocalMacros
[Name
] = Value
95 self
._ConstructSectionMacroDict
(Name
, Value
)
97 # EDK_GLOBAL defined macros
98 elif not isinstance(self
, DscParser
):
99 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL can only be used in .dsc file",
100 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
101 elif self
._SectionType
!= MODEL_META_DATA_HEADER
:
102 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL can only be used under [Defines] section",
103 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
104 elif (Name
in self
._FileLocalMacros
) and (self
._FileLocalMacros
[Name
] != Value
):
105 EdkLogger
.error('Parser', FORMAT_INVALID
, "EDK_GLOBAL defined a macro with the same name and different value as one defined by 'DEFINE'",
106 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
108 self
._ValueList
= [Type
, Name
, Value
]
112 ## Base class of parser
114 # This class is used for derivation purpose. The specific parser for one kind
115 # type file must derive this class and implement some public interfaces.
117 # @param FilePath The path of platform description file
118 # @param FileType The raw data of DSC file
119 # @param Table Database used to retrieve module/package information
120 # @param Macros Macros used for replacement in file
121 # @param Owner Owner ID (for sub-section parsing)
122 # @param From ID from which the data comes (for !INCLUDE directive)
124 class MetaFileParser(object):
125 # data type (file content) for specific file type
128 # Parser objects used to implement singleton
133 # One file, one parser object. This factory method makes sure that there's
134 # only one object constructed for one meta file.
136 # @param Class class object of real AutoGen class
137 # (InfParser, DecParser or DscParser)
138 # @param FilePath The path of meta file
139 # @param *args The specific class related parameters
140 # @param **kwargs The specific class related dict parameters
142 def __new__(Class
, FilePath
, *args
, **kwargs
):
143 if FilePath
in Class
.MetaFiles
:
144 return Class
.MetaFiles
[FilePath
]
146 ParserObject
= super(MetaFileParser
, Class
).__new
__(Class
)
147 Class
.MetaFiles
[FilePath
] = ParserObject
150 ## Constructor of MetaFileParser
152 # Initialize object of MetaFileParser
154 # @param FilePath The path of platform description file
155 # @param FileType The raw data of DSC file
156 # @param Arch Default Arch value for filtering sections
157 # @param Table Database used to retrieve module/package information
158 # @param Owner Owner ID (for sub-section parsing)
159 # @param From ID from which the data comes (for !INCLUDE directive)
161 def __init__(self
, FilePath
, FileType
, Arch
, Table
, Owner
= -1, From
= -1):
163 self
._RawTable
= Table
165 self
._FileType
= FileType
166 self
.MetaFile
= FilePath
167 self
._FileDir
= self
.MetaFile
.Dir
169 self
._FileLocalMacros
= {}
170 self
._SectionsMacroDict
= defaultdict(dict)
172 # for recursive parsing
173 self
._Owner
= [Owner
]
176 # parsr status for parsing
177 self
._ValueList
= ['', '', '', '', '']
180 self
._CurrentLine
= ''
181 self
._SectionType
= MODEL_UNKNOWN
182 self
._SectionName
= ''
183 self
._InSubsection
= False
184 self
._SubsectionType
= MODEL_UNKNOWN
185 self
._SubsectionName
= ''
186 self
._ItemType
= MODEL_UNKNOWN
189 self
._Finished
= False
190 self
._PostProcessed
= False
191 # Different version of meta-file has different way to parse.
193 self
._GuidDict
= {} # for Parser PCD value {GUID(gTokeSpaceGuidName)}
195 self
._PcdCodeValue
= ""
196 self
._PcdDataTypeCODE
= False
197 self
._CurrentPcdName
= ""
199 ## Store the parsed data in table
200 def _Store(self
, *Args
):
201 return self
._Table
.Insert(*Args
)
203 ## Virtual method for starting parse
205 raise NotImplementedError
207 ## Notify a post-process is needed
208 def DoPostProcess(self
):
209 self
._PostProcessed
= False
211 ## Set parsing complete flag in both class and table
213 self
._Finished
= True
214 self
._Table
.SetEndFlag()
216 def _PostProcess(self
):
217 self
._PostProcessed
= True
219 ## Get the parse complete flag
222 return self
._Finished
224 ## Set the complete flag
226 def Finished(self
, Value
):
227 self
._Finished
= Value
229 ## Remove records that do not match given Filter Arch
230 def _FilterRecordList(self
, RecordList
, FilterArch
):
232 for Record
in RecordList
:
234 if Arch
== TAB_ARCH_COMMON
or Arch
== FilterArch
:
235 NewRecordList
.append(Record
)
238 ## Use [] style to query data in table, just for readability
240 # DataInfo = [data_type, scope1(arch), scope2(platform/moduletype)]
242 def __getitem__(self
, DataInfo
):
243 if not isinstance(DataInfo
, type(())):
244 DataInfo
= (DataInfo
,)
246 # Parse the file first, if necessary
249 # No specific ARCH or Platform given, use raw data
250 if self
._RawTable
and (len(DataInfo
) == 1 or DataInfo
[1] is None):
251 return self
._FilterRecordList
(self
._RawTable
.Query(*DataInfo
), self
._Arch
)
253 # Do post-process if necessary
254 if not self
._PostProcessed
:
257 return self
._FilterRecordList
(self
._Table
.Query(*DataInfo
), DataInfo
[1])
259 def StartParse(self
):
260 if not self
._Finished
:
261 if self
._RawTable
.IsIntegrity():
262 self
._Finished
= True
264 self
._Table
= self
._RawTable
265 self
._PostProcessed
= False
267 ## Data parser for the common format in different type of file
269 # The common format in the meatfile is like
274 def _CommonParser(self
):
275 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
276 self
._ValueList
[0:len(TokenList
)] = TokenList
278 ## Data parser for the format in which there's path
280 # Only path can have macro used. So we need to replace them before use.
283 def _PathParser(self
):
284 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
285 self
._ValueList
[0:len(TokenList
)] = TokenList
286 # Don't do macro replacement for dsc file at this point
287 if not isinstance(self
, DscParser
):
288 Macros
= self
._Macros
289 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
291 ## Skip unsupported data
293 EdkLogger
.warn("Parser", "Unrecognized content", File
=self
.MetaFile
,
294 Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
);
295 self
._ValueList
[0:1] = [self
._CurrentLine
]
297 ## Skip unsupported data for UserExtension Section
298 def _SkipUserExtension(self
):
299 self
._ValueList
[0:1] = [self
._CurrentLine
]
301 ## Section header parser
303 # The section header is always in following format:
305 # [section_name.arch<.platform|module_type>]
307 def _SectionHeaderParser(self
):
309 self
._SectionName
= ''
311 for Item
in GetSplitValueList(self
._CurrentLine
[1:-1], TAB_COMMA_SPLIT
):
314 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
, 3)
315 # different section should not mix in one section
316 if self
._SectionName
!= '' and self
._SectionName
!= ItemList
[0].upper():
317 EdkLogger
.error('Parser', FORMAT_INVALID
, "Different section names in the same section",
318 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
319 self
._SectionName
= ItemList
[0].upper()
320 if self
._SectionName
in self
.DataType
:
321 self
._SectionType
= self
.DataType
[self
._SectionName
]
322 # Check if the section name is valid
323 if self
._SectionName
not in SECTIONS_HAVE_ITEM_AFTER_ARCH_SET
and len(ItemList
) > 3:
324 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
325 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
326 elif self
._Version
>= 0x00010005:
327 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
328 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
330 self
._SectionType
= MODEL_UNKNOWN
333 if len(ItemList
) > 1:
334 S1
= ItemList
[1].upper()
339 # S2 may be Platform or ModuleType
340 if len(ItemList
) > 2:
341 if self
._SectionName
.upper() in SECTIONS_HAVE_ITEM_PCD_SET
:
344 S2
= ItemList
[2].upper()
347 if len(ItemList
) > 3:
351 self
._Scope
.append([S1
, S2
, S3
])
353 # 'COMMON' must not be used with specific ARCHs at the same section
354 if TAB_ARCH_COMMON
in ArchList
and len(ArchList
) > 1:
355 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
356 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
357 # If the section information is needed later, it should be stored in database
358 self
._ValueList
[0] = self
._SectionName
360 ## [defines] section parser
362 def _DefineParser(self
):
363 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
364 self
._ValueList
[1:len(TokenList
)] = TokenList
365 if not self
._ValueList
[1]:
366 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
367 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
368 if not self
._ValueList
[2]:
369 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
370 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
372 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
373 Name
, Value
= self
._ValueList
[1], self
._ValueList
[2]
374 MacroUsed
= GlobalData
.gMacroRefPattern
.findall(Value
)
375 if len(MacroUsed
) != 0:
376 for Macro
in MacroUsed
:
377 if Macro
in GlobalData
.gGlobalDefines
:
378 EdkLogger
.error("Parser", FORMAT_INVALID
, "Global macro %s is not permitted." % (Macro
), ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
380 EdkLogger
.error("Parser", FORMAT_INVALID
, "%s not defined" % (Macro
), ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
381 # Sometimes, we need to make differences between EDK and EDK2 modules
382 if Name
== 'INF_VERSION':
383 if hexVersionPattern
.match(Value
):
384 self
._Version
= int(Value
, 0)
385 elif decVersionPattern
.match(Value
):
386 ValueList
= Value
.split('.')
387 Major
= int(ValueList
[0], 0)
388 Minor
= int(ValueList
[1], 0)
389 if Major
> 0xffff or Minor
> 0xffff:
390 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid version number",
391 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
392 self
._Version
= int('0x{0:04x}{1:04x}'.format(Major
, Minor
), 0)
394 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid version number",
395 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
397 if isinstance(self
, InfParser
) and self
._Version
< 0x00010005:
398 # EDK module allows using defines as macros
399 self
._FileLocalMacros
[Name
] = Value
400 self
._Defines
[Name
] = Value
402 ## [BuildOptions] section parser
404 def _BuildOptionParser(self
):
405 self
._CurrentLine
= CleanString(self
._CurrentLine
, BuildOption
=True)
406 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
407 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
408 if len(TokenList2
) == 2:
409 self
._ValueList
[0] = TokenList2
[0] # toolchain family
410 self
._ValueList
[1] = TokenList2
[1] # keys
412 self
._ValueList
[1] = TokenList
[0]
413 if len(TokenList
) == 2 and not isinstance(self
, DscParser
): # value
414 self
._ValueList
[2] = ReplaceMacro(TokenList
[1], self
._Macros
)
416 if self
._ValueList
[1].count('_') != 4:
420 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
421 ExtraData
=self
._CurrentLine
,
423 Line
=self
._LineIndex
+ 1
425 def GetValidExpression(self
, TokenSpaceGuid
, PcdCName
):
426 return self
._Table
.GetValidExpression(TokenSpaceGuid
, PcdCName
)
431 Macros
.update(self
._FileLocalMacros
)
432 Macros
.update(self
._GetApplicableSectionMacro
())
435 ## Construct section Macro dict
436 def _ConstructSectionMacroDict(self
, Name
, Value
):
437 ScopeKey
= [(Scope
[0], Scope
[1], Scope
[2]) for Scope
in self
._Scope
]
438 ScopeKey
= tuple(ScopeKey
)
440 # DecParser SectionType is a list, will contain more than one item only in Pcd Section
441 # As Pcd section macro usage is not allowed, so here it is safe
443 if isinstance(self
, DecParser
):
444 SectionDictKey
= self
._SectionType
[0], ScopeKey
446 SectionDictKey
= self
._SectionType
, ScopeKey
448 self
._SectionsMacroDict
[SectionDictKey
][Name
] = Value
450 ## Get section Macros that are applicable to current line, which may come from other sections
451 ## that share the same name while scope is wider
452 def _GetApplicableSectionMacro(self
):
459 ActiveSectionType
= self
._SectionType
460 if isinstance(self
, DecParser
):
461 ActiveSectionType
= self
._SectionType
[0]
463 for (SectionType
, Scope
) in self
._SectionsMacroDict
:
464 if SectionType
!= ActiveSectionType
:
467 for ActiveScope
in self
._Scope
:
468 Scope0
, Scope1
, Scope2
= ActiveScope
[0], ActiveScope
[1], ActiveScope
[2]
469 if(Scope0
, Scope1
, Scope2
) not in Scope
:
472 SpeSpeMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
474 for ActiveScope
in self
._Scope
:
475 Scope0
, Scope1
, Scope2
= ActiveScope
[0], ActiveScope
[1], ActiveScope
[2]
476 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
:
479 ComSpeMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
481 if (TAB_COMMON
, TAB_COMMON
, TAB_COMMON
) in Scope
:
482 ComComMacroDict
.update(self
._SectionsMacroDict
[(SectionType
, Scope
)])
484 Macros
.update(ComComMacroDict
)
485 Macros
.update(ComSpeMacroDict
)
486 Macros
.update(SpeSpeMacroDict
)
490 def ProcessMultipleLineCODEValue(self
,Content
):
493 continuelinecount
= 0
495 for Index
in range(0, len(Content
)):
496 Line
= Content
[Index
]
498 CODELine
= CODELine
+ Line
499 continuelinecount
+=1
501 newContent
.append(CODELine
)
502 for _
in range(continuelinecount
):
503 newContent
.append("")
506 continuelinecount
= 0
509 newContent
.append(Line
)
511 if "{CODE(" not in Line
:
512 newContent
.append(Line
)
514 elif CODEPattern
.findall(Line
):
515 newContent
.append(Line
)
525 ## INF file parser class
527 # @param FilePath The path of platform description file
528 # @param FileType The raw data of DSC file
529 # @param Table Database used to retrieve module/package information
530 # @param Macros Macros used for replacement in file
532 class InfParser(MetaFileParser
):
533 # INF file supported data types (one type per section)
535 TAB_UNKNOWN
.upper() : MODEL_UNKNOWN
,
536 TAB_INF_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
537 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
538 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
539 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
540 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
541 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
542 TAB_PACKAGES
.upper() : MODEL_META_DATA_PACKAGE
,
543 TAB_NMAKE
.upper() : MODEL_META_DATA_NMAKE
,
544 TAB_INF_FIXED_PCD
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
545 TAB_INF_PATCH_PCD
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
546 TAB_INF_FEATURE_PCD
.upper() : MODEL_PCD_FEATURE_FLAG
,
547 TAB_INF_PCD_EX
.upper() : MODEL_PCD_DYNAMIC_EX
,
548 TAB_INF_PCD
.upper() : MODEL_PCD_DYNAMIC
,
549 TAB_SOURCES
.upper() : MODEL_EFI_SOURCE_FILE
,
550 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
551 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
552 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
553 TAB_DEPEX
.upper() : MODEL_EFI_DEPEX
,
554 TAB_BINARIES
.upper() : MODEL_EFI_BINARY_FILE
,
555 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
558 ## Constructor of InfParser
560 # Initialize object of InfParser
562 # @param FilePath The path of module description file
563 # @param FileType The raw data of DSC file
564 # @param Arch Default Arch value for filtering sections
565 # @param Table Database used to retrieve module/package information
567 def __init__(self
, FilePath
, FileType
, Arch
, Table
):
568 # prevent re-initialization
569 if hasattr(self
, "_Table"):
571 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
)
579 Content
= open(str(self
.MetaFile
), 'r').readlines()
581 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
583 # parse the file line by line
584 IsFindBlockComment
= False
585 GetHeaderComment
= False
590 for Index
in range(0, len(Content
)):
591 # skip empty, commented, block commented lines
592 Line
, Comment
= CleanString2(Content
[Index
], AllowCppStyleComment
=True)
594 if Index
+ 1 < len(Content
):
595 NextLine
, NextComment
= CleanString2(Content
[Index
+ 1])
598 Comments
.append((Comment
, Index
+ 1))
599 elif GetHeaderComment
:
600 SectionComments
.extend(Comments
)
603 if Line
.find(TAB_COMMENT_EDK_START
) > -1:
604 IsFindBlockComment
= True
606 if Line
.find(TAB_COMMENT_EDK_END
) > -1:
607 IsFindBlockComment
= False
609 if IsFindBlockComment
:
612 self
._LineIndex
= Index
613 self
._CurrentLine
= Line
616 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
617 if not GetHeaderComment
:
618 for Cmt
, LNo
in Comments
:
619 self
._Store
(MODEL_META_DATA_HEADER_COMMENT
, Cmt
, '', '', TAB_COMMON
,
620 TAB_COMMON
, self
._Owner
[-1], LNo
, -1, LNo
, -1, 0)
621 GetHeaderComment
= True
623 TailComments
.extend(SectionComments
+ Comments
)
625 self
._SectionHeaderParser
()
626 # Check invalid sections
627 if self
._Version
< 0x00010005:
628 if self
._SectionType
in [MODEL_META_DATA_BUILD_OPTION
,
629 MODEL_EFI_LIBRARY_CLASS
,
630 MODEL_META_DATA_PACKAGE
,
631 MODEL_PCD_FIXED_AT_BUILD
,
632 MODEL_PCD_PATCHABLE_IN_MODULE
,
633 MODEL_PCD_FEATURE_FLAG
,
634 MODEL_PCD_DYNAMIC_EX
,
639 MODEL_META_DATA_USER_EXTENSION
]:
640 EdkLogger
.error('Parser', FORMAT_INVALID
,
641 "Section [%s] is not allowed in inf file without version" % (self
._SectionName
),
642 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
643 elif self
._SectionType
in [MODEL_EFI_INCLUDE
,
644 MODEL_EFI_LIBRARY_INSTANCE
,
645 MODEL_META_DATA_NMAKE
]:
646 EdkLogger
.error('Parser', FORMAT_INVALID
,
647 "Section [%s] is not allowed in inf file with version 0x%08x" % (self
._SectionName
, self
._Version
),
648 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
650 # merge two lines specified by '\' in section NMAKE
651 elif self
._SectionType
== MODEL_META_DATA_NMAKE
:
654 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
657 if NextLine
[0] == TAB_SECTION_START
and NextLine
[-1] == TAB_SECTION_END
:
658 self
._CurrentLine
= NmakeLine
+ Line
[0:-1]
661 NmakeLine
= NmakeLine
+ ' ' + Line
[0:-1]
664 self
._CurrentLine
= NmakeLine
+ Line
668 self
._ValueList
= ['', '', '']
669 # parse current line, result will be put in self._ValueList
670 self
._SectionParser
[self
._SectionType
](self
)
671 if self
._ValueList
is None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
676 Comments
.append((Comment
, Index
+ 1))
677 if GlobalData
.gOptions
and GlobalData
.gOptions
.CheckUsage
:
678 CheckInfComment(self
._SectionType
, Comments
, str(self
.MetaFile
), Index
+ 1, self
._ValueList
)
680 # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
681 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
683 for Arch
, Platform
, _
in self
._Scope
:
684 LastItem
= self
._Store
(self
._SectionType
,
697 for Comment
, LineNo
in Comments
:
698 self
._Store
(MODEL_META_DATA_COMMENT
, Comment
, '', '', Arch
, Platform
,
699 LastItem
, LineNo
, -1, LineNo
, -1, 0)
702 TailComments
.extend(SectionComments
+ Comments
)
703 if IsFindBlockComment
:
704 EdkLogger
.error("Parser", FORMAT_INVALID
, "Open block comments (starting with /*) are expected to end with */",
707 # If there are tail comments in INF file, save to database whatever the comments are
708 for Comment
in TailComments
:
709 self
._Store
(MODEL_META_DATA_TAIL_COMMENT
, Comment
[0], '', '', TAB_COMMON
,
710 TAB_COMMON
, self
._Owner
[-1], -1, -1, -1, -1, 0)
713 ## Data parser for the format in which there's path
715 # Only path can have macro used. So we need to replace them before use.
717 def _IncludeParser(self
):
718 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
719 self
._ValueList
[0:len(TokenList
)] = TokenList
720 Macros
= self
._Macros
722 for Index
in range(0, len(self
._ValueList
)):
723 Value
= self
._ValueList
[Index
]
726 self
._ValueList
[Index
] = ReplaceMacro(Value
, Macros
)
728 ## Parse [Sources] section
730 # Only path can have macro used. So we need to replace them before use.
733 def _SourceFileParser(self
):
734 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
735 self
._ValueList
[0:len(TokenList
)] = TokenList
736 Macros
= self
._Macros
737 # For Acpi tables, remove macro like ' TABLE_NAME=Sata1'
738 if 'COMPONENT_TYPE' in Macros
:
739 if self
._Defines
['COMPONENT_TYPE'].upper() == 'ACPITABLE':
740 self
._ValueList
[0] = GetSplitValueList(self
._ValueList
[0], ' ', 1)[0]
741 if self
._Defines
['BASE_NAME'] == 'Microcode':
743 self
._ValueList
= [ReplaceMacro(Value
, Macros
) for Value
in self
._ValueList
]
745 ## Parse [Binaries] section
747 # Only path can have macro used. So we need to replace them before use.
750 def _BinaryFileParser(self
):
751 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 2)
752 if len(TokenList
) < 2:
753 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type or path specified",
754 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
755 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
757 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file type specified",
758 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
759 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
761 EdkLogger
.error('Parser', FORMAT_INVALID
, "No file path specified",
762 ExtraData
=self
._CurrentLine
+ " (<FileType> | <FilePath> [| <Target>])",
763 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
764 self
._ValueList
[0:len(TokenList
)] = TokenList
765 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
767 ## [nmake] section parser (Edk.x style only)
768 def _NmakeParser(self
):
769 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
770 self
._ValueList
[0:len(TokenList
)] = TokenList
772 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
)
773 # remove self-reference in macro setting
774 #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
776 ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
778 def _PcdParser(self
):
779 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
780 ValueList
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
781 if len(ValueList
) != 2:
782 EdkLogger
.error('Parser', FORMAT_INVALID
, "Illegal token space GUID and PCD name format",
783 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
784 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
785 self
._ValueList
[0:1] = ValueList
786 if len(TokenList
) > 1:
787 self
._ValueList
[2] = TokenList
[1]
788 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
789 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
790 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
791 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
793 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
794 if self
._ValueList
[2] != '':
795 InfPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
796 if InfPcdValueList
[0] in ['True', 'true', 'TRUE']:
797 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '1', 1)
798 elif InfPcdValueList
[0] in ['False', 'false', 'FALSE']:
799 self
._ValueList
[2] = TokenList
[1].replace(InfPcdValueList
[0], '0', 1)
800 elif isinstance(InfPcdValueList
[0], str) and InfPcdValueList
[0].find('$(') >= 0:
801 Value
= ReplaceExprMacro(InfPcdValueList
[0],self
._Macros
)
803 self
._ValueList
[2] = Value
804 if (self
._ValueList
[0], self
._ValueList
[1]) not in self
.PcdsDict
:
805 self
.PcdsDict
[self
._ValueList
[0], self
._ValueList
[1]] = self
._SectionType
806 elif self
.PcdsDict
[self
._ValueList
[0], self
._ValueList
[1]] != self
._SectionType
:
807 EdkLogger
.error('Parser', FORMAT_INVALID
, "It is not permissible to list a specified PCD in different PCD type sections.",
808 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<PcdCName>)",
809 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
811 ## [depex] section parser
813 def _DepexParser(self
):
814 self
._ValueList
[0:1] = [self
._CurrentLine
]
817 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
818 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
819 MODEL_META_DATA_BUILD_OPTION
: MetaFileParser
._BuildOptionParser
,
820 MODEL_EFI_INCLUDE
: _IncludeParser
, # for Edk.x modules
821 MODEL_EFI_LIBRARY_INSTANCE
: MetaFileParser
._CommonParser
, # for Edk.x modules
822 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
823 MODEL_META_DATA_PACKAGE
: MetaFileParser
._PathParser
,
824 MODEL_META_DATA_NMAKE
: _NmakeParser
, # for Edk.x modules
825 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
826 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
827 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
828 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
829 MODEL_PCD_DYNAMIC
: _PcdParser
,
830 MODEL_EFI_SOURCE_FILE
: _SourceFileParser
,
831 MODEL_EFI_GUID
: MetaFileParser
._CommonParser
,
832 MODEL_EFI_PROTOCOL
: MetaFileParser
._CommonParser
,
833 MODEL_EFI_PPI
: MetaFileParser
._CommonParser
,
834 MODEL_EFI_DEPEX
: _DepexParser
,
835 MODEL_EFI_BINARY_FILE
: _BinaryFileParser
,
836 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
839 ## DSC file parser class
841 # @param FilePath The path of platform description file
842 # @param FileType The raw data of DSC file
843 # @param Table Database used to retrieve module/package information
844 # @param Macros Macros used for replacement in file
845 # @param Owner Owner ID (for sub-section parsing)
846 # @param From ID from which the data comes (for !INCLUDE directive)
848 class DscParser(MetaFileParser
):
849 # DSC file supported data types (one type per section)
851 TAB_SKUIDS
.upper() : MODEL_EFI_SKU_ID
,
852 TAB_DEFAULT_STORES
.upper() : MODEL_EFI_DEFAULT_STORES
,
853 TAB_LIBRARIES
.upper() : MODEL_EFI_LIBRARY_INSTANCE
,
854 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
855 TAB_BUILD_OPTIONS
.upper() : MODEL_META_DATA_BUILD_OPTION
,
856 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
857 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
858 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
859 TAB_PCDS_DYNAMIC_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_DEFAULT
,
860 TAB_PCDS_DYNAMIC_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_HII
,
861 TAB_PCDS_DYNAMIC_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_VPD
,
862 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT
,
863 TAB_PCDS_DYNAMIC_EX_HII_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_HII
,
864 TAB_PCDS_DYNAMIC_EX_VPD_NULL
.upper() : MODEL_PCD_DYNAMIC_EX_VPD
,
865 TAB_COMPONENTS
.upper() : MODEL_META_DATA_COMPONENT
,
866 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
.upper() : MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
,
867 TAB_DSC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
868 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
869 TAB_DSC_DEFINES_EDKGLOBAL
: MODEL_META_DATA_GLOBAL_DEFINE
,
870 TAB_INCLUDE
.upper() : MODEL_META_DATA_INCLUDE
,
871 TAB_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
872 TAB_IF_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
873 TAB_IF_N_DEF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
,
874 TAB_ELSE_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
,
875 TAB_ELSE
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
,
876 TAB_END_IF
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
,
877 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
,
878 TAB_ERROR
.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR
,
881 # Valid names in define section
888 "PCD_INFO_GENERATION",
889 "PCD_VAR_CHECK_GENERATION",
890 "SUPPORTED_ARCHITECTURES",
899 "FIX_LOAD_TOP_MEMORY_ADDRESS",
904 SubSectionDefineKeywords
= [
908 SymbolPattern
= ValueExpression
.SymbolPattern
910 IncludedFiles
= set()
912 ## Constructor of DscParser
914 # Initialize object of DscParser
916 # @param FilePath The path of platform description file
917 # @param FileType The raw data of DSC file
918 # @param Arch Default Arch value for filtering sections
919 # @param Table Database used to retrieve module/package information
920 # @param Owner Owner ID (for sub-section parsing)
921 # @param From ID from which the data comes (for !INCLUDE directive)
923 def __init__(self
, FilePath
, FileType
, Arch
, Table
, Owner
= -1, From
= -1):
924 # prevent re-initialization
925 if hasattr(self
, "_Table") and self
._Table
is Table
:
927 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
, Owner
, From
)
928 self
._Version
= 0x00010005 # Only EDK2 dsc file is supported
929 # to store conditional directive evaluation result
930 self
._DirectiveStack
= []
931 self
._DirectiveEvalStack
= []
935 # Specify whether current line is in uncertain condition
937 self
._InDirective
= -1
939 # Final valid replacable symbols
942 # Map the ID between the original table and new table to track
945 self
._IdMapping
= {-1:-1}
953 Content
= open(str(self
.MetaFile
), 'r').readlines()
955 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
959 Content
= self
.ProcessMultipleLineCODEValue(Content
)
961 for Index
in range(0, len(Content
)):
962 Line
= CleanString(Content
[Index
])
967 self
._CurrentLine
= Line
968 self
._LineIndex
= Index
969 if self
._InSubsection
and self
._Owner
[-1] == -1:
970 self
._Owner
.append(self
._LastItem
)
973 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
974 self
._SectionType
= MODEL_META_DATA_SECTION_HEADER
976 elif Line
[0] == '}' and self
._InSubsection
:
977 self
._InSubsection
= False
978 self
._SubsectionType
= MODEL_UNKNOWN
979 self
._SubsectionName
= ''
984 elif Line
[0] == TAB_OPTION_START
and Line
[-1] == TAB_OPTION_END
:
985 self
._SubsectionType
= MODEL_META_DATA_SUBSECTION_HEADER
988 TokenList
= GetSplitValueList(Line
, ' ', 1)
989 if TokenList
[0] == TAB_INCLUDE
:
990 for Arch
, ModuleType
, DefaultStore
in self
._Scope
:
991 if self
._SubsectionType
!= MODEL_UNKNOWN
and Arch
in OwnerId
:
992 self
._Owner
[-1] = OwnerId
[Arch
]
993 self
._DirectiveParser
()
995 self
._DirectiveParser
()
997 if Line
[0] == TAB_OPTION_START
and not self
._InSubsection
:
998 EdkLogger
.error("Parser", FILE_READ_FAILURE
, "Missing the '{' before %s in Line %s" % (Line
, Index
+1), ExtraData
=self
.MetaFile
)
1000 if self
._InSubsection
:
1001 SectionType
= self
._SubsectionType
1003 SectionType
= self
._SectionType
1004 self
._ItemType
= SectionType
1006 self
._ValueList
= ['', '', '']
1007 # "SET pcd = pcd_expression" syntax is not supported in Dsc file.
1008 if self
._CurrentLine
.upper().strip().startswith("SET "):
1009 EdkLogger
.error('Parser', FORMAT_INVALID
, '''"SET pcd = pcd_expression" syntax is not support in Dsc file''',
1010 ExtraData
=self
._CurrentLine
,
1011 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1012 self
._SectionParser
[SectionType
](self
)
1013 if self
._ValueList
is None:
1016 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
1017 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
1019 for Arch
, ModuleType
, DefaultStore
in self
._Scope
:
1020 Owner
= self
._Owner
[-1]
1021 if self
._SubsectionType
!= MODEL_UNKNOWN
and Arch
in OwnerId
:
1022 Owner
= OwnerId
[Arch
]
1023 self
._LastItem
= self
._Store
(
1033 self
._LineIndex
+ 1,
1035 self
._LineIndex
+ 1,
1039 if self
._SubsectionType
== MODEL_UNKNOWN
and self
._InSubsection
:
1040 OwnerId
[Arch
] = self
._LastItem
1042 if self
._DirectiveStack
:
1043 Type
, Line
, Text
= self
._DirectiveStack
[-1]
1044 EdkLogger
.error('Parser', FORMAT_INVALID
, "No matching '!endif' found",
1045 ExtraData
=Text
, File
=self
.MetaFile
, Line
=Line
)
1048 ## <subsection_header> parser
1049 def _SubsectionHeaderParser(self
):
1050 self
._SubsectionName
= self
._CurrentLine
[1:-1].upper()
1051 if self
._SubsectionName
in self
.DataType
:
1052 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
1054 self
._SubsectionType
= MODEL_UNKNOWN
1055 EdkLogger
.warn("Parser", "Unrecognized sub-section", File
=self
.MetaFile
,
1056 Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1057 self
._ValueList
[0] = self
._SubsectionName
1059 ## Directive statement parser
1060 def _DirectiveParser(self
):
1061 self
._ValueList
= ['', '', '']
1062 TokenList
= GetSplitValueList(self
._CurrentLine
, ' ', 1)
1063 self
._ValueList
[0:len(TokenList
)] = TokenList
1066 DirectiveName
= self
._ValueList
[0].upper()
1067 if DirectiveName
not in self
.DataType
:
1068 EdkLogger
.error("Parser", FORMAT_INVALID
, "Unknown directive [%s]" % DirectiveName
,
1069 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1071 if DirectiveName
in ['!IF', '!IFDEF', '!IFNDEF']:
1072 self
._InDirective
+= 1
1074 if DirectiveName
in ['!ENDIF']:
1075 self
._InDirective
-= 1
1077 if DirectiveName
in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self
._ValueList
[1] == '':
1078 EdkLogger
.error("Parser", FORMAT_INVALID
, "Missing expression",
1079 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1080 ExtraData
=self
._CurrentLine
)
1082 ItemType
= self
.DataType
[DirectiveName
]
1083 Scope
= [[TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]]
1084 if ItemType
== MODEL_META_DATA_INCLUDE
:
1086 elif ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR
:
1088 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1089 # Remove all directives between !if and !endif, including themselves
1090 while self
._DirectiveStack
:
1091 # Remove any !else or !elseif
1092 DirectiveInfo
= self
._DirectiveStack
.pop()
1093 if DirectiveInfo
[0] in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1094 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1095 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1098 EdkLogger
.error("Parser", FORMAT_INVALID
, "Redundant '!endif'",
1099 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1100 ExtraData
=self
._CurrentLine
)
1101 elif ItemType
not in {MODEL_META_DATA_INCLUDE
, MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR
}:
1102 # Break if there's a !else is followed by a !elseif
1103 if ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
and \
1104 self
._DirectiveStack
and \
1105 self
._DirectiveStack
[-1][0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1106 EdkLogger
.error("Parser", FORMAT_INVALID
, "'!elseif' after '!else'",
1107 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1,
1108 ExtraData
=self
._CurrentLine
)
1109 self
._DirectiveStack
.append((ItemType
, self
._LineIndex
+ 1, self
._CurrentLine
))
1112 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
1113 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
1115 for Arch
, ModuleType
, DefaultStore
in Scope
:
1116 self
._LastItem
= self
._Store
(
1126 self
._LineIndex
+ 1,
1128 self
._LineIndex
+ 1,
1133 ## [defines] section parser
1135 def _DefineParser(self
):
1136 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1137 self
._ValueList
[1:len(TokenList
)] = TokenList
1140 if not self
._ValueList
[1]:
1141 EdkLogger
.error('Parser', FORMAT_INVALID
, "No name specified",
1142 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1143 if not self
._ValueList
[2]:
1144 EdkLogger
.error('Parser', FORMAT_INVALID
, "No value specified",
1145 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1146 if (not self
._ValueList
[1] in self
.DefineKeywords
and
1147 (self
._InSubsection
and self
._ValueList
[1] not in self
.SubSectionDefineKeywords
)):
1148 EdkLogger
.error('Parser', FORMAT_INVALID
,
1149 "Unknown keyword found: %s. "
1150 "If this is a macro you must "
1151 "add it as a DEFINE in the DSC" % self
._ValueList
[1],
1152 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1153 if not self
._InSubsection
:
1154 self
._Defines
[self
._ValueList
[1]] = self
._ValueList
[2]
1155 self
._ItemType
= self
.DataType
[TAB_DSC_DEFINES
.upper()]
1158 def _SkuIdParser(self
):
1159 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1160 if len(TokenList
) not in (2, 3):
1161 EdkLogger
.error('Parser', FORMAT_INVALID
, "Correct format is '<Number>|<UiName>[|<UiName>]'",
1162 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1163 self
._ValueList
[0:len(TokenList
)] = TokenList
1165 def _DefaultStoresParser(self
):
1166 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1167 if len(TokenList
) != 2:
1168 EdkLogger
.error('Parser', FORMAT_INVALID
, "Correct format is '<Number>|<UiName>'",
1169 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1170 self
._ValueList
[0:len(TokenList
)] = TokenList
1172 ## Parse Edk style of library modules
1174 def _LibraryInstanceParser(self
):
1175 self
._ValueList
[0] = self
._CurrentLine
1178 def _DecodeCODEData(self
):
1180 ## PCD sections parser
1182 # [PcdsFixedAtBuild]
1183 # [PcdsPatchableInModule]
1186 # [PcdsDynamicExDefault]
1187 # [PcdsDynamicExVpd]
1188 # [PcdsDynamicExHii]
1190 # [PcdsDynamicDefault]
1195 def _PcdParser(self
):
1196 if self
._PcdDataTypeCODE
:
1197 self
._PcdCodeValue
= self
._PcdCodeValue
+ "\n " + self
._CurrentLine
1198 if self
._CurrentLine
.endswith(")}"):
1199 self
._CurrentLine
= "|".join((self
._CurrentPcdName
, self
._PcdCodeValue
))
1200 self
._PcdDataTypeCODE
= False
1201 self
._PcdCodeValue
= ""
1203 self
._ValueList
= None
1205 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
1206 self
._CurrentPcdName
= TokenList
[0]
1207 if len(TokenList
) == 2 and TokenList
[1].strip().startswith("{CODE"):
1208 self
._PcdDataTypeCODE
= True
1209 self
._PcdCodeValue
= TokenList
[1].strip()
1211 if self
._PcdDataTypeCODE
:
1212 if self
._CurrentLine
.endswith(")}"):
1213 self
._PcdDataTypeCODE
= False
1214 self
._PcdCodeValue
= ""
1216 self
._ValueList
= None
1218 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1219 PcdNameTockens
= GetSplitValueList(TokenList
[0], TAB_SPLIT
)
1220 if len(PcdNameTockens
) == 2:
1221 self
._ValueList
[0], self
._ValueList
[1] = PcdNameTockens
[0], PcdNameTockens
[1]
1222 elif len(PcdNameTockens
) == 3:
1223 self
._ValueList
[0], self
._ValueList
[1] = ".".join((PcdNameTockens
[0], PcdNameTockens
[1])), PcdNameTockens
[2]
1224 elif len(PcdNameTockens
) > 3:
1225 self
._ValueList
[0], self
._ValueList
[1] = ".".join((PcdNameTockens
[0], PcdNameTockens
[1])), ".".join(PcdNameTockens
[2:])
1226 if len(TokenList
) == 2:
1227 self
._ValueList
[2] = TokenList
[1]
1228 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
1229 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
1230 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1231 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1232 if self
._ValueList
[2] == '':
1234 # The PCD values are optional for FIXEDATBUILD, PATCHABLEINMODULE, Dynamic/DynamicEx default
1236 if self
._SectionType
in (MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
):
1238 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD value given",
1239 ExtraData
=self
._CurrentLine
+ " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1240 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1242 # Validate the datum type of Dynamic Defaul PCD and DynamicEx Default PCD
1243 ValueList
= GetSplitValueList(self
._ValueList
[2])
1244 if len(ValueList
) > 1 and ValueList
[1] in [TAB_UINT8
, TAB_UINT16
, TAB_UINT32
, TAB_UINT64
] \
1245 and self
._ItemType
in [MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
]:
1246 EdkLogger
.error('Parser', FORMAT_INVALID
, "The datum type '%s' of PCD is wrong" % ValueList
[1],
1247 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1249 # Validate the VariableName of DynamicHii and DynamicExHii for PCD Entry must not be an empty string
1250 if self
._ItemType
in [MODEL_PCD_DYNAMIC_HII
, MODEL_PCD_DYNAMIC_EX_HII
]:
1251 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
1252 if len(DscPcdValueList
[0].replace('L', '').replace('"', '').strip()) == 0:
1253 EdkLogger
.error('Parser', FORMAT_INVALID
, "The VariableName field in the HII format PCD entry must not be an empty string",
1254 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1256 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
1257 DscPcdValueList
= GetSplitValueList(TokenList
[1], TAB_VALUE_SPLIT
, 1)
1258 if DscPcdValueList
[0] in ['True', 'true', 'TRUE']:
1259 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '1', 1);
1260 elif DscPcdValueList
[0] in ['False', 'false', 'FALSE']:
1261 self
._ValueList
[2] = TokenList
[1].replace(DscPcdValueList
[0], '0', 1);
1264 ## [components] section parser
1266 def _ComponentParser(self
):
1267 if self
._CurrentLine
[-1] == '{':
1268 self
._ValueList
[0] = self
._CurrentLine
[0:-1].strip()
1269 self
._InSubsection
= True
1270 self
._SubsectionType
= MODEL_UNKNOWN
1272 self
._ValueList
[0] = self
._CurrentLine
1274 ## [LibraryClasses] section
1276 def _LibraryClassParser(self
):
1277 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
)
1278 if len(TokenList
) < 2:
1279 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class or instance specified",
1280 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1281 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1282 if TokenList
[0] == '':
1283 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library class specified",
1284 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1285 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1286 if TokenList
[1] == '':
1287 EdkLogger
.error('Parser', FORMAT_INVALID
, "No library instance specified",
1288 ExtraData
=self
._CurrentLine
+ " (<LibraryClassName>|<LibraryInstancePath>)",
1289 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1291 self
._ValueList
[0:len(TokenList
)] = TokenList
1293 def _CompponentSourceOverridePathParser(self
):
1294 self
._ValueList
[0] = self
._CurrentLine
1296 ## [BuildOptions] section parser
1298 def _BuildOptionParser(self
):
1299 self
._CurrentLine
= CleanString(self
._CurrentLine
, BuildOption
=True)
1300 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1301 TokenList2
= GetSplitValueList(TokenList
[0], ':', 1)
1302 if len(TokenList2
) == 2:
1303 self
._ValueList
[0] = TokenList2
[0] # toolchain family
1304 self
._ValueList
[1] = TokenList2
[1] # keys
1306 self
._ValueList
[1] = TokenList
[0]
1307 if len(TokenList
) == 2: # value
1308 self
._ValueList
[2] = TokenList
[1]
1310 if self
._ValueList
[1].count('_') != 4:
1314 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self
._ValueList
[1],
1315 ExtraData
=self
._CurrentLine
,
1317 Line
=self
._LineIndex
+ 1
1320 ## Override parent's method since we'll do all macro replacements in parser
1324 Macros
.update(self
._FileLocalMacros
)
1325 Macros
.update(self
._GetApplicableSectionMacro
())
1326 Macros
.update(GlobalData
.gEdkGlobal
)
1327 Macros
.update(GlobalData
.gPlatformDefines
)
1328 Macros
.update(GlobalData
.gCommandLineDefines
)
1329 # PCD cannot be referenced in macro definition
1330 if self
._ItemType
not in [MODEL_META_DATA_DEFINE
, MODEL_META_DATA_GLOBAL_DEFINE
]:
1331 Macros
.update(self
._Symbols
)
1332 if GlobalData
.BuildOptionPcd
:
1333 for Item
in GlobalData
.BuildOptionPcd
:
1334 if isinstance(Item
, tuple):
1336 PcdName
, TmpValue
= Item
.split("=")
1337 TmpValue
= BuildOptionValue(TmpValue
, self
._GuidDict
)
1338 Macros
[PcdName
.strip()] = TmpValue
1341 def _PostProcess(self
):
1343 MODEL_META_DATA_SECTION_HEADER
: self
.__ProcessSectionHeader
,
1344 MODEL_META_DATA_SUBSECTION_HEADER
: self
.__ProcessSubsectionHeader
,
1345 MODEL_META_DATA_HEADER
: self
.__ProcessDefine
,
1346 MODEL_META_DATA_DEFINE
: self
.__ProcessDefine
,
1347 MODEL_META_DATA_GLOBAL_DEFINE
: self
.__ProcessDefine
,
1348 MODEL_META_DATA_INCLUDE
: self
.__ProcessDirective
,
1349 MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
: self
.__ProcessDirective
,
1350 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
: self
.__ProcessDirective
,
1351 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
: self
.__ProcessDirective
,
1352 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
: self
.__ProcessDirective
,
1353 MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
: self
.__ProcessDirective
,
1354 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
: self
.__ProcessDirective
,
1355 MODEL_EFI_SKU_ID
: self
.__ProcessSkuId
,
1356 MODEL_EFI_DEFAULT_STORES
: self
.__ProcessDefaultStores
,
1357 MODEL_EFI_LIBRARY_INSTANCE
: self
.__ProcessLibraryInstance
,
1358 MODEL_EFI_LIBRARY_CLASS
: self
.__ProcessLibraryClass
,
1359 MODEL_PCD_FIXED_AT_BUILD
: self
.__ProcessPcd
,
1360 MODEL_PCD_PATCHABLE_IN_MODULE
: self
.__ProcessPcd
,
1361 MODEL_PCD_FEATURE_FLAG
: self
.__ProcessPcd
,
1362 MODEL_PCD_DYNAMIC_DEFAULT
: self
.__ProcessPcd
,
1363 MODEL_PCD_DYNAMIC_HII
: self
.__ProcessPcd
,
1364 MODEL_PCD_DYNAMIC_VPD
: self
.__ProcessPcd
,
1365 MODEL_PCD_DYNAMIC_EX_DEFAULT
: self
.__ProcessPcd
,
1366 MODEL_PCD_DYNAMIC_EX_HII
: self
.__ProcessPcd
,
1367 MODEL_PCD_DYNAMIC_EX_VPD
: self
.__ProcessPcd
,
1368 MODEL_META_DATA_COMPONENT
: self
.__ProcessComponent
,
1369 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: self
.__ProcessSourceOverridePath
,
1370 MODEL_META_DATA_BUILD_OPTION
: self
.__ProcessBuildOption
,
1371 MODEL_UNKNOWN
: self
._Skip
,
1372 MODEL_META_DATA_USER_EXTENSION
: self
._SkipUserExtension
,
1373 MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR
: self
._ProcessError
,
1376 self
._Table
= MetaFileStorage(self
._RawTable
.DB
, self
.MetaFile
, MODEL_FILE_DSC
, True)
1377 self
._DirectiveStack
= []
1378 self
._DirectiveEvalStack
= []
1379 self
._FileWithError
= self
.MetaFile
1380 self
._FileLocalMacros
= {}
1381 self
._SectionsMacroDict
.clear()
1382 GlobalData
.gPlatformDefines
= {}
1384 # Get all macro and PCD which has straitforward value
1385 self
.__RetrievePcdValue
()
1386 self
._Content
= self
._RawTable
.GetAll()
1387 self
._ContentIndex
= 0
1388 self
._InSubsection
= False
1389 while self
._ContentIndex
< len(self
._Content
) :
1390 Id
, self
._ItemType
, V1
, V2
, V3
, S1
, S2
, S3
, Owner
, self
._From
, \
1391 LineStart
, ColStart
, LineEnd
, ColEnd
, Enabled
= self
._Content
[self
._ContentIndex
]
1394 self
._FileWithError
= self
.MetaFile
1396 self
._ContentIndex
+= 1
1398 self
._Scope
= [[S1
, S2
, S3
]]
1400 # For !include directive, handle it specially,
1401 # merge arch and module type in case of duplicate items
1403 while self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1404 if self
._ContentIndex
>= len(self
._Content
):
1406 Record
= self
._Content
[self
._ContentIndex
]
1407 if LineStart
== Record
[10] and LineEnd
== Record
[12]:
1408 if [Record
[5], Record
[6], Record
[7]] not in self
._Scope
:
1409 self
._Scope
.append([Record
[5], Record
[6], Record
[7]])
1410 self
._ContentIndex
+= 1
1414 self
._LineIndex
= LineStart
- 1
1415 self
._ValueList
= [V1
, V2
, V3
]
1417 if Owner
> 0 and Owner
in self
._IdMapping
:
1418 self
._InSubsection
= True
1420 self
._InSubsection
= False
1422 Processer
[self
._ItemType
]()
1423 except EvaluationException
as Excpt
:
1425 # Only catch expression evaluation error here. We need to report
1426 # the precise number of line on which the error occurred
1428 if hasattr(Excpt
, 'Pcd'):
1429 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
1430 Info
= GlobalData
.gPlatformOtherPcds
[Excpt
.Pcd
]
1431 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
1432 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
1433 " of the DSC file, and it is currently defined in this section:"
1434 " %s, line #: %d." % (Excpt
.Pcd
, Info
[0], Info
[1]),
1435 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1436 Line
=self
._LineIndex
+ 1)
1438 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
1439 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1440 Line
=self
._LineIndex
+ 1)
1442 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
1443 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1444 Line
=self
._LineIndex
+ 1)
1445 except MacroException
as Excpt
:
1446 EdkLogger
.error('Parser', FORMAT_INVALID
, str(Excpt
),
1447 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1448 Line
=self
._LineIndex
+ 1)
1450 if self
._ValueList
is None:
1453 NewOwner
= self
._IdMapping
.get(Owner
, -1)
1454 self
._Enabled
= int((not self
._DirectiveEvalStack
) or (False not in self
._DirectiveEvalStack
))
1455 self
._LastItem
= self
._Store
(
1465 self
._LineIndex
+ 1,
1467 self
._LineIndex
+ 1,
1471 self
._IdMapping
[Id
] = self
._LastItem
1473 GlobalData
.gPlatformDefines
.update(self
._FileLocalMacros
)
1474 self
._PostProcessed
= True
1475 self
._Content
= None
1476 def _ProcessError(self
):
1477 if not self
._Enabled
:
1479 EdkLogger
.error('Parser', ERROR_STATEMENT
, self
._ValueList
[1], File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1481 def __ProcessSectionHeader(self
):
1482 self
._SectionName
= self
._ValueList
[0]
1483 if self
._SectionName
in self
.DataType
:
1484 self
._SectionType
= self
.DataType
[self
._SectionName
]
1486 self
._SectionType
= MODEL_UNKNOWN
1488 def __ProcessSubsectionHeader(self
):
1489 self
._SubsectionName
= self
._ValueList
[0]
1490 if self
._SubsectionName
in self
.DataType
:
1491 self
._SubsectionType
= self
.DataType
[self
._SubsectionName
]
1493 self
._SubsectionType
= MODEL_UNKNOWN
1495 def __RetrievePcdValue(self
):
1496 Content
= open(str(self
.MetaFile
), 'r').readlines()
1497 GlobalData
.gPlatformOtherPcds
['DSCFILE'] = str(self
.MetaFile
)
1498 for PcdType
in (MODEL_PCD_PATCHABLE_IN_MODULE
, MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_HII
,
1499 MODEL_PCD_DYNAMIC_VPD
, MODEL_PCD_DYNAMIC_EX_DEFAULT
, MODEL_PCD_DYNAMIC_EX_HII
,
1500 MODEL_PCD_DYNAMIC_EX_VPD
):
1501 Records
= self
._RawTable
.Query(PcdType
, BelongsToItem
= -1.0)
1502 for TokenSpaceGuid
, PcdName
, Value
, Dummy2
, Dummy3
, Dummy4
, ID
, Line
in Records
:
1503 Name
= TokenSpaceGuid
+ '.' + PcdName
1504 if Name
not in GlobalData
.gPlatformOtherPcds
:
1506 while not Content
[Line
- 1].lstrip().startswith(TAB_SECTION_START
):
1508 GlobalData
.gPlatformOtherPcds
[Name
] = (CleanString(Content
[Line
- 1]), PcdLine
, PcdType
)
1510 def __ProcessDefine(self
):
1511 if not self
._Enabled
:
1514 Type
, Name
, Value
= self
._ValueList
1515 Value
= ReplaceMacro(Value
, self
._Macros
, False)
1517 # If it is <Defines>, return
1519 if self
._InSubsection
:
1520 self
._ValueList
= [Type
, Name
, Value
]
1523 if self
._ItemType
== MODEL_META_DATA_DEFINE
:
1524 if self
._SectionType
== MODEL_META_DATA_HEADER
:
1525 self
._FileLocalMacros
[Name
] = Value
1527 self
._ConstructSectionMacroDict
(Name
, Value
)
1528 elif self
._ItemType
== MODEL_META_DATA_GLOBAL_DEFINE
:
1529 GlobalData
.gEdkGlobal
[Name
] = Value
1532 # Keyword in [Defines] section can be used as Macros
1534 if (self
._ItemType
== MODEL_META_DATA_HEADER
) and (self
._SectionType
== MODEL_META_DATA_HEADER
):
1535 self
._FileLocalMacros
[Name
] = Value
1537 self
._ValueList
= [Type
, Name
, Value
]
1539 def __ProcessDirective(self
):
1541 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1542 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
]:
1543 Macros
= self
._Macros
1544 Macros
.update(GlobalData
.gGlobalDefines
)
1546 Result
= ValueExpression(self
._ValueList
[1], Macros
)()
1547 except SymbolNotFound
as Exc
:
1548 EdkLogger
.debug(EdkLogger
.DEBUG_5
, str(Exc
), self
._ValueList
[1])
1550 except WrnExpression
as Excpt
:
1552 # Catch expression evaluation warning here. We need to report
1553 # the precise number of line and return the evaluation result
1555 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
1556 File
=self
._FileWithError
, ExtraData
=' '.join(self
._ValueList
),
1557 Line
=self
._LineIndex
+ 1)
1558 Result
= Excpt
.result
1560 if self
._ItemType
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1561 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1562 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1563 self
._DirectiveStack
.append(self
._ItemType
)
1564 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
:
1565 Result
= bool(Result
)
1567 Macro
= self
._ValueList
[1]
1568 Macro
= Macro
[2:-1] if (Macro
.startswith("$(") and Macro
.endswith(")")) else Macro
1569 Result
= Macro
in self
._Macros
1570 if self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
:
1572 self
._DirectiveEvalStack
.append(Result
)
1573 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF
:
1574 self
._DirectiveStack
.append(self
._ItemType
)
1575 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1576 self
._DirectiveEvalStack
.append(bool(Result
))
1577 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE
:
1578 self
._DirectiveStack
.append(self
._ItemType
)
1579 self
._DirectiveEvalStack
[-1] = not self
._DirectiveEvalStack
[-1]
1580 self
._DirectiveEvalStack
.append(True)
1581 elif self
._ItemType
== MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF
:
1582 # Back to the nearest !if/!ifdef/!ifndef
1583 while self
._DirectiveStack
:
1584 self
._DirectiveEvalStack
.pop()
1585 Directive
= self
._DirectiveStack
.pop()
1586 if Directive
in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF
,
1587 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF
,
1588 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF
]:
1590 elif self
._ItemType
== MODEL_META_DATA_INCLUDE
:
1591 # The included file must be relative to workspace or same directory as DSC file
1592 __IncludeMacros
= {}
1594 # Allow using system environment variables in path after !include
1596 __IncludeMacros
['WORKSPACE'] = GlobalData
.gGlobalDefines
['WORKSPACE']
1598 # Allow using MACROs comes from [Defines] section to keep compatible.
1600 __IncludeMacros
.update(self
._Macros
)
1602 IncludedFile
= NormPath(ReplaceMacro(self
._ValueList
[1], __IncludeMacros
, RaiseError
=True))
1604 # First search the include file under the same directory as DSC file
1606 IncludedFile1
= PathClass(IncludedFile
, self
.MetaFile
.Dir
)
1607 ErrorCode
, ErrorInfo1
= IncludedFile1
.Validate()
1610 # Also search file under the WORKSPACE directory
1612 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
1613 ErrorCode
, ErrorInfo2
= IncludedFile1
.Validate()
1615 EdkLogger
.error('parser', ErrorCode
, File
=self
._FileWithError
,
1616 Line
=self
._LineIndex
+ 1, ExtraData
=ErrorInfo1
+ "\n" + ErrorInfo2
)
1618 self
._FileWithError
= IncludedFile1
1620 FromItem
= self
._Content
[self
._ContentIndex
- 1][0]
1621 if self
._InSubsection
:
1622 Owner
= self
._Content
[self
._ContentIndex
- 1][8]
1624 Owner
= self
._Content
[self
._ContentIndex
- 1][0]
1625 IncludedFileTable
= MetaFileStorage(self
._RawTable
.DB
, IncludedFile1
, MODEL_FILE_DSC
, False, FromItem
=FromItem
)
1626 Parser
= DscParser(IncludedFile1
, self
._FileType
, self
._Arch
, IncludedFileTable
,
1627 Owner
=Owner
, From
=FromItem
)
1629 self
.IncludedFiles
.add (IncludedFile1
)
1631 # set the parser status with current status
1632 Parser
._SectionName
= self
._SectionName
1633 Parser
._SubsectionType
= self
._SubsectionType
1634 Parser
._InSubsection
= self
._InSubsection
1635 Parser
._SectionType
= self
._SectionType
1636 Parser
._Scope
= self
._Scope
1637 Parser
._Enabled
= self
._Enabled
1638 # Parse the included file
1640 # Insert all records in the table for the included file into dsc file table
1641 Records
= IncludedFileTable
.GetAll()
1643 self
._Content
[self
._ContentIndex
:self
._ContentIndex
] = Records
1644 self
._Content
.pop(self
._ContentIndex
- 1)
1645 self
._ValueList
= None
1646 self
._ContentIndex
-= 1
1648 def __ProcessSkuId(self
):
1649 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=True)
1650 for Value
in self
._ValueList
]
1651 def __ProcessDefaultStores(self
):
1652 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=True)
1653 for Value
in self
._ValueList
]
1655 def __ProcessLibraryInstance(self
):
1656 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
) for Value
in self
._ValueList
]
1658 def __ProcessLibraryClass(self
):
1659 self
._ValueList
[1] = ReplaceMacro(self
._ValueList
[1], self
._Macros
, RaiseError
=True)
1661 def __ProcessPcd(self
):
1662 if self
._ItemType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
1663 self
._ValueList
[2] = ReplaceMacro(self
._ValueList
[2], self
._Macros
, RaiseError
=True)
1666 ValList
, Valid
, Index
= AnalyzeDscPcd(self
._ValueList
[2], self
._ItemType
)
1668 if self
._ItemType
in (MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
, MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
):
1669 if ValList
[1] != TAB_VOID
and StructPattern
.match(ValList
[1]) is None and ValList
[2]:
1670 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect. The datum type info should be VOID* or a valid struct name.", File
=self
._FileWithError
,
1671 Line
=self
._LineIndex
+ 1, ExtraData
="%s.%s|%s" % (self
._ValueList
[0], self
._ValueList
[1], self
._ValueList
[2]))
1672 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
._FileWithError
, Line
=self
._LineIndex
+ 1,
1673 ExtraData
="%s.%s|%s" % (self
._ValueList
[0], self
._ValueList
[1], self
._ValueList
[2]))
1674 PcdValue
= ValList
[Index
]
1675 if PcdValue
and "." not in self
._ValueList
[0]:
1677 ValList
[Index
] = ValueExpression(PcdValue
, self
._Macros
)(True)
1678 except WrnExpression
as Value
:
1679 ValList
[Index
] = Value
.result
1683 if ValList
[Index
] == 'True':
1684 ValList
[Index
] = '1'
1685 if ValList
[Index
] == 'False':
1686 ValList
[Index
] = '0'
1688 if (not self
._DirectiveEvalStack
) or (False not in self
._DirectiveEvalStack
):
1689 GlobalData
.gPlatformPcds
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = PcdValue
1690 self
._Symbols
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = PcdValue
1692 self
._ValueList
[2] = '|'.join(ValList
)
1696 def __ProcessComponent(self
):
1697 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1699 def __ProcessSourceOverridePath(self
):
1700 self
._ValueList
[0] = ReplaceMacro(self
._ValueList
[0], self
._Macros
)
1702 def __ProcessBuildOption(self
):
1703 self
._ValueList
= [ReplaceMacro(Value
, self
._Macros
, RaiseError
=False)
1704 for Value
in self
._ValueList
]
1706 def DisableOverrideComponent(self
,module_id
):
1707 for ori_id
in self
._IdMapping
:
1708 if self
._IdMapping
[ori_id
] == module_id
:
1709 self
._RawTable
.DisableComponent(ori_id
)
1712 MODEL_META_DATA_HEADER
: _DefineParser
,
1713 MODEL_EFI_SKU_ID
: _SkuIdParser
,
1714 MODEL_EFI_DEFAULT_STORES
: _DefaultStoresParser
,
1715 MODEL_EFI_LIBRARY_INSTANCE
: _LibraryInstanceParser
,
1716 MODEL_EFI_LIBRARY_CLASS
: _LibraryClassParser
,
1717 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
1718 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
1719 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
1720 MODEL_PCD_DYNAMIC_DEFAULT
: _PcdParser
,
1721 MODEL_PCD_DYNAMIC_HII
: _PcdParser
,
1722 MODEL_PCD_DYNAMIC_VPD
: _PcdParser
,
1723 MODEL_PCD_DYNAMIC_EX_DEFAULT
: _PcdParser
,
1724 MODEL_PCD_DYNAMIC_EX_HII
: _PcdParser
,
1725 MODEL_PCD_DYNAMIC_EX_VPD
: _PcdParser
,
1726 MODEL_META_DATA_COMPONENT
: _ComponentParser
,
1727 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
: _CompponentSourceOverridePathParser
,
1728 MODEL_META_DATA_BUILD_OPTION
: _BuildOptionParser
,
1729 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
1730 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
1731 MODEL_META_DATA_SECTION_HEADER
: MetaFileParser
._SectionHeaderParser
,
1732 MODEL_META_DATA_SUBSECTION_HEADER
: _SubsectionHeaderParser
,
1735 ## DEC file parser class
1737 # @param FilePath The path of platform description file
1738 # @param FileType The raw data of DSC file
1739 # @param Table Database used to retrieve module/package information
1740 # @param Macros Macros used for replacement in file
1742 class DecParser(MetaFileParser
):
1743 # DEC file supported data types (one type per section)
1745 TAB_DEC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
1746 TAB_DSC_DEFINES_DEFINE
: MODEL_META_DATA_DEFINE
,
1747 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
1748 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
1749 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
1750 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
1751 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
1752 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
1753 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
1754 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
1755 TAB_PCDS_DYNAMIC_NULL
.upper() : MODEL_PCD_DYNAMIC
,
1756 TAB_PCDS_DYNAMIC_EX_NULL
.upper() : MODEL_PCD_DYNAMIC_EX
,
1757 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
,
1760 ## Constructor of DecParser
1762 # Initialize object of DecParser
1764 # @param FilePath The path of platform description file
1765 # @param FileType The raw data of DSC file
1766 # @param Arch Default Arch value for filtering sections
1767 # @param Table Database used to retrieve module/package information
1769 def __init__(self
, FilePath
, FileType
, Arch
, Table
):
1770 # prevent re-initialization
1771 if hasattr(self
, "_Table"):
1773 MetaFileParser
.__init
__(self
, FilePath
, FileType
, Arch
, Table
, -1)
1775 self
._Version
= 0x00010005 # Only EDK2 dec file is supported
1776 self
._AllPCDs
= [] # Only for check duplicate PCD
1777 self
._AllPcdDict
= {}
1779 self
._CurrentStructurePcdName
= ""
1780 self
._include
_flag
= False
1781 self
._package
_flag
= False
1783 self
._RestofValue
= ""
1789 Content
= open(str(self
.MetaFile
), 'r').readlines()
1791 EdkLogger
.error("Parser", FILE_READ_FAILURE
, ExtraData
=self
.MetaFile
)
1793 Content
= self
.ProcessMultipleLineCODEValue(Content
)
1795 self
._DefinesCount
= 0
1796 for Index
in range(0, len(Content
)):
1797 Line
, Comment
= CleanString2(Content
[Index
])
1798 self
._CurrentLine
= Line
1799 self
._LineIndex
= Index
1801 # save comment for later use
1803 self
._Comments
.append((Comment
, self
._LineIndex
+ 1))
1809 if Line
[0] == TAB_SECTION_START
and Line
[-1] == TAB_SECTION_END
:
1810 self
._SectionHeaderParser
()
1811 if self
._SectionName
== TAB_DEC_DEFINES
.upper():
1812 self
._DefinesCount
+= 1
1815 if self
._SectionType
== MODEL_UNKNOWN
:
1816 EdkLogger
.error("Parser", FORMAT_INVALID
,
1818 "Not able to determine \"%s\" in which section."%self
._CurrentLine
,
1819 self
.MetaFile
, self
._LineIndex
+ 1)
1820 elif len(self
._SectionType
) == 0:
1825 self
._ValueList
= ['', '', '']
1826 self
._SectionParser
[self
._SectionType
[0]](self
)
1827 if self
._ValueList
is None or self
._ItemType
== MODEL_META_DATA_DEFINE
:
1833 # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,
1834 # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1
1836 for Arch
, ModuleType
, Type
in self
._Scope
:
1837 self
._LastItem
= self
._Store
(
1845 self
._LineIndex
+ 1,
1847 self
._LineIndex
+ 1,
1851 for Comment
, LineNo
in self
._Comments
:
1853 MODEL_META_DATA_COMMENT
,
1867 if self
._DefinesCount
> 1:
1868 EdkLogger
.error('Parser', FORMAT_INVALID
, 'Multiple [Defines] section is exist.', self
.MetaFile
)
1869 if self
._DefinesCount
== 0:
1870 EdkLogger
.error('Parser', FORMAT_INVALID
, 'No [Defines] section exist.', self
.MetaFile
)
1874 ## Section header parser
1876 # The section header is always in following format:
1878 # [section_name.arch<.platform|module_type>]
1880 def _SectionHeaderParser(self
):
1882 self
._SectionName
= ''
1883 self
._SectionType
= []
1886 Line
= re
.sub(',[\s]*', TAB_COMMA_SPLIT
, self
._CurrentLine
)
1887 for Item
in Line
[1:-1].split(TAB_COMMA_SPLIT
):
1889 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
,
1890 "section name can NOT be empty or incorrectly use separator comma",
1891 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1892 ItemList
= Item
.split(TAB_SPLIT
)
1894 # different types of PCD are permissible in one section
1895 self
._SectionName
= ItemList
[0].upper()
1896 if self
._SectionName
== TAB_DEC_DEFINES
.upper() and (len(ItemList
) > 1 or len(Line
.split(TAB_COMMA_SPLIT
)) > 1):
1897 EdkLogger
.error("Parser", FORMAT_INVALID
, "Defines section format is invalid",
1898 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1899 if self
._SectionName
in self
.DataType
:
1900 if self
.DataType
[self
._SectionName
] not in self
._SectionType
:
1901 self
._SectionType
.append(self
.DataType
[self
._SectionName
])
1903 EdkLogger
.error("Parser", FORMAT_UNKNOWN_ERROR
, "%s is not a valid section name" % Item
,
1904 self
.MetaFile
, self
._LineIndex
+ 1, self
._CurrentLine
)
1906 if MODEL_PCD_FEATURE_FLAG
in self
._SectionType
and len(self
._SectionType
) > 1:
1910 "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL
,
1912 Line
=self
._LineIndex
+ 1,
1913 ExtraData
=self
._CurrentLine
1916 if len(ItemList
) > 1:
1917 S1
= ItemList
[1].upper()
1919 S1
= TAB_ARCH_COMMON
1921 # S2 may be Platform or ModuleType
1922 if len(ItemList
) > 2:
1923 S2
= ItemList
[2].upper()
1924 # only Includes, GUIDs, PPIs, Protocols section have Private tag
1925 if self
._SectionName
in [TAB_INCLUDES
.upper(), TAB_GUIDS
.upper(), TAB_PROTOCOLS
.upper(), TAB_PPIS
.upper()]:
1927 EdkLogger
.error("Parser", FORMAT_INVALID
, 'Please use keyword "Private" as section tag modifier.',
1928 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1932 if [S1
, S2
, self
.DataType
[self
._SectionName
]] not in self
._Scope
:
1933 self
._Scope
.append([S1
, S2
, self
.DataType
[self
._SectionName
]])
1935 # 'COMMON' must not be used with specific ARCHs at the same section
1936 if TAB_ARCH_COMMON
in ArchList
and len(ArchList
) > 1:
1937 EdkLogger
.error('Parser', FORMAT_INVALID
, "'common' ARCH must not be used with specific ARCHs",
1938 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1940 # It is not permissible to mix section tags without the Private attribute with section tags with the Private attribute
1941 if TAB_COMMON
in PrivateList
and len(PrivateList
) > 1:
1942 EdkLogger
.error('Parser', FORMAT_INVALID
, "Can't mix section tags without the Private attribute with section tags with the Private attribute",
1943 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1, ExtraData
=self
._CurrentLine
)
1945 ## [guids], [ppis] and [protocols] section parser
1947 def _GuidParser(self
):
1948 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_EQUAL_SPLIT
, 1)
1949 if len(TokenList
) < 2:
1950 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name or value specified",
1951 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1952 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1953 if TokenList
[0] == '':
1954 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID name specified",
1955 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1956 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1957 if TokenList
[1] == '':
1958 EdkLogger
.error('Parser', FORMAT_INVALID
, "No GUID value specified",
1959 ExtraData
=self
._CurrentLine
+ " (<CName> = <GuidValueInCFormat>)",
1960 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1961 if TokenList
[1][0] != '{' or TokenList
[1][-1] != '}' or GuidStructureStringToGuidString(TokenList
[1]) == '':
1962 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid GUID value format",
1963 ExtraData
=self
._CurrentLine
+ \
1964 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
1965 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
1966 self
._ValueList
[0] = TokenList
[0]
1967 self
._ValueList
[1] = TokenList
[1]
1968 if self
._ValueList
[0] not in self
._GuidDict
:
1969 self
._GuidDict
[self
._ValueList
[0]] = self
._ValueList
[1]
1971 def ParsePcdName(self
,namelist
):
1972 if "[" in namelist
[1]:
1973 pcdname
= namelist
[1][:namelist
[1].index("[")]
1974 arrayindex
= namelist
[1][namelist
[1].index("["):]
1975 namelist
[1] = pcdname
1976 if len(namelist
) == 2:
1977 namelist
.append(arrayindex
)
1979 namelist
[2] = ".".join((arrayindex
,namelist
[2]))
1982 ## PCD sections parser
1984 # [PcdsFixedAtBuild]
1985 # [PcdsPatchableInModule]
1991 def _PcdParser(self
):
1993 if self
._CurrentStructurePcdName
:
1994 self
._ValueList
[0] = self
._CurrentStructurePcdName
1996 if "|" not in self
._CurrentLine
:
1997 if "<HeaderFiles>" == self
._CurrentLine
:
1998 self
._include
_flag
= True
1999 self
._package
_flag
= False
2000 self
._ValueList
= None
2002 if "<Packages>" == self
._CurrentLine
:
2003 self
._package
_flag
= True
2004 self
._ValueList
= None
2005 self
._include
_flag
= False
2008 if self
._include
_flag
:
2009 self
._ValueList
[1] = "<HeaderFiles>_" + md5(self
._CurrentLine
.encode('utf-8')).hexdigest()
2010 self
._ValueList
[2] = self
._CurrentLine
2011 if self
._package
_flag
and "}" != self
._CurrentLine
:
2012 self
._ValueList
[1] = "<Packages>_" + md5(self
._CurrentLine
.encode('utf-8')).hexdigest()
2013 self
._ValueList
[2] = self
._CurrentLine
2014 if self
._CurrentLine
== "}":
2015 self
._package
_flag
= False
2016 self
._include
_flag
= False
2017 self
._ValueList
= None
2020 PcdTockens
= self
._CurrentLine
.split(TAB_VALUE_SPLIT
)
2021 PcdNames
= self
.ParsePcdName(PcdTockens
[0].split(TAB_SPLIT
))
2022 if len(PcdNames
) == 2:
2023 if PcdNames
[1].strip().endswith("]"):
2024 PcdName
= PcdNames
[1][:PcdNames
[1].index('[')]
2025 Index
= PcdNames
[1][PcdNames
[1].index('['):]
2026 self
._ValueList
[0] = TAB_SPLIT
.join((PcdNames
[0],PcdName
))
2027 self
._ValueList
[1] = Index
2028 self
._ValueList
[2] = PcdTockens
[1]
2030 self
._CurrentStructurePcdName
= ""
2032 if self
._CurrentStructurePcdName
!= TAB_SPLIT
.join(PcdNames
[:2]):
2033 EdkLogger
.error('Parser', FORMAT_INVALID
, "Pcd Name does not match: %s and %s " % (self
._CurrentStructurePcdName
, TAB_SPLIT
.join(PcdNames
[:2])),
2034 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2035 self
._ValueList
[1] = TAB_SPLIT
.join(PcdNames
[2:])
2036 self
._ValueList
[2] = PcdTockens
[1]
2037 if not self
._CurrentStructurePcdName
:
2038 if self
._PcdDataTypeCODE
:
2039 if ")}" in self
._CurrentLine
:
2040 ValuePart
,RestofValue
= self
._CurrentLine
.split(")}")
2041 self
._PcdCodeValue
= self
._PcdCodeValue
+ "\n " + ValuePart
2042 self
._CurrentLine
= "|".join((self
._CurrentPcdName
, self
._PcdCodeValue
,RestofValue
))
2043 self
._PcdDataTypeCODE
= False
2044 self
._PcdCodeValue
= ""
2046 self
._PcdCodeValue
= self
._PcdCodeValue
+ "\n " + self
._CurrentLine
2047 self
._ValueList
= None
2049 TokenList
= GetSplitValueList(self
._CurrentLine
, TAB_VALUE_SPLIT
, 1)
2050 self
._CurrentPcdName
= TokenList
[0]
2051 if len(TokenList
) == 2 and TokenList
[1].strip().startswith("{CODE"):
2052 if ")}" in self
._CurrentLine
:
2053 self
._PcdDataTypeCODE
= False
2054 self
._PcdCodeValue
= ""
2056 self
._PcdDataTypeCODE
= True
2057 self
._PcdCodeValue
= TokenList
[1].strip()
2058 self
._ValueList
= None
2061 self
._ValueList
[0:1] = GetSplitValueList(TokenList
[0], TAB_SPLIT
)
2062 ValueRe
= re
.compile(r
'^[a-zA-Z_][a-zA-Z0-9_]*')
2063 # check PCD information
2064 if self
._ValueList
[0] == '' or self
._ValueList
[1] == '':
2065 EdkLogger
.error('Parser', FORMAT_INVALID
, "No token space GUID or PCD name specified",
2066 ExtraData
=self
._CurrentLine
+ \
2067 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2068 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2069 # check format of token space GUID CName
2070 if not ValueRe
.match(self
._ValueList
[0]):
2071 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_]*'",
2072 ExtraData
=self
._CurrentLine
+ \
2073 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2074 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2075 # check format of PCD CName
2076 if not ValueRe
.match(self
._ValueList
[1]):
2077 EdkLogger
.error('Parser', FORMAT_INVALID
, "The format of the PCD CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",
2078 ExtraData
=self
._CurrentLine
+ \
2079 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2080 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2081 # check PCD datum information
2082 if len(TokenList
) < 2 or TokenList
[1] == '':
2083 EdkLogger
.error('Parser', FORMAT_INVALID
, "No PCD Datum information given",
2084 ExtraData
=self
._CurrentLine
+ \
2085 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2086 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2089 ValueRe
= re
.compile(r
'^\s*L?\".*\|.*\"')
2090 PtrValue
= ValueRe
.findall(TokenList
[1])
2092 # Has VOID* type string, may contain "|" character in the string.
2093 if len(PtrValue
) != 0:
2094 ptrValueList
= re
.sub(ValueRe
, '', TokenList
[1])
2095 ValueList
= AnalyzePcdExpression(ptrValueList
)
2096 ValueList
[0] = PtrValue
[0]
2098 ValueList
= AnalyzePcdExpression(TokenList
[1])
2101 # check if there's enough datum information given
2102 if len(ValueList
) != 3:
2103 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid PCD Datum information given",
2104 ExtraData
=self
._CurrentLine
+ \
2105 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2106 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2107 # check default value
2108 if ValueList
[0] == '':
2109 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DefaultValue in PCD Datum information",
2110 ExtraData
=self
._CurrentLine
+ \
2111 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2112 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2114 if ValueList
[1] == '':
2115 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing DatumType in PCD Datum information",
2116 ExtraData
=self
._CurrentLine
+ \
2117 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2118 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2119 # check token of the PCD
2120 if ValueList
[2] == '':
2121 EdkLogger
.error('Parser', FORMAT_INVALID
, "Missing Token in PCD Datum information",
2122 ExtraData
=self
._CurrentLine
+ \
2123 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
2124 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2126 PcdValue
= ValueList
[0]
2129 self
._GuidDict
.update(self
._AllPcdDict
)
2130 ValueList
[0] = ValueExpressionEx(ValueList
[0], ValueList
[1], self
._GuidDict
)(True)
2131 except BadExpression
as Value
:
2132 EdkLogger
.error('Parser', FORMAT_INVALID
, Value
, ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2133 # check format of default value against the datum type
2134 IsValid
, Cause
= CheckPcdDatum(ValueList
[1], ValueList
[0])
2136 EdkLogger
.error('Parser', FORMAT_INVALID
, Cause
, ExtraData
=self
._CurrentLine
,
2137 File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2139 if Cause
== "StructurePcd":
2140 self
._CurrentStructurePcdName
= TAB_SPLIT
.join(self
._ValueList
[0:2])
2141 self
._ValueList
[0] = self
._CurrentStructurePcdName
2142 self
._ValueList
[1] = ValueList
[1].strip()
2144 if ValueList
[0] in ['True', 'true', 'TRUE']:
2146 elif ValueList
[0] in ['False', 'false', 'FALSE']:
2149 # check for duplicate PCD definition
2150 if (self
._Scope
[0], self
._ValueList
[0], self
._ValueList
[1]) in self
._AllPCDs
:
2151 EdkLogger
.error('Parser', FORMAT_INVALID
,
2152 "The same PCD name and GUID have been already defined",
2153 ExtraData
=self
._CurrentLine
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
2155 self
._AllPCDs
.append((self
._Scope
[0], self
._ValueList
[0], self
._ValueList
[1]))
2156 self
._AllPcdDict
[TAB_SPLIT
.join(self
._ValueList
[0:2])] = ValueList
[0]
2158 self
._ValueList
[2] = ValueList
[0].strip() + '|' + ValueList
[1].strip() + '|' + ValueList
[2].strip()
2161 MODEL_META_DATA_HEADER
: MetaFileParser
._DefineParser
,
2162 MODEL_EFI_INCLUDE
: MetaFileParser
._PathParser
,
2163 MODEL_EFI_LIBRARY_CLASS
: MetaFileParser
._PathParser
,
2164 MODEL_EFI_GUID
: _GuidParser
,
2165 MODEL_EFI_PPI
: _GuidParser
,
2166 MODEL_EFI_PROTOCOL
: _GuidParser
,
2167 MODEL_PCD_FIXED_AT_BUILD
: _PcdParser
,
2168 MODEL_PCD_PATCHABLE_IN_MODULE
: _PcdParser
,
2169 MODEL_PCD_FEATURE_FLAG
: _PcdParser
,
2170 MODEL_PCD_DYNAMIC
: _PcdParser
,
2171 MODEL_PCD_DYNAMIC_EX
: _PcdParser
,
2172 MODEL_UNKNOWN
: MetaFileParser
._Skip
,
2173 MODEL_META_DATA_USER_EXTENSION
: MetaFileParser
._SkipUserExtension
,
2178 # This acts like the main() function for the script, unless it is 'import'ed into another
2181 if __name__
== '__main__':