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