6a30d45b3dbf7059cd21309776769ae1ef1e3d81
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / MetaFileParser.py
1 ## @file
2 # This file is used to parse meta files
3 #
4 # Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.<BR>
5 # (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
6 # This program and the accompanying materials
7 # are licensed and made available under the terms and conditions of the BSD License
8 # which accompanies this distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
10 #
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.
13 #
14
15 ##
16 # Import Modules
17 #
18 import Common.LongFilePathOs as os
19 import re
20 import time
21 import copy
22 import md5
23
24 import Common.EdkLogger as EdkLogger
25 import Common.GlobalData as GlobalData
26
27 from CommonDataClass.DataClass import *
28 from Common.DataType import *
29 from Common.String import *
30 from Common.Misc import GuidStructureStringToGuidString, CheckPcdDatum, PathClass, AnalyzePcdData, AnalyzeDscPcd, AnalyzePcdExpression
31 from Common.Expression import *
32 from CommonDataClass.Exceptions import *
33 from Common.LongFilePathSupport import OpenLongFilePath as open
34
35 from MetaFileTable import MetaFileStorage
36 from MetaFileCommentParser import CheckInfComment
37
38 ## A decorator used to parse macro definition
39 def ParseMacro(Parser):
40 def MacroParser(self):
41 Match = gMacroDefPattern.match(self._CurrentLine)
42 if not Match:
43 # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method
44 Parser(self)
45 return
46
47 TokenList = GetSplitValueList(self._CurrentLine[Match.end(1):], TAB_EQUAL_SPLIT, 1)
48 # Syntax check
49 if not TokenList[0]:
50 EdkLogger.error('Parser', FORMAT_INVALID, "No macro name given",
51 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
52 if len(TokenList) < 2:
53 TokenList.append('')
54
55 Type = Match.group(1)
56 Name, Value = TokenList
57 # Global macros can be only defined via environment variable
58 if Name in GlobalData.gGlobalDefines:
59 EdkLogger.error('Parser', FORMAT_INVALID, "%s can only be defined via environment variable" % Name,
60 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
61 # Only upper case letters, digit and '_' are allowed
62 if not gMacroNamePattern.match(Name):
63 EdkLogger.error('Parser', FORMAT_INVALID, "The macro name must be in the pattern [A-Z][A-Z0-9_]*",
64 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
65
66 Value = ReplaceMacro(Value, self._Macros)
67 if Type in self.DataType:
68 self._ItemType = self.DataType[Type]
69 else:
70 self._ItemType = MODEL_META_DATA_DEFINE
71 # DEFINE defined macros
72 if Type == TAB_DSC_DEFINES_DEFINE:
73 #
74 # First judge whether this DEFINE is in conditional directive statements or not.
75 #
76 if type(self) == DscParser and self._InDirective > -1:
77 pass
78 else:
79 if type(self) == DecParser:
80 if MODEL_META_DATA_HEADER in self._SectionType:
81 self._FileLocalMacros[Name] = Value
82 else:
83 self._ConstructSectionMacroDict(Name, Value)
84 elif self._SectionType == MODEL_META_DATA_HEADER:
85 self._FileLocalMacros[Name] = Value
86 else:
87 self._ConstructSectionMacroDict(Name, Value)
88
89 # EDK_GLOBAL defined macros
90 elif type(self) != DscParser:
91 EdkLogger.error('Parser', FORMAT_INVALID, "EDK_GLOBAL can only be used in .dsc file",
92 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
93 elif self._SectionType != MODEL_META_DATA_HEADER:
94 EdkLogger.error('Parser', FORMAT_INVALID, "EDK_GLOBAL can only be used under [Defines] section",
95 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
96 elif (Name in self._FileLocalMacros) and (self._FileLocalMacros[Name] != Value):
97 EdkLogger.error('Parser', FORMAT_INVALID, "EDK_GLOBAL defined a macro with the same name and different value as one defined by 'DEFINE'",
98 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
99
100 self._ValueList = [Type, Name, Value]
101
102 return MacroParser
103
104 ## Base class of parser
105 #
106 # This class is used for derivation purpose. The specific parser for one kind
107 # type file must derive this class and implement some public interfaces.
108 #
109 # @param FilePath The path of platform description file
110 # @param FileType The raw data of DSC file
111 # @param Table Database used to retrieve module/package information
112 # @param Macros Macros used for replacement in file
113 # @param Owner Owner ID (for sub-section parsing)
114 # @param From ID from which the data comes (for !INCLUDE directive)
115 #
116 class MetaFileParser(object):
117 # data type (file content) for specific file type
118 DataType = {}
119
120 # Parser objects used to implement singleton
121 MetaFiles = {}
122
123 ## Factory method
124 #
125 # One file, one parser object. This factory method makes sure that there's
126 # only one object constructed for one meta file.
127 #
128 # @param Class class object of real AutoGen class
129 # (InfParser, DecParser or DscParser)
130 # @param FilePath The path of meta file
131 # @param *args The specific class related parameters
132 # @param **kwargs The specific class related dict parameters
133 #
134 def __new__(Class, FilePath, *args, **kwargs):
135 if FilePath in Class.MetaFiles:
136 return Class.MetaFiles[FilePath]
137 else:
138 ParserObject = super(MetaFileParser, Class).__new__(Class)
139 Class.MetaFiles[FilePath] = ParserObject
140 return ParserObject
141
142 ## Constructor of MetaFileParser
143 #
144 # Initialize object of MetaFileParser
145 #
146 # @param FilePath The path of platform description file
147 # @param FileType The raw data of DSC file
148 # @param Arch Default Arch value for filtering sections
149 # @param Table Database used to retrieve module/package information
150 # @param Owner Owner ID (for sub-section parsing)
151 # @param From ID from which the data comes (for !INCLUDE directive)
152 #
153 def __init__(self, FilePath, FileType, Arch, Table, Owner= -1, From= -1):
154 self._Table = Table
155 self._RawTable = Table
156 self._Arch = Arch
157 self._FileType = FileType
158 self.MetaFile = FilePath
159 self._FileDir = self.MetaFile.Dir
160 self._Defines = {}
161 self._FileLocalMacros = {}
162 self._SectionsMacroDict = {}
163
164 # for recursive parsing
165 self._Owner = [Owner]
166 self._From = From
167
168 # parsr status for parsing
169 self._ValueList = ['', '', '', '', '']
170 self._Scope = []
171 self._LineIndex = 0
172 self._CurrentLine = ''
173 self._SectionType = MODEL_UNKNOWN
174 self._SectionName = ''
175 self._InSubsection = False
176 self._SubsectionType = MODEL_UNKNOWN
177 self._SubsectionName = ''
178 self._ItemType = MODEL_UNKNOWN
179 self._LastItem = -1
180 self._Enabled = 0
181 self._Finished = False
182 self._PostProcessed = False
183 # Different version of meta-file has different way to parse.
184 self._Version = 0
185
186 ## Store the parsed data in table
187 def _Store(self, *Args):
188 return self._Table.Insert(*Args)
189
190 ## Virtual method for starting parse
191 def Start(self):
192 raise NotImplementedError
193
194 ## Notify a post-process is needed
195 def DoPostProcess(self):
196 self._PostProcessed = False
197
198 ## Set parsing complete flag in both class and table
199 def _Done(self):
200 self._Finished = True
201 ## Do not set end flag when processing included files
202 if self._From == -1:
203 self._Table.SetEndFlag()
204
205 def _PostProcess(self):
206 self._PostProcessed = True
207
208 ## Get the parse complete flag
209 def _GetFinished(self):
210 return self._Finished
211
212 ## Set the complete flag
213 def _SetFinished(self, Value):
214 self._Finished = Value
215
216 ## Remove records that do not match given Filter Arch
217 def _FilterRecordList(self, RecordList, FilterArch):
218 NewRecordList = []
219 for Record in RecordList:
220 Arch = Record[3]
221 if Arch == 'COMMON' or Arch == FilterArch:
222 NewRecordList.append(Record)
223 return NewRecordList
224
225 ## Use [] style to query data in table, just for readability
226 #
227 # DataInfo = [data_type, scope1(arch), scope2(platform/moduletype)]
228 #
229 def __getitem__(self, DataInfo):
230 if type(DataInfo) != type(()):
231 DataInfo = (DataInfo,)
232
233 # Parse the file first, if necessary
234 if not self._Finished:
235 if self._RawTable.IsIntegrity():
236 self._Finished = True
237 else:
238 self._Table = self._RawTable
239 self._PostProcessed = False
240 self.Start()
241
242 # No specific ARCH or Platform given, use raw data
243 if self._RawTable and (len(DataInfo) == 1 or DataInfo[1] == None):
244 return self._FilterRecordList(self._RawTable.Query(*DataInfo), self._Arch)
245
246 # Do post-process if necessary
247 if not self._PostProcessed:
248 self._PostProcess()
249
250 return self._FilterRecordList(self._Table.Query(*DataInfo), DataInfo[1])
251
252 ## Data parser for the common format in different type of file
253 #
254 # The common format in the meatfile is like
255 #
256 # xxx1 | xxx2 | xxx3
257 #
258 @ParseMacro
259 def _CommonParser(self):
260 TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
261 self._ValueList[0:len(TokenList)] = TokenList
262
263 ## Data parser for the format in which there's path
264 #
265 # Only path can have macro used. So we need to replace them before use.
266 #
267 @ParseMacro
268 def _PathParser(self):
269 TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
270 self._ValueList[0:len(TokenList)] = TokenList
271 # Don't do macro replacement for dsc file at this point
272 if type(self) != DscParser:
273 Macros = self._Macros
274 self._ValueList = [ReplaceMacro(Value, Macros) for Value in self._ValueList]
275
276 ## Skip unsupported data
277 def _Skip(self):
278 EdkLogger.warn("Parser", "Unrecognized content", File=self.MetaFile,
279 Line=self._LineIndex + 1, ExtraData=self._CurrentLine);
280 self._ValueList[0:1] = [self._CurrentLine]
281
282 ## Skip unsupported data for UserExtension Section
283 def _SkipUserExtension(self):
284 self._ValueList[0:1] = [self._CurrentLine]
285
286 ## Section header parser
287 #
288 # The section header is always in following format:
289 #
290 # [section_name.arch<.platform|module_type>]
291 #
292 def _SectionHeaderParser(self):
293 self._Scope = []
294 self._SectionName = ''
295 ArchList = set()
296 for Item in GetSplitValueList(self._CurrentLine[1:-1], TAB_COMMA_SPLIT):
297 if Item == '':
298 continue
299 ItemList = GetSplitValueList(Item, TAB_SPLIT,2)
300 # different section should not mix in one section
301 if self._SectionName != '' and self._SectionName != ItemList[0].upper():
302 EdkLogger.error('Parser', FORMAT_INVALID, "Different section names in the same section",
303 File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)
304 self._SectionName = ItemList[0].upper()
305 if self._SectionName in self.DataType:
306 self._SectionType = self.DataType[self._SectionName]
307 # Check if the section name is valid
308 if self._SectionName not in SECTIONS_HAVE_ITEM_AFTER_ARCH and len(ItemList) > 3:
309 EdkLogger.error("Parser", FORMAT_UNKNOWN_ERROR, "%s is not a valid section name" % Item,
310 self.MetaFile, self._LineIndex + 1, self._CurrentLine)
311 elif self._Version >= 0x00010005:
312 EdkLogger.error("Parser", FORMAT_UNKNOWN_ERROR, "%s is not a valid section name" % Item,
313 self.MetaFile, self._LineIndex + 1, self._CurrentLine)
314 else:
315 self._SectionType = MODEL_UNKNOWN
316
317 # S1 is always Arch
318 if len(ItemList) > 1:
319 S1 = ItemList[1].upper()
320 else:
321 S1 = 'COMMON'
322 ArchList.add(S1)
323
324 # S2 may be Platform or ModuleType
325 if len(ItemList) > 2:
326 if self._SectionName.upper() in SECTIONS_HAVE_ITEM_PCD:
327 S2 = ItemList[2]
328 else:
329 S2 = ItemList[2].upper()
330 else:
331 S2 = 'COMMON'
332 self._Scope.append([S1, S2])
333
334 # 'COMMON' must not be used with specific ARCHs at the same section
335 if 'COMMON' in ArchList and len(ArchList) > 1:
336 EdkLogger.error('Parser', FORMAT_INVALID, "'common' ARCH must not be used with specific ARCHs",
337 File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)
338 # If the section information is needed later, it should be stored in database
339 self._ValueList[0] = self._SectionName
340
341 ## [defines] section parser
342 @ParseMacro
343 def _DefineParser(self):
344 TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
345 self._ValueList[1:len(TokenList)] = TokenList
346 if not self._ValueList[1]:
347 EdkLogger.error('Parser', FORMAT_INVALID, "No name specified",
348 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
349 if not self._ValueList[2]:
350 EdkLogger.error('Parser', FORMAT_INVALID, "No value specified",
351 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
352
353 self._ValueList = [ReplaceMacro(Value, self._Macros) for Value in self._ValueList]
354 Name, Value = self._ValueList[1], self._ValueList[2]
355 MacroUsed = GlobalData.gMacroRefPattern.findall(Value)
356 if len(MacroUsed) != 0:
357 for Macro in MacroUsed:
358 if Macro in GlobalData.gGlobalDefines:
359 EdkLogger.error("Parser", FORMAT_INVALID, "Global macro %s is not permitted." % (Macro), ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
360 else:
361 EdkLogger.error("Parser", FORMAT_INVALID, "%s not defined" % (Macro), ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
362 # Sometimes, we need to make differences between EDK and EDK2 modules
363 if Name == 'INF_VERSION':
364 if re.match(r'0[xX][\da-f-A-F]{5,8}', Value):
365 self._Version = int(Value, 0)
366 elif re.match(r'\d+\.\d+', Value):
367 ValueList = Value.split('.')
368 Major = '%04o' % int(ValueList[0], 0)
369 Minor = '%04o' % int(ValueList[1], 0)
370 self._Version = int('0x' + Major + Minor, 0)
371 else:
372 EdkLogger.error('Parser', FORMAT_INVALID, "Invalid version number",
373 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
374
375 if type(self) == InfParser and self._Version < 0x00010005:
376 # EDK module allows using defines as macros
377 self._FileLocalMacros[Name] = Value
378 self._Defines[Name] = Value
379
380 ## [BuildOptions] section parser
381 @ParseMacro
382 def _BuildOptionParser(self):
383 self._CurrentLine = CleanString(self._CurrentLine, BuildOption=True)
384 TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
385 TokenList2 = GetSplitValueList(TokenList[0], ':', 1)
386 if len(TokenList2) == 2:
387 self._ValueList[0] = TokenList2[0] # toolchain family
388 self._ValueList[1] = TokenList2[1] # keys
389 else:
390 self._ValueList[1] = TokenList[0]
391 if len(TokenList) == 2 and type(self) != DscParser: # value
392 self._ValueList[2] = ReplaceMacro(TokenList[1], self._Macros)
393
394 if self._ValueList[1].count('_') != 4:
395 EdkLogger.error(
396 'Parser',
397 FORMAT_INVALID,
398 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self._ValueList[1],
399 ExtraData=self._CurrentLine,
400 File=self.MetaFile,
401 Line=self._LineIndex + 1
402 )
403 def GetValidExpression(self, TokenSpaceGuid, PcdCName):
404 return self._Table.GetValidExpression(TokenSpaceGuid, PcdCName)
405 def _GetMacros(self):
406 Macros = {}
407 Macros.update(self._FileLocalMacros)
408 Macros.update(self._GetApplicableSectionMacro())
409 return Macros
410
411 ## Construct section Macro dict
412 def _ConstructSectionMacroDict(self, Name, Value):
413 ScopeKey = [(Scope[0], Scope[1]) for Scope in self._Scope]
414 ScopeKey = tuple(ScopeKey)
415 SectionDictKey = self._SectionType, ScopeKey
416 #
417 # DecParser SectionType is a list, will contain more than one item only in Pcd Section
418 # As Pcd section macro usage is not alllowed, so here it is safe
419 #
420 if type(self) == DecParser:
421 SectionDictKey = self._SectionType[0], ScopeKey
422 if SectionDictKey not in self._SectionsMacroDict:
423 self._SectionsMacroDict[SectionDictKey] = {}
424 SectionLocalMacros = self._SectionsMacroDict[SectionDictKey]
425 SectionLocalMacros[Name] = Value
426
427 ## Get section Macros that are applicable to current line, which may come from other sections
428 ## that share the same name while scope is wider
429 def _GetApplicableSectionMacro(self):
430 Macros = {}
431
432 ComComMacroDict = {}
433 ComSpeMacroDict = {}
434 SpeSpeMacroDict = {}
435
436 ActiveSectionType = self._SectionType
437 if type(self) == DecParser:
438 ActiveSectionType = self._SectionType[0]
439
440 for (SectionType, Scope) in self._SectionsMacroDict:
441 if SectionType != ActiveSectionType:
442 continue
443
444 for ActiveScope in self._Scope:
445 Scope0, Scope1 = ActiveScope[0], ActiveScope[1]
446 if(Scope0, Scope1) not in Scope:
447 break
448 else:
449 SpeSpeMacroDict.update(self._SectionsMacroDict[(SectionType, Scope)])
450
451 for ActiveScope in self._Scope:
452 Scope0, Scope1 = ActiveScope[0], ActiveScope[1]
453 if(Scope0, Scope1) not in Scope and (Scope0, "COMMON") not in Scope and ("COMMON", Scope1) not in Scope:
454 break
455 else:
456 ComSpeMacroDict.update(self._SectionsMacroDict[(SectionType, Scope)])
457
458 if ("COMMON", "COMMON") in Scope:
459 ComComMacroDict.update(self._SectionsMacroDict[(SectionType, Scope)])
460
461 Macros.update(ComComMacroDict)
462 Macros.update(ComSpeMacroDict)
463 Macros.update(SpeSpeMacroDict)
464
465 return Macros
466
467 _SectionParser = {}
468 Finished = property(_GetFinished, _SetFinished)
469 _Macros = property(_GetMacros)
470
471
472 ## INF file parser class
473 #
474 # @param FilePath The path of platform description file
475 # @param FileType The raw data of DSC file
476 # @param Table Database used to retrieve module/package information
477 # @param Macros Macros used for replacement in file
478 #
479 class InfParser(MetaFileParser):
480 # INF file supported data types (one type per section)
481 DataType = {
482 TAB_UNKNOWN.upper() : MODEL_UNKNOWN,
483 TAB_INF_DEFINES.upper() : MODEL_META_DATA_HEADER,
484 TAB_DSC_DEFINES_DEFINE : MODEL_META_DATA_DEFINE,
485 TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION,
486 TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE,
487 TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE,
488 TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS,
489 TAB_PACKAGES.upper() : MODEL_META_DATA_PACKAGE,
490 TAB_NMAKE.upper() : MODEL_META_DATA_NMAKE,
491 TAB_INF_FIXED_PCD.upper() : MODEL_PCD_FIXED_AT_BUILD,
492 TAB_INF_PATCH_PCD.upper() : MODEL_PCD_PATCHABLE_IN_MODULE,
493 TAB_INF_FEATURE_PCD.upper() : MODEL_PCD_FEATURE_FLAG,
494 TAB_INF_PCD_EX.upper() : MODEL_PCD_DYNAMIC_EX,
495 TAB_INF_PCD.upper() : MODEL_PCD_DYNAMIC,
496 TAB_SOURCES.upper() : MODEL_EFI_SOURCE_FILE,
497 TAB_GUIDS.upper() : MODEL_EFI_GUID,
498 TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL,
499 TAB_PPIS.upper() : MODEL_EFI_PPI,
500 TAB_DEPEX.upper() : MODEL_EFI_DEPEX,
501 TAB_BINARIES.upper() : MODEL_EFI_BINARY_FILE,
502 TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION
503 }
504
505 ## Constructor of InfParser
506 #
507 # Initialize object of InfParser
508 #
509 # @param FilePath The path of module description file
510 # @param FileType The raw data of DSC file
511 # @param Arch Default Arch value for filtering sections
512 # @param Table Database used to retrieve module/package information
513 #
514 def __init__(self, FilePath, FileType, Arch, Table):
515 # prevent re-initialization
516 if hasattr(self, "_Table"):
517 return
518 MetaFileParser.__init__(self, FilePath, FileType, Arch, Table)
519 self.PcdsDict = {}
520
521 ## Parser starter
522 def Start(self):
523 NmakeLine = ''
524 Content = ''
525 try:
526 Content = open(str(self.MetaFile), 'r').readlines()
527 except:
528 EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile)
529
530 # parse the file line by line
531 IsFindBlockComment = False
532 GetHeaderComment = False
533 TailComments = []
534 SectionComments = []
535 Comments = []
536
537 for Index in range(0, len(Content)):
538 # skip empty, commented, block commented lines
539 Line, Comment = CleanString2(Content[Index], AllowCppStyleComment=True)
540 NextLine = ''
541 if Index + 1 < len(Content):
542 NextLine, NextComment = CleanString2(Content[Index + 1])
543 if Line == '':
544 if Comment:
545 Comments.append((Comment, Index + 1))
546 elif GetHeaderComment:
547 SectionComments.extend(Comments)
548 Comments = []
549 continue
550 if Line.find(DataType.TAB_COMMENT_EDK_START) > -1:
551 IsFindBlockComment = True
552 continue
553 if Line.find(DataType.TAB_COMMENT_EDK_END) > -1:
554 IsFindBlockComment = False
555 continue
556 if IsFindBlockComment:
557 continue
558
559 self._LineIndex = Index
560 self._CurrentLine = Line
561
562 # section header
563 if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:
564 if not GetHeaderComment:
565 for Cmt, LNo in Comments:
566 self._Store(MODEL_META_DATA_HEADER_COMMENT, Cmt, '', '', 'COMMON',
567 'COMMON', self._Owner[-1], LNo, -1, LNo, -1, 0)
568 GetHeaderComment = True
569 else:
570 TailComments.extend(SectionComments + Comments)
571 Comments = []
572 self._SectionHeaderParser()
573 # Check invalid sections
574 if self._Version < 0x00010005:
575 if self._SectionType in [MODEL_META_DATA_BUILD_OPTION,
576 MODEL_EFI_LIBRARY_CLASS,
577 MODEL_META_DATA_PACKAGE,
578 MODEL_PCD_FIXED_AT_BUILD,
579 MODEL_PCD_PATCHABLE_IN_MODULE,
580 MODEL_PCD_FEATURE_FLAG,
581 MODEL_PCD_DYNAMIC_EX,
582 MODEL_PCD_DYNAMIC,
583 MODEL_EFI_GUID,
584 MODEL_EFI_PROTOCOL,
585 MODEL_EFI_PPI,
586 MODEL_META_DATA_USER_EXTENSION]:
587 EdkLogger.error('Parser', FORMAT_INVALID,
588 "Section [%s] is not allowed in inf file without version" % (self._SectionName),
589 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
590 elif self._SectionType in [MODEL_EFI_INCLUDE,
591 MODEL_EFI_LIBRARY_INSTANCE,
592 MODEL_META_DATA_NMAKE]:
593 EdkLogger.error('Parser', FORMAT_INVALID,
594 "Section [%s] is not allowed in inf file with version 0x%08x" % (self._SectionName, self._Version),
595 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
596 continue
597 # merge two lines specified by '\' in section NMAKE
598 elif self._SectionType == MODEL_META_DATA_NMAKE:
599 if Line[-1] == '\\':
600 if NextLine == '':
601 self._CurrentLine = NmakeLine + Line[0:-1]
602 NmakeLine = ''
603 else:
604 if NextLine[0] == TAB_SECTION_START and NextLine[-1] == TAB_SECTION_END:
605 self._CurrentLine = NmakeLine + Line[0:-1]
606 NmakeLine = ''
607 else:
608 NmakeLine = NmakeLine + ' ' + Line[0:-1]
609 continue
610 else:
611 self._CurrentLine = NmakeLine + Line
612 NmakeLine = ''
613
614 # section content
615 self._ValueList = ['', '', '']
616 # parse current line, result will be put in self._ValueList
617 self._SectionParser[self._SectionType](self)
618 if self._ValueList == None or self._ItemType == MODEL_META_DATA_DEFINE:
619 self._ItemType = -1
620 Comments = []
621 continue
622 if Comment:
623 Comments.append((Comment, Index + 1))
624 if GlobalData.gOptions and GlobalData.gOptions.CheckUsage:
625 CheckInfComment(self._SectionType, Comments, str(self.MetaFile), Index + 1, self._ValueList)
626 #
627 # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
628 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
629 #
630 for Arch, Platform in self._Scope:
631 LastItem = self._Store(self._SectionType,
632 self._ValueList[0],
633 self._ValueList[1],
634 self._ValueList[2],
635 Arch,
636 Platform,
637 self._Owner[-1],
638 self._LineIndex + 1,
639 - 1,
640 self._LineIndex + 1,
641 - 1,
642 0
643 )
644 for Comment, LineNo in Comments:
645 self._Store(MODEL_META_DATA_COMMENT, Comment, '', '', Arch, Platform,
646 LastItem, LineNo, -1, LineNo, -1, 0)
647 Comments = []
648 SectionComments = []
649 TailComments.extend(SectionComments + Comments)
650 if IsFindBlockComment:
651 EdkLogger.error("Parser", FORMAT_INVALID, "Open block comments (starting with /*) are expected to end with */",
652 File=self.MetaFile)
653
654 # If there are tail comments in INF file, save to database whatever the comments are
655 for Comment in TailComments:
656 self._Store(MODEL_META_DATA_TAIL_COMMENT, Comment[0], '', '', 'COMMON',
657 'COMMON', self._Owner[-1], -1, -1, -1, -1, 0)
658 self._Done()
659
660 ## Data parser for the format in which there's path
661 #
662 # Only path can have macro used. So we need to replace them before use.
663 #
664 def _IncludeParser(self):
665 TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
666 self._ValueList[0:len(TokenList)] = TokenList
667 Macros = self._Macros
668 if Macros:
669 for Index in range(0, len(self._ValueList)):
670 Value = self._ValueList[Index]
671 if not Value:
672 continue
673
674 if Value.upper().find('$(EFI_SOURCE)\Edk'.upper()) > -1 or Value.upper().find('$(EFI_SOURCE)/Edk'.upper()) > -1:
675 Value = '$(EDK_SOURCE)' + Value[17:]
676 if Value.find('$(EFI_SOURCE)') > -1 or Value.find('$(EDK_SOURCE)') > -1:
677 pass
678 elif Value.startswith('.'):
679 pass
680 elif Value.startswith('$('):
681 pass
682 else:
683 Value = '$(EFI_SOURCE)/' + Value
684
685 self._ValueList[Index] = ReplaceMacro(Value, Macros)
686
687 ## Parse [Sources] section
688 #
689 # Only path can have macro used. So we need to replace them before use.
690 #
691 @ParseMacro
692 def _SourceFileParser(self):
693 TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
694 self._ValueList[0:len(TokenList)] = TokenList
695 Macros = self._Macros
696 # For Acpi tables, remove macro like ' TABLE_NAME=Sata1'
697 if 'COMPONENT_TYPE' in Macros:
698 if self._Defines['COMPONENT_TYPE'].upper() == 'ACPITABLE':
699 self._ValueList[0] = GetSplitValueList(self._ValueList[0], ' ', 1)[0]
700 if self._Defines['BASE_NAME'] == 'Microcode':
701 pass
702 self._ValueList = [ReplaceMacro(Value, Macros) for Value in self._ValueList]
703
704 ## Parse [Binaries] section
705 #
706 # Only path can have macro used. So we need to replace them before use.
707 #
708 @ParseMacro
709 def _BinaryFileParser(self):
710 TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 2)
711 if len(TokenList) < 2:
712 EdkLogger.error('Parser', FORMAT_INVALID, "No file type or path specified",
713 ExtraData=self._CurrentLine + " (<FileType> | <FilePath> [| <Target>])",
714 File=self.MetaFile, Line=self._LineIndex + 1)
715 if not TokenList[0]:
716 EdkLogger.error('Parser', FORMAT_INVALID, "No file type specified",
717 ExtraData=self._CurrentLine + " (<FileType> | <FilePath> [| <Target>])",
718 File=self.MetaFile, Line=self._LineIndex + 1)
719 if not TokenList[1]:
720 EdkLogger.error('Parser', FORMAT_INVALID, "No file path specified",
721 ExtraData=self._CurrentLine + " (<FileType> | <FilePath> [| <Target>])",
722 File=self.MetaFile, Line=self._LineIndex + 1)
723 self._ValueList[0:len(TokenList)] = TokenList
724 self._ValueList[1] = ReplaceMacro(self._ValueList[1], self._Macros)
725
726 ## [nmake] section parser (Edk.x style only)
727 def _NmakeParser(self):
728 TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
729 self._ValueList[0:len(TokenList)] = TokenList
730 # remove macros
731 self._ValueList[1] = ReplaceMacro(self._ValueList[1], self._Macros)
732 # remove self-reference in macro setting
733 #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})
734
735 ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser
736 @ParseMacro
737 def _PcdParser(self):
738 TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)
739 ValueList = GetSplitValueList(TokenList[0], TAB_SPLIT)
740 if len(ValueList) != 2:
741 EdkLogger.error('Parser', FORMAT_INVALID, "Illegal token space GUID and PCD name format",
742 ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<PcdCName>)",
743 File=self.MetaFile, Line=self._LineIndex + 1)
744 self._ValueList[0:1] = ValueList
745 if len(TokenList) > 1:
746 self._ValueList[2] = TokenList[1]
747 if self._ValueList[0] == '' or self._ValueList[1] == '':
748 EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",
749 ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<PcdCName>)",
750 File=self.MetaFile, Line=self._LineIndex + 1)
751
752 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
753 if self._ValueList[2] != '':
754 InfPcdValueList = GetSplitValueList(TokenList[1], TAB_VALUE_SPLIT, 1)
755 if InfPcdValueList[0] in ['True', 'true', 'TRUE']:
756 self._ValueList[2] = TokenList[1].replace(InfPcdValueList[0], '1', 1);
757 elif InfPcdValueList[0] in ['False', 'false', 'FALSE']:
758 self._ValueList[2] = TokenList[1].replace(InfPcdValueList[0], '0', 1);
759 if (self._ValueList[0], self._ValueList[1]) not in self.PcdsDict:
760 self.PcdsDict[self._ValueList[0], self._ValueList[1]] = self._SectionType
761 elif self.PcdsDict[self._ValueList[0], self._ValueList[1]] != self._SectionType:
762 EdkLogger.error('Parser', FORMAT_INVALID, "It is not permissible to list a specified PCD in different PCD type sections.",
763 ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<PcdCName>)",
764 File=self.MetaFile, Line=self._LineIndex + 1)
765
766 ## [depex] section parser
767 @ParseMacro
768 def _DepexParser(self):
769 self._ValueList[0:1] = [self._CurrentLine]
770
771 _SectionParser = {
772 MODEL_UNKNOWN : MetaFileParser._Skip,
773 MODEL_META_DATA_HEADER : MetaFileParser._DefineParser,
774 MODEL_META_DATA_BUILD_OPTION : MetaFileParser._BuildOptionParser,
775 MODEL_EFI_INCLUDE : _IncludeParser, # for Edk.x modules
776 MODEL_EFI_LIBRARY_INSTANCE : MetaFileParser._CommonParser, # for Edk.x modules
777 MODEL_EFI_LIBRARY_CLASS : MetaFileParser._PathParser,
778 MODEL_META_DATA_PACKAGE : MetaFileParser._PathParser,
779 MODEL_META_DATA_NMAKE : _NmakeParser, # for Edk.x modules
780 MODEL_PCD_FIXED_AT_BUILD : _PcdParser,
781 MODEL_PCD_PATCHABLE_IN_MODULE : _PcdParser,
782 MODEL_PCD_FEATURE_FLAG : _PcdParser,
783 MODEL_PCD_DYNAMIC_EX : _PcdParser,
784 MODEL_PCD_DYNAMIC : _PcdParser,
785 MODEL_EFI_SOURCE_FILE : _SourceFileParser,
786 MODEL_EFI_GUID : MetaFileParser._CommonParser,
787 MODEL_EFI_PROTOCOL : MetaFileParser._CommonParser,
788 MODEL_EFI_PPI : MetaFileParser._CommonParser,
789 MODEL_EFI_DEPEX : _DepexParser,
790 MODEL_EFI_BINARY_FILE : _BinaryFileParser,
791 MODEL_META_DATA_USER_EXTENSION : MetaFileParser._SkipUserExtension,
792 }
793
794 ## DSC file parser class
795 #
796 # @param FilePath The path of platform description file
797 # @param FileType The raw data of DSC file
798 # @param Table Database used to retrieve module/package information
799 # @param Macros Macros used for replacement in file
800 # @param Owner Owner ID (for sub-section parsing)
801 # @param From ID from which the data comes (for !INCLUDE directive)
802 #
803 class DscParser(MetaFileParser):
804 # DSC file supported data types (one type per section)
805 DataType = {
806 TAB_SKUIDS.upper() : MODEL_EFI_SKU_ID,
807 TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE,
808 TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS,
809 TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION,
810 TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : MODEL_PCD_FIXED_AT_BUILD,
811 TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : MODEL_PCD_PATCHABLE_IN_MODULE,
812 TAB_PCDS_FEATURE_FLAG_NULL.upper() : MODEL_PCD_FEATURE_FLAG,
813 TAB_PCDS_DYNAMIC_DEFAULT_NULL.upper() : MODEL_PCD_DYNAMIC_DEFAULT,
814 TAB_PCDS_DYNAMIC_HII_NULL.upper() : MODEL_PCD_DYNAMIC_HII,
815 TAB_PCDS_DYNAMIC_VPD_NULL.upper() : MODEL_PCD_DYNAMIC_VPD,
816 TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT,
817 TAB_PCDS_DYNAMIC_EX_HII_NULL.upper() : MODEL_PCD_DYNAMIC_EX_HII,
818 TAB_PCDS_DYNAMIC_EX_VPD_NULL.upper() : MODEL_PCD_DYNAMIC_EX_VPD,
819 TAB_COMPONENTS.upper() : MODEL_META_DATA_COMPONENT,
820 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH.upper() : MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH,
821 TAB_DSC_DEFINES.upper() : MODEL_META_DATA_HEADER,
822 TAB_DSC_DEFINES_DEFINE : MODEL_META_DATA_DEFINE,
823 TAB_DSC_DEFINES_EDKGLOBAL : MODEL_META_DATA_GLOBAL_DEFINE,
824 TAB_INCLUDE.upper() : MODEL_META_DATA_INCLUDE,
825 TAB_IF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,
826 TAB_IF_DEF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,
827 TAB_IF_N_DEF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF,
828 TAB_ELSE_IF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF,
829 TAB_ELSE.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE,
830 TAB_END_IF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF,
831 TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION,
832 }
833
834 # Valid names in define section
835 DefineKeywords = [
836 "DSC_SPECIFICATION",
837 "PLATFORM_NAME",
838 "PLATFORM_GUID",
839 "PLATFORM_VERSION",
840 "SKUID_IDENTIFIER",
841 "PCD_INFO_GENERATION",
842 "PCD_VAR_CHECK_GENERATION",
843 "SUPPORTED_ARCHITECTURES",
844 "BUILD_TARGETS",
845 "OUTPUT_DIRECTORY",
846 "FLASH_DEFINITION",
847 "BUILD_NUMBER",
848 "RFC_LANGUAGES",
849 "ISO_LANGUAGES",
850 "TIME_STAMP_FILE",
851 "VPD_TOOL_GUID",
852 "FIX_LOAD_TOP_MEMORY_ADDRESS",
853 "PREBUILD",
854 "POSTBUILD"
855 ]
856
857 SubSectionDefineKeywords = [
858 "FILE_GUID"
859 ]
860
861 SymbolPattern = ValueExpression.SymbolPattern
862
863 IncludedFiles = set()
864
865 ## Constructor of DscParser
866 #
867 # Initialize object of DscParser
868 #
869 # @param FilePath The path of platform description file
870 # @param FileType The raw data of DSC file
871 # @param Arch Default Arch value for filtering sections
872 # @param Table Database used to retrieve module/package information
873 # @param Owner Owner ID (for sub-section parsing)
874 # @param From ID from which the data comes (for !INCLUDE directive)
875 #
876 def __init__(self, FilePath, FileType, Arch, Table, Owner= -1, From= -1):
877 # prevent re-initialization
878 if hasattr(self, "_Table"):
879 return
880 MetaFileParser.__init__(self, FilePath, FileType, Arch, Table, Owner, From)
881 self._Version = 0x00010005 # Only EDK2 dsc file is supported
882 # to store conditional directive evaluation result
883 self._DirectiveStack = []
884 self._DirectiveEvalStack = []
885 self._Enabled = 1
886
887 #
888 # Specify whether current line is in uncertain condition
889 #
890 self._InDirective = -1
891
892 # Final valid replacable symbols
893 self._Symbols = {}
894 #
895 # Map the ID between the original table and new table to track
896 # the owner item
897 #
898 self._IdMapping = {-1:-1}
899
900 ## Parser starter
901 def Start(self):
902 Content = ''
903 try:
904 Content = open(str(self.MetaFile), 'r').readlines()
905 except:
906 EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile)
907
908 OwnerId = {}
909 for Index in range(0, len(Content)):
910 Line = CleanString(Content[Index])
911 # skip empty line
912 if Line == '':
913 continue
914
915 self._CurrentLine = Line
916 self._LineIndex = Index
917 if self._InSubsection and self._Owner[-1] == -1:
918 self._Owner.append(self._LastItem)
919
920 # section header
921 if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:
922 self._SectionType = MODEL_META_DATA_SECTION_HEADER
923 # subsection ending
924 elif Line[0] == '}' and self._InSubsection:
925 self._InSubsection = False
926 self._SubsectionType = MODEL_UNKNOWN
927 self._SubsectionName = ''
928 self._Owner[-1] = -1
929 OwnerId = {}
930 continue
931 # subsection header
932 elif Line[0] == TAB_OPTION_START and Line[-1] == TAB_OPTION_END:
933 self._SubsectionType = MODEL_META_DATA_SUBSECTION_HEADER
934 # directive line
935 elif Line[0] == '!':
936 self._DirectiveParser()
937 continue
938 if Line[0] == TAB_OPTION_START and not self._InSubsection:
939 EdkLogger.error("Parser", FILE_READ_FAILURE, "Missing the '{' before %s in Line %s" % (Line, Index+1),ExtraData=self.MetaFile)
940
941 if self._InSubsection:
942 SectionType = self._SubsectionType
943 else:
944 SectionType = self._SectionType
945 self._ItemType = SectionType
946
947 self._ValueList = ['', '', '']
948 self._SectionParser[SectionType](self)
949 if self._ValueList == None:
950 continue
951 #
952 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
953 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
954 #
955 for Arch, ModuleType in self._Scope:
956 Owner = self._Owner[-1]
957 if self._SubsectionType != MODEL_UNKNOWN:
958 Owner = OwnerId[Arch]
959 self._LastItem = self._Store(
960 self._ItemType,
961 self._ValueList[0],
962 self._ValueList[1],
963 self._ValueList[2],
964 Arch,
965 ModuleType,
966 Owner,
967 self._From,
968 self._LineIndex + 1,
969 - 1,
970 self._LineIndex + 1,
971 - 1,
972 self._Enabled
973 )
974 if self._SubsectionType == MODEL_UNKNOWN and self._InSubsection:
975 OwnerId[Arch] = self._LastItem
976
977 if self._DirectiveStack:
978 Type, Line, Text = self._DirectiveStack[-1]
979 EdkLogger.error('Parser', FORMAT_INVALID, "No matching '!endif' found",
980 ExtraData=Text, File=self.MetaFile, Line=Line)
981 self._Done()
982
983 ## <subsection_header> parser
984 def _SubsectionHeaderParser(self):
985 self._SubsectionName = self._CurrentLine[1:-1].upper()
986 if self._SubsectionName in self.DataType:
987 self._SubsectionType = self.DataType[self._SubsectionName]
988 else:
989 self._SubsectionType = MODEL_UNKNOWN
990 EdkLogger.warn("Parser", "Unrecognized sub-section", File=self.MetaFile,
991 Line=self._LineIndex + 1, ExtraData=self._CurrentLine)
992 self._ValueList[0] = self._SubsectionName
993
994 ## Directive statement parser
995 def _DirectiveParser(self):
996 self._ValueList = ['', '', '']
997 TokenList = GetSplitValueList(self._CurrentLine, ' ', 1)
998 self._ValueList[0:len(TokenList)] = TokenList
999
1000 # Syntax check
1001 DirectiveName = self._ValueList[0].upper()
1002 if DirectiveName not in self.DataType:
1003 EdkLogger.error("Parser", FORMAT_INVALID, "Unknown directive [%s]" % DirectiveName,
1004 File=self.MetaFile, Line=self._LineIndex + 1)
1005
1006 if DirectiveName in ['!IF', '!IFDEF', '!IFNDEF']:
1007 self._InDirective += 1
1008
1009 if DirectiveName in ['!ENDIF']:
1010 self._InDirective -= 1
1011
1012 if DirectiveName in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self._ValueList[1] == '':
1013 EdkLogger.error("Parser", FORMAT_INVALID, "Missing expression",
1014 File=self.MetaFile, Line=self._LineIndex + 1,
1015 ExtraData=self._CurrentLine)
1016
1017 ItemType = self.DataType[DirectiveName]
1018 Scope = [['COMMON', 'COMMON']]
1019 if ItemType == MODEL_META_DATA_INCLUDE:
1020 Scope = self._Scope
1021 if ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF:
1022 # Remove all directives between !if and !endif, including themselves
1023 while self._DirectiveStack:
1024 # Remove any !else or !elseif
1025 DirectiveInfo = self._DirectiveStack.pop()
1026 if DirectiveInfo[0] in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,
1027 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,
1028 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF]:
1029 break
1030 else:
1031 EdkLogger.error("Parser", FORMAT_INVALID, "Redundant '!endif'",
1032 File=self.MetaFile, Line=self._LineIndex + 1,
1033 ExtraData=self._CurrentLine)
1034 elif ItemType != MODEL_META_DATA_INCLUDE:
1035 # Break if there's a !else is followed by a !elseif
1036 if ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF and \
1037 self._DirectiveStack and \
1038 self._DirectiveStack[-1][0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE:
1039 EdkLogger.error("Parser", FORMAT_INVALID, "'!elseif' after '!else'",
1040 File=self.MetaFile, Line=self._LineIndex + 1,
1041 ExtraData=self._CurrentLine)
1042 self._DirectiveStack.append((ItemType, self._LineIndex + 1, self._CurrentLine))
1043
1044 #
1045 # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1,
1046 # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
1047 #
1048 for Arch, ModuleType in Scope:
1049 self._LastItem = self._Store(
1050 ItemType,
1051 self._ValueList[0],
1052 self._ValueList[1],
1053 self._ValueList[2],
1054 Arch,
1055 ModuleType,
1056 self._Owner[-1],
1057 self._From,
1058 self._LineIndex + 1,
1059 - 1,
1060 self._LineIndex + 1,
1061 - 1,
1062 0
1063 )
1064
1065 ## [defines] section parser
1066 @ParseMacro
1067 def _DefineParser(self):
1068 TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
1069 self._ValueList[1:len(TokenList)] = TokenList
1070
1071 # Syntax check
1072 if not self._ValueList[1]:
1073 EdkLogger.error('Parser', FORMAT_INVALID, "No name specified",
1074 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
1075 if not self._ValueList[2]:
1076 EdkLogger.error('Parser', FORMAT_INVALID, "No value specified",
1077 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
1078 if (not self._ValueList[1] in self.DefineKeywords and
1079 (self._InSubsection and self._ValueList[1] not in self.SubSectionDefineKeywords)):
1080 EdkLogger.error('Parser', FORMAT_INVALID,
1081 "Unknown keyword found: %s. "
1082 "If this is a macro you must "
1083 "add it as a DEFINE in the DSC" % self._ValueList[1],
1084 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
1085 if not self._InSubsection:
1086 self._Defines[self._ValueList[1]] = self._ValueList[2]
1087 self._ItemType = self.DataType[TAB_DSC_DEFINES.upper()]
1088
1089 @ParseMacro
1090 def _SkuIdParser(self):
1091 TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
1092 if len(TokenList) != 2:
1093 EdkLogger.error('Parser', FORMAT_INVALID, "Correct format is '<Integer>|<UiName>'",
1094 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
1095 self._ValueList[0:len(TokenList)] = TokenList
1096
1097 ## Parse Edk style of library modules
1098 @ParseMacro
1099 def _LibraryInstanceParser(self):
1100 self._ValueList[0] = self._CurrentLine
1101
1102 ## PCD sections parser
1103 #
1104 # [PcdsFixedAtBuild]
1105 # [PcdsPatchableInModule]
1106 # [PcdsFeatureFlag]
1107 # [PcdsDynamicEx
1108 # [PcdsDynamicExDefault]
1109 # [PcdsDynamicExVpd]
1110 # [PcdsDynamicExHii]
1111 # [PcdsDynamic]
1112 # [PcdsDynamicDefault]
1113 # [PcdsDynamicVpd]
1114 # [PcdsDynamicHii]
1115 #
1116 @ParseMacro
1117 def _PcdParser(self):
1118 TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)
1119 self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)
1120 PcdNameTockens = GetSplitValueList(TokenList[0], TAB_SPLIT)
1121 if len(PcdNameTockens) == 2:
1122 self._ValueList[0], self._ValueList[1] = PcdNameTockens[0], PcdNameTockens[1]
1123 elif len(PcdNameTockens) == 3:
1124 self._ValueList[0], self._ValueList[1] = ".".join((PcdNameTockens[0], PcdNameTockens[1])), PcdNameTockens[2]
1125 if len(TokenList) == 2:
1126 self._ValueList[2] = TokenList[1]
1127 if self._ValueList[0] == '' or self._ValueList[1] == '':
1128 EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",
1129 ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1130 File=self.MetaFile, Line=self._LineIndex + 1)
1131 if self._ValueList[2] == '':
1132 #
1133 # The PCD values are optional for FIXEDATBUILD and PATCHABLEINMODULE
1134 #
1135 if self._SectionType in (MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE):
1136 return
1137 EdkLogger.error('Parser', FORMAT_INVALID, "No PCD value given",
1138 ExtraData=self._CurrentLine + " (<TokenSpaceGuidCName>.<TokenCName>|<PcdValue>)",
1139 File=self.MetaFile, Line=self._LineIndex + 1)
1140
1141 # Validate the datum type of Dynamic Defaul PCD and DynamicEx Default PCD
1142 ValueList = GetSplitValueList(self._ValueList[2])
1143 if len(ValueList) > 1 and ValueList[1] in [TAB_UINT8 , TAB_UINT16, TAB_UINT32 , TAB_UINT64] \
1144 and self._ItemType in [MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT]:
1145 EdkLogger.error('Parser', FORMAT_INVALID, "The datum type '%s' of PCD is wrong" % ValueList[1],
1146 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
1147
1148 # Validate the VariableName of DynamicHii and DynamicExHii for PCD Entry must not be an empty string
1149 if self._ItemType in [MODEL_PCD_DYNAMIC_HII, MODEL_PCD_DYNAMIC_EX_HII]:
1150 DscPcdValueList = GetSplitValueList(TokenList[1], TAB_VALUE_SPLIT, 1)
1151 if len(DscPcdValueList[0].replace('L','').replace('"','').strip()) == 0:
1152 EdkLogger.error('Parser', FORMAT_INVALID, "The VariableName field in the HII format PCD entry must not be an empty string",
1153 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
1154
1155 # if value are 'True', 'true', 'TRUE' or 'False', 'false', 'FALSE', replace with integer 1 or 0.
1156 DscPcdValueList = GetSplitValueList(TokenList[1], TAB_VALUE_SPLIT, 1)
1157 if DscPcdValueList[0] in ['True', 'true', 'TRUE']:
1158 self._ValueList[2] = TokenList[1].replace(DscPcdValueList[0], '1', 1);
1159 elif DscPcdValueList[0] in ['False', 'false', 'FALSE']:
1160 self._ValueList[2] = TokenList[1].replace(DscPcdValueList[0], '0', 1);
1161
1162
1163 ## [components] section parser
1164 @ParseMacro
1165 def _ComponentParser(self):
1166 if self._CurrentLine[-1] == '{':
1167 self._ValueList[0] = self._CurrentLine[0:-1].strip()
1168 self._InSubsection = True
1169 else:
1170 self._ValueList[0] = self._CurrentLine
1171
1172 ## [LibraryClasses] section
1173 @ParseMacro
1174 def _LibraryClassParser(self):
1175 TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)
1176 if len(TokenList) < 2:
1177 EdkLogger.error('Parser', FORMAT_INVALID, "No library class or instance specified",
1178 ExtraData=self._CurrentLine + " (<LibraryClassName>|<LibraryInstancePath>)",
1179 File=self.MetaFile, Line=self._LineIndex + 1)
1180 if TokenList[0] == '':
1181 EdkLogger.error('Parser', FORMAT_INVALID, "No library class specified",
1182 ExtraData=self._CurrentLine + " (<LibraryClassName>|<LibraryInstancePath>)",
1183 File=self.MetaFile, Line=self._LineIndex + 1)
1184 if TokenList[1] == '':
1185 EdkLogger.error('Parser', FORMAT_INVALID, "No library instance specified",
1186 ExtraData=self._CurrentLine + " (<LibraryClassName>|<LibraryInstancePath>)",
1187 File=self.MetaFile, Line=self._LineIndex + 1)
1188
1189 self._ValueList[0:len(TokenList)] = TokenList
1190
1191 def _CompponentSourceOverridePathParser(self):
1192 self._ValueList[0] = self._CurrentLine
1193
1194 ## [BuildOptions] section parser
1195 @ParseMacro
1196 def _BuildOptionParser(self):
1197 self._CurrentLine = CleanString(self._CurrentLine, BuildOption=True)
1198 TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
1199 TokenList2 = GetSplitValueList(TokenList[0], ':', 1)
1200 if len(TokenList2) == 2:
1201 self._ValueList[0] = TokenList2[0] # toolchain family
1202 self._ValueList[1] = TokenList2[1] # keys
1203 else:
1204 self._ValueList[1] = TokenList[0]
1205 if len(TokenList) == 2: # value
1206 self._ValueList[2] = TokenList[1]
1207
1208 if self._ValueList[1].count('_') != 4:
1209 EdkLogger.error(
1210 'Parser',
1211 FORMAT_INVALID,
1212 "'%s' must be in format of <TARGET>_<TOOLCHAIN>_<ARCH>_<TOOL>_FLAGS" % self._ValueList[1],
1213 ExtraData=self._CurrentLine,
1214 File=self.MetaFile,
1215 Line=self._LineIndex + 1
1216 )
1217
1218 ## Override parent's method since we'll do all macro replacements in parser
1219 def _GetMacros(self):
1220 Macros = {}
1221 Macros.update(self._FileLocalMacros)
1222 Macros.update(self._GetApplicableSectionMacro())
1223 Macros.update(GlobalData.gEdkGlobal)
1224 Macros.update(GlobalData.gPlatformDefines)
1225 Macros.update(GlobalData.gCommandLineDefines)
1226 # PCD cannot be referenced in macro definition
1227 if self._ItemType not in [MODEL_META_DATA_DEFINE, MODEL_META_DATA_GLOBAL_DEFINE]:
1228 Macros.update(self._Symbols)
1229 return Macros
1230
1231 def _PostProcess(self):
1232 Processer = {
1233 MODEL_META_DATA_SECTION_HEADER : self.__ProcessSectionHeader,
1234 MODEL_META_DATA_SUBSECTION_HEADER : self.__ProcessSubsectionHeader,
1235 MODEL_META_DATA_HEADER : self.__ProcessDefine,
1236 MODEL_META_DATA_DEFINE : self.__ProcessDefine,
1237 MODEL_META_DATA_GLOBAL_DEFINE : self.__ProcessDefine,
1238 MODEL_META_DATA_INCLUDE : self.__ProcessDirective,
1239 MODEL_META_DATA_CONDITIONAL_STATEMENT_IF : self.__ProcessDirective,
1240 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE : self.__ProcessDirective,
1241 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF : self.__ProcessDirective,
1242 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF : self.__ProcessDirective,
1243 MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF : self.__ProcessDirective,
1244 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF : self.__ProcessDirective,
1245 MODEL_EFI_SKU_ID : self.__ProcessSkuId,
1246 MODEL_EFI_LIBRARY_INSTANCE : self.__ProcessLibraryInstance,
1247 MODEL_EFI_LIBRARY_CLASS : self.__ProcessLibraryClass,
1248 MODEL_PCD_FIXED_AT_BUILD : self.__ProcessPcd,
1249 MODEL_PCD_PATCHABLE_IN_MODULE : self.__ProcessPcd,
1250 MODEL_PCD_FEATURE_FLAG : self.__ProcessPcd,
1251 MODEL_PCD_DYNAMIC_DEFAULT : self.__ProcessPcd,
1252 MODEL_PCD_DYNAMIC_HII : self.__ProcessPcd,
1253 MODEL_PCD_DYNAMIC_VPD : self.__ProcessPcd,
1254 MODEL_PCD_DYNAMIC_EX_DEFAULT : self.__ProcessPcd,
1255 MODEL_PCD_DYNAMIC_EX_HII : self.__ProcessPcd,
1256 MODEL_PCD_DYNAMIC_EX_VPD : self.__ProcessPcd,
1257 MODEL_META_DATA_COMPONENT : self.__ProcessComponent,
1258 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH : self.__ProcessSourceOverridePath,
1259 MODEL_META_DATA_BUILD_OPTION : self.__ProcessBuildOption,
1260 MODEL_UNKNOWN : self._Skip,
1261 MODEL_META_DATA_USER_EXTENSION : self._SkipUserExtension,
1262 }
1263
1264 self._Table = MetaFileStorage(self._RawTable.Cur, self.MetaFile, MODEL_FILE_DSC, True)
1265 self._Table.Create()
1266 self._DirectiveStack = []
1267 self._DirectiveEvalStack = []
1268 self._FileWithError = self.MetaFile
1269 self._FileLocalMacros = {}
1270 self._SectionsMacroDict = {}
1271 GlobalData.gPlatformDefines = {}
1272
1273 # Get all macro and PCD which has straitforward value
1274 self.__RetrievePcdValue()
1275 self._Content = self._RawTable.GetAll()
1276 self._ContentIndex = 0
1277 self._InSubsection = False
1278 while self._ContentIndex < len(self._Content) :
1279 Id, self._ItemType, V1, V2, V3, S1, S2, Owner, self._From, \
1280 LineStart, ColStart, LineEnd, ColEnd, Enabled = self._Content[self._ContentIndex]
1281
1282 if self._From < 0:
1283 self._FileWithError = self.MetaFile
1284
1285 self._ContentIndex += 1
1286
1287 self._Scope = [[S1, S2]]
1288 #
1289 # For !include directive, handle it specially,
1290 # merge arch and module type in case of duplicate items
1291 #
1292 while self._ItemType == MODEL_META_DATA_INCLUDE:
1293 if self._ContentIndex >= len(self._Content):
1294 break
1295 Record = self._Content[self._ContentIndex]
1296 if LineStart == Record[9] and LineEnd == Record[11]:
1297 if [Record[5], Record[6]] not in self._Scope:
1298 self._Scope.append([Record[5], Record[6]])
1299 self._ContentIndex += 1
1300 else:
1301 break
1302
1303 self._LineIndex = LineStart - 1
1304 self._ValueList = [V1, V2, V3]
1305
1306 if Owner > 0 and Owner in self._IdMapping:
1307 self._InSubsection = True
1308 else:
1309 self._InSubsection = False
1310 try:
1311 Processer[self._ItemType]()
1312 except EvaluationException, Excpt:
1313 #
1314 # Only catch expression evaluation error here. We need to report
1315 # the precise number of line on which the error occurred
1316 #
1317 if hasattr(Excpt, 'Pcd'):
1318 if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
1319 Info = GlobalData.gPlatformOtherPcds[Excpt.Pcd]
1320 EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"
1321 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
1322 " of the DSC file, and it is currently defined in this section:"
1323 " %s, line #: %d." % (Excpt.Pcd, Info[0], Info[1]),
1324 File=self._FileWithError, ExtraData=' '.join(self._ValueList),
1325 Line=self._LineIndex + 1)
1326 else:
1327 EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,
1328 File=self._FileWithError, ExtraData=' '.join(self._ValueList),
1329 Line=self._LineIndex + 1)
1330 else:
1331 EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),
1332 File=self._FileWithError, ExtraData=' '.join(self._ValueList),
1333 Line=self._LineIndex + 1)
1334 except MacroException, Excpt:
1335 EdkLogger.error('Parser', FORMAT_INVALID, str(Excpt),
1336 File=self._FileWithError, ExtraData=' '.join(self._ValueList),
1337 Line=self._LineIndex + 1)
1338
1339 if self._ValueList == None:
1340 continue
1341
1342 NewOwner = self._IdMapping.get(Owner, -1)
1343 self._Enabled = int((not self._DirectiveEvalStack) or (False not in self._DirectiveEvalStack))
1344 self._LastItem = self._Store(
1345 self._ItemType,
1346 self._ValueList[0],
1347 self._ValueList[1],
1348 self._ValueList[2],
1349 S1,
1350 S2,
1351 NewOwner,
1352 self._From,
1353 self._LineIndex + 1,
1354 - 1,
1355 self._LineIndex + 1,
1356 - 1,
1357 self._Enabled
1358 )
1359 self._IdMapping[Id] = self._LastItem
1360
1361 GlobalData.gPlatformDefines.update(self._FileLocalMacros)
1362 self._PostProcessed = True
1363 self._Content = None
1364
1365 def __ProcessSectionHeader(self):
1366 self._SectionName = self._ValueList[0]
1367 if self._SectionName in self.DataType:
1368 self._SectionType = self.DataType[self._SectionName]
1369 else:
1370 self._SectionType = MODEL_UNKNOWN
1371
1372 def __ProcessSubsectionHeader(self):
1373 self._SubsectionName = self._ValueList[0]
1374 if self._SubsectionName in self.DataType:
1375 self._SubsectionType = self.DataType[self._SubsectionName]
1376 else:
1377 self._SubsectionType = MODEL_UNKNOWN
1378
1379 def __RetrievePcdValue(self):
1380 Content = open(str(self.MetaFile), 'r').readlines()
1381 GlobalData.gPlatformOtherPcds['DSCFILE'] = str(self.MetaFile)
1382 for PcdType in (MODEL_PCD_PATCHABLE_IN_MODULE, MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_HII,
1383 MODEL_PCD_DYNAMIC_VPD, MODEL_PCD_DYNAMIC_EX_DEFAULT, MODEL_PCD_DYNAMIC_EX_HII,
1384 MODEL_PCD_DYNAMIC_EX_VPD):
1385 Records = self._RawTable.Query(PcdType, BelongsToItem= -1.0)
1386 for TokenSpaceGuid, PcdName, Value, Dummy2, Dummy3, ID, Line in Records:
1387 Name = TokenSpaceGuid + '.' + PcdName
1388 if Name not in GlobalData.gPlatformOtherPcds:
1389 PcdLine = Line
1390 while not Content[Line - 1].lstrip().startswith(TAB_SECTION_START):
1391 Line -= 1
1392 GlobalData.gPlatformOtherPcds[Name] = (CleanString(Content[Line - 1]), PcdLine, PcdType)
1393
1394 def __ProcessDefine(self):
1395 if not self._Enabled:
1396 return
1397
1398 Type, Name, Value = self._ValueList
1399 Value = ReplaceMacro(Value, self._Macros, False)
1400 #
1401 # If it is <Defines>, return
1402 #
1403 if self._InSubsection:
1404 self._ValueList = [Type, Name, Value]
1405 return
1406
1407 if self._ItemType == MODEL_META_DATA_DEFINE:
1408 if self._SectionType == MODEL_META_DATA_HEADER:
1409 self._FileLocalMacros[Name] = Value
1410 else:
1411 self._ConstructSectionMacroDict(Name, Value)
1412 elif self._ItemType == MODEL_META_DATA_GLOBAL_DEFINE:
1413 GlobalData.gEdkGlobal[Name] = Value
1414
1415 #
1416 # Keyword in [Defines] section can be used as Macros
1417 #
1418 if (self._ItemType == MODEL_META_DATA_HEADER) and (self._SectionType == MODEL_META_DATA_HEADER):
1419 self._FileLocalMacros[Name] = Value
1420
1421 self._ValueList = [Type, Name, Value]
1422
1423 def __ProcessDirective(self):
1424 Result = None
1425 if self._ItemType in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,
1426 MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF]:
1427 Macros = self._Macros
1428 Macros.update(GlobalData.gGlobalDefines)
1429 try:
1430 Result = ValueExpression(self._ValueList[1], Macros)()
1431 except SymbolNotFound, Exc:
1432 EdkLogger.debug(EdkLogger.DEBUG_5, str(Exc), self._ValueList[1])
1433 Result = False
1434 except WrnExpression, Excpt:
1435 #
1436 # Catch expression evaluation warning here. We need to report
1437 # the precise number of line and return the evaluation result
1438 #
1439 EdkLogger.warn('Parser', "Suspicious expression: %s" % str(Excpt),
1440 File=self._FileWithError, ExtraData=' '.join(self._ValueList),
1441 Line=self._LineIndex + 1)
1442 Result = Excpt.result
1443
1444 if self._ItemType in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,
1445 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,
1446 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF]:
1447 self._DirectiveStack.append(self._ItemType)
1448 if self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_IF:
1449 Result = bool(Result)
1450 else:
1451 Macro = self._ValueList[1]
1452 Macro = Macro[2:-1] if (Macro.startswith("$(") and Macro.endswith(")")) else Macro
1453 Result = Macro in self._Macros
1454 if self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF:
1455 Result = not Result
1456 self._DirectiveEvalStack.append(Result)
1457 elif self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF:
1458 self._DirectiveStack.append(self._ItemType)
1459 self._DirectiveEvalStack[-1] = not self._DirectiveEvalStack[-1]
1460 self._DirectiveEvalStack.append(bool(Result))
1461 elif self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE:
1462 self._DirectiveStack.append(self._ItemType)
1463 self._DirectiveEvalStack[-1] = not self._DirectiveEvalStack[-1]
1464 self._DirectiveEvalStack.append(True)
1465 elif self._ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF:
1466 # Back to the nearest !if/!ifdef/!ifndef
1467 while self._DirectiveStack:
1468 self._DirectiveEvalStack.pop()
1469 Directive = self._DirectiveStack.pop()
1470 if Directive in [MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,
1471 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,
1472 MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF]:
1473 break
1474 elif self._ItemType == MODEL_META_DATA_INCLUDE:
1475 # The included file must be relative to workspace or same directory as DSC file
1476 __IncludeMacros = {}
1477 #
1478 # Allow using system environment variables in path after !include
1479 #
1480 __IncludeMacros['WORKSPACE'] = GlobalData.gGlobalDefines['WORKSPACE']
1481 if "ECP_SOURCE" in GlobalData.gGlobalDefines.keys():
1482 __IncludeMacros['ECP_SOURCE'] = GlobalData.gGlobalDefines['ECP_SOURCE']
1483 #
1484 # During GenFds phase call DSC parser, will go into this branch.
1485 #
1486 elif "ECP_SOURCE" in GlobalData.gCommandLineDefines.keys():
1487 __IncludeMacros['ECP_SOURCE'] = GlobalData.gCommandLineDefines['ECP_SOURCE']
1488
1489 __IncludeMacros['EFI_SOURCE'] = GlobalData.gGlobalDefines['EFI_SOURCE']
1490 __IncludeMacros['EDK_SOURCE'] = GlobalData.gGlobalDefines['EDK_SOURCE']
1491 #
1492 # Allow using MACROs comes from [Defines] section to keep compatible.
1493 #
1494 __IncludeMacros.update(self._Macros)
1495
1496 IncludedFile = NormPath(ReplaceMacro(self._ValueList[1], __IncludeMacros, RaiseError=True))
1497 #
1498 # First search the include file under the same directory as DSC file
1499 #
1500 IncludedFile1 = PathClass(IncludedFile, self.MetaFile.Dir)
1501 ErrorCode, ErrorInfo1 = IncludedFile1.Validate()
1502 if ErrorCode != 0:
1503 #
1504 # Also search file under the WORKSPACE directory
1505 #
1506 IncludedFile1 = PathClass(IncludedFile, GlobalData.gWorkspace)
1507 ErrorCode, ErrorInfo2 = IncludedFile1.Validate()
1508 if ErrorCode != 0:
1509 EdkLogger.error('parser', ErrorCode, File=self._FileWithError,
1510 Line=self._LineIndex + 1, ExtraData=ErrorInfo1 + "\n" + ErrorInfo2)
1511
1512 self._FileWithError = IncludedFile1
1513
1514 IncludedFileTable = MetaFileStorage(self._Table.Cur, IncludedFile1, MODEL_FILE_DSC, False)
1515 Owner = self._Content[self._ContentIndex - 1][0]
1516 Parser = DscParser(IncludedFile1, self._FileType, self._Arch, IncludedFileTable,
1517 Owner=Owner, From=Owner)
1518
1519 self.IncludedFiles.add (IncludedFile1)
1520
1521 # Does not allow lower level included file to include upper level included file
1522 if Parser._From != Owner and int(Owner) > int (Parser._From):
1523 EdkLogger.error('parser', FILE_ALREADY_EXIST, File=self._FileWithError,
1524 Line=self._LineIndex + 1, ExtraData="{0} is already included at a higher level.".format(IncludedFile1))
1525
1526
1527 # set the parser status with current status
1528 Parser._SectionName = self._SectionName
1529 Parser._SectionType = self._SectionType
1530 Parser._Scope = self._Scope
1531 Parser._Enabled = self._Enabled
1532 # Parse the included file
1533 Parser.Start()
1534
1535 # update current status with sub-parser's status
1536 self._SectionName = Parser._SectionName
1537 self._SectionType = Parser._SectionType
1538 self._Scope = Parser._Scope
1539 self._Enabled = Parser._Enabled
1540
1541 # Insert all records in the table for the included file into dsc file table
1542 Records = IncludedFileTable.GetAll()
1543 if Records:
1544 self._Content[self._ContentIndex:self._ContentIndex] = Records
1545 self._Content.pop(self._ContentIndex - 1)
1546 self._ValueList = None
1547 self._ContentIndex -= 1
1548
1549 def __ProcessSkuId(self):
1550 self._ValueList = [ReplaceMacro(Value, self._Macros, RaiseError=True)
1551 for Value in self._ValueList]
1552
1553 def __ProcessLibraryInstance(self):
1554 self._ValueList = [ReplaceMacro(Value, self._Macros) for Value in self._ValueList]
1555
1556 def __ProcessLibraryClass(self):
1557 self._ValueList[1] = ReplaceMacro(self._ValueList[1], self._Macros, RaiseError=True)
1558
1559 def __ProcessPcd(self):
1560 if self._ItemType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:
1561 self._ValueList[2] = ReplaceMacro(self._ValueList[2], self._Macros, RaiseError=True)
1562 return
1563
1564 ValList, Valid, Index = AnalyzeDscPcd(self._ValueList[2], self._ItemType)
1565 if not Valid:
1566 EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self._FileWithError, Line=self._LineIndex + 1,
1567 ExtraData="%s.%s|%s" % (self._ValueList[0], self._ValueList[1], self._ValueList[2]))
1568 PcdValue = ValList[Index]
1569 if PcdValue and "." not in self._ValueList[0]:
1570 try:
1571 ValList[Index] = ValueExpression(PcdValue, self._Macros)(True)
1572 except WrnExpression, Value:
1573 ValList[Index] = Value.result
1574
1575 if ValList[Index] == 'True':
1576 ValList[Index] = '1'
1577 if ValList[Index] == 'False':
1578 ValList[Index] = '0'
1579
1580 if (not self._DirectiveEvalStack) or (False not in self._DirectiveEvalStack):
1581 GlobalData.gPlatformPcds[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue
1582 self._Symbols[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue
1583 try:
1584 self._ValueList[2] = '|'.join(ValList)
1585 except Exception:
1586 print ValList
1587
1588 def __ProcessComponent(self):
1589 self._ValueList[0] = ReplaceMacro(self._ValueList[0], self._Macros)
1590
1591 def __ProcessSourceOverridePath(self):
1592 self._ValueList[0] = ReplaceMacro(self._ValueList[0], self._Macros)
1593
1594 def __ProcessBuildOption(self):
1595 self._ValueList = [ReplaceMacro(Value, self._Macros, RaiseError=False)
1596 for Value in self._ValueList]
1597
1598 _SectionParser = {
1599 MODEL_META_DATA_HEADER : _DefineParser,
1600 MODEL_EFI_SKU_ID : _SkuIdParser,
1601 MODEL_EFI_LIBRARY_INSTANCE : _LibraryInstanceParser,
1602 MODEL_EFI_LIBRARY_CLASS : _LibraryClassParser,
1603 MODEL_PCD_FIXED_AT_BUILD : _PcdParser,
1604 MODEL_PCD_PATCHABLE_IN_MODULE : _PcdParser,
1605 MODEL_PCD_FEATURE_FLAG : _PcdParser,
1606 MODEL_PCD_DYNAMIC_DEFAULT : _PcdParser,
1607 MODEL_PCD_DYNAMIC_HII : _PcdParser,
1608 MODEL_PCD_DYNAMIC_VPD : _PcdParser,
1609 MODEL_PCD_DYNAMIC_EX_DEFAULT : _PcdParser,
1610 MODEL_PCD_DYNAMIC_EX_HII : _PcdParser,
1611 MODEL_PCD_DYNAMIC_EX_VPD : _PcdParser,
1612 MODEL_META_DATA_COMPONENT : _ComponentParser,
1613 MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH : _CompponentSourceOverridePathParser,
1614 MODEL_META_DATA_BUILD_OPTION : _BuildOptionParser,
1615 MODEL_UNKNOWN : MetaFileParser._Skip,
1616 MODEL_META_DATA_USER_EXTENSION : MetaFileParser._SkipUserExtension,
1617 MODEL_META_DATA_SECTION_HEADER : MetaFileParser._SectionHeaderParser,
1618 MODEL_META_DATA_SUBSECTION_HEADER : _SubsectionHeaderParser,
1619 }
1620
1621 _Macros = property(_GetMacros)
1622
1623 ## DEC file parser class
1624 #
1625 # @param FilePath The path of platform description file
1626 # @param FileType The raw data of DSC file
1627 # @param Table Database used to retrieve module/package information
1628 # @param Macros Macros used for replacement in file
1629 #
1630 class DecParser(MetaFileParser):
1631 # DEC file supported data types (one type per section)
1632 DataType = {
1633 TAB_DEC_DEFINES.upper() : MODEL_META_DATA_HEADER,
1634 TAB_DSC_DEFINES_DEFINE : MODEL_META_DATA_DEFINE,
1635 TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE,
1636 TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS,
1637 TAB_GUIDS.upper() : MODEL_EFI_GUID,
1638 TAB_PPIS.upper() : MODEL_EFI_PPI,
1639 TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL,
1640 TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : MODEL_PCD_FIXED_AT_BUILD,
1641 TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : MODEL_PCD_PATCHABLE_IN_MODULE,
1642 TAB_PCDS_FEATURE_FLAG_NULL.upper() : MODEL_PCD_FEATURE_FLAG,
1643 TAB_PCDS_DYNAMIC_NULL.upper() : MODEL_PCD_DYNAMIC,
1644 TAB_PCDS_DYNAMIC_EX_NULL.upper() : MODEL_PCD_DYNAMIC_EX,
1645 TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION,
1646 }
1647
1648 ## Constructor of DecParser
1649 #
1650 # Initialize object of DecParser
1651 #
1652 # @param FilePath The path of platform description file
1653 # @param FileType The raw data of DSC file
1654 # @param Arch Default Arch value for filtering sections
1655 # @param Table Database used to retrieve module/package information
1656 #
1657 def __init__(self, FilePath, FileType, Arch, Table):
1658 # prevent re-initialization
1659 if hasattr(self, "_Table"):
1660 return
1661 MetaFileParser.__init__(self, FilePath, FileType, Arch, Table, -1)
1662 self._Comments = []
1663 self._Version = 0x00010005 # Only EDK2 dec file is supported
1664 self._AllPCDs = [] # Only for check duplicate PCD
1665 self._AllPcdDict = {}
1666
1667 self._CurrentStructurePcdName = ""
1668 self._include_flag = False
1669 self._package_flag = False
1670
1671 ## Parser starter
1672 def Start(self):
1673 Content = ''
1674 try:
1675 Content = open(str(self.MetaFile), 'r').readlines()
1676 except:
1677 EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile)
1678
1679 self._DefinesCount = 0
1680 for Index in range(0, len(Content)):
1681 Line, Comment = CleanString2(Content[Index])
1682 self._CurrentLine = Line
1683 self._LineIndex = Index
1684
1685 # save comment for later use
1686 if Comment:
1687 self._Comments.append((Comment, self._LineIndex + 1))
1688 # skip empty line
1689 if Line == '':
1690 continue
1691
1692 # section header
1693 if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:
1694 self._SectionHeaderParser()
1695 if self._SectionName == TAB_DEC_DEFINES.upper():
1696 self._DefinesCount += 1
1697 self._Comments = []
1698 continue
1699 if self._SectionType == MODEL_UNKNOWN:
1700 EdkLogger.error("Parser", FORMAT_INVALID,
1701 ""
1702 "Not able to determine \"%s\" in which section."%self._CurrentLine,
1703 self.MetaFile, self._LineIndex + 1)
1704 elif len(self._SectionType) == 0:
1705 self._Comments = []
1706 continue
1707
1708 # section content
1709 self._ValueList = ['', '', '']
1710 self._SectionParser[self._SectionType[0]](self)
1711 if self._ValueList == None or self._ItemType == MODEL_META_DATA_DEFINE:
1712 self._ItemType = -1
1713 self._Comments = []
1714 continue
1715
1716 #
1717 # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1,
1718 # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1
1719 #
1720 for Arch, ModuleType, Type in self._Scope:
1721 self._LastItem = self._Store(
1722 Type,
1723 self._ValueList[0],
1724 self._ValueList[1],
1725 self._ValueList[2],
1726 Arch,
1727 ModuleType,
1728 self._Owner[-1],
1729 self._LineIndex + 1,
1730 - 1,
1731 self._LineIndex + 1,
1732 - 1,
1733 0
1734 )
1735 for Comment, LineNo in self._Comments:
1736 self._Store(
1737 MODEL_META_DATA_COMMENT,
1738 Comment,
1739 self._ValueList[0],
1740 self._ValueList[1],
1741 Arch,
1742 ModuleType,
1743 self._LastItem,
1744 LineNo,
1745 - 1,
1746 LineNo,
1747 - 1,
1748 0
1749 )
1750 self._Comments = []
1751 if self._DefinesCount > 1:
1752 EdkLogger.error('Parser', FORMAT_INVALID, 'Multiple [Defines] section is exist.', self.MetaFile )
1753 if self._DefinesCount == 0:
1754 EdkLogger.error('Parser', FORMAT_INVALID, 'No [Defines] section exist.',self.MetaFile)
1755 self._Done()
1756
1757
1758 ## Section header parser
1759 #
1760 # The section header is always in following format:
1761 #
1762 # [section_name.arch<.platform|module_type>]
1763 #
1764 def _SectionHeaderParser(self):
1765 self._Scope = []
1766 self._SectionName = ''
1767 self._SectionType = []
1768 ArchList = set()
1769 PrivateList = set()
1770 Line = re.sub(',[\s]*', TAB_COMMA_SPLIT, self._CurrentLine)
1771 for Item in Line[1:-1].split(TAB_COMMA_SPLIT):
1772 if Item == '':
1773 EdkLogger.error("Parser", FORMAT_UNKNOWN_ERROR,
1774 "section name can NOT be empty or incorrectly use separator comma",
1775 self.MetaFile, self._LineIndex + 1, self._CurrentLine)
1776 ItemList = Item.split(TAB_SPLIT)
1777
1778 # different types of PCD are permissible in one section
1779 self._SectionName = ItemList[0].upper()
1780 if self._SectionName == TAB_DEC_DEFINES.upper() and (len(ItemList) > 1 or len(Line.split(TAB_COMMA_SPLIT)) > 1):
1781 EdkLogger.error("Parser", FORMAT_INVALID, "Defines section format is invalid",
1782 self.MetaFile, self._LineIndex + 1, self._CurrentLine)
1783 if self._SectionName in self.DataType:
1784 if self.DataType[self._SectionName] not in self._SectionType:
1785 self._SectionType.append(self.DataType[self._SectionName])
1786 else:
1787 EdkLogger.error("Parser", FORMAT_UNKNOWN_ERROR, "%s is not a valid section name" % Item,
1788 self.MetaFile, self._LineIndex + 1, self._CurrentLine)
1789
1790 if MODEL_PCD_FEATURE_FLAG in self._SectionType and len(self._SectionType) > 1:
1791 EdkLogger.error(
1792 'Parser',
1793 FORMAT_INVALID,
1794 "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL,
1795 File=self.MetaFile,
1796 Line=self._LineIndex + 1,
1797 ExtraData=self._CurrentLine
1798 )
1799 # S1 is always Arch
1800 if len(ItemList) > 1:
1801 S1 = ItemList[1].upper()
1802 else:
1803 S1 = 'COMMON'
1804 ArchList.add(S1)
1805 # S2 may be Platform or ModuleType
1806 if len(ItemList) > 2:
1807 S2 = ItemList[2].upper()
1808 # only Includes, GUIDs, PPIs, Protocols section have Private tag
1809 if self._SectionName in [TAB_INCLUDES.upper(), TAB_GUIDS.upper(), TAB_PROTOCOLS.upper(), TAB_PPIS.upper()]:
1810 if S2 != 'PRIVATE':
1811 EdkLogger.error("Parser", FORMAT_INVALID, 'Please use keyword "Private" as section tag modifier.',
1812 File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)
1813 else:
1814 S2 = 'COMMON'
1815 PrivateList.add(S2)
1816 if [S1, S2, self.DataType[self._SectionName]] not in self._Scope:
1817 self._Scope.append([S1, S2, self.DataType[self._SectionName]])
1818
1819 # 'COMMON' must not be used with specific ARCHs at the same section
1820 if 'COMMON' in ArchList and len(ArchList) > 1:
1821 EdkLogger.error('Parser', FORMAT_INVALID, "'common' ARCH must not be used with specific ARCHs",
1822 File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)
1823
1824 # It is not permissible to mix section tags without the Private attribute with section tags with the Private attribute
1825 if 'COMMON' in PrivateList and len(PrivateList) > 1:
1826 EdkLogger.error('Parser', FORMAT_INVALID, "Can't mix section tags without the Private attribute with section tags with the Private attribute",
1827 File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)
1828
1829 ## [guids], [ppis] and [protocols] section parser
1830 @ParseMacro
1831 def _GuidParser(self):
1832 TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)
1833 if len(TokenList) < 2:
1834 EdkLogger.error('Parser', FORMAT_INVALID, "No GUID name or value specified",
1835 ExtraData=self._CurrentLine + " (<CName> = <GuidValueInCFormat>)",
1836 File=self.MetaFile, Line=self._LineIndex + 1)
1837 if TokenList[0] == '':
1838 EdkLogger.error('Parser', FORMAT_INVALID, "No GUID name specified",
1839 ExtraData=self._CurrentLine + " (<CName> = <GuidValueInCFormat>)",
1840 File=self.MetaFile, Line=self._LineIndex + 1)
1841 if TokenList[1] == '':
1842 EdkLogger.error('Parser', FORMAT_INVALID, "No GUID value specified",
1843 ExtraData=self._CurrentLine + " (<CName> = <GuidValueInCFormat>)",
1844 File=self.MetaFile, Line=self._LineIndex + 1)
1845 if TokenList[1][0] != '{' or TokenList[1][-1] != '}' or GuidStructureStringToGuidString(TokenList[1]) == '':
1846 EdkLogger.error('Parser', FORMAT_INVALID, "Invalid GUID value format",
1847 ExtraData=self._CurrentLine + \
1848 " (<CName> = <GuidValueInCFormat:{8,4,4,{2,2,2,2,2,2,2,2}}>)",
1849 File=self.MetaFile, Line=self._LineIndex + 1)
1850 self._ValueList[0] = TokenList[0]
1851 self._ValueList[1] = TokenList[1]
1852
1853 ## PCD sections parser
1854 #
1855 # [PcdsFixedAtBuild]
1856 # [PcdsPatchableInModule]
1857 # [PcdsFeatureFlag]
1858 # [PcdsDynamicEx
1859 # [PcdsDynamic]
1860 #
1861 @ParseMacro
1862 def _PcdParser(self):
1863 if self._CurrentStructurePcdName:
1864 self._ValueList[0] = self._CurrentStructurePcdName
1865
1866 if "|" not in self._CurrentLine:
1867 if "<HeaderFiles>" == self._CurrentLine:
1868 self._include_flag = True
1869 self._ValueList = None
1870 return
1871 if "<Packages>" == self._CurrentLine:
1872 self._package_flag = True
1873 self._ValueList = None
1874 return
1875
1876 if self._include_flag:
1877 self._ValueList[1] = "<HeaderFiles>_" + md5.new(self._CurrentLine).hexdigest()
1878 self._ValueList[2] = self._CurrentLine
1879 self._include_flag = False
1880 if self._package_flag and "}" != self._CurrentLine:
1881 self._ValueList[1] = "<Packages>_" + md5.new(self._CurrentLine).hexdigest()
1882 self._ValueList[2] = self._CurrentLine
1883 if self._CurrentLine == "}":
1884 self._package_flag = False
1885 self._ValueList = None
1886 return
1887 else:
1888 PcdTockens = self._CurrentLine.split(TAB_VALUE_SPLIT)
1889 PcdNames = PcdTockens[0].split(TAB_SPLIT)
1890 if len(PcdNames) == 2:
1891 self._CurrentStructurePcdName = ""
1892 else:
1893 self._ValueList[1] = PcdNames[2]
1894 self._ValueList[2] = PcdTockens[1]
1895 if not self._CurrentStructurePcdName:
1896 TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)
1897 self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)
1898 ValueRe = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*')
1899 # check PCD information
1900 if self._ValueList[0] == '' or self._ValueList[1] == '':
1901 EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",
1902 ExtraData=self._CurrentLine + \
1903 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1904 File=self.MetaFile, Line=self._LineIndex + 1)
1905 # check format of token space GUID CName
1906 if not ValueRe.match(self._ValueList[0]):
1907 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_]*'",
1908 ExtraData=self._CurrentLine + \
1909 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1910 File=self.MetaFile, Line=self._LineIndex + 1)
1911 # check format of PCD CName
1912 if not ValueRe.match(self._ValueList[1]):
1913 EdkLogger.error('Parser', FORMAT_INVALID, "The format of the PCD CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",
1914 ExtraData=self._CurrentLine + \
1915 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1916 File=self.MetaFile, Line=self._LineIndex + 1)
1917 # check PCD datum information
1918 if len(TokenList) < 2 or TokenList[1] == '':
1919 EdkLogger.error('Parser', FORMAT_INVALID, "No PCD Datum information given",
1920 ExtraData=self._CurrentLine + \
1921 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1922 File=self.MetaFile, Line=self._LineIndex + 1)
1923
1924
1925 ValueRe = re.compile(r'^\s*L?\".*\|.*\"')
1926 PtrValue = ValueRe.findall(TokenList[1])
1927
1928 # Has VOID* type string, may contain "|" character in the string.
1929 if len(PtrValue) != 0:
1930 ptrValueList = re.sub(ValueRe, '', TokenList[1])
1931 ValueList = AnalyzePcdExpression(ptrValueList)
1932 ValueList[0] = PtrValue[0]
1933 else:
1934 ValueList = AnalyzePcdExpression(TokenList[1])
1935
1936
1937 # check if there's enough datum information given
1938 if len(ValueList) != 3:
1939 EdkLogger.error('Parser', FORMAT_INVALID, "Invalid PCD Datum information given",
1940 ExtraData=self._CurrentLine + \
1941 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1942 File=self.MetaFile, Line=self._LineIndex + 1)
1943 # check default value
1944 if ValueList[0] == '':
1945 EdkLogger.error('Parser', FORMAT_INVALID, "Missing DefaultValue in PCD Datum information",
1946 ExtraData=self._CurrentLine + \
1947 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1948 File=self.MetaFile, Line=self._LineIndex + 1)
1949 # check datum type
1950 if ValueList[1] == '':
1951 EdkLogger.error('Parser', FORMAT_INVALID, "Missing DatumType in PCD Datum information",
1952 ExtraData=self._CurrentLine + \
1953 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1954 File=self.MetaFile, Line=self._LineIndex + 1)
1955 # check token of the PCD
1956 if ValueList[2] == '':
1957 EdkLogger.error('Parser', FORMAT_INVALID, "Missing Token in PCD Datum information",
1958 ExtraData=self._CurrentLine + \
1959 " (<TokenSpaceGuidCName>.<PcdCName>|<DefaultValue>|<DatumType>|<Token>)",
1960 File=self.MetaFile, Line=self._LineIndex + 1)
1961
1962 PcdValue = ValueList[0]
1963 if PcdValue:
1964 try:
1965 ValueList[0] = ValueExpression(PcdValue, self._AllPcdDict)(True)
1966 except WrnExpression, Value:
1967 ValueList[0] = Value.result
1968
1969 if ValueList[0] == 'True':
1970 ValueList[0] = '1'
1971 if ValueList[0] == 'False':
1972 ValueList[0] = '0'
1973
1974 # check format of default value against the datum type
1975 IsValid, Cause = CheckPcdDatum(ValueList[1], ValueList[0])
1976 if not IsValid:
1977 EdkLogger.error('Parser', FORMAT_INVALID, Cause, ExtraData=self._CurrentLine,
1978 File=self.MetaFile, Line=self._LineIndex + 1)
1979
1980 if Cause == "StructurePcd":
1981 self._CurrentStructurePcdName = TAB_SPLIT.join(self._ValueList[0:2])
1982 self._ValueList[0] = self._CurrentStructurePcdName
1983 self._ValueList[1] = ValueList[1].strip()
1984
1985 if ValueList[0] in ['True', 'true', 'TRUE']:
1986 ValueList[0] = '1'
1987 elif ValueList[0] in ['False', 'false', 'FALSE']:
1988 ValueList[0] = '0'
1989
1990 # check for duplicate PCD definition
1991 if (self._Scope[0], self._ValueList[0], self._ValueList[1]) in self._AllPCDs:
1992 EdkLogger.error('Parser', FORMAT_INVALID,
1993 "The same PCD name and GUID have been already defined",
1994 ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
1995 else:
1996 self._AllPCDs.append((self._Scope[0], self._ValueList[0], self._ValueList[1]))
1997 self._AllPcdDict[TAB_SPLIT.join(self._ValueList[0:2])] = ValueList[0]
1998
1999 self._ValueList[2] = ValueList[0].strip() + '|' + ValueList[1].strip() + '|' + ValueList[2].strip()
2000
2001 _SectionParser = {
2002 MODEL_META_DATA_HEADER : MetaFileParser._DefineParser,
2003 MODEL_EFI_INCLUDE : MetaFileParser._PathParser,
2004 MODEL_EFI_LIBRARY_CLASS : MetaFileParser._PathParser,
2005 MODEL_EFI_GUID : _GuidParser,
2006 MODEL_EFI_PPI : _GuidParser,
2007 MODEL_EFI_PROTOCOL : _GuidParser,
2008 MODEL_PCD_FIXED_AT_BUILD : _PcdParser,
2009 MODEL_PCD_PATCHABLE_IN_MODULE : _PcdParser,
2010 MODEL_PCD_FEATURE_FLAG : _PcdParser,
2011 MODEL_PCD_DYNAMIC : _PcdParser,
2012 MODEL_PCD_DYNAMIC_EX : _PcdParser,
2013 MODEL_UNKNOWN : MetaFileParser._Skip,
2014 MODEL_META_DATA_USER_EXTENSION : MetaFileParser._SkipUserExtension,
2015 }
2016
2017 ##
2018 #
2019 # This acts like the main() function for the script, unless it is 'import'ed into another
2020 # script.
2021 #
2022 if __name__ == '__main__':
2023 pass
2024