## @file # This file is used to define each component of DEC file # # Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
# This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License # which accompanies this distribution. The full text of the license may be found at # http://opensource.org/licenses/bsd-license.php # # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. # ## # Import Modules # import Common.LongFilePathOs as os from String import * from DataType import * from Identification import * from Dictionary import * from CommonDataClass.PackageClass import * from CommonDataClass.CommonClass import PcdClass from BuildToolError import * from Table.TableDec import TableDec import Database from Parsing import * import GlobalData from Common.LongFilePathSupport import OpenLongFilePath as open # # Global variable # Section = {TAB_UNKNOWN.upper() : MODEL_UNKNOWN, TAB_DEC_DEFINES.upper() : MODEL_META_DATA_HEADER, TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE, TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS, TAB_COMPONENTS.upper() : MODEL_META_DATA_COMPONENT, TAB_GUIDS.upper() : MODEL_EFI_GUID, TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL, TAB_PPIS.upper() : MODEL_EFI_PPI, TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : MODEL_PCD_FIXED_AT_BUILD, TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : MODEL_PCD_PATCHABLE_IN_MODULE, TAB_PCDS_FEATURE_FLAG_NULL.upper() : MODEL_PCD_FEATURE_FLAG, TAB_PCDS_DYNAMIC_EX_NULL.upper() : MODEL_PCD_DYNAMIC_EX, TAB_PCDS_DYNAMIC_NULL.upper() : MODEL_PCD_DYNAMIC, TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION } ## DecObject # # This class defined basic Dec object which is used by inheriting # # @param object: Inherited from object class # class DecObject(object): def __init__(self): object.__init__() ## Dec # # This class defined the structure used in Dec object # # @param DecObject: Inherited from DecObject class # @param Filename: Input value for Filename of Dec file, default is None # @param IsMergeAllArches: Input value for IsMergeAllArches # True is to merge all arches # Fales is not to merge all arches # default is False # @param IsToPackage: Input value for IsToPackage # True is to transfer to PackageObject automatically # False is not to transfer to PackageObject automatically # default is False # @param WorkspaceDir: Input value for current workspace directory, default is None # # @var Identification: To store value for Identification, it is a structure as Identification # @var Defines: To store value for Defines, it is a structure as DecDefines # @var UserExtensions: To store value for UserExtensions # @var Package: To store value for Package, it is a structure as PackageClass # @var WorkspaceDir: To store value for WorkspaceDir # @var Contents: To store value for Contents, it is a structure as DecContents # @var KeyList: To store value for KeyList, a list for all Keys used in Dec # class Dec(DecObject): def __init__(self, Filename=None, IsToDatabase=False, IsToPackage=False, WorkspaceDir=None, Database=None, SupArchList=DataType.ARCH_LIST): self.Identification = Identification() self.Package = PackageClass() self.UserExtensions = '' self.WorkspaceDir = WorkspaceDir self.SupArchList = SupArchList self.IsToDatabase = IsToDatabase self.Cur = Database.Cur self.TblFile = Database.TblFile self.TblDec = Database.TblDec self.FileID = -1 self.KeyList = [ TAB_INCLUDES, TAB_GUIDS, TAB_PROTOCOLS, TAB_PPIS, TAB_LIBRARY_CLASSES, \ TAB_PCDS_FIXED_AT_BUILD_NULL, TAB_PCDS_PATCHABLE_IN_MODULE_NULL, TAB_PCDS_FEATURE_FLAG_NULL, \ TAB_PCDS_DYNAMIC_NULL, TAB_PCDS_DYNAMIC_EX_NULL, TAB_DEC_DEFINES ] # # Upper all KEYs to ignore case sensitive when parsing # self.KeyList = map(lambda c: c.upper(), self.KeyList) # # Init RecordSet # self.RecordSet = {} for Key in self.KeyList: self.RecordSet[Section[Key]] = [] # # Load Dec file if filename is not None # if Filename != None: self.LoadDecFile(Filename) # # Transfer to Package Object if IsToPackage is True # if IsToPackage: self.DecToPackage() ## Load Dec file # # Load the file if it exists # # @param Filename: Input value for filename of Dec file # def LoadDecFile(self, Filename): # # Insert a record for file # Filename = NormPath(Filename) self.Identification.FileFullPath = Filename (self.Identification.FileRelativePath, self.Identification.FileName) = os.path.split(Filename) self.FileID = self.TblFile.InsertFile(Filename, MODEL_FILE_DEC) # # Init DecTable # #self.TblDec.Table = "Dec%s" % self.FileID #self.TblDec.Create() # # Init common datas # IfDefList, SectionItemList, CurrentSection, ArchList, ThirdList, IncludeFiles = \ [], [], TAB_UNKNOWN, [], [], [] LineNo = 0 # # Parse file content # IsFindBlockComment = False ReservedLine = '' for Line in open(Filename, 'r'): LineNo = LineNo + 1 # # Remove comment block # if Line.find(TAB_COMMENT_EDK_START) > -1: ReservedLine = GetSplitList(Line, TAB_COMMENT_EDK_START, 1)[0] IsFindBlockComment = True if Line.find(TAB_COMMENT_EDK_END) > -1: Line = ReservedLine + GetSplitList(Line, TAB_COMMENT_EDK_END, 1)[1] ReservedLine = '' IsFindBlockComment = False if IsFindBlockComment: continue # # Remove comments at tail and remove spaces again # Line = CleanString(Line) if Line == '': continue # # Find a new section tab # First insert previous section items # And then parse the content of the new section # if Line.startswith(TAB_SECTION_START) and Line.endswith(TAB_SECTION_END): # # Insert items data of previous section # Model = Section[CurrentSection.upper()] InsertSectionItemsIntoDatabase(self.TblDec, self.FileID, Filename, Model, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList, self.RecordSet) # # Parse the new section # SectionItemList = [] ArchList = [] ThirdList = [] CurrentSection = '' LineList = GetSplitValueList(Line[len(TAB_SECTION_START):len(Line) - len(TAB_SECTION_END)], TAB_COMMA_SPLIT) for Item in LineList: ItemList = GetSplitValueList(Item, TAB_SPLIT) if CurrentSection == '': CurrentSection = ItemList[0] else: if CurrentSection != ItemList[0]: 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) if CurrentSection.upper() not in self.KeyList: RaiseParserError(Line, CurrentSection, Filename, '', LineNo) ItemList.append('') ItemList.append('') if len(ItemList) > 5: RaiseParserError(Line, CurrentSection, Filename, '', LineNo) else: if ItemList[1] != '' and ItemList[1].upper() not in ARCH_LIST_FULL: EdkLogger.error("Parser", PARSER_ERROR, "Invalid Arch definition '%s' found" % ItemList[1], File=Filename, Line=LineNo, RaiseError=EdkLogger.IsRaiseError) ArchList.append(ItemList[1].upper()) ThirdList.append(ItemList[2]) continue # # Not in any defined section # if CurrentSection == TAB_UNKNOWN: ErrorMsg = "%s is not in any defined section" % Line EdkLogger.error("Parser", PARSER_ERROR, ErrorMsg, File=Filename, Line=LineNo, RaiseError=EdkLogger.IsRaiseError) # # Add a section item # SectionItemList.append([Line, LineNo]) # End of parse #End of For # # Insert items data of last section # Model = Section[CurrentSection.upper()] InsertSectionItemsIntoDatabase(self.TblDec, self.FileID, Filename, Model, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList, self.RecordSet) # # Replace all DEFINE macros with its actual values # ParseDefineMacro2(self.TblDec, self.RecordSet, GlobalData.gGlobalDefines) ## Transfer to Package Object # # Transfer all contents of a Dec file to a standard Package Object # def DecToPackage(self): # # Init global information for the file # ContainerFile = self.Identification.FileFullPath # # Generate Package Header # self.GenPackageHeader(ContainerFile) # # Generate Includes # self.GenIncludes(ContainerFile) # # Generate Guids # self.GenGuidProtocolPpis(DataType.TAB_GUIDS, ContainerFile) # # Generate Protocols # self.GenGuidProtocolPpis(DataType.TAB_PROTOCOLS, ContainerFile) # # Generate Ppis # self.GenGuidProtocolPpis(DataType.TAB_PPIS, ContainerFile) # # Generate LibraryClasses # self.GenLibraryClasses(ContainerFile) # # Generate Pcds # self.GenPcds(ContainerFile) ## Get Package Header # # Gen Package Header of Dec as = # # @param ContainerFile: The Dec file full path # def GenPackageHeader(self, ContainerFile): EdkLogger.debug(2, "Generate PackageHeader ...") # # Update all defines item in database # RecordSet = self.RecordSet[MODEL_META_DATA_HEADER] for Record in RecordSet: ValueList = GetSplitValueList(Record[0], TAB_EQUAL_SPLIT) if len(ValueList) != 2: RaiseParserError(Record[0], 'Defines', ContainerFile, ' = ', Record[2]) ID, Value1, Value2, Arch, LineNo = Record[3], ValueList[0], ValueList[1], Record[1], Record[2] SqlCommand = """update %s set Value1 = '%s', Value2 = '%s' where ID = %s""" % (self.TblDec.Table, ConvertToSqlString2(Value1), ConvertToSqlString2(Value2), ID) self.TblDec.Exec(SqlCommand) # # Get detailed information # for Arch in self.SupArchList: PackageHeader = PackageHeaderClass() PackageHeader.Name = QueryDefinesItem(self.TblDec, TAB_DEC_DEFINES_PACKAGE_NAME, Arch, self.FileID)[0] PackageHeader.Guid = QueryDefinesItem(self.TblDec, TAB_DEC_DEFINES_PACKAGE_GUID, Arch, self.FileID)[0] PackageHeader.Version = QueryDefinesItem(self.TblDec, TAB_DEC_DEFINES_PACKAGE_VERSION, Arch, self.FileID)[0] PackageHeader.FileName = self.Identification.FileName PackageHeader.FullPath = self.Identification.FileFullPath PackageHeader.DecSpecification = QueryDefinesItem(self.TblDec, TAB_DEC_DEFINES_DEC_SPECIFICATION, Arch, self.FileID)[0] self.Package.Header[Arch] = PackageHeader ## GenIncludes # # Gen Includes of Dec # # # @param ContainerFile: The Dec file full path # def GenIncludes(self, ContainerFile): EdkLogger.debug(2, "Generate %s ..." % TAB_INCLUDES) Includes = {} # # Get all Includes # RecordSet = self.RecordSet[MODEL_EFI_INCLUDE] # # Go through each arch # for Arch in self.SupArchList: for Record in RecordSet: if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: MergeArches(Includes, Record[0], Arch) for Key in Includes.keys(): Include = IncludeClass() Include.FilePath = NormPath(Key) Include.SupArchList = Includes[Key] self.Package.Includes.append(Include) ## GenPpis # # Gen Ppis of Dec # = # # @param ContainerFile: The Dec file full path # def GenGuidProtocolPpis(self, Type, ContainerFile): EdkLogger.debug(2, "Generate %s ..." % Type) Lists = {} # # Get all Items # RecordSet = self.RecordSet[Section[Type.upper()]] # # Go through each arch # for Arch in self.SupArchList: for Record in RecordSet: if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: (Name, Value) = GetGuidsProtocolsPpisOfDec(Record[0], Type, ContainerFile, Record[2]) MergeArches(Lists, (Name, Value), Arch) if self.IsToDatabase: SqlCommand = """update %s set Value1 = '%s', Value2 = '%s' where ID = %s""" % (self.TblDec.Table, ConvertToSqlString2(Name), ConvertToSqlString2(Value), Record[3]) self.TblDec.Exec(SqlCommand) ListMember = None if Type == TAB_GUIDS: ListMember = self.Package.GuidDeclarations elif Type == TAB_PROTOCOLS: ListMember = self.Package.ProtocolDeclarations elif Type == TAB_PPIS: ListMember = self.Package.PpiDeclarations for Key in Lists.keys(): ListClass = GuidProtocolPpiCommonClass() ListClass.CName = Key[0] ListClass.Guid = Key[1] ListClass.SupArchList = Lists[Key] ListMember.append(ListClass) ## GenLibraryClasses # # Gen LibraryClasses of Dec # = # # @param ContainerFile: The Dec file full path # def GenLibraryClasses(self, ContainerFile): EdkLogger.debug(2, "Generate %s ..." % TAB_LIBRARY_CLASSES) LibraryClasses = {} # # Get all Guids # RecordSet = self.RecordSet[MODEL_EFI_LIBRARY_CLASS] # # Go through each arch # for Arch in self.SupArchList: for Record in RecordSet: if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: List = GetSplitValueList(Record[0], DataType.TAB_VALUE_SPLIT) if len(List) != 2: RaiseParserError(Record[0], 'LibraryClasses', ContainerFile, '|', Record[2]) else: CheckFileExist(self.Identification.FileRelativePath, List[1], ContainerFile, 'LibraryClasses', Record[0]) MergeArches(LibraryClasses, (List[0], List[1]), Arch) if self.IsToDatabase: SqlCommand = """update %s set Value1 = '%s', Value2 = '%s', Value3 = '%s' where ID = %s""" % (self.TblDec.Table, ConvertToSqlString2(List[0]), ConvertToSqlString2(List[1]), SUP_MODULE_LIST_STRING, Record[3]) self.TblDec.Exec(SqlCommand) for Key in LibraryClasses.keys(): LibraryClass = LibraryClassClass() LibraryClass.LibraryClass = Key[0] LibraryClass.RecommendedInstance = NormPath(Key[1]) LibraryClass.SupModuleList = SUP_MODULE_LIST LibraryClass.SupArchList = LibraryClasses[Key] self.Package.LibraryClassDeclarations.append(LibraryClass) ## GenPcds # # Gen Pcds of Dec # .||| # # @param ContainerFile: The Dec file full path # def GenPcds(self, ContainerFile): EdkLogger.debug(2, "Generate %s ..." % TAB_PCDS) Pcds = {} PcdToken = {} # # Get all Guids # RecordSet1 = self.RecordSet[MODEL_PCD_FIXED_AT_BUILD] RecordSet2 = self.RecordSet[MODEL_PCD_PATCHABLE_IN_MODULE] RecordSet3 = self.RecordSet[MODEL_PCD_FEATURE_FLAG] RecordSet4 = self.RecordSet[MODEL_PCD_DYNAMIC_EX] RecordSet5 = self.RecordSet[MODEL_PCD_DYNAMIC] # # Go through each arch # for Arch in self.SupArchList: for Record in RecordSet1: if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: (TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_FIXED_AT_BUILD, ContainerFile, Record[2]) MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch) PcdToken[Record[3]] = (TokenGuidCName, TokenName) for Record in RecordSet2: if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: (TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_PATCHABLE_IN_MODULE, ContainerFile, Record[2]) MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch) PcdToken[Record[3]] = (TokenGuidCName, TokenName) for Record in RecordSet3: if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: (TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_FEATURE_FLAG, ContainerFile, Record[2]) MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch) PcdToken[Record[3]] = (TokenGuidCName, TokenName) for Record in RecordSet4: if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: (TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_DYNAMIC_EX, ContainerFile, Record[2]) MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch) PcdToken[Record[3]] = (TokenGuidCName, TokenName) for Record in RecordSet5: if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: (TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_DYNAMIC, ContainerFile, Record[2]) MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch) PcdToken[Record[3]] = (TokenGuidCName, TokenName) # # Update to database # if self.IsToDatabase: for Key in PcdToken.keys(): SqlCommand = """update %s set Value2 = '%s' where ID = %s""" % (self.TblDec.Table, ".".join((PcdToken[Key][0], PcdToken[Key][1])), Key) self.TblDec.Exec(SqlCommand) for Key in Pcds.keys(): Pcd = PcdClass() Pcd.CName = Key[1] Pcd.Token = Key[4] Pcd.TokenSpaceGuidCName = Key[0] Pcd.DatumType = Key[3] Pcd.DefaultValue = Key[2] Pcd.ItemType = Key[5] Pcd.SupArchList = Pcds[Key] self.Package.PcdDeclarations.append(Pcd) ## Show detailed information of Package # # Print all members and their values of Package class # def ShowPackage(self): M = self.Package for Arch in M.Header.keys(): print '\nArch =', Arch print 'Filename =', M.Header[Arch].FileName print 'FullPath =', M.Header[Arch].FullPath print 'BaseName =', M.Header[Arch].Name print 'Guid =', M.Header[Arch].Guid print 'Version =', M.Header[Arch].Version print 'DecSpecification =', M.Header[Arch].DecSpecification print '\nIncludes =', M.Includes for Item in M.Includes: print Item.FilePath, Item.SupArchList print '\nGuids =', M.GuidDeclarations for Item in M.GuidDeclarations: print Item.CName, Item.Guid, Item.SupArchList print '\nProtocols =', M.ProtocolDeclarations for Item in M.ProtocolDeclarations: print Item.CName, Item.Guid, Item.SupArchList print '\nPpis =', M.PpiDeclarations for Item in M.PpiDeclarations: print Item.CName, Item.Guid, Item.SupArchList print '\nLibraryClasses =', M.LibraryClassDeclarations for Item in M.LibraryClassDeclarations: print Item.LibraryClass, Item.RecommendedInstance, Item.SupModuleList, Item.SupArchList print '\nPcds =', M.PcdDeclarations for Item in M.PcdDeclarations: print 'CName=', Item.CName, 'TokenSpaceGuidCName=', Item.TokenSpaceGuidCName, 'DefaultValue=', Item.DefaultValue, 'ItemType=', Item.ItemType, 'Token=', Item.Token, 'DatumType=', Item.DatumType, Item.SupArchList ## # # This acts like the main() function for the script, unless it is 'import'ed into another # script. # if __name__ == '__main__': EdkLogger.Initialize() EdkLogger.SetLevel(EdkLogger.DEBUG_0) W = os.getenv('WORKSPACE') F = os.path.join(W, 'Nt32Pkg/Nt32Pkg.dec') Db = Database.Database('Dec.db') Db.InitDatabase() P = Dec(os.path.normpath(F), True, True, W, Db) P.ShowPackage() Db.Close()