2
# This file is used to define each component of DEC file
4
# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
5
# This program and the accompanying materials
6
# are licensed and made available under the terms and conditions of the BSD License
7
# which accompanies this distribution. The full text of the license may be found at
8
# http://opensource.org/licenses/bsd-license.php
10
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19
from DataType import *
20
from Identification import *
21
from Dictionary import *
22
from CommonDataClass.PackageClass import *
23
from CommonDataClass.CommonClass import PcdClass
24
from BuildToolError import *
25
from Table.TableDec import TableDec
33
Section = {TAB_UNKNOWN.upper() : MODEL_UNKNOWN,
34
TAB_DEC_DEFINES.upper() : MODEL_META_DATA_HEADER,
35
TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE,
36
TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS,
37
TAB_COMPONENTS.upper() : MODEL_META_DATA_COMPONENT,
38
TAB_GUIDS.upper() : MODEL_EFI_GUID,
39
TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL,
40
TAB_PPIS.upper() : MODEL_EFI_PPI,
41
TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : MODEL_PCD_FIXED_AT_BUILD,
42
TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : MODEL_PCD_PATCHABLE_IN_MODULE,
43
TAB_PCDS_FEATURE_FLAG_NULL.upper() : MODEL_PCD_FEATURE_FLAG,
44
TAB_PCDS_DYNAMIC_EX_NULL.upper() : MODEL_PCD_DYNAMIC_EX,
45
TAB_PCDS_DYNAMIC_NULL.upper() : MODEL_PCD_DYNAMIC,
46
TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION
52
# This class defined basic Dec object which is used by inheriting
54
# @param object: Inherited from object class
56
class DecObject(object):
62
# This class defined the structure used in Dec object
64
# @param DecObject: Inherited from DecObject class
65
# @param Filename: Input value for Filename of Dec file, default is None
66
# @param IsMergeAllArches: Input value for IsMergeAllArches
67
# True is to merge all arches
68
# Fales is not to merge all arches
70
# @param IsToPackage: Input value for IsToPackage
71
# True is to transfer to PackageObject automatically
72
# False is not to transfer to PackageObject automatically
74
# @param WorkspaceDir: Input value for current workspace directory, default is None
76
# @var Identification: To store value for Identification, it is a structure as Identification
77
# @var Defines: To store value for Defines, it is a structure as DecDefines
78
# @var UserExtensions: To store value for UserExtensions
79
# @var Package: To store value for Package, it is a structure as PackageClass
80
# @var WorkspaceDir: To store value for WorkspaceDir
81
# @var Contents: To store value for Contents, it is a structure as DecContents
82
# @var KeyList: To store value for KeyList, a list for all Keys used in Dec
85
def __init__(self, Filename=None, IsToDatabase=False, IsToPackage=False, WorkspaceDir=None, Database=None, SupArchList=DataType.ARCH_LIST):
86
self.Identification = Identification()
87
self.Package = PackageClass()
88
self.UserExtensions = ''
89
self.WorkspaceDir = WorkspaceDir
90
self.SupArchList = SupArchList
91
self.IsToDatabase = IsToDatabase
93
self.Cur = Database.Cur
94
self.TblFile = Database.TblFile
95
self.TblDec = Database.TblDec
99
TAB_INCLUDES, TAB_GUIDS, TAB_PROTOCOLS, TAB_PPIS, TAB_LIBRARY_CLASSES, \
100
TAB_PCDS_FIXED_AT_BUILD_NULL, TAB_PCDS_PATCHABLE_IN_MODULE_NULL, TAB_PCDS_FEATURE_FLAG_NULL, \
101
TAB_PCDS_DYNAMIC_NULL, TAB_PCDS_DYNAMIC_EX_NULL, TAB_DEC_DEFINES
104
# Upper all KEYs to ignore case sensitive when parsing
106
self.KeyList = map(lambda c: c.upper(), self.KeyList)
112
for Key in self.KeyList:
113
self.RecordSet[Section[Key]] = []
116
# Load Dec file if filename is not None
119
self.LoadDecFile(Filename)
122
# Transfer to Package Object if IsToPackage is True
129
# Load the file if it exists
131
# @param Filename: Input value for filename of Dec file
133
def LoadDecFile(self, Filename):
135
# Insert a record for file
137
Filename = NormPath(Filename)
138
self.Identification.FileFullPath = Filename
139
(self.Identification.FileRelativePath, self.Identification.FileName) = os.path.split(Filename)
140
self.FileID = self.TblFile.InsertFile(Filename, MODEL_FILE_DEC)
145
#self.TblDec.Table = "Dec%s" % self.FileID
146
#self.TblDec.Create()
151
IfDefList, SectionItemList, CurrentSection, ArchList, ThirdList, IncludeFiles = \
152
[], [], TAB_UNKNOWN, [], [], []
158
IsFindBlockComment = False
160
for Line in open(Filename, 'r'):
163
# Remove comment block
165
if Line.find(TAB_COMMENT_EDK_START) > -1:
166
ReservedLine = GetSplitList(Line, TAB_COMMENT_EDK_START, 1)[0]
167
IsFindBlockComment = True
168
if Line.find(TAB_COMMENT_EDK_END) > -1:
169
Line = ReservedLine + GetSplitList(Line, TAB_COMMENT_EDK_END, 1)[1]
171
IsFindBlockComment = False
172
if IsFindBlockComment:
176
# Remove comments at tail and remove spaces again
178
Line = CleanString(Line)
183
# Find a new section tab
184
# First insert previous section items
185
# And then parse the content of the new section
187
if Line.startswith(TAB_SECTION_START) and Line.endswith(TAB_SECTION_END):
189
# Insert items data of previous section
191
Model = Section[CurrentSection.upper()]
192
InsertSectionItemsIntoDatabase(self.TblDec, self.FileID, Filename, Model, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList, self.RecordSet)
195
# Parse the new section
202
LineList = GetSplitValueList(Line[len(TAB_SECTION_START):len(Line) - len(TAB_SECTION_END)], TAB_COMMA_SPLIT)
203
for Item in LineList:
204
ItemList = GetSplitValueList(Item, TAB_SPLIT)
205
if CurrentSection == '':
206
CurrentSection = ItemList[0]
208
if CurrentSection != ItemList[0]:
209
EdkLogger.error("Parser", PARSER_ERROR, "Different section names '%s' and '%s' are found in one section definition, this is not allowed." % (CurrentSection, ItemList[0]), File=Filename, Line=LineNo, RaiseError=EdkLogger.IsRaiseError)
210
if CurrentSection.upper() not in self.KeyList:
211
RaiseParserError(Line, CurrentSection, Filename, '', LineNo)
214
if len(ItemList) > 5:
215
RaiseParserError(Line, CurrentSection, Filename, '', LineNo)
217
if ItemList[1] != '' and ItemList[1].upper() not in ARCH_LIST_FULL:
218
EdkLogger.error("Parser", PARSER_ERROR, "Invalid Arch definition '%s' found" % ItemList[1], File=Filename, Line=LineNo, RaiseError=EdkLogger.IsRaiseError)
219
ArchList.append(ItemList[1].upper())
220
ThirdList.append(ItemList[2])
225
# Not in any defined section
227
if CurrentSection == TAB_UNKNOWN:
228
ErrorMsg = "%s is not in any defined section" % Line
229
EdkLogger.error("Parser", PARSER_ERROR, ErrorMsg, File=Filename, Line=LineNo, RaiseError=EdkLogger.IsRaiseError)
234
SectionItemList.append([Line, LineNo])
239
# Insert items data of last section
241
Model = Section[CurrentSection.upper()]
242
InsertSectionItemsIntoDatabase(self.TblDec, self.FileID, Filename, Model, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList, self.RecordSet)
245
# Replace all DEFINE macros with its actual values
247
ParseDefineMacro2(self.TblDec, self.RecordSet, GlobalData.gGlobalDefines)
249
## Transfer to Package Object
251
# Transfer all contents of a Dec file to a standard Package Object
253
def DecToPackage(self):
255
# Init global information for the file
257
ContainerFile = self.Identification.FileFullPath
260
# Generate Package Header
262
self.GenPackageHeader(ContainerFile)
267
self.GenIncludes(ContainerFile)
272
self.GenGuidProtocolPpis(DataType.TAB_GUIDS, ContainerFile)
277
self.GenGuidProtocolPpis(DataType.TAB_PROTOCOLS, ContainerFile)
282
self.GenGuidProtocolPpis(DataType.TAB_PPIS, ContainerFile)
285
# Generate LibraryClasses
287
self.GenLibraryClasses(ContainerFile)
292
self.GenPcds(ContainerFile)
294
## Get Package Header
296
# Gen Package Header of Dec as <Key> = <Value>
298
# @param ContainerFile: The Dec file full path
300
def GenPackageHeader(self, ContainerFile):
301
EdkLogger.debug(2, "Generate PackageHeader ...")
303
# Update all defines item in database
305
RecordSet = self.RecordSet[MODEL_META_DATA_HEADER]
306
for Record in RecordSet:
307
ValueList = GetSplitValueList(Record[0], TAB_EQUAL_SPLIT)
308
if len(ValueList) != 2:
309
RaiseParserError(Record[0], 'Defines', ContainerFile, '<Key> = <Value>', Record[2])
310
ID, Value1, Value2, Arch, LineNo = Record[3], ValueList[0], ValueList[1], Record[1], Record[2]
311
SqlCommand = """update %s set Value1 = '%s', Value2 = '%s'
312
where ID = %s""" % (self.TblDec.Table, ConvertToSqlString2(Value1), ConvertToSqlString2(Value2), ID)
313
self.TblDec.Exec(SqlCommand)
316
# Get detailed information
318
for Arch in self.SupArchList:
319
PackageHeader = PackageHeaderClass()
321
PackageHeader.Name = QueryDefinesItem(self.TblDec, TAB_DEC_DEFINES_PACKAGE_NAME, Arch, self.FileID)[0]
322
PackageHeader.Guid = QueryDefinesItem(self.TblDec, TAB_DEC_DEFINES_PACKAGE_GUID, Arch, self.FileID)[0]
323
PackageHeader.Version = QueryDefinesItem(self.TblDec, TAB_DEC_DEFINES_PACKAGE_VERSION, Arch, self.FileID)[0]
324
PackageHeader.FileName = self.Identification.FileName
325
PackageHeader.FullPath = self.Identification.FileFullPath
326
PackageHeader.DecSpecification = QueryDefinesItem(self.TblDec, TAB_DEC_DEFINES_DEC_SPECIFICATION, Arch, self.FileID)[0]
328
self.Package.Header[Arch] = PackageHeader
332
# Gen Includes of Dec
335
# @param ContainerFile: The Dec file full path
337
def GenIncludes(self, ContainerFile):
338
EdkLogger.debug(2, "Generate %s ..." % TAB_INCLUDES)
343
RecordSet = self.RecordSet[MODEL_EFI_INCLUDE]
346
# Go through each arch
348
for Arch in self.SupArchList:
349
for Record in RecordSet:
350
if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:
351
MergeArches(Includes, Record[0], Arch)
353
for Key in Includes.keys():
354
Include = IncludeClass()
355
Include.FilePath = NormPath(Key)
356
Include.SupArchList = Includes[Key]
357
self.Package.Includes.append(Include)
362
# <CName>=<GuidValue>
364
# @param ContainerFile: The Dec file full path
366
def GenGuidProtocolPpis(self, Type, ContainerFile):
367
EdkLogger.debug(2, "Generate %s ..." % Type)
372
RecordSet = self.RecordSet[Section[Type.upper()]]
375
# Go through each arch
377
for Arch in self.SupArchList:
378
for Record in RecordSet:
379
if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:
380
(Name, Value) = GetGuidsProtocolsPpisOfDec(Record[0], Type, ContainerFile, Record[2])
381
MergeArches(Lists, (Name, Value), Arch)
382
if self.IsToDatabase:
383
SqlCommand = """update %s set Value1 = '%s', Value2 = '%s'
384
where ID = %s""" % (self.TblDec.Table, ConvertToSqlString2(Name), ConvertToSqlString2(Value), Record[3])
385
self.TblDec.Exec(SqlCommand)
388
if Type == TAB_GUIDS:
389
ListMember = self.Package.GuidDeclarations
390
elif Type == TAB_PROTOCOLS:
391
ListMember = self.Package.ProtocolDeclarations
392
elif Type == TAB_PPIS:
393
ListMember = self.Package.PpiDeclarations
395
for Key in Lists.keys():
396
ListClass = GuidProtocolPpiCommonClass()
397
ListClass.CName = Key[0]
398
ListClass.Guid = Key[1]
399
ListClass.SupArchList = Lists[Key]
400
ListMember.append(ListClass)
405
# Gen LibraryClasses of Dec
406
# <CName>=<GuidValue>
408
# @param ContainerFile: The Dec file full path
410
def GenLibraryClasses(self, ContainerFile):
411
EdkLogger.debug(2, "Generate %s ..." % TAB_LIBRARY_CLASSES)
416
RecordSet = self.RecordSet[MODEL_EFI_LIBRARY_CLASS]
419
# Go through each arch
421
for Arch in self.SupArchList:
422
for Record in RecordSet:
423
if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:
424
List = GetSplitValueList(Record[0], DataType.TAB_VALUE_SPLIT)
426
RaiseParserError(Record[0], 'LibraryClasses', ContainerFile, '<LibraryClassName>|<LibraryClassInstanceFilename>', Record[2])
428
CheckFileExist(self.Identification.FileRelativePath, List[1], ContainerFile, 'LibraryClasses', Record[0])
429
MergeArches(LibraryClasses, (List[0], List[1]), Arch)
430
if self.IsToDatabase:
431
SqlCommand = """update %s set Value1 = '%s', Value2 = '%s', Value3 = '%s'
432
where ID = %s""" % (self.TblDec.Table, ConvertToSqlString2(List[0]), ConvertToSqlString2(List[1]), SUP_MODULE_LIST_STRING, Record[3])
433
self.TblDec.Exec(SqlCommand)
436
for Key in LibraryClasses.keys():
437
LibraryClass = LibraryClassClass()
438
LibraryClass.LibraryClass = Key[0]
439
LibraryClass.RecommendedInstance = NormPath(Key[1])
440
LibraryClass.SupModuleList = SUP_MODULE_LIST
441
LibraryClass.SupArchList = LibraryClasses[Key]
442
self.Package.LibraryClassDeclarations.append(LibraryClass)
447
# <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
449
# @param ContainerFile: The Dec file full path
451
def GenPcds(self, ContainerFile):
452
EdkLogger.debug(2, "Generate %s ..." % TAB_PCDS)
458
RecordSet1 = self.RecordSet[MODEL_PCD_FIXED_AT_BUILD]
459
RecordSet2 = self.RecordSet[MODEL_PCD_PATCHABLE_IN_MODULE]
460
RecordSet3 = self.RecordSet[MODEL_PCD_FEATURE_FLAG]
461
RecordSet4 = self.RecordSet[MODEL_PCD_DYNAMIC_EX]
462
RecordSet5 = self.RecordSet[MODEL_PCD_DYNAMIC]
465
# Go through each arch
467
for Arch in self.SupArchList:
468
for Record in RecordSet1:
469
if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:
470
(TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_FIXED_AT_BUILD, ContainerFile, Record[2])
471
MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch)
472
PcdToken[Record[3]] = (TokenGuidCName, TokenName)
473
for Record in RecordSet2:
474
if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:
475
(TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_PATCHABLE_IN_MODULE, ContainerFile, Record[2])
476
MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch)
477
PcdToken[Record[3]] = (TokenGuidCName, TokenName)
478
for Record in RecordSet3:
479
if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:
480
(TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_FEATURE_FLAG, ContainerFile, Record[2])
481
MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch)
482
PcdToken[Record[3]] = (TokenGuidCName, TokenName)
483
for Record in RecordSet4:
484
if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:
485
(TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_DYNAMIC_EX, ContainerFile, Record[2])
486
MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch)
487
PcdToken[Record[3]] = (TokenGuidCName, TokenName)
488
for Record in RecordSet5:
489
if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON:
490
(TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_DYNAMIC, ContainerFile, Record[2])
491
MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch)
492
PcdToken[Record[3]] = (TokenGuidCName, TokenName)
496
if self.IsToDatabase:
497
for Key in PcdToken.keys():
498
SqlCommand = """update %s set Value2 = '%s' where ID = %s""" % (self.TblDec.Table, ".".join((PcdToken[Key][0], PcdToken[Key][1])), Key)
499
self.TblDec.Exec(SqlCommand)
501
for Key in Pcds.keys():
505
Pcd.TokenSpaceGuidCName = Key[0]
506
Pcd.DatumType = Key[3]
507
Pcd.DefaultValue = Key[2]
508
Pcd.ItemType = Key[5]
509
Pcd.SupArchList = Pcds[Key]
510
self.Package.PcdDeclarations.append(Pcd)
512
## Show detailed information of Package
514
# Print all members and their values of Package class
516
def ShowPackage(self):
518
for Arch in M.Header.keys():
519
print '\nArch =', Arch
520
print 'Filename =', M.Header[Arch].FileName
521
print 'FullPath =', M.Header[Arch].FullPath
522
print 'BaseName =', M.Header[Arch].Name
523
print 'Guid =', M.Header[Arch].Guid
524
print 'Version =', M.Header[Arch].Version
525
print 'DecSpecification =', M.Header[Arch].DecSpecification
526
print '\nIncludes =', M.Includes
527
for Item in M.Includes:
528
print Item.FilePath, Item.SupArchList
529
print '\nGuids =', M.GuidDeclarations
530
for Item in M.GuidDeclarations:
531
print Item.CName, Item.Guid, Item.SupArchList
532
print '\nProtocols =', M.ProtocolDeclarations
533
for Item in M.ProtocolDeclarations:
534
print Item.CName, Item.Guid, Item.SupArchList
535
print '\nPpis =', M.PpiDeclarations
536
for Item in M.PpiDeclarations:
537
print Item.CName, Item.Guid, Item.SupArchList
538
print '\nLibraryClasses =', M.LibraryClassDeclarations
539
for Item in M.LibraryClassDeclarations:
540
print Item.LibraryClass, Item.RecommendedInstance, Item.SupModuleList, Item.SupArchList
541
print '\nPcds =', M.PcdDeclarations
542
for Item in M.PcdDeclarations:
543
print 'CName=', Item.CName, 'TokenSpaceGuidCName=', Item.TokenSpaceGuidCName, 'DefaultValue=', Item.DefaultValue, 'ItemType=', Item.ItemType, 'Token=', Item.Token, 'DatumType=', Item.DatumType, Item.SupArchList
547
# This acts like the main() function for the script, unless it is 'import'ed into another
550
if __name__ == '__main__':
551
EdkLogger.Initialize()
552
EdkLogger.SetLevel(EdkLogger.DEBUG_0)
554
W = os.getenv('WORKSPACE')
555
F = os.path.join(W, 'Nt32Pkg/Nt32Pkg.dec')
557
Db = Database.Database('Dec.db')
560
P = Dec(os.path.normpath(F), True, True, W, Db)