2 # This file is used to define each component of DEC file
4 # Copyright (c) 2007 - 2014, 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.
17 import Common
.LongFilePathOs
as os
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
29 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
34 Section
= {TAB_UNKNOWN
.upper() : MODEL_UNKNOWN
,
35 TAB_DEC_DEFINES
.upper() : MODEL_META_DATA_HEADER
,
36 TAB_INCLUDES
.upper() : MODEL_EFI_INCLUDE
,
37 TAB_LIBRARY_CLASSES
.upper() : MODEL_EFI_LIBRARY_CLASS
,
38 TAB_COMPONENTS
.upper() : MODEL_META_DATA_COMPONENT
,
39 TAB_GUIDS
.upper() : MODEL_EFI_GUID
,
40 TAB_PROTOCOLS
.upper() : MODEL_EFI_PROTOCOL
,
41 TAB_PPIS
.upper() : MODEL_EFI_PPI
,
42 TAB_PCDS_FIXED_AT_BUILD_NULL
.upper() : MODEL_PCD_FIXED_AT_BUILD
,
43 TAB_PCDS_PATCHABLE_IN_MODULE_NULL
.upper() : MODEL_PCD_PATCHABLE_IN_MODULE
,
44 TAB_PCDS_FEATURE_FLAG_NULL
.upper() : MODEL_PCD_FEATURE_FLAG
,
45 TAB_PCDS_DYNAMIC_EX_NULL
.upper() : MODEL_PCD_DYNAMIC_EX
,
46 TAB_PCDS_DYNAMIC_NULL
.upper() : MODEL_PCD_DYNAMIC
,
47 TAB_USER_EXTENSIONS
.upper() : MODEL_META_DATA_USER_EXTENSION
53 # This class defined basic Dec object which is used by inheriting
55 # @param object: Inherited from object class
57 class DecObject(object):
63 # This class defined the structure used in Dec object
65 # @param DecObject: Inherited from DecObject class
66 # @param Filename: Input value for Filename of Dec file, default is None
67 # @param IsMergeAllArches: Input value for IsMergeAllArches
68 # True is to merge all arches
69 # Fales is not to merge all arches
71 # @param IsToPackage: Input value for IsToPackage
72 # True is to transfer to PackageObject automatically
73 # False is not to transfer to PackageObject automatically
75 # @param WorkspaceDir: Input value for current workspace directory, default is None
77 # @var Identification: To store value for Identification, it is a structure as Identification
78 # @var Defines: To store value for Defines, it is a structure as DecDefines
79 # @var UserExtensions: To store value for UserExtensions
80 # @var Package: To store value for Package, it is a structure as PackageClass
81 # @var WorkspaceDir: To store value for WorkspaceDir
82 # @var Contents: To store value for Contents, it is a structure as DecContents
83 # @var KeyList: To store value for KeyList, a list for all Keys used in Dec
86 def __init__(self
, Filename
=None, IsToDatabase
=False, IsToPackage
=False, WorkspaceDir
=None, Database
=None, SupArchList
=DataType
.ARCH_LIST
):
87 self
.Identification
= Identification()
88 self
.Package
= PackageClass()
89 self
.UserExtensions
= ''
90 self
.WorkspaceDir
= WorkspaceDir
91 self
.SupArchList
= SupArchList
92 self
.IsToDatabase
= IsToDatabase
94 self
.Cur
= Database
.Cur
95 self
.TblFile
= Database
.TblFile
96 self
.TblDec
= Database
.TblDec
100 TAB_INCLUDES
, TAB_GUIDS
, TAB_PROTOCOLS
, TAB_PPIS
, TAB_LIBRARY_CLASSES
, \
101 TAB_PCDS_FIXED_AT_BUILD_NULL
, TAB_PCDS_PATCHABLE_IN_MODULE_NULL
, TAB_PCDS_FEATURE_FLAG_NULL
, \
102 TAB_PCDS_DYNAMIC_NULL
, TAB_PCDS_DYNAMIC_EX_NULL
, TAB_DEC_DEFINES
105 # Upper all KEYs to ignore case sensitive when parsing
107 self
.KeyList
= map(lambda c
: c
.upper(), self
.KeyList
)
113 for Key
in self
.KeyList
:
114 self
.RecordSet
[Section
[Key
]] = []
117 # Load Dec file if filename is not None
120 self
.LoadDecFile(Filename
)
123 # Transfer to Package Object if IsToPackage is True
130 # Load the file if it exists
132 # @param Filename: Input value for filename of Dec file
134 def LoadDecFile(self
, Filename
):
136 # Insert a record for file
138 Filename
= NormPath(Filename
)
139 self
.Identification
.FileFullPath
= Filename
140 (self
.Identification
.FileRelativePath
, self
.Identification
.FileName
) = os
.path
.split(Filename
)
141 self
.FileID
= self
.TblFile
.InsertFile(Filename
, MODEL_FILE_DEC
)
146 #self.TblDec.Table = "Dec%s" % self.FileID
147 #self.TblDec.Create()
152 IfDefList
, SectionItemList
, CurrentSection
, ArchList
, ThirdList
, IncludeFiles
= \
153 [], [], TAB_UNKNOWN
, [], [], []
159 IsFindBlockComment
= False
161 for Line
in open(Filename
, 'r'):
164 # Remove comment block
166 if Line
.find(TAB_COMMENT_EDK_START
) > -1:
167 ReservedLine
= GetSplitList(Line
, TAB_COMMENT_EDK_START
, 1)[0]
168 IsFindBlockComment
= True
169 if Line
.find(TAB_COMMENT_EDK_END
) > -1:
170 Line
= ReservedLine
+ GetSplitList(Line
, TAB_COMMENT_EDK_END
, 1)[1]
172 IsFindBlockComment
= False
173 if IsFindBlockComment
:
177 # Remove comments at tail and remove spaces again
179 Line
= CleanString(Line
)
184 # Find a new section tab
185 # First insert previous section items
186 # And then parse the content of the new section
188 if Line
.startswith(TAB_SECTION_START
) and Line
.endswith(TAB_SECTION_END
):
190 # Insert items data of previous section
192 Model
= Section
[CurrentSection
.upper()]
193 InsertSectionItemsIntoDatabase(self
.TblDec
, self
.FileID
, Filename
, Model
, CurrentSection
, SectionItemList
, ArchList
, ThirdList
, IfDefList
, self
.RecordSet
)
196 # Parse the new section
203 LineList
= GetSplitValueList(Line
[len(TAB_SECTION_START
):len(Line
) - len(TAB_SECTION_END
)], TAB_COMMA_SPLIT
)
204 for Item
in LineList
:
205 ItemList
= GetSplitValueList(Item
, TAB_SPLIT
)
206 if CurrentSection
== '':
207 CurrentSection
= ItemList
[0]
209 if CurrentSection
!= ItemList
[0]:
210 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
)
211 if CurrentSection
.upper() not in self
.KeyList
:
212 RaiseParserError(Line
, CurrentSection
, Filename
, '', LineNo
)
215 if len(ItemList
) > 5:
216 RaiseParserError(Line
, CurrentSection
, Filename
, '', LineNo
)
218 if ItemList
[1] != '' and ItemList
[1].upper() not in ARCH_LIST_FULL
:
219 EdkLogger
.error("Parser", PARSER_ERROR
, "Invalid Arch definition '%s' found" % ItemList
[1], File
=Filename
, Line
=LineNo
, RaiseError
=EdkLogger
.IsRaiseError
)
220 ArchList
.append(ItemList
[1].upper())
221 ThirdList
.append(ItemList
[2])
226 # Not in any defined section
228 if CurrentSection
== TAB_UNKNOWN
:
229 ErrorMsg
= "%s is not in any defined section" % Line
230 EdkLogger
.error("Parser", PARSER_ERROR
, ErrorMsg
, File
=Filename
, Line
=LineNo
, RaiseError
=EdkLogger
.IsRaiseError
)
235 SectionItemList
.append([Line
, LineNo
])
240 # Insert items data of last section
242 Model
= Section
[CurrentSection
.upper()]
243 InsertSectionItemsIntoDatabase(self
.TblDec
, self
.FileID
, Filename
, Model
, CurrentSection
, SectionItemList
, ArchList
, ThirdList
, IfDefList
, self
.RecordSet
)
246 # Replace all DEFINE macros with its actual values
248 ParseDefineMacro2(self
.TblDec
, self
.RecordSet
, GlobalData
.gGlobalDefines
)
250 ## Transfer to Package Object
252 # Transfer all contents of a Dec file to a standard Package Object
254 def DecToPackage(self
):
256 # Init global information for the file
258 ContainerFile
= self
.Identification
.FileFullPath
261 # Generate Package Header
263 self
.GenPackageHeader(ContainerFile
)
268 self
.GenIncludes(ContainerFile
)
273 self
.GenGuidProtocolPpis(DataType
.TAB_GUIDS
, ContainerFile
)
278 self
.GenGuidProtocolPpis(DataType
.TAB_PROTOCOLS
, ContainerFile
)
283 self
.GenGuidProtocolPpis(DataType
.TAB_PPIS
, ContainerFile
)
286 # Generate LibraryClasses
288 self
.GenLibraryClasses(ContainerFile
)
293 self
.GenPcds(ContainerFile
)
295 ## Get Package Header
297 # Gen Package Header of Dec as <Key> = <Value>
299 # @param ContainerFile: The Dec file full path
301 def GenPackageHeader(self
, ContainerFile
):
302 EdkLogger
.debug(2, "Generate PackageHeader ...")
304 # Update all defines item in database
306 RecordSet
= self
.RecordSet
[MODEL_META_DATA_HEADER
]
307 for Record
in RecordSet
:
308 ValueList
= GetSplitValueList(Record
[0], TAB_EQUAL_SPLIT
)
309 if len(ValueList
) != 2:
310 RaiseParserError(Record
[0], 'Defines', ContainerFile
, '<Key> = <Value>', Record
[2])
311 ID
, Value1
, Value2
, Arch
, LineNo
= Record
[3], ValueList
[0], ValueList
[1], Record
[1], Record
[2]
312 SqlCommand
= """update %s set Value1 = '%s', Value2 = '%s'
313 where ID = %s""" % (self
.TblDec
.Table
, ConvertToSqlString2(Value1
), ConvertToSqlString2(Value2
), ID
)
314 self
.TblDec
.Exec(SqlCommand
)
317 # Get detailed information
319 for Arch
in self
.SupArchList
:
320 PackageHeader
= PackageHeaderClass()
322 PackageHeader
.Name
= QueryDefinesItem(self
.TblDec
, TAB_DEC_DEFINES_PACKAGE_NAME
, Arch
, self
.FileID
)[0]
323 PackageHeader
.Guid
= QueryDefinesItem(self
.TblDec
, TAB_DEC_DEFINES_PACKAGE_GUID
, Arch
, self
.FileID
)[0]
324 PackageHeader
.Version
= QueryDefinesItem(self
.TblDec
, TAB_DEC_DEFINES_PACKAGE_VERSION
, Arch
, self
.FileID
)[0]
325 PackageHeader
.FileName
= self
.Identification
.FileName
326 PackageHeader
.FullPath
= self
.Identification
.FileFullPath
327 PackageHeader
.DecSpecification
= QueryDefinesItem(self
.TblDec
, TAB_DEC_DEFINES_DEC_SPECIFICATION
, Arch
, self
.FileID
)[0]
329 self
.Package
.Header
[Arch
] = PackageHeader
333 # Gen Includes of Dec
336 # @param ContainerFile: The Dec file full path
338 def GenIncludes(self
, ContainerFile
):
339 EdkLogger
.debug(2, "Generate %s ..." % TAB_INCLUDES
)
344 RecordSet
= self
.RecordSet
[MODEL_EFI_INCLUDE
]
347 # Go through each arch
349 for Arch
in self
.SupArchList
:
350 for Record
in RecordSet
:
351 if Record
[1] == Arch
or Record
[1] == TAB_ARCH_COMMON
:
352 MergeArches(Includes
, Record
[0], Arch
)
354 for Key
in Includes
.keys():
355 Include
= IncludeClass()
356 Include
.FilePath
= NormPath(Key
)
357 Include
.SupArchList
= Includes
[Key
]
358 self
.Package
.Includes
.append(Include
)
363 # <CName>=<GuidValue>
365 # @param ContainerFile: The Dec file full path
367 def GenGuidProtocolPpis(self
, Type
, ContainerFile
):
368 EdkLogger
.debug(2, "Generate %s ..." % Type
)
373 RecordSet
= self
.RecordSet
[Section
[Type
.upper()]]
376 # Go through each arch
378 for Arch
in self
.SupArchList
:
379 for Record
in RecordSet
:
380 if Record
[1] == Arch
or Record
[1] == TAB_ARCH_COMMON
:
381 (Name
, Value
) = GetGuidsProtocolsPpisOfDec(Record
[0], Type
, ContainerFile
, Record
[2])
382 MergeArches(Lists
, (Name
, Value
), Arch
)
383 if self
.IsToDatabase
:
384 SqlCommand
= """update %s set Value1 = '%s', Value2 = '%s'
385 where ID = %s""" % (self
.TblDec
.Table
, ConvertToSqlString2(Name
), ConvertToSqlString2(Value
), Record
[3])
386 self
.TblDec
.Exec(SqlCommand
)
389 if Type
== TAB_GUIDS
:
390 ListMember
= self
.Package
.GuidDeclarations
391 elif Type
== TAB_PROTOCOLS
:
392 ListMember
= self
.Package
.ProtocolDeclarations
393 elif Type
== TAB_PPIS
:
394 ListMember
= self
.Package
.PpiDeclarations
396 for Key
in Lists
.keys():
397 ListClass
= GuidProtocolPpiCommonClass()
398 ListClass
.CName
= Key
[0]
399 ListClass
.Guid
= Key
[1]
400 ListClass
.SupArchList
= Lists
[Key
]
401 ListMember
.append(ListClass
)
406 # Gen LibraryClasses of Dec
407 # <CName>=<GuidValue>
409 # @param ContainerFile: The Dec file full path
411 def GenLibraryClasses(self
, ContainerFile
):
412 EdkLogger
.debug(2, "Generate %s ..." % TAB_LIBRARY_CLASSES
)
417 RecordSet
= self
.RecordSet
[MODEL_EFI_LIBRARY_CLASS
]
420 # Go through each arch
422 for Arch
in self
.SupArchList
:
423 for Record
in RecordSet
:
424 if Record
[1] == Arch
or Record
[1] == TAB_ARCH_COMMON
:
425 List
= GetSplitValueList(Record
[0], DataType
.TAB_VALUE_SPLIT
)
427 RaiseParserError(Record
[0], 'LibraryClasses', ContainerFile
, '<LibraryClassName>|<LibraryClassInstanceFilename>', Record
[2])
429 CheckFileExist(self
.Identification
.FileRelativePath
, List
[1], ContainerFile
, 'LibraryClasses', Record
[0])
430 MergeArches(LibraryClasses
, (List
[0], List
[1]), Arch
)
431 if self
.IsToDatabase
:
432 SqlCommand
= """update %s set Value1 = '%s', Value2 = '%s', Value3 = '%s'
433 where ID = %s""" % (self
.TblDec
.Table
, ConvertToSqlString2(List
[0]), ConvertToSqlString2(List
[1]), SUP_MODULE_LIST_STRING
, Record
[3])
434 self
.TblDec
.Exec(SqlCommand
)
437 for Key
in LibraryClasses
.keys():
438 LibraryClass
= LibraryClassClass()
439 LibraryClass
.LibraryClass
= Key
[0]
440 LibraryClass
.RecommendedInstance
= NormPath(Key
[1])
441 LibraryClass
.SupModuleList
= SUP_MODULE_LIST
442 LibraryClass
.SupArchList
= LibraryClasses
[Key
]
443 self
.Package
.LibraryClassDeclarations
.append(LibraryClass
)
448 # <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
450 # @param ContainerFile: The Dec file full path
452 def GenPcds(self
, ContainerFile
):
453 EdkLogger
.debug(2, "Generate %s ..." % TAB_PCDS
)
459 RecordSet1
= self
.RecordSet
[MODEL_PCD_FIXED_AT_BUILD
]
460 RecordSet2
= self
.RecordSet
[MODEL_PCD_PATCHABLE_IN_MODULE
]
461 RecordSet3
= self
.RecordSet
[MODEL_PCD_FEATURE_FLAG
]
462 RecordSet4
= self
.RecordSet
[MODEL_PCD_DYNAMIC_EX
]
463 RecordSet5
= self
.RecordSet
[MODEL_PCD_DYNAMIC
]
466 # Go through each arch
468 for Arch
in self
.SupArchList
:
469 for Record
in RecordSet1
:
470 if Record
[1] == Arch
or Record
[1] == TAB_ARCH_COMMON
:
471 (TokenGuidCName
, TokenName
, Value
, DatumType
, Token
, Type
) = GetPcdOfDec(Record
[0], TAB_PCDS_FIXED_AT_BUILD
, ContainerFile
, Record
[2])
472 MergeArches(Pcds
, (TokenGuidCName
, TokenName
, Value
, DatumType
, Token
, Type
), Arch
)
473 PcdToken
[Record
[3]] = (TokenGuidCName
, TokenName
)
474 for Record
in RecordSet2
:
475 if Record
[1] == Arch
or Record
[1] == TAB_ARCH_COMMON
:
476 (TokenGuidCName
, TokenName
, Value
, DatumType
, Token
, Type
) = GetPcdOfDec(Record
[0], TAB_PCDS_PATCHABLE_IN_MODULE
, ContainerFile
, Record
[2])
477 MergeArches(Pcds
, (TokenGuidCName
, TokenName
, Value
, DatumType
, Token
, Type
), Arch
)
478 PcdToken
[Record
[3]] = (TokenGuidCName
, TokenName
)
479 for Record
in RecordSet3
:
480 if Record
[1] == Arch
or Record
[1] == TAB_ARCH_COMMON
:
481 (TokenGuidCName
, TokenName
, Value
, DatumType
, Token
, Type
) = GetPcdOfDec(Record
[0], TAB_PCDS_FEATURE_FLAG
, ContainerFile
, Record
[2])
482 MergeArches(Pcds
, (TokenGuidCName
, TokenName
, Value
, DatumType
, Token
, Type
), Arch
)
483 PcdToken
[Record
[3]] = (TokenGuidCName
, TokenName
)
484 for Record
in RecordSet4
:
485 if Record
[1] == Arch
or Record
[1] == TAB_ARCH_COMMON
:
486 (TokenGuidCName
, TokenName
, Value
, DatumType
, Token
, Type
) = GetPcdOfDec(Record
[0], TAB_PCDS_DYNAMIC_EX
, ContainerFile
, Record
[2])
487 MergeArches(Pcds
, (TokenGuidCName
, TokenName
, Value
, DatumType
, Token
, Type
), Arch
)
488 PcdToken
[Record
[3]] = (TokenGuidCName
, TokenName
)
489 for Record
in RecordSet5
:
490 if Record
[1] == Arch
or Record
[1] == TAB_ARCH_COMMON
:
491 (TokenGuidCName
, TokenName
, Value
, DatumType
, Token
, Type
) = GetPcdOfDec(Record
[0], TAB_PCDS_DYNAMIC
, ContainerFile
, Record
[2])
492 MergeArches(Pcds
, (TokenGuidCName
, TokenName
, Value
, DatumType
, Token
, Type
), Arch
)
493 PcdToken
[Record
[3]] = (TokenGuidCName
, TokenName
)
497 if self
.IsToDatabase
:
498 for Key
in PcdToken
.keys():
499 SqlCommand
= """update %s set Value2 = '%s' where ID = %s""" % (self
.TblDec
.Table
, ".".join((PcdToken
[Key
][0], PcdToken
[Key
][1])), Key
)
500 self
.TblDec
.Exec(SqlCommand
)
502 for Key
in Pcds
.keys():
506 Pcd
.TokenSpaceGuidCName
= Key
[0]
507 Pcd
.DatumType
= Key
[3]
508 Pcd
.DefaultValue
= Key
[2]
509 Pcd
.ItemType
= Key
[5]
510 Pcd
.SupArchList
= Pcds
[Key
]
511 self
.Package
.PcdDeclarations
.append(Pcd
)
513 ## Show detailed information of Package
515 # Print all members and their values of Package class
517 def ShowPackage(self
):
519 for Arch
in M
.Header
.keys():
520 print '\nArch =', Arch
521 print 'Filename =', M
.Header
[Arch
].FileName
522 print 'FullPath =', M
.Header
[Arch
].FullPath
523 print 'BaseName =', M
.Header
[Arch
].Name
524 print 'Guid =', M
.Header
[Arch
].Guid
525 print 'Version =', M
.Header
[Arch
].Version
526 print 'DecSpecification =', M
.Header
[Arch
].DecSpecification
527 print '\nIncludes =', M
.Includes
528 for Item
in M
.Includes
:
529 print Item
.FilePath
, Item
.SupArchList
530 print '\nGuids =', M
.GuidDeclarations
531 for Item
in M
.GuidDeclarations
:
532 print Item
.CName
, Item
.Guid
, Item
.SupArchList
533 print '\nProtocols =', M
.ProtocolDeclarations
534 for Item
in M
.ProtocolDeclarations
:
535 print Item
.CName
, Item
.Guid
, Item
.SupArchList
536 print '\nPpis =', M
.PpiDeclarations
537 for Item
in M
.PpiDeclarations
:
538 print Item
.CName
, Item
.Guid
, Item
.SupArchList
539 print '\nLibraryClasses =', M
.LibraryClassDeclarations
540 for Item
in M
.LibraryClassDeclarations
:
541 print Item
.LibraryClass
, Item
.RecommendedInstance
, Item
.SupModuleList
, Item
.SupArchList
542 print '\nPcds =', M
.PcdDeclarations
543 for Item
in M
.PcdDeclarations
:
544 print 'CName=', Item
.CName
, 'TokenSpaceGuidCName=', Item
.TokenSpaceGuidCName
, 'DefaultValue=', Item
.DefaultValue
, 'ItemType=', Item
.ItemType
, 'Token=', Item
.Token
, 'DatumType=', Item
.DatumType
, Item
.SupArchList
548 # This acts like the main() function for the script, unless it is 'import'ed into another
551 if __name__
== '__main__':
552 EdkLogger
.Initialize()
553 EdkLogger
.SetLevel(EdkLogger
.DEBUG_0
)
555 W
= os
.getenv('WORKSPACE')
556 F
= os
.path
.join(W
, 'Nt32Pkg/Nt32Pkg.dec')
558 Db
= Database
.Database('Dec.db')
561 P
= Dec(os
.path
.normpath(F
), True, True, W
, Db
)